From 7ea7af3ab81b8605e5df91d2d30eafb97151d1c6 Mon Sep 17 00:00:00 2001 From: Louis Adrien Dufrene Date: Fri, 24 Aug 2018 08:56:06 +0200 Subject: [PATCH 001/233] initial commit --- .gitignore | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000000..3e530027e0 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +cmake_targets/log/ +cmake_targets/lte_build_oai/ +targets/bin/ From a8f6accc9a4bb8dac375ce894b3083b04ba2fccc Mon Sep 17 00:00:00 2001 From: Louis Adrien Dufrene Date: Mon, 27 Aug 2018 14:41:29 +0200 Subject: [PATCH 002/233] rm .gitignore for repo consistancy --- .gitignore | 3 --- 1 file changed, 3 deletions(-) delete mode 100644 .gitignore diff --git a/.gitignore b/.gitignore deleted file mode 100644 index 3e530027e0..0000000000 --- a/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -cmake_targets/log/ -cmake_targets/lte_build_oai/ -targets/bin/ From c12e3234b035b8960374c0b6d25397181f3b815e Mon Sep 17 00:00:00 2001 From: Louis Adrien Dufrene Date: Tue, 28 Aug 2018 14:03:37 +0200 Subject: [PATCH 003/233] modification of tracer/gui/x.c for T tracer to work on screen --- common/utils/T/tracer/gui/x.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/utils/T/tracer/gui/x.c b/common/utils/T/tracer/gui/x.c index 94448eb666..9c7456b5cd 100644 --- a/common/utils/T/tracer/gui/x.c +++ b/common/utils/T/tracer/gui/x.c @@ -141,7 +141,7 @@ x_image *x_create_image(x_connection *_x, unsigned char *data, ret = calloc(1, sizeof(struct x_image)); if (ret == NULL) OOM; template.class = TrueColor; - template.depth = 24; + template.depth = 32; template.red_mask = 0xff0000; template.green_mask = 0x00ff00; template.blue_mask = 0x0000ff; From ec702c88f38fb716f251f0fc1bafa6706b791cd2 Mon Sep 17 00:00:00 2001 From: Louis Adrien Dufrene Date: Wed, 29 Aug 2018 14:27:09 +0200 Subject: [PATCH 004/233] Commentaries modifications --- openair2/RRC/LTE/MESSAGES/asn1_msg.c | 48 +++++++++---------- openair2/RRC/LTE/MESSAGES/asn1_msg.h | 2 +- .../asn1c/ASN1_files/lte-rrc-13.9.1.asn1 | 2 +- 3 files changed, 26 insertions(+), 26 deletions(-) diff --git a/openair2/RRC/LTE/MESSAGES/asn1_msg.c b/openair2/RRC/LTE/MESSAGES/asn1_msg.c index 66aae4237a..41e72d59c1 100644 --- a/openair2/RRC/LTE/MESSAGES/asn1_msg.c +++ b/openair2/RRC/LTE/MESSAGES/asn1_msg.c @@ -183,45 +183,45 @@ uint8_t do_MIB(rrc_eNB_carrier_data_t *carrier, uint32_t N_RB_DL, uint32_t phich { asn_enc_rval_t enc_rval; - BCCH_BCH_Message_t *mib=&carrier->mib ; + BCCH_BCH_Message_t *mib = &carrier->mib ; uint8_t sfn = (uint8_t)((frame>>2)&0xff); - uint16_t *spare= calloc(1, sizeof(uint16_t)); + uint16_t *spare = calloc(1, sizeof(uint16_t)); if (spare == NULL) abort(); switch (N_RB_DL) { + + case 6: + mib->message.dl_Bandwidth = MasterInformationBlock__dl_Bandwidth_n6; + break; - case 6: - mib->message.dl_Bandwidth = MasterInformationBlock__dl_Bandwidth_n6; - break; + case 15: + mib->message.dl_Bandwidth = MasterInformationBlock__dl_Bandwidth_n15; + break; - case 15: - mib->message.dl_Bandwidth = MasterInformationBlock__dl_Bandwidth_n15; - break; + case 25: + mib->message.dl_Bandwidth = MasterInformationBlock__dl_Bandwidth_n25; + break; - case 25: - mib->message.dl_Bandwidth = MasterInformationBlock__dl_Bandwidth_n25; - break; + case 50: + mib->message.dl_Bandwidth = MasterInformationBlock__dl_Bandwidth_n50; + break; - case 50: - mib->message.dl_Bandwidth = MasterInformationBlock__dl_Bandwidth_n50; - break; + case 75: + mib->message.dl_Bandwidth = MasterInformationBlock__dl_Bandwidth_n75; + break; - case 75: - mib->message.dl_Bandwidth = MasterInformationBlock__dl_Bandwidth_n75; - break; - - case 100: - mib->message.dl_Bandwidth = MasterInformationBlock__dl_Bandwidth_n100; - break; - default: - AssertFatal(1==0,"Unknown dl_Bandwidth %d\n",N_RB_DL); + case 100: + mib->message.dl_Bandwidth = MasterInformationBlock__dl_Bandwidth_n100; + break; + default: + AssertFatal(1==0,"Unknown dl_Bandwidth %d\n",N_RB_DL); } AssertFatal(phich_Resource <= PHICH_Config__phich_Resource_two,"Illegal phich_Resource\n"); mib->message.phich_Config.phich_Resource = phich_Resource; AssertFatal(phich_duration <= PHICH_Config__phich_Duration_extended,"Illegal phich_Duration\n"); mib->message.phich_Config.phich_Duration = phich_duration; - LOG_I(RRC,"[MIB] systemBandwidth %x, phich_duration %x, phich_resource %x,sfn %x\n", + LOG_I(RRC,"[MIB] systemBandwidth %x, phich_duration %x, phich_resource %x, sfn %x\n", (uint32_t)mib->message.dl_Bandwidth, (uint32_t)phich_duration, (uint32_t)phich_Resource, diff --git a/openair2/RRC/LTE/MESSAGES/asn1_msg.h b/openair2/RRC/LTE/MESSAGES/asn1_msg.h index a4da38c019..db24521cd5 100644 --- a/openair2/RRC/LTE/MESSAGES/asn1_msg.h +++ b/openair2/RRC/LTE/MESSAGES/asn1_msg.h @@ -57,7 +57,7 @@ uint16_t get_adjacent_cell_id(uint8_t Mod_id,uint8_t index); uint8_t get_adjacent_cell_mod_id(uint16_t phyCellId); /** -\brief Generate configuration for SIB1 (eNB). +\brief Generate configuration for MIB (eNB). @param carrier pointer to Carrier information @param N_RB_DL Number of downlink PRBs @param phich_Resource PHICH resoure parameter diff --git a/openair2/RRC/LTE/MESSAGES/asn1c/ASN1_files/lte-rrc-13.9.1.asn1 b/openair2/RRC/LTE/MESSAGES/asn1c/ASN1_files/lte-rrc-13.9.1.asn1 index b6f64a99ed..ceb4a7cd37 100755 --- a/openair2/RRC/LTE/MESSAGES/asn1c/ASN1_files/lte-rrc-13.9.1.asn1 +++ b/openair2/RRC/LTE/MESSAGES/asn1c/ASN1_files/lte-rrc-13.9.1.asn1 @@ -735,7 +735,7 @@ Paging-v1130-IEs ::= SEQUENCE { } Paging-v1310-IEs ::= SEQUENCE { - redistributionIndication-r13 ENUMERATED {true} OPTIONAL, --Need ON + redistributionIndication-r13 ENUMERATED {true} OPTIONAL, -- Need ON systemInfoModification-eDRX-r13 ENUMERATED {true} OPTIONAL, -- Need ON nonCriticalExtension SEQUENCE {} OPTIONAL } From 80920618e6e62b8ce6c1fb4009114ead7095a489 Mon Sep 17 00:00:00 2001 From: Louis Adrien Dufrene Date: Fri, 31 Aug 2018 14:14:28 +0200 Subject: [PATCH 005/233] Code guidelines --- openair2/RRC/LTE/MESSAGES/asn1_msg.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/openair2/RRC/LTE/MESSAGES/asn1_msg.c b/openair2/RRC/LTE/MESSAGES/asn1_msg.c index 41e72d59c1..373a3efa48 100644 --- a/openair2/RRC/LTE/MESSAGES/asn1_msg.c +++ b/openair2/RRC/LTE/MESSAGES/asn1_msg.c @@ -183,13 +183,13 @@ uint8_t do_MIB(rrc_eNB_carrier_data_t *carrier, uint32_t N_RB_DL, uint32_t phich { asn_enc_rval_t enc_rval; - BCCH_BCH_Message_t *mib = &carrier->mib ; + BCCH_BCH_Message_t *mib = &carrier->mib; uint8_t sfn = (uint8_t)((frame>>2)&0xff); uint16_t *spare = calloc(1, sizeof(uint16_t)); if (spare == NULL) abort(); switch (N_RB_DL) { - + case 6: mib->message.dl_Bandwidth = MasterInformationBlock__dl_Bandwidth_n6; break; @@ -698,6 +698,9 @@ uint8_t do_SIB23(uint8_t Mod_id, = configuration->pcch_defaultPagingCycle[CC_id]; (*sib2)->radioResourceConfigCommon.pcch_Config.nB = configuration->pcch_nB[CC_id]; + LOG_E(RRC,"[SIB2] With ITTI. Basic config of paging cycle DRX: radio frame cycle length %x, paging occasion number %x\n", + (uint32_t)configuration->pcch_defaultPagingCycle[CC_id], + (uint32_t)configuration->pcch_nB[CC_id]); // PRACH-Config (*sib2)->radioResourceConfigCommon.prach_Config.rootSequenceIndex From 753a664c0654711574be4d50124f5dd48d71efb5 Mon Sep 17 00:00:00 2001 From: Rajeev Gangula Date: Tue, 25 Sep 2018 15:07:22 +0200 Subject: [PATCH 006/233] Corrected PHR calculation. --- openair2/LAYER2/MAC/eNB_scheduler_ulsch.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c b/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c index 31c11e2c0a..0ae1b8255e 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c @@ -298,7 +298,10 @@ rx_sdu(const module_id_t enb_mod_idP, case POWER_HEADROOM: if (UE_id != -1) { UE_list->UE_template[CC_idP][UE_id].phr_info = - (payload_ptr[0] & 0x3f) - PHR_MAPPING_OFFSET; + (payload_ptr[0] & 0x3f) - PHR_MAPPING_OFFSET + (int8_t)(hundred_times_log10_NPRB[UE_list->UE_template[CC_idP][UE_id].nb_rb_ul[harq_pid]-1]/100); + if(UE_list->UE_template[CC_idP][UE_id].phr_info > 40) + UE_list->UE_template[CC_idP][UE_id].phr_info = 40; + LOG_D(MAC, "[eNB %d] CC_id %d MAC CE_LCID %d : Received PHR PH = %d (db)\n", enb_mod_idP, CC_idP, rx_ces[i], From 72406041156f770d0f56eb53844aaaed24097b46 Mon Sep 17 00:00:00 2001 From: Florian Kaltenberger Date: Thu, 11 Oct 2018 06:05:59 -0700 Subject: [PATCH 007/233] changing default uhd version when installing from source this is the one that also works with the n310 --- cmake_targets/tools/build_helper | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake_targets/tools/build_helper b/cmake_targets/tools/build_helper index 3363bd2e76..2318cd7790 100755 --- a/cmake_targets/tools/build_helper +++ b/cmake_targets/tools/build_helper @@ -252,7 +252,7 @@ install_usrp_uhd_driver_from_source(){ rm -rf /tmp/uhd git clone https://github.com/EttusResearch/uhd.git cd uhd - git checkout tags/release_003_010_001_001 + git checkout tags/v3.13.0.2 mkdir -p host/build cd host/build $CMAKE ../ From bd1c609ca89b551ee0805525fd085b75c459be21 Mon Sep 17 00:00:00 2001 From: laurent Date: Fri, 12 Oct 2018 18:17:57 +0200 Subject: [PATCH 008/233] issue 359 dlsim CPU measurements --- cmake_targets/lte-simulators/CMakeLists.txt | 1 + openair1/PHY/defs_UE.h | 1 + openair1/PHY/defs_eNB.h | 2 +- openair1/SCHED/phy_procedures_lte_eNb.c | 2 + openair1/SCHED_UE/phy_procedures_lte_ue.c | 54 +- openair1/SIMULATION/LTE_PHY/common_sim.h | 164 +++++ openair1/SIMULATION/LTE_PHY/dlsim.c | 779 +++++++------------- openair1/SIMULATION/LTE_PHY/ulsim.c | 348 +++------ 8 files changed, 604 insertions(+), 747 deletions(-) create mode 100644 openair1/SIMULATION/LTE_PHY/common_sim.h diff --git a/cmake_targets/lte-simulators/CMakeLists.txt b/cmake_targets/lte-simulators/CMakeLists.txt index b7e83a92a0..1bfac2b20d 100644 --- a/cmake_targets/lte-simulators/CMakeLists.txt +++ b/cmake_targets/lte-simulators/CMakeLists.txt @@ -9,4 +9,5 @@ set(MU_RECIEVER False) set(NAS_UE False) set(MESSAGE_CHART_GENERATOR False) set(RRC_ASN1_VERSION "Rel14") +set (UE_TIMING_TRACE True) include(${CMAKE_CURRENT_SOURCE_DIR}/../CMakeLists.txt) diff --git a/openair1/PHY/defs_UE.h b/openair1/PHY/defs_UE.h index 55f8c9639a..a303902b07 100644 --- a/openair1/PHY/defs_UE.h +++ b/openair1/PHY/defs_UE.h @@ -847,6 +847,7 @@ typedef struct { time_stats_t pdsch_procedures_stat[RX_NB_TH]; time_stats_t pdsch_procedures_per_slot_stat[RX_NB_TH][LTE_SLOTS_PER_SUBFRAME]; time_stats_t dlsch_procedures_stat[RX_NB_TH]; + time_stats_t crnti_procedures_stats; time_stats_t ofdm_demod_stats; time_stats_t dlsch_rx_pdcch_stats; diff --git a/openair1/PHY/defs_eNB.h b/openair1/PHY/defs_eNB.h index f23485cad8..e62c4d766f 100644 --- a/openair1/PHY/defs_eNB.h +++ b/openair1/PHY/defs_eNB.h @@ -1074,12 +1074,12 @@ typedef struct PHY_VARS_eNB_s { int hw_timing_advance; - time_stats_t phy_proc; time_stats_t phy_proc_tx; time_stats_t phy_proc_rx; time_stats_t rx_prach; time_stats_t ofdm_mod_stats; + time_stats_t dlsch_common_and_dci; time_stats_t dlsch_encoding_stats; time_stats_t dlsch_modulation_stats; time_stats_t dlsch_scrambling_stats; diff --git a/openair1/SCHED/phy_procedures_lte_eNb.c b/openair1/SCHED/phy_procedures_lte_eNb.c index 276006ec3b..f5d5334850 100644 --- a/openair1/SCHED/phy_procedures_lte_eNb.c +++ b/openair1/SCHED/phy_procedures_lte_eNb.c @@ -484,6 +484,7 @@ void phy_procedures_eNB_TX(PHY_VARS_eNB *eNB, VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_ENB_TX+(eNB->CC_id),1); if (do_meas==1) start_meas(&eNB->phy_proc_tx); + if (do_meas==1) start_meas(&eNB->dlsch_common_and_dci); // clear the transmit data array for the current subframe for (aa=0; aanb_antenna_ports_eNB; aa++) { @@ -578,6 +579,7 @@ void phy_procedures_eNB_TX(PHY_VARS_eNB *eNB, subframe); } + if (do_meas==1) stop_meas(&eNB->dlsch_common_and_dci); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_ENB_PDCCH_TX,0); diff --git a/openair1/SCHED_UE/phy_procedures_lte_ue.c b/openair1/SCHED_UE/phy_procedures_lte_ue.c index b7d05ba006..3b4d60230c 100644 --- a/openair1/SCHED_UE/phy_procedures_lte_ue.c +++ b/openair1/SCHED_UE/phy_procedures_lte_ue.c @@ -1715,7 +1715,7 @@ void ue_ulsch_uespec_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB if ( LOG_DEBUGFLAG(UE_TIMING)) { stop_meas(&ue->phy_proc_tx); - LOG_UI(PHY,"------FULL TX PROC : %5.2f ------\n",ue->phy_proc_tx.p_time/(cpuf*1000.0)); + LOG_I(PHY,"------FULL TX PROC : %5.2f ------\n",ue->phy_proc_tx.p_time/(cpuf*1000.0)); stop_meas(&ue->ulsch_encoding_stats); } @@ -3369,7 +3369,7 @@ void ue_pdsch_procedures(PHY_VARS_UE *ue, UE_rxtx_proc_t *proc, int eNB_id, PDSC if(m >= ue->frame_parms.symbols_per_tti>>1) slot = 1; stop_meas(&ue->dlsch_llr_stats_parallelization[ue->current_thread_id[subframe_rx]][slot]); - LOG_UI(PHY, "[AbsSFN %d.%d] LLR Computation Symbol %d %5.2f \n",proc->frame_rx,subframe_rx,m,ue->dlsch_llr_stats_parallelization[ue->current_thread_id[subframe_rx]][slot].p_time/(cpuf*1000.0)); + LOG_I(PHY, "[AbsSFN %d.%d] LLR Computation Symbol %d %5.2f \n",proc->frame_rx,subframe_rx,m,ue->dlsch_llr_stats_parallelization[ue->current_thread_id[subframe_rx]][slot].p_time/(cpuf*1000.0)); } @@ -3604,9 +3604,9 @@ void ue_dlsch_procedures(PHY_VARS_UE *ue, if (LOG_DEBUGFLAG(UE_TIMING)) { stop_meas(&ue->dlsch_decoding_stats[ue->current_thread_id[subframe_rx]]); - LOG_UI(PHY, " --> Unscrambling for CW0 %5.3f\n", + LOG_I(PHY, " --> Unscrambling for CW0 %5.3f\n", (ue->dlsch_unscrambling_stats.p_time)/(cpuf*1000.0)); - LOG_UI(PHY, "AbsSubframe %d.%d --> Turbo Decoding for CW0 %5.3f\n", + LOG_I(PHY, "AbsSubframe %d.%d --> Turbo Decoding for CW0 %5.3f\n", frame_rx%1024, subframe_rx,(ue->dlsch_decoding_stats[ue->current_thread_id[subframe_rx]].p_time)/(cpuf*1000.0)); } @@ -3661,9 +3661,9 @@ void ue_dlsch_procedures(PHY_VARS_UE *ue, if (LOG_DEBUGFLAG(UE_TIMING)) { stop_meas(&ue->dlsch_decoding_stats[ue->current_thread_id[subframe_rx]]); - LOG_UI(PHY, " --> Unscrambling for CW1 %5.3f\n", + LOG_I(PHY, " --> Unscrambling for CW1 %5.3f\n", (ue->dlsch_unscrambling_stats.p_time)/(cpuf*1000.0)); - LOG_UI(PHY, "AbsSubframe %d.%d --> Turbo Decoding for CW1 %5.3f\n", + LOG_I(PHY, "AbsSubframe %d.%d --> Turbo Decoding for CW1 %5.3f\n", frame_rx%1024, subframe_rx,(ue->dlsch_decoding_stats[ue->current_thread_id[subframe_rx]].p_time)/(cpuf*1000.0)); } @@ -4005,7 +4005,7 @@ void *UE_thread_slot1_dl_processing(void *arg) { if ( LOG_DEBUGFLAG(UE_TIMING)) { stop_meas(&ue->ue_front_end_per_slot_stat[ue->current_thread_id[subframe_rx]][1]); - LOG_UI(PHY, "[AbsSFN %d.%d] Slot1: FFT + Channel Estimate + Pdsch Proc Slot0 %5.2f \n",frame_rx,subframe_rx,ue->ue_front_end_per_slot_stat[ue->current_thread_id[subframe_rx]][1].p_time/(cpuf*1000.0)); + LOG_I(PHY, "[AbsSFN %d.%d] Slot1: FFT + Channel Estimate + Pdsch Proc Slot0 %5.2f \n",frame_rx,subframe_rx,ue->ue_front_end_per_slot_stat[ue->current_thread_id[subframe_rx]][1].p_time/(cpuf*1000.0)); } @@ -4099,7 +4099,7 @@ void *UE_thread_slot1_dl_processing(void *arg) { if ( LOG_DEBUGFLAG(UE_TIMING)) { stop_meas(&ue->pdsch_procedures_per_slot_stat[ue->current_thread_id[subframe_rx]][1]); - LOG_UI(PHY, "[AbsSFN %d.%d] Slot1: LLR Computation %5.2f \n",frame_rx,subframe_rx,ue->pdsch_procedures_per_slot_stat[ue->current_thread_id[subframe_rx]][1].p_time/(cpuf*1000.0)); + LOG_I(PHY, "[AbsSFN %d.%d] Slot1: LLR Computation %5.2f \n",frame_rx,subframe_rx,ue->pdsch_procedures_per_slot_stat[ue->current_thread_id[subframe_rx]][1].p_time/(cpuf*1000.0)); } @@ -4319,7 +4319,7 @@ int phy_procedures_slot_parallelization_UE_RX(PHY_VARS_UE *ue,UE_rxtx_proc_t *pr if (ue_pdcch_procedures(eNB_id,ue,proc,abstraction_flag) == -1) { LOG_E(PHY,"[UE %d] Frame %d, subframe %d: Error in pdcch procedures\n",ue->Mod_id,frame_rx,subframe_rx); if (LOG_DEBUGFLAG(UE_TIMING)) { - LOG_UI(PHY, "[AbsSFN %d.%d] Slot0: PDCCH %5.2f \n",frame_rx,subframe_rx,ue->pdcch_procedures_stat[ue->current_thread_id[subframe_rx]].p_time/(cpuf*1000.0)); + LOG_I(PHY, "[AbsSFN %d.%d] Slot0: PDCCH %5.2f \n",frame_rx,subframe_rx,ue->pdcch_procedures_stat[ue->current_thread_id[subframe_rx]].p_time/(cpuf*1000.0)); } //proc->dci_slot0_available = 1; @@ -4328,7 +4328,7 @@ int phy_procedures_slot_parallelization_UE_RX(PHY_VARS_UE *ue,UE_rxtx_proc_t *pr //proc->dci_slot0_available=1; if (LOG_DEBUGFLAG(UE_TIMING)) { stop_meas(&ue->pdcch_procedures_stat[ue->current_thread_id[subframe_rx]]); - LOG_UI(PHY, "[AbsSFN %d.%d] Slot0: PDCCH %5.2f \n",frame_rx,subframe_rx,ue->pdcch_procedures_stat[ue->current_thread_id[subframe_rx]].p_time/(cpuf*1000.0)); + LOG_I(PHY, "[AbsSFN %d.%d] Slot0: PDCCH %5.2f \n",frame_rx,subframe_rx,ue->pdcch_procedures_stat[ue->current_thread_id[subframe_rx]].p_time/(cpuf*1000.0)); } } @@ -4337,7 +4337,7 @@ int phy_procedures_slot_parallelization_UE_RX(PHY_VARS_UE *ue,UE_rxtx_proc_t *pr // first slot has been processed (FFTs + Channel Estimation, PCFICH/PHICH/PDCCH) if (LOG_DEBUGFLAG(UE_TIMING)) { stop_meas(&ue->ue_front_end_per_slot_stat[ue->current_thread_id[subframe_rx]][0]); - LOG_UI(PHY, "[AbsSFN %d.%d] Slot0: FFT + Channel Estimate + PCFICH/PHICH/PDCCH %5.2f \n",frame_rx,subframe_rx,ue->ue_front_end_per_slot_stat[ue->current_thread_id[subframe_rx]][0].p_time/(cpuf*1000.0)); + LOG_I(PHY, "[AbsSFN %d.%d] Slot0: FFT + Channel Estimate + PCFICH/PHICH/PDCCH %5.2f \n",frame_rx,subframe_rx,ue->ue_front_end_per_slot_stat[ue->current_thread_id[subframe_rx]][0].p_time/(cpuf*1000.0)); } //wait until slot1 FE is done @@ -4350,7 +4350,7 @@ int phy_procedures_slot_parallelization_UE_RX(PHY_VARS_UE *ue,UE_rxtx_proc_t *pr if (LOG_DEBUGFLAG(UE_TIMING)) { stop_meas(&ue->ue_front_end_stat[ue->current_thread_id[subframe_rx]]); - LOG_UI(PHY, "[AbsSFN %d.%d] FULL FE Processing %5.2f \n",frame_rx,subframe_rx,ue->ue_front_end_per_slot_stat[ue->current_thread_id[subframe_rx]][0].p_time/(cpuf*1000.0)); + LOG_I(PHY, "[AbsSFN %d.%d] FULL FE Processing %5.2f \n",frame_rx,subframe_rx,ue->ue_front_end_per_slot_stat[ue->current_thread_id[subframe_rx]][0].p_time/(cpuf*1000.0)); } /**** End Subframe FE Processing ****/ @@ -4439,7 +4439,7 @@ int phy_procedures_slot_parallelization_UE_RX(PHY_VARS_UE *ue,UE_rxtx_proc_t *pr if (LOG_DEBUGFLAG(UE_TIMING)){ stop_meas(&ue->pdsch_procedures_per_slot_stat[ue->current_thread_id[subframe_rx]][0]); - LOG_UI(PHY, "[AbsSFN %d.%d] Slot0: LLR Computation %5.2f \n",frame_rx,subframe_rx,ue->pdsch_procedures_per_slot_stat[ue->current_thread_id[subframe_rx]][0].p_time/(cpuf*1000.0)); + LOG_I(PHY, "[AbsSFN %d.%d] Slot0: LLR Computation %5.2f \n",frame_rx,subframe_rx,ue->pdsch_procedures_per_slot_stat[ue->current_thread_id[subframe_rx]][0].p_time/(cpuf*1000.0)); } @@ -4455,7 +4455,7 @@ int phy_procedures_slot_parallelization_UE_RX(PHY_VARS_UE *ue,UE_rxtx_proc_t *pr if (LOG_DEBUGFLAG(UE_TIMING)){ stop_meas(&ue->pdsch_procedures_stat[ue->current_thread_id[subframe_rx]]); - LOG_UI(PHY, "[AbsSFN %d.%d] Full LLR Computation %5.2f \n",frame_rx,subframe_rx,ue->pdsch_procedures_stat[ue->current_thread_id[subframe_rx]].p_time/(cpuf*1000.0)); + LOG_I(PHY, "[AbsSFN %d.%d] Full LLR Computation %5.2f \n",frame_rx,subframe_rx,ue->pdsch_procedures_stat[ue->current_thread_id[subframe_rx]].p_time/(cpuf*1000.0)); } @@ -4526,7 +4526,7 @@ int phy_procedures_slot_parallelization_UE_RX(PHY_VARS_UE *ue,UE_rxtx_proc_t *pr if (LOG_DEBUGFLAG(UE_TIMING) stop_meas(&ue->dlsch_procedures_stat[ue->current_thread_id[subframe_rx]]); - LOG_UI(PHY, "[AbsSFN %d.%d] Channel Decoder: %5.2f \n",frame_rx,subframe_rx,ue->dlsch_procedures_stat[ue->current_thread_id[subframe_rx]].p_time/(cpuf*1000.0)); + LOG_I(PHY, "[AbsSFN %d.%d] Channel Decoder: %5.2f \n",frame_rx,subframe_rx,ue->dlsch_procedures_stat[ue->current_thread_id[subframe_rx]].p_time/(cpuf*1000.0)); } // duplicate harq structure @@ -4589,7 +4589,7 @@ int phy_procedures_slot_parallelization_UE_RX(PHY_VARS_UE *ue,UE_rxtx_proc_t *pr if (LOG_DEBUGFLAG(UE_TIMING)){ stop_meas(&ue->phy_proc_rx[ue->current_thread_id[subframe_rx]]); - LOG_UI(PHY, "------FULL RX PROC [AbsSFN %d.%d]: %5.2f ------\n",frame_rx,subframe_rx,ue->phy_proc_rx[ue->current_thread_id[subframe_rx]].p_time/(cpuf*1000.0)); + LOG_I(PHY, "------FULL RX PROC [AbsSFN %d.%d]: %5.2f ------\n",frame_rx,subframe_rx,ue->phy_proc_rx[ue->current_thread_id[subframe_rx]].p_time/(cpuf*1000.0)); } LOG_D(PHY," ****** end RX-Chain for AbsSubframe %d.%d ****** \n", frame_rx%1024, subframe_rx); @@ -4632,7 +4632,7 @@ int phy_procedures_UE_RX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id, if(LOG_DEBUGFLAG(UE_TIMING)) { start_meas(&ue->phy_proc_rx[ue->current_thread_id[subframe_rx]]); - start_meas(&ue->generic_stat); + start_meas(&ue->ue_front_end_stat[ue->current_thread_id[subframe_rx]]); } pmch_flag = is_pmch_subframe(frame_rx,subframe_rx,&ue->frame_parms) ? 1 : 0; @@ -4757,15 +4757,17 @@ int phy_procedures_UE_RX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id, // first slot has been processed (FFTs + Channel Estimation, PCFICH/PHICH/PDCCH) if (LOG_DEBUGFLAG(UE_TIMING)) { - stop_meas(&ue->generic_stat); - LOG_UI(PHY, "[SFN %d] Slot0: FFT + Channel Estimate + PCFICH/PHICH/PDCCH %5.2f \n",subframe_rx,ue->generic_stat.p_time/(cpuf*1000.0)); + stop_meas(&ue->ue_front_end_stat[ue->current_thread_id[subframe_rx]]); + LOG_I(PHY, "[SFN %d] Slot0: FFT + Channel Estimate + PCFICH/PHICH/PDCCH %5.2f \n",subframe_rx,ue->ue_front_end_stat[ue->current_thread_id[subframe_rx]].p_time/(cpuf*1000.0)); } LOG_D(PHY," ------ --> PDSCH ChannelComp/LLR slot 0: AbsSubframe %d.%d ------ \n", frame_rx%1024, subframe_rx); if (LOG_DEBUGFLAG(UE_TIMING)) { start_meas(&ue->generic_stat); + start_meas(&ue->crnti_procedures_stats); } + // do procedures for C-RNTI if (ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0]->active == 1) { VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC, VCD_FUNCTION_IN); @@ -4782,12 +4784,14 @@ int phy_procedures_UE_RX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id, VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC, VCD_FUNCTION_OUT); } + if (LOG_DEBUGFLAG(UE_TIMING)) { + stop_meas(&ue->crnti_procedures_stats); + } LOG_D(PHY," ------ end PDSCH ChannelComp/LLR slot 0: AbsSubframe %d.%d ------ \n", frame_rx%1024, subframe_rx); // do procedures for SI-RNTI if ((ue->dlsch_SI[eNB_id]) && (ue->dlsch_SI[eNB_id]->active == 1)) { VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_SI, VCD_FUNCTION_IN); ue_pdsch_procedures(ue, - proc, eNB_id, SI_PDSCH, @@ -4870,7 +4874,7 @@ int phy_procedures_UE_RX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id, } // not an S-subframe if(LOG_DEBUGFLAG(UE_TIMING)) { stop_meas(&ue->generic_stat); - LOG_UI(PHY, "[SFN %d] Slot1: FFT + Channel Estimate + Pdsch Proc Slot0 %5.2f \n",subframe_rx,ue->generic_stat.p_time/(cpuf*1000.0)); + LOG_I(PHY, "[SFN %d] Slot1: FFT + Channel Estimate + Pdsch Proc Slot0 %5.2f \n",subframe_rx,ue->generic_stat.p_time/(cpuf*1000.0)); } LOG_D(PHY," ------ end FFT/ChannelEst/PDCCH slot 1: AbsSubframe %d.%d ------ \n", frame_rx%1024, subframe_rx); @@ -4915,8 +4919,8 @@ int phy_procedures_UE_RX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id, abstraction_flag); if (LOG_DEBUGFLAG(UE_TIMING)) { stop_meas(&ue->dlsch_procedures_stat[ue->current_thread_id[subframe_rx]]); - LOG_UI(PHY, "[SFN %d] Slot1: Pdsch Proc %5.2f\n",subframe_rx,ue->pdsch_procedures_stat[ue->current_thread_id[subframe_rx]].p_time/(cpuf*1000.0)); - LOG_UI(PHY, "[SFN %d] Slot0 Slot1: Dlsch Proc %5.2f\n",subframe_rx,ue->dlsch_procedures_stat[ue->current_thread_id[subframe_rx]].p_time/(cpuf*1000.0)); + LOG_I(PHY, "[SFN %d] Slot1: Pdsch Proc %5.2f\n",subframe_rx,ue->pdsch_procedures_stat[ue->current_thread_id[subframe_rx]].p_time/(cpuf*1000.0)); + LOG_I(PHY, "[SFN %d] Slot0 Slot1: Dlsch Proc %5.2f\n",subframe_rx,ue->dlsch_procedures_stat[ue->current_thread_id[subframe_rx]].p_time/(cpuf*1000.0)); } VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC, VCD_FUNCTION_OUT); @@ -5059,14 +5063,14 @@ int phy_procedures_UE_RX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id, if ( LOG_DEBUGFLAG(UE_TIMING)) { stop_meas(&ue->generic_stat); - LOG_UI(PHY,"after tubo until end of Rx %5.2f \n",ue->generic_stat.p_time/(cpuf*1000.0)); + LOG_I(PHY,"after tubo until end of Rx %5.2f \n",ue->generic_stat.p_time/(cpuf*1000.0)); } VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_RX, VCD_FUNCTION_OUT); if ( LOG_DEBUGFLAG(UE_TIMING) ) { stop_meas(&ue->phy_proc_rx[ue->current_thread_id[subframe_rx]]); - LOG_UI(PHY, "------FULL RX PROC [SFN %d]: %5.2f ------\n",subframe_rx,ue->phy_proc_rx[ue->current_thread_id[subframe_rx]].p_time/(cpuf*1000.0)); + LOG_I(PHY, "------FULL RX PROC [SFN %d]: %5.2f ------\n",subframe_rx,ue->phy_proc_rx[ue->current_thread_id[subframe_rx]].p_time/(cpuf*1000.0)); } LOG_D(PHY," ****** end RX-Chain for AbsSubframe %d.%d ****** \n", frame_rx%1024, subframe_rx); diff --git a/openair1/SIMULATION/LTE_PHY/common_sim.h b/openair1/SIMULATION/LTE_PHY/common_sim.h new file mode 100644 index 0000000000..46f4cdf161 --- /dev/null +++ b/openair1/SIMULATION/LTE_PHY/common_sim.h @@ -0,0 +1,164 @@ + +static int cmpdouble(const void *p1, const void *p2) { + return *(double *)p1 > *(double *)p2; +} + +double median(varArray_t *input) { + return *(double *)((uint8_t *)(input+1)+(input->size/2)*input->atomSize); +} + +double q1(varArray_t *input) { + return *(double *)((uint8_t *)(input+1)+(input->size/4)*input->atomSize); +} + +double q3(varArray_t *input) { + return *(double *)((uint8_t *)(input+1)+(3*input->size/4)*input->atomSize); +} + +void dumpVarArray(varArray_t *input) { + double *ptr=dataArray(input); + printf("dumping size=%ld\n", input->size); + + for (int i=0; i < input->size; i++) + printf("%.1f:", *ptr++); + + printf("\n"); +} +void sumUpStats(time_stats_t * res, time_stats_t * src, int lastActive) { + reset_meas(res); + for (int i=0; idiff+=src[i].diff; + res->diff_square+=src[i].diff_square; + res->trials+=src[i].trials; + if (src[i].max > res->max) + res->max=src[i].max; + } + res->p_time=src[lastActive].p_time; +} +void sumUpStatsSlot(time_stats_t *res, time_stats_t src[RX_NB_TH][2], int lastActive) { + reset_meas(res); + for (int i=0; idiff+=src[i][0].diff+src[i][1].diff; + res->diff_square+=src[i][0].diff_square+src[i][1].diff_square; + res->trials+=src[i][0].trials+src[i][1].trials; + if (src[i][0].max > res->max) + res->max=src[i][0].max; + if (src[i][1].max > res->max) + res->max=src[i][1].max;} + int last=src[lastActive][0].in < src[lastActive][1].in? 1 : 0 ; + res->p_time=src[lastActive][last].p_time; +} + +void printStatIndent(time_stats_t *ptr, char *txt) { + printf("|__ %-50s %.2f us (%d trials)\n", + txt, + ptr->trials?inMicroS(ptr->diff/ptr->trials):0, + ptr->trials); +} + +void printStatIndent2(time_stats_t *ptr, char *txt, int turbo_iter) { + double timeBase=1/(1000*cpu_freq_GHz); + printf(" |__ %-45s %.2f us (cycles/block %ld, %5d trials)\n", + txt, + ptr->trials?((double)ptr->diff)/ptr->trials*timeBase:0, + turbo_iter?(uint64_t)round(((double)ptr->diff)/turbo_iter):0, + ptr->trials); +} + +double squareRoot(time_stats_t *ptr) { + double timeBase=1/(1000*cpu_freq_GHz); + return sqrt((double)ptr->diff_square*pow(timeBase,2)/ptr->trials - + pow((double)ptr->diff/ptr->trials*timeBase,2)); +} + +void printDistribution(time_stats_t *ptr, varArray_t *sortedList, char *txt) { + double timeBase=1/(1000*cpu_freq_GHz); + printf("%-50s :%.2f us (%d trials)\n", + txt, + (double)ptr->diff/ptr->trials*timeBase, + ptr->trials); + printf("|__ Statistics std=%.2f, median=%.2f, q1=%.2f, q3=%.2f µs (on %ld trials)\n", + squareRoot(ptr), median(sortedList),q1(sortedList),q3(sortedList), sortedList->size); +} + +void logDistribution(FILE* fd, time_stats_t *ptr, varArray_t *sortedList, int dropped) { + fprintf(fd,"%f;%f;%f;%f;%f;%f;%d;", + squareRoot(ptr), + (double)ptr->max, *(double*)dataArray(sortedList), + median(sortedList),q1(sortedList),q3(sortedList), + dropped); +} + +struct option * parse_oai_options(paramdef_t *options) { + int l; + + for(l=0; options[l].optname[0]!=0; l++) {}; + + struct option *long_options=calloc(sizeof(struct option),l); + + for(int i=0; options[i].optname[0]!=0; i++) { + long_options[i].name=options[i].optname; + long_options[i].has_arg=options[i].paramflags==PARAMFLAG_BOOL?no_argument:required_argument; + + if ( options[i].voidptr) + switch (options[i].type) { + case TYPE_INT: + *options[i].iptr=options[i].defintval; + break; + + case TYPE_DOUBLE: + *options[i].dblptr=options[i].defdblval; + break; + + case TYPE_UINT8: + *options[i].u8ptr=options[i].defintval; + break; + + case TYPE_UINT16: + *options[i].u16ptr=options[i].defintval; + break; + + default: + printf("not parsed type for default value %s\n", options[i].optname ); + exit(1); + } + + continue; + }; + return long_options; +} + +void display_options_values(paramdef_t *options, int verbose) { + for(paramdef_t * ptr=options; ptr->optname[0]!=0; ptr++) { + char varText[256]="need specific display"; + + if (ptr->voidptr != NULL) { + if ( (ptr->paramflags & PARAMFLAG_BOOL) ) + strcpy(varText, *(bool *)ptr->iptr ? "True": "False" ); + else switch (ptr->type) { + case TYPE_INT: + sprintf(varText,"%d",*ptr->iptr); + break; + + case TYPE_DOUBLE: + sprintf(varText,"%.2f",*ptr->dblptr); + break; + + case TYPE_UINT8: + sprintf(varText,"%d",(int)*ptr->u8ptr); + break; + + case TYPE_UINT16: + sprintf(varText,"%d",(int)*ptr->u16ptr); + break; + + default: + printf("not decoded type\n"); + exit(1); + } + } + + printf("--%-20s set to %s\n",ptr->optname, varText); + if (verbose) printf("%s\n",ptr->helpstr); + } +} diff --git a/openair1/SIMULATION/LTE_PHY/dlsim.c b/openair1/SIMULATION/LTE_PHY/dlsim.c index 3583c0f25e..0f4655eb2c 100644 --- a/openair1/SIMULATION/LTE_PHY/dlsim.c +++ b/openair1/SIMULATION/LTE_PHY/dlsim.c @@ -72,6 +72,9 @@ void feptx_ofdm(RU_t *ru); void feptx_prec(RU_t *ru); double cpuf; +#define inMicroS(a) (((double)(a))/(cpu_freq_GHz*1000.0)) +//#define MCS_COUNT 23//added for PHY abstraction +#include int otg_enabled=0; /*the following parameters are used to control the processing times calculations*/ @@ -535,23 +538,42 @@ void fill_DCI(PHY_VARS_eNB *eNB, } int n_users = 1; -sub_frame_t subframe=7; +int subframe=7; int num_common_dci=0,num_ue_spec_dci=0,num_dci=0,num_pdcch_symbols=1; uint16_t n_rnti=0x1234; - int nfapi_mode=0; +int nfapi_mode=0; +int abstx=0; +int Nid_cell=0; +int N_RB_DL=25; +int tdd_config=3; +int dci_flag=0; +int threequarter_fs=0; +double snr_step=1,input_snr_step=1, snr_int=30; +double forgetting_factor=0.0; //in [0,1] 0 means a new channel every time, 1 means keep the same channel +int test_perf=0; +int n_frames; +int n_ch_rlz = 1; +int rx_sample_offset = 0; +int xforms=0; +int dump_table=0; +int loglvl=OAILOG_WARNING; +int mcs1=0,mcs2=0,mcs_i=0,dual_stream_UE = 0,awgn_flag=0; +int two_thread_flag=0; +int num_rounds = 4;//,fix_rounds=0; +int perfect_ce = 0; +int extended_prefix_flag=0; +int verbose=0, help=0; +double SNR,snr0=-2.0,snr1,rate = 0; +int print_perf=0; int main(int argc, char **argv) { - int c; int k,i,j,aa; int re; - int loglvl=OAILOG_DEBUG; int s,Kr,Kr_bytes; - double SNR,snr0=-2.0,snr1,rate = 0; - double snr_step=1,input_snr_step=1, snr_int=30; LTE_DL_FRAME_PARMS *frame_parms; double s_re0[30720*2],s_im0[30720*2],r_re0[30720*2],r_im0[30720*2]; @@ -560,17 +582,14 @@ int main(int argc, char **argv) double *s_im[2]={s_im0,s_im1}; double *r_re[2]={r_re0,r_re1}; double *r_im[2]={r_im0,r_im1}; - double forgetting_factor=0.0; //in [0,1] 0 means a new channel every time, 1 means keep the same channel - uint8_t extended_prefix_flag=0,transmission_mode=1,n_tx_port=1,n_tx_phy=1,n_rx=2; - uint16_t Nid_cell=0; + uint8_t transmission_mode=1,n_tx_port=1,n_tx_phy=1,n_rx=2; int eNB_id = 0; - unsigned char mcs1=0,mcs2=0,mcs_i=0,dual_stream_UE = 0,awgn_flag=0,round; + unsigned char round; unsigned char i_mod = 2; unsigned short NB_RB; - uint16_t tdd_config=3; SCM_t channel_model=Rayleigh1; @@ -602,18 +621,13 @@ int main(int argc, char **argv) FILE *input_fd=NULL; unsigned char input_file=0; - int n_frames; - int n_ch_rlz = 1; channel_desc_t *eNB2UE[4]; //uint8_t num_pdcch_symbols_2=0; - uint8_t rx_sample_offset = 0; //char stats_buffer[4096]; //int len; - uint8_t num_rounds = 4;//,fix_rounds=0; //int u; int n=0; - int abstx=0; //int iii; int ch_realization; @@ -625,9 +639,8 @@ int main(int argc, char **argv) // int bler; double blerr[4]; short *uncoded_ber_bit=NULL; - uint8_t N_RB_DL=25,osf=1; + int osf=1; frame_t frame_type = FDD; - int xforms=0; FD_lte_phy_scope_ue *form_ue = NULL; char title[255]; @@ -640,16 +653,12 @@ int main(int argc, char **argv) // time_stats_t ts;//,sts,usts; int avg_iter,iter_trials; int rballocset=0; - int print_perf=0; - int test_perf=0; int test_passed=0; - int dump_table=0; double effective_rate=0.0; char channel_model_input[10]="I"; int TB0_active = 1; - uint32_t perfect_ce = 0; // LTE_DL_UE_HARQ_t *dlsch0_ue_harq; // LTE_DL_eNB_HARQ_t *dlsch0_eNB_harq; @@ -657,20 +666,11 @@ int main(int argc, char **argv) uint8_t ue_category=4; uint32_t Nsoft; int sf; - - - int CCE_table[800]; - - int threequarter_fs=0; - - opp_enabled=1; // to enable the time meas FILE *csv_fd=NULL; - char csv_fname[32]; - int dci_flag=0; - int two_thread_flag=0; + char csv_fname[FILENAME_MAX]; int DLSCH_RB_ALLOC = 0; int dci_received; @@ -726,38 +726,97 @@ int main(int argc, char **argv) snr0 = 0; // num_layers = 1; perfect_ce = 0; + static paramdef_t options[] = { + { "awgn", "Use AWGN channel and not multipath", PARAMFLAG_BOOL, strptr:NULL, defintval:0, TYPE_INT, 0, NULL, NULL }, + { "Abstx", "Turns on calibration mode for abstraction.", PARAMFLAG_BOOL, iptr:&abstx, defintval:0, TYPE_INT, 0 }, + { "bTDD", "Set the tdd configuration mode",0, iptr:&tdd_config, defintval:3, TYPE_INT, 0 }, + { "BnbRBs", "The LTE bandwith in RBs (100 is 20MHz)",0, iptr:&N_RB_DL, defintval:25, TYPE_INT, 0 }, + { "cPdcch", "Number of PDCCH symbols",0, iptr:&num_pdcch_symbols, defintval:1, TYPE_INT, 0 }, + { "CnidCell", "The cell id ",0, iptr:&Nid_cell, defintval:0, TYPE_INT, 0 }, + { "dciFlag", "Transmit the DCI and compute its error statistics", PARAMFLAG_BOOL, iptr:&dci_flag, defintval:0, TYPE_INT, 0 }, + { "Dtdd", "Enable tdd", PARAMFLAG_BOOL, strptr:NULL, defintval:0, TYPE_INT, 0, NULL, NULL }, + { "eRounds", "Number of rounds",0, iptr:NULL, defintval:25, TYPE_INT, 0 }, + { "EsubSampling","three quarters sub-sampling",PARAMFLAG_BOOL, iptr:&threequarter_fs, defintval:0, TYPE_INT, 0 }, + { "f_snr_step", "step size of SNR, default value is 1.",0, dblptr:&input_snr_step, defdblval:1, TYPE_DOUBLE, 0 }, + { "Forgetting", "forgetting factor (0 new channel every trial, 1 channel constant)",0, dblptr:&forgetting_factor, defdblval:0.0, TYPE_DOUBLE, 0 }, + { "input_file", "input IQ data file",0, iptr:NULL, defintval:0, TYPE_INT, 0 }, + { "Input_file_trch", " Input filename for TrCH data (binary)",0, iptr:NULL, defintval:0, TYPE_INT, 0 }, + { "WtwoThreads", "two_thread_flag", PARAMFLAG_BOOL, iptr:&two_thread_flag, defintval:0, TYPE_INT, 0 }, + { "lMuMimo", "offset_mumimo_llr_drange_fix",0, u8ptr:&offset_mumimo_llr_drange_fix, defintval:0, TYPE_UINT8, 0 }, + { "mcs1", "The MCS for TB 1", 0, iptr:&mcs1, defintval:0, TYPE_INT, 0 }, + { "Mcs2", "The MCS for TB 2", 0, iptr:&mcs2, defintval:0, TYPE_INT, 0 }, + { "Operf", "Set the percenatge of effective rate to testbench the modem performance (typically 30 and 70, range 1-100)",0, iptr:&test_perf, defintval:0, TYPE_INT, 0 }, + { "tmcs_i", "MCS of interfering UE",0, iptr:NULL, defintval:0, TYPE_INT, 0 }, + { "nb_frame", "number of frame in a test",0, iptr:&n_frames, defintval:1, TYPE_INT, 0 }, + { "offsetRxSample", "Sample offset for receiver", 0, iptr:&rx_sample_offset, defintval:0, TYPE_INT, 0 }, + { "rballocset", "ressource block allocation (see section 7.1.6.3 in 36.213)",0, iptr:NULL, defintval:0, TYPE_INT, 0 }, + { "snr", "Starting SNR, runs from SNR to SNR+%.1fdB in steps of %.1fdB. If n_frames is 1 then just SNR is simulated and MATLAB/OCTAVE output is generated", dblptr:&snr0, defdblval:-2.0, TYPE_DOUBLE, 0 }, + { "wsnrInterrupt", "snr int ?", 0, dblptr:&snr_int, defdblval:30, TYPE_DOUBLE, 0 }, + { "N_ch_rlzN0", "Determines the number of Channel Realizations in Abstraction mode. Default value is 1",0, iptr:&n_ch_rlz, defintval:1, TYPE_INT, 0 }, + { "prefix_extended","Enable extended prefix", PARAMFLAG_BOOL, iptr:&extended_prefix_flag, defintval:0, TYPE_INT, 0 }, + { "RNumRound", "Number of HARQ rounds (fixed)",0, iptr:&num_rounds, defintval:4, TYPE_INT, 0 }, + { "Subframe", "subframe ",0, iptr:&subframe, defintval:7, TYPE_INT, 0 }, + { "Trnti", "rnti",0, u16ptr:&n_rnti, defuintval:0x1234, TYPE_UINT16, 0 }, + { "vi_mod", "i_mod",0, iptr:NULL, defintval:0, TYPE_INT, 0 }, + { "Performance", "Display CPU perfomance of each L1 piece", PARAMFLAG_BOOL, iptr:&print_perf, defintval:0, TYPE_INT, 0 }, + { "q_tx_port", "Number of TX antennas ports used in eNB",0, iptr:NULL, defintval:0, TYPE_INT, 0 }, + { "uEdual", "Enables the Interference Aware Receiver for TM5 (default is normal receiver)",0, iptr:NULL, defintval:0, TYPE_INT, 0 }, + { "xTransmission","Transmission mode (1,2,6,7 for the moment)",0, iptr:NULL, defintval:25, TYPE_INT, 0 }, + { "yn_tx_phy","Number of TX antennas used in eNB",0, iptr:NULL, defintval:25, TYPE_INT, 0 }, + { "XForms", "Display the soft scope", PARAMFLAG_BOOL, iptr:&xforms, defintval:0, TYPE_INT, 0 }, + { "Yperfect_ce","Perfect CE", PARAMFLAG_BOOL, iptr:&perfect_ce, defintval:0, TYPE_INT, 0 }, + { "Zdump", "dump table",PARAMFLAG_BOOL, iptr:&dump_table, defintval:0, TYPE_INT, 0 }, + { "Loglvl", "log level",0, iptr:&loglvl, defintval:OAILOG_DEBUG, TYPE_INT, 0 }, + { "zn_rx", "Number of RX antennas used in UE",0, iptr:NULL, defintval:2, TYPE_INT, 0 }, + { "gchannel", "[A:M] Use 3GPP 25.814 SCM-A/B/C/D('A','B','C','D') or 36-101 EPA('E'), EVA ('F'),ETU('G') models (ignores delay spread and Ricean factor), Rayghleigh8 ('H'), Rayleigh1('I'), Rayleigh1_corr('J'), Rayleigh1_anticorr ('K'), Rice8('L'), Rice1('M')",0, strptr:NULL, defstrval:NULL, TYPE_STRING, 0 }, + { "verbose", "display debug text", PARAMFLAG_BOOL, iptr:&verbose, defintval:0, TYPE_INT, 0 }, + { "help", "display help and exit", PARAMFLAG_BOOL, iptr:&help, defintval:0, TYPE_INT, 0 }, + { "", "",0, iptr:NULL, defintval:0, TYPE_INT, 0 }, + }; - while ((c = getopt (argc, argv, "ahdpZDe:Em:n:o:s:f:t:c:g:r:F:x:q:y:z:AM:N:I:i:O:R:S:C:T:b:u:v:w:B:Pl:WXYL:")) != -1) { - switch (c) { + + struct option * long_options = parse_oai_options(options); + + + int option_index; + + int res; + + while ((res=getopt_long_only(argc, argv, "", long_options, &option_index)) == 0) { + if (options[option_index].voidptr != NULL ) { + if (long_options[option_index].has_arg==no_argument) + *(bool *)options[option_index].iptr=1; + else switch (options[option_index].type) { + case TYPE_INT: + *(int *)options[option_index].iptr=atoi(optarg); + break; + + case TYPE_DOUBLE: + *(double *)options[option_index].dblptr=atof(optarg); + break; + + case TYPE_UINT8: + *(uint8_t *)options[option_index].dblptr=atoi(optarg); + break; + + case TYPE_UINT16: + *(uint16_t *)options[option_index].dblptr=atoi(optarg); + break; + + default: + printf("not decoded type.\n"); + exit(1); + } + + continue; + } + + switch (long_options[option_index].name[0]) { case 'a': awgn_flag = 1; channel_model = AWGN; break; - case 'A': - abstx = 1; - break; - - case 'b': - tdd_config=atoi(optarg); - break; - - case 'B': - N_RB_DL=atoi(optarg); - break; - - case 'c': - num_pdcch_symbols=atoi(optarg); - break; - - case 'C': - Nid_cell = atoi(optarg); - break; - - case 'd': - dci_flag = 1; - break; - case 'D': frame_type=TDD; break; @@ -768,18 +827,6 @@ int main(int argc, char **argv) TPC = atoi(optarg); break; - case 'E': - threequarter_fs=1; - break; - - case 'f': - input_snr_step= atof(optarg); - break; - - case 'F': - forgetting_factor = atof(optarg); - break; - case 'i': input_fd = fopen(optarg,"r"); input_file=1; @@ -791,139 +838,51 @@ int main(int argc, char **argv) input_trch_file=1; break; - case 'W': - two_thread_flag = 1; - break; - case 'l': - offset_mumimo_llr_drange_fix=atoi(optarg); - break; - - case 'm': - mcs1 = atoi(optarg); - break; - - case 'M': - mcs2 = atoi(optarg); - break; - - case 'O': - test_perf=atoi(optarg); - //print_perf =1; - break; - case 't': mcs_i = atoi(optarg); i_mod = get_Qm(mcs_i); break; - case 'n': - n_frames = atoi(optarg); - break; - - - case 'o': - rx_sample_offset = atoi(optarg); - break; - case 'r': DLSCH_RB_ALLOC = atoi(optarg); rballocset = 1; break; - case 's': - snr0 = atof(optarg); - break; - - case 'w': - snr_int = atof(optarg); - break; - - - case 'N': - n_ch_rlz= atof(optarg); - break; - - case 'p': - extended_prefix_flag=1; - break; - case 'g': - memcpy(channel_model_input,optarg,10); + strncpy(channel_model_input,optarg,9); + struct tmp { + char opt; + int m; + int M; + } + tmp[]= { + {'A',SCM_A,2}, + {'B',SCM_B,3}, + {'C',SCM_C,4}, + {'D',SCM_D,5}, + {'E',EPA,6}, + {'F',EVA,6}, + {'G',ETU,8}, + {'H',Rayleigh8,9}, + {'I',Rayleigh1,10}, + {'J',Rayleigh1_corr,11}, + {'K',Rayleigh1_anticorr,12}, + {'L',Rice8,13}, + {'M',Rice1,14}, + {'N',AWGN,1}, + {0,0,0} + }; + struct tmp *ptr; - switch((char)*optarg) { - case 'A': - channel_model=SCM_A; + for (ptr=tmp; ptr->opt!=0; ptr++) + if ( ptr->opt == optarg[0] ) { + channel_model=ptr->m; + break; + } + + AssertFatal(ptr->opt != 0, "Unsupported channel model: %s !\n", optarg ); break; - case 'B': - channel_model=SCM_B; - break; - - case 'C': - channel_model=SCM_C; - break; - - case 'D': - channel_model=SCM_D; - break; - - case 'E': - channel_model=EPA; - break; - - case 'F': - channel_model=EVA; - break; - - case 'G': - channel_model=ETU; - break; - - case 'H': - channel_model=Rayleigh8; - break; - - case 'I': - channel_model=Rayleigh1; - break; - - case 'J': - channel_model=Rayleigh1_corr; - break; - - case 'K': - channel_model=Rayleigh1_anticorr; - break; - - case 'L': - channel_model=Rice8; - break; - - case 'M': - channel_model=Rice1; - break; - - case 'N': - channel_model=AWGN; - break; - default: - printf("Unsupported channel model!\n"); - exit(-1); - } - - break; - case 'R': - num_rounds=atoi(optarg); - break; - - case 'S': - subframe=atoi(optarg); - break; - - case 'T': - n_rnti=atoi(optarg); - break; - case 'u': dual_stream_UE=1; UE->use_ia_receiver = 1; @@ -945,10 +904,6 @@ int main(int argc, char **argv) break; - case 'P': - print_perf=1; - break; - case 'q': n_tx_port=atoi(optarg); @@ -999,15 +954,6 @@ int main(int argc, char **argv) } break; - break; - - case 'X': - xforms=1; - break; - - case 'Y': - perfect_ce=1; - break; case 'z': n_rx=atoi(optarg); @@ -1019,51 +965,23 @@ int main(int argc, char **argv) break; - case 'Z': - dump_table=1; - break; - - case 'L': - loglvl = atoi(optarg); - break; - - case 'h': default: - printf("%s -h(elp) -a(wgn on) -d(ci decoding on) -p(extended prefix on) -m mcs1 -M mcs2 -n n_frames -s snr0 -x transmission mode (1,2,5,6,7) -y TXant -z RXant -I trch_file\n",argv[0]); - printf("-h This message\n"); - printf("-a Use AWGN channel and not multipath\n"); - printf("-c Number of PDCCH symbols\n"); - printf("-m MCS1 for TB 1\n"); - printf("-M MCS2 for TB 2\n"); - printf("-d Transmit the DCI and compute its error statistics\n"); - printf("-p Use extended prefix mode\n"); - printf("-n Number of frames to simulate\n"); - printf("-o Sample offset for receiver\n"); - printf("-s Starting SNR, runs from SNR to SNR+%.1fdB in steps of %.1fdB. If n_frames is 1 then just SNR is simulated and MATLAB/OCTAVE output is generated\n", snr_int, snr_step); - printf("-f step size of SNR, default value is 1.\n"); - printf("-C cell id\n"); - printf("-S subframe\n"); - printf("-D use TDD mode\n"); - printf("-b TDD config\n"); - printf("-B bandwidth configuration (in number of ressource blocks): 6, 25, 50, 100\n"); - printf("-r ressource block allocation (see section 7.1.6.3 in 36.213\n"); - printf("-g [A:M] Use 3GPP 25.814 SCM-A/B/C/D('A','B','C','D') or 36-101 EPA('E'), EVA ('F'),ETU('G') models (ignores delay spread and Ricean factor), Rayghleigh8 ('H'), Rayleigh1('I'), Rayleigh1_corr('J'), Rayleigh1_anticorr ('K'), Rice8('L'), Rice1('M')\n"); - printf("-F forgetting factor (0 new channel every trial, 1 channel constant\n"); - printf("-x Transmission mode (1,2,6,7 for the moment)\n"); - printf("-q Number of TX antennas ports used in eNB\n"); - printf("-y Number of TX antennas used in eNB\n"); - printf("-z Number of RX antennas used in UE\n"); - printf("-t MCS of interfering UE\n"); - printf("-R Number of HARQ rounds (fixed)\n"); - printf("-A Turns on calibration mode for abstraction.\n"); - printf("-N Determines the number of Channel Realizations in Abstraction mode. Default value is 1. \n"); - printf("-O Set the percenatge of effective rate to testbench the modem performance (typically 30 and 70, range 1-100) \n"); - printf("-I Input filename for TrCH data (binary)\n"); - printf("-u Enables the Interference Aware Receiver for TM5 (default is normal receiver)\n"); + printf("Wrong option: %s\n",long_options[option_index].name); exit(1); break; } } + + if ( res != -1 ) { + printf("A wrong option has been found\n"); + exit(1); + } + + if (help || verbose ) + display_options_values(options, true); + if (help) + exit(0); + set_parallel_conf("PARALLEL_RU_L1_TRX_SPLIT"); set_worker_conf("WORKER_ENABLE"); @@ -1073,8 +991,10 @@ int main(int argc, char **argv) AssertFatal(load_configmodule(argc,argv) != NULL, "cannot load configuration module, exiting\n"); logInit(); + set_glog_onlinelog(true); // enable these lines if you need debug info set_glog(loglvl); + SET_LOG_DEBUG(UE_TIMING); // moreover you need to init itti with the following line // however itti will catch all signals, so ctrl-c won't work anymore // alternatively you can disable ITTI completely in CMakeLists.txt @@ -1522,9 +1442,17 @@ int main(int argc, char **argv) reset_meas(&eNB->dlsch_interleaving_stats); reset_meas(&eNB->dlsch_rate_matching_stats); reset_meas(&eNB->dlsch_turbo_encoding_stats); - - reset_meas(&UE->phy_proc_rx[UE->current_thread_id[subframe]]); // total UE rx + for (int i=0; iphy_proc_rx[i]); // total UE rx + reset_meas(&UE->ue_front_end_stat[i]); + reset_meas(&UE->pdsch_procedures_stat[i]); + reset_meas(&UE->dlsch_procedures_stat[i]); + reset_meas(&UE->dlsch_decoding_stats[i]); + reset_meas(&UE->dlsch_llr_stats_parallelization[i][0]); + reset_meas(&UE->dlsch_llr_stats_parallelization[i][1]); + } reset_meas(&UE->ofdm_demod_stats); + reset_meas(&UE->crnti_procedures_stats); reset_meas(&UE->dlsch_channel_estimation_stats); reset_meas(&UE->dlsch_freq_offset_estimation_stats); reset_meas(&UE->rx_dft_stats); @@ -1541,25 +1469,21 @@ int main(int argc, char **argv) reset_meas(&UE->dlsch_tc_intl1_stats); reset_meas(&UE->dlsch_tc_intl2_stats); // initialization - struct list time_vector_tx; - initialize(&time_vector_tx); - struct list time_vector_tx_ifft; - initialize(&time_vector_tx_ifft); - struct list time_vector_tx_mod; - initialize(&time_vector_tx_mod); - struct list time_vector_tx_enc; - initialize(&time_vector_tx_enc); - - struct list time_vector_rx; - initialize(&time_vector_rx); - struct list time_vector_rx_fft; - initialize(&time_vector_rx_fft); - struct list time_vector_rx_demod; - initialize(&time_vector_rx_demod); - struct list time_vector_rx_dec; - initialize(&time_vector_rx_dec); - - + // initialization + varArray_t *table_tx=initVarArray(1000,sizeof(double)); + varArray_t *table_tx_ifft=initVarArray(1000,sizeof(double)); + varArray_t *table_tx_mod=initVarArray(1000,sizeof(double)); + varArray_t *table_tx_enc=initVarArray(1000,sizeof(double)); + varArray_t *table_rx=initVarArray(1000,sizeof(double)); + time_stats_t phy_proc_rx_tot; + time_stats_t pdsch_procedures_tot; + time_stats_t dlsch_procedures_tot; + time_stats_t dlsch_decoding_tot; + time_stats_t dlsch_llr_tot; + time_stats_t ue_front_end_tot; + varArray_t *table_rx_fft=initVarArray(1000,sizeof(double)); + varArray_t *table_rx_demod=initVarArray(1000,sizeof(double)); + varArray_t *table_rx_dec=initVarArray(1000,sizeof(double)); for (trials = 0; trials2000us */ - double t_tx = (double)eNB->phy_proc_tx.p_time/cpu_freq_GHz/1000.0; - double t_tx_ifft = (double)eNB->ofdm_mod_stats.p_time/cpu_freq_GHz/1000.0; - double t_tx_mod = (double)eNB->dlsch_modulation_stats.p_time/cpu_freq_GHz/1000.0; - double t_tx_enc = (double)eNB->dlsch_encoding_stats.p_time/cpu_freq_GHz/1000.0; + double t_tx = inMicroS(eNB->phy_proc_tx.p_time); + double t_tx_ifft = inMicroS(eNB->ofdm_mod_stats.p_time); + double t_rx = inMicroS(UE->phy_proc_rx[UE->current_thread_id[subframe]].p_time); + sumUpStats(&phy_proc_rx_tot, UE->phy_proc_rx, UE->current_thread_id[subframe]); + sumUpStats(&ue_front_end_tot, UE->ue_front_end_stat, UE->current_thread_id[subframe]); + sumUpStats(&pdsch_procedures_tot, UE->pdsch_procedures_stat, UE->current_thread_id[subframe]); + sumUpStats(&dlsch_procedures_tot, UE->dlsch_procedures_stat, UE->current_thread_id[subframe]); + sumUpStats(&dlsch_decoding_tot, UE->dlsch_decoding_stats, UE->current_thread_id[subframe]); + sumUpStatsSlot(&dlsch_llr_tot, UE->dlsch_llr_stats_parallelization, UE->current_thread_id[subframe]); - double t_rx = (double)UE->phy_proc_rx[UE->current_thread_id[subframe]].p_time/cpu_freq_GHz/1000.0; - double t_rx_fft = (double)UE->ofdm_demod_stats.p_time/cpu_freq_GHz/1000.0; - double t_rx_demod = (double)UE->dlsch_rx_pdcch_stats.p_time/cpu_freq_GHz/1000.0; - double t_rx_dec = (double)UE->dlsch_decoding_stats[UE->current_thread_id[subframe]].p_time/cpu_freq_GHz/1000.0; + double t_rx_fft = inMicroS(UE->ofdm_demod_stats.p_time); + double t_rx_demod = inMicroS(UE->dlsch_rx_pdcch_stats.p_time); + double t_rx_dec = inMicroS(UE->dlsch_decoding_stats[UE->current_thread_id[subframe]].p_time); - if (t_tx > t_tx_max) - t_tx_max = t_tx; - - if (t_tx < t_tx_min) - t_tx_min = t_tx; - - if (t_rx > t_rx_max) - t_rx_max = t_rx; - - if (t_rx < t_rx_min) - t_rx_min = t_rx; - - if (t_tx > 2000) + if (t_tx > 2000 )// 2ms is too much time for a subframe n_tx_dropped++; - - if (t_rx > 2000) + + if (t_rx > 2000 ) n_rx_dropped++; - - push_front(&time_vector_tx, t_tx); - push_front(&time_vector_tx_ifft, t_tx_ifft); - push_front(&time_vector_tx_mod, t_tx_mod); - push_front(&time_vector_tx_enc, t_tx_enc); - - push_front(&time_vector_rx, t_rx); - push_front(&time_vector_rx_fft, t_rx_fft); - push_front(&time_vector_rx_demod, t_rx_demod); - push_front(&time_vector_rx_dec, t_rx_dec); - + + appendVarArray(table_tx, &t_tx); + appendVarArray(table_tx_ifft, &t_tx_ifft); + appendVarArray(table_rx, &t_rx ); + appendVarArray(table_rx_fft, &t_rx_fft ); + appendVarArray(table_rx_demod, &t_rx_demod ); + appendVarArray(table_rx_dec, &t_rx_dec ); } //trials // round_trials[0]: number of code word : goodput the protocol - double table_tx[time_vector_tx.size]; - totable(table_tx, &time_vector_tx); - double table_tx_ifft[time_vector_tx_ifft.size]; - totable(table_tx_ifft, &time_vector_tx_ifft); - double table_tx_mod[time_vector_tx_mod.size]; - totable(table_tx_mod, &time_vector_tx_mod); - double table_tx_enc[time_vector_tx_enc.size]; - totable(table_tx_enc, &time_vector_tx_enc); - - double table_rx[time_vector_rx.size]; - totable(table_rx, &time_vector_rx); - double table_rx_fft[time_vector_rx_fft.size]; - totable(table_rx_fft, &time_vector_rx_fft); - double table_rx_demod[time_vector_rx_demod.size]; - totable(table_rx_demod, &time_vector_rx_demod); - double table_rx_dec[time_vector_rx_dec.size]; - totable(table_rx_dec, &time_vector_rx_dec); - - // sort table - qsort (table_tx, time_vector_tx.size, sizeof(double), &compare); - qsort (table_rx, time_vector_rx.size, sizeof(double), &compare); + qsort (dataArray(table_tx), table_tx->size, table_tx->atomSize, &cmpdouble); + qsort (dataArray(table_tx_ifft), table_tx_ifft->size, table_tx_ifft->atomSize, &cmpdouble); + qsort (dataArray(table_tx_mod), table_tx_mod->size, table_tx_mod->atomSize, &cmpdouble); + qsort (dataArray(table_tx_enc), table_tx_enc->size, table_tx_enc->atomSize, &cmpdouble); + qsort (dataArray(table_rx), table_rx->size, table_rx->atomSize, &cmpdouble); + qsort (dataArray(table_rx_fft), table_rx_fft->size, table_rx_fft->atomSize, &cmpdouble); + qsort (dataArray(table_rx_demod), table_rx_demod->size, table_rx_demod->atomSize, &cmpdouble); + qsort (dataArray(table_rx_dec), table_rx_dec->size, table_rx_dec->atomSize, &cmpdouble); if (dump_table == 1 ) { set_component_filelog(SIM); // file located in /tmp/usim.txt - LOG_UDUMPMSG(SIM,table_tx,time_vector_tx.size,LOG_DUMP_DOUBLE,"The transmitter raw data: \n"); - LOG_UDUMPMSG(SIM,table_rx,time_vector_rx.size,LOG_DUMP_DOUBLE,"Thereceiver raw data: \n"); + LOG_UDUMPMSG(SIM,table_tx,table_tx->size,LOG_DUMP_DOUBLE,"The transmitter raw data: \n"); + LOG_UDUMPMSG(SIM,table_rx,table_rx->size,LOG_DUMP_DOUBLE,"Thereceiver raw data: \n"); } - double tx_median = table_tx[time_vector_tx.size/2]; - double tx_q1 = table_tx[time_vector_tx.size/4]; - double tx_q3 = table_tx[3*time_vector_tx.size/4]; - - double tx_ifft_median = table_tx_ifft[time_vector_tx_ifft.size/2]; - double tx_ifft_q1 = table_tx_ifft[time_vector_tx_ifft.size/4]; - double tx_ifft_q3 = table_tx_ifft[3*time_vector_tx_ifft.size/4]; - - double tx_mod_median = table_tx_mod[time_vector_tx_mod.size/2]; - double tx_mod_q1 = table_tx_mod[time_vector_tx_mod.size/4]; - double tx_mod_q3 = table_tx_mod[3*time_vector_tx_mod.size/4]; - - double tx_enc_median = table_tx_enc[time_vector_tx_enc.size/2]; - double tx_enc_q1 = table_tx_enc[time_vector_tx_enc.size/4]; - double tx_enc_q3 = table_tx_enc[3*time_vector_tx_enc.size/4]; - - double rx_median = table_rx[time_vector_rx.size/2]; - double rx_q1 = table_rx[time_vector_rx.size/4]; - double rx_q3 = table_rx[3*time_vector_rx.size/4]; - - double rx_fft_median = table_rx_fft[time_vector_rx_fft.size/2]; - double rx_fft_q1 = table_rx_fft[time_vector_rx_fft.size/4]; - double rx_fft_q3 = table_rx_fft[3*time_vector_rx_fft.size/4]; - - double rx_demod_median = table_rx_demod[time_vector_rx_demod.size/2]; - double rx_demod_q1 = table_rx_demod[time_vector_rx_demod.size/4]; - double rx_demod_q3 = table_rx_demod[3*time_vector_rx_demod.size/4]; - - double rx_dec_median = table_rx_dec[time_vector_rx_dec.size/2]; - double rx_dec_q1 = table_rx_dec[time_vector_rx_dec.size/4]; - double rx_dec_q3 = table_rx_dec[3*time_vector_rx_dec.size/4]; - - double std_phy_proc_tx=0; - double std_phy_proc_tx_ifft=0; - double std_phy_proc_tx_mod=0; - double std_phy_proc_tx_enc=0; - - double std_phy_proc_rx=0; - double std_phy_proc_rx_fft=0; - double std_phy_proc_rx_demod=0; - double std_phy_proc_rx_dec=0; - effective_rate = 1.0-((double)(errs[0]+errs[1]+errs[2]+errs[3])/((double)round_trials[0] + round_trials[1] + round_trials[2] + round_trials[3])); printf("\n**********************SNR = %f dB (tx_lev %f)**************************\n", @@ -2149,108 +2006,49 @@ int main(int argc, char **argv) (double)eNB->dlsch[0][0]->harq_processes[0]->TBS, (1.0*(round_trials[0]-errs[0])+2.0*(round_trials[1]-errs[1])+3.0*(round_trials[2]-errs[2])+4.0*(round_trials[3]-errs[3]))/((double)round_trials[0])); + double timeBase=1/(1000*cpu_freq_GHz); if (print_perf==1) { - printf("eNB TX function statistics (per 1ms subframe)\n\n"); - std_phy_proc_tx = sqrt((double)eNB->phy_proc_tx.diff_square/pow(cpu_freq_GHz,2)/pow(1000, - 2)/eNB->phy_proc_tx.trials - pow((double)eNB->phy_proc_tx.diff/eNB->phy_proc_tx.trials/cpu_freq_GHz/1000,2)); - std_phy_proc_tx_ifft = sqrt((double)eNB->ofdm_mod_stats.diff_square/pow(cpu_freq_GHz,2)/pow(1000, - 2)/eNB->ofdm_mod_stats.trials - pow((double)eNB->ofdm_mod_stats.diff/eNB->ofdm_mod_stats.trials/cpu_freq_GHz/1000,2)); - printf("OFDM_mod time :%f us (%d trials)\n",(double)eNB->ofdm_mod_stats.diff/eNB->ofdm_mod_stats.trials/cpu_freq_GHz/1000.0,eNB->ofdm_mod_stats.trials); - printf("|__ Statistcs std: %fus median %fus q1 %fus q3 %fus \n",std_phy_proc_tx_ifft, tx_ifft_median, tx_ifft_q1, tx_ifft_q3); - printf("Total PHY proc tx :%f us (%d trials)\n",(double)eNB->phy_proc_tx.diff/eNB->phy_proc_tx.trials/cpu_freq_GHz/1000.0,eNB->phy_proc_tx.trials); - printf("|__ Statistcs std: %fus max: %fus min: %fus median %fus q1 %fus q3 %fus n_dropped: %d packet \n",std_phy_proc_tx, t_tx_max, t_tx_min, tx_median, tx_q1, tx_q3, - n_tx_dropped); + printf("\neNB TX function statistics (per 1ms subframe)\n"); + printDistribution(&eNB->phy_proc_tx,table_tx,"PHY proc tx"); + printStatIndent(&eNB->dlsch_common_and_dci,"DL common channels and dci time"); + printStatIndent(&eNB->dlsch_encoding_stats,"DLSCH encoding time"); + printStatIndent2(&eNB->dlsch_rate_matching_stats,"DLSCH rate matching time",eNB->dlsch_rate_matching_stats.trials); + printStatIndent2(&eNB->dlsch_turbo_encoding_stats,"DLSCH turbo encoding time", eNB->dlsch_turbo_encoding_stats.trials); + printStatIndent2(&eNB->dlsch_interleaving_stats,"DLSCH interleaving time", eNB->dlsch_interleaving_stats.trials); + printStatIndent(&eNB->dlsch_scrambling_stats, "DLSCH scrambling time"); + printStatIndent(&eNB->dlsch_modulation_stats, "DLSCH modulation time"); + printDistribution(&eNB->ofdm_mod_stats,table_tx_ifft,"OFDM_mod (idft) time"); - std_phy_proc_tx_mod = sqrt((double)eNB->dlsch_modulation_stats.diff_square/pow(cpu_freq_GHz,2)/pow(1000, - 2)/eNB->dlsch_modulation_stats.trials - pow((double)eNB->dlsch_modulation_stats.diff/eNB->dlsch_modulation_stats.trials/cpu_freq_GHz/1000,2)); - printf("DLSCH modulation time :%f us (%d trials)\n",(double)eNB->dlsch_modulation_stats.diff/eNB->dlsch_modulation_stats.trials/cpu_freq_GHz/1000.0, - eNB->dlsch_modulation_stats.trials); - printf("|__ Statistcs std: %fus median %fus q1 %fus q3 %fus \n",std_phy_proc_tx_mod, tx_mod_median, tx_mod_q1, tx_mod_q3); - printf("DLSCH scrambling time :%f us (%d trials)\n",(double)eNB->dlsch_scrambling_stats.diff/eNB->dlsch_scrambling_stats.trials/cpu_freq_GHz/1000.0, - eNB->dlsch_scrambling_stats.trials); - std_phy_proc_tx_enc = sqrt((double)eNB->dlsch_encoding_stats.diff_square/pow(cpu_freq_GHz,2)/pow(1000, - 2)/eNB->dlsch_encoding_stats.trials - pow((double)eNB->dlsch_encoding_stats.diff/eNB->dlsch_encoding_stats.trials/cpu_freq_GHz/1000,2)); - printf("DLSCH encoding time :%f us (%d trials)\n",(double)eNB->dlsch_encoding_stats.diff/eNB->dlsch_encoding_stats.trials/cpu_freq_GHz/1000.0, - eNB->dlsch_modulation_stats.trials); - printf("|__ Statistcs std: %fus median %fus q1 %fus q3 %fus \n",std_phy_proc_tx_enc, tx_enc_median, tx_enc_q1, tx_enc_q3); - printf("|__ DLSCH turbo encoding time :%f us (%d trials)\n", - ((double)eNB->dlsch_turbo_encoding_stats.trials/eNB->dlsch_encoding_stats.trials)*(double) - eNB->dlsch_turbo_encoding_stats.diff/eNB->dlsch_turbo_encoding_stats.trials/cpu_freq_GHz/1000.0,eNB->dlsch_turbo_encoding_stats.trials); - printf("|__ DLSCH rate-matching time :%f us (%d trials)\n", - ((double)eNB->dlsch_rate_matching_stats.trials/eNB->dlsch_encoding_stats.trials)*(double) - eNB->dlsch_rate_matching_stats.diff/eNB->dlsch_rate_matching_stats.trials/cpu_freq_GHz/1000.0,eNB->dlsch_rate_matching_stats.trials); - printf("|__ DLSCH sub-block interleaving time :%f us (%d trials)\n", - ((double)eNB->dlsch_interleaving_stats.trials/eNB->dlsch_encoding_stats.trials)*(double) - eNB->dlsch_interleaving_stats.diff/eNB->dlsch_interleaving_stats.trials/cpu_freq_GHz/1000.0,eNB->dlsch_interleaving_stats.trials); + printf("\nUE RX function statistics (per 1ms subframe)\n"); + printDistribution(&phy_proc_rx_tot, table_rx,"Total PHY proc rx"); + printStatIndent(&ue_front_end_tot,"Front end processing"); + printStatIndent(&dlsch_llr_tot,"rx_pdsch processing"); + printStatIndent2(&pdsch_procedures_tot,"pdsch processing", pdsch_procedures_tot.trials); + printStatIndent2(&dlsch_procedures_tot,"dlsch processing", dlsch_procedures_tot.trials); + printStatIndent2(&UE->crnti_procedures_stats,"C-RNTI processing", UE->crnti_procedures_stats.trials); + printStatIndent(&UE->ofdm_demod_stats,"ofdm demodulation"); + printStatIndent(&UE->dlsch_channel_estimation_stats,"DLSCH channel estimation time"); + printStatIndent(&UE->dlsch_freq_offset_estimation_stats,"DLSCH frequency offset estimation time"); + printStatIndent(&dlsch_decoding_tot, "DLSCH Decoding time "); + printStatIndent(&UE->dlsch_unscrambling_stats,"DLSCH unscrambling time"); + printStatIndent(&UE->dlsch_rate_unmatching_stats,"DLSCH Rate Unmatching"); + printf("|__ DLSCH Turbo Decoding(%d bits), avg iterations: %.1f %.2f us (%d cycles, %d trials)\n", + UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[0]->Cminus ? + UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[0]->Kminus : + UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[0]->Kplus, - printf("\n\nUE RX function statistics (per 1ms subframe)\n\n"); - std_phy_proc_rx = sqrt((double)UE->phy_proc_rx[UE->current_thread_id[subframe]].diff_square/pow(cpu_freq_GHz,2)/pow(1000, - 2)/UE->phy_proc_rx[UE->current_thread_id[subframe]].trials - pow((double)UE->phy_proc_rx[UE->current_thread_id[subframe]].diff/UE->phy_proc_rx[UE->current_thread_id[subframe]].trials/cpu_freq_GHz/1000,2)); - printf("Total PHY proc rx :%f us (%d trials)\n",(double)UE->phy_proc_rx[UE->current_thread_id[subframe]].diff/UE->phy_proc_rx[UE->current_thread_id[subframe]].trials/cpu_freq_GHz/1000.0, - UE->phy_proc_rx[UE->current_thread_id[subframe]].trials*2/3); - printf("|__Statistcs std: %fus max: %fus min: %fus median %fus q1 %fus q3 %fus n_dropped: %d packet \n", std_phy_proc_rx, t_rx_max, t_rx_min, rx_median, - rx_q1, rx_q3, n_rx_dropped); - std_phy_proc_rx_fft = sqrt((double)UE->ofdm_demod_stats.diff_square/pow(cpu_freq_GHz,2)/pow(1000, - 2)/UE->ofdm_demod_stats.trials - pow((double)UE->ofdm_demod_stats.diff/UE->ofdm_demod_stats.trials/cpu_freq_GHz/1000,2)); - printf("DLSCH OFDM demodulation and channel_estimation time :%f us (%d trials)\n",(nsymb)*(double)UE->ofdm_demod_stats.diff/UE->ofdm_demod_stats.trials/cpu_freq_GHz/1000.0, - UE->ofdm_demod_stats.trials*2/3); - printf("|__ Statistcs std: %fus median %fus q1 %fus q3 %fus \n",std_phy_proc_rx_fft, rx_fft_median, rx_fft_q1, rx_fft_q3); - printf("|__ DLSCH rx dft :%f us (%d trials)\n", - (nsymb*UE->frame_parms.nb_antennas_rx)*(double)UE->rx_dft_stats.diff/UE->rx_dft_stats.trials/cpu_freq_GHz/1000.0,UE->rx_dft_stats.trials*2/3); - printf("|__ DLSCH channel estimation time :%f us (%d trials)\n", - (4.0)*(double)UE->dlsch_channel_estimation_stats.diff/UE->dlsch_channel_estimation_stats.trials/cpu_freq_GHz/1000.0,UE->dlsch_channel_estimation_stats.trials*2/3); - printf("|__ DLSCH frequency offset estimation time :%f us (%d trials)\n", - (4.0)*(double)UE->dlsch_freq_offset_estimation_stats.diff/UE->dlsch_freq_offset_estimation_stats.trials/cpu_freq_GHz/1000.0, - UE->dlsch_freq_offset_estimation_stats.trials*2/3); - printf("DLSCH rx pdcch :%f us (%d trials)\n",(double)UE->dlsch_rx_pdcch_stats.diff/UE->dlsch_rx_pdcch_stats.trials/cpu_freq_GHz/1000.0, - UE->dlsch_rx_pdcch_stats.trials); - std_phy_proc_rx_demod = sqrt((double)UE->dlsch_llr_stats.diff_square/pow(cpu_freq_GHz,2)/pow(1000, - 2)/UE->dlsch_llr_stats.trials - pow((double)UE->dlsch_llr_stats.diff/UE->dlsch_llr_stats.trials/cpu_freq_GHz/1000,2)); - printf("DLSCH Channel Compensation and LLR generation time :%f us (%d trials)\n",(14-num_pdcch_symbols)*(double)UE->dlsch_llr_stats.diff/UE->dlsch_llr_stats.trials/cpu_freq_GHz/1000.0, - UE->dlsch_llr_stats.trials/3); - printf("|__ Statistcs std: %fus median %fus q1 %fus q3 %fus \n",std_phy_proc_rx_demod, rx_demod_median, rx_demod_q1, rx_demod_q3); - printf("DLSCH unscrambling time :%f us (%d trials)\n",(double)UE->dlsch_unscrambling_stats.diff/UE->dlsch_unscrambling_stats.trials/cpu_freq_GHz/1000.0, - UE->dlsch_unscrambling_stats.trials); - std_phy_proc_rx_dec = sqrt((double)UE->dlsch_decoding_stats[UE->current_thread_id[subframe]].diff_square/pow(cpu_freq_GHz,2)/pow(1000, - 2)/UE->dlsch_decoding_stats[UE->current_thread_id[subframe]].trials - pow((double)UE->dlsch_decoding_stats[UE->current_thread_id[subframe]].diff/UE->dlsch_decoding_stats[UE->current_thread_id[subframe]].trials/cpu_freq_GHz/1000,2)); - printf("DLSCH Decoding time (%02.2f Mbit/s, avg iter %1.2f) :%f us (%d trials, max %f)\n", - eNB->dlsch[0][0]->harq_processes[0]->TBS/1000.0,(double)avg_iter/iter_trials, - (double)UE->dlsch_decoding_stats[UE->current_thread_id[subframe]].diff/UE->dlsch_decoding_stats[UE->current_thread_id[subframe]].trials/cpu_freq_GHz/1000.0,UE->dlsch_decoding_stats[UE->current_thread_id[subframe]].trials, - (double)UE->dlsch_decoding_stats[UE->current_thread_id[subframe]].max/cpu_freq_GHz/1000.0); - printf("|__ Statistcs std: %fus median %fus q1 %fus q3 %fus \n",std_phy_proc_rx_dec, rx_dec_median, rx_dec_q1, rx_dec_q3); - printf("|__ DLSCH Rate Unmatching :%f us (%d trials)\n", - (double)UE->dlsch_rate_unmatching_stats.diff/UE->dlsch_rate_unmatching_stats.trials/cpu_freq_GHz/1000.0,UE->dlsch_rate_unmatching_stats.trials); - printf("|__ DLSCH Turbo Decoding(%d bits) :%f us (%d trials)\n", - UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[0]->Cminus ? UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[0]->Kminus : UE->dlsch[UE->current_thread_id[subframe]][0][0]->harq_processes[0]->Kplus, - (double)UE->dlsch_turbo_decoding_stats.diff/UE->dlsch_turbo_decoding_stats.trials/cpu_freq_GHz/1000.0,UE->dlsch_turbo_decoding_stats.trials); - printf(" |__ init %f us (cycles/iter %f, %d trials)\n", - (double)UE->dlsch_tc_init_stats.diff/UE->dlsch_tc_init_stats.trials/cpu_freq_GHz/1000.0, - (double)UE->dlsch_tc_init_stats.diff/UE->dlsch_tc_init_stats.trials/((double)avg_iter/iter_trials), - UE->dlsch_tc_init_stats.trials); - printf(" |__ alpha %f us (cycles/iter %f, %d trials)\n", - (double)UE->dlsch_tc_alpha_stats.diff/UE->dlsch_tc_alpha_stats.trials/cpu_freq_GHz/1000.0, - (double)UE->dlsch_tc_alpha_stats.diff/UE->dlsch_tc_alpha_stats.trials*2, - UE->dlsch_tc_alpha_stats.trials); - printf(" |__ beta %f us (cycles/iter %f,%d trials)\n", - (double)UE->dlsch_tc_beta_stats.diff/UE->dlsch_tc_beta_stats.trials/cpu_freq_GHz/1000.0, - (double)UE->dlsch_tc_beta_stats.diff/UE->dlsch_tc_beta_stats.trials*2, - UE->dlsch_tc_beta_stats.trials); - printf(" |__ gamma %f us (cycles/iter %f,%d trials)\n", - (double)UE->dlsch_tc_gamma_stats.diff/UE->dlsch_tc_gamma_stats.trials/cpu_freq_GHz/1000.0, - (double)UE->dlsch_tc_gamma_stats.diff/UE->dlsch_tc_gamma_stats.trials*2, - UE->dlsch_tc_gamma_stats.trials); - printf(" |__ ext %f us (cycles/iter %f,%d trials)\n", - (double)UE->dlsch_tc_ext_stats.diff/UE->dlsch_tc_ext_stats.trials/cpu_freq_GHz/1000.0, - (double)UE->dlsch_tc_ext_stats.diff/UE->dlsch_tc_ext_stats.trials*2, - UE->dlsch_tc_ext_stats.trials); - printf(" |__ intl1 %f us (cycles/iter %f,%d trials)\n", - (double)UE->dlsch_tc_intl1_stats.diff/UE->dlsch_tc_intl1_stats.trials/cpu_freq_GHz/1000.0, - (double)UE->dlsch_tc_intl1_stats.diff/UE->dlsch_tc_intl1_stats.trials, - UE->dlsch_tc_intl1_stats.trials); - printf(" |__ intl2+HD+CRC %f us (cycles/iter %f,%d trials)\n", - (double)UE->dlsch_tc_intl2_stats.diff/UE->dlsch_tc_intl2_stats.trials/cpu_freq_GHz/1000.0, - (double)UE->dlsch_tc_intl2_stats.diff/UE->dlsch_tc_intl2_stats.trials, - UE->dlsch_tc_intl2_stats.trials); + UE->dlsch_tc_intl1_stats.trials/(double)UE->dlsch_tc_init_stats.trials, + (double)UE->dlsch_turbo_decoding_stats.diff/UE->dlsch_turbo_decoding_stats.trials*timeBase, + (int)((double)UE->dlsch_turbo_decoding_stats.diff/UE->dlsch_turbo_decoding_stats.trials), + UE->dlsch_turbo_decoding_stats.trials); + printStatIndent2(&UE->dlsch_tc_init_stats,"init", UE->dlsch_tc_init_stats.trials); + printStatIndent2(&UE->dlsch_tc_alpha_stats,"alpha", UE->dlsch_tc_init_stats.trials); + printStatIndent2(&UE->dlsch_tc_beta_stats,"beta", UE->dlsch_tc_init_stats.trials); + printStatIndent2(&UE->dlsch_tc_gamma_stats,"gamma", UE->dlsch_tc_init_stats.trials); + printStatIndent2(&UE->dlsch_tc_ext_stats,"ext", UE->dlsch_tc_init_stats.trials); + printStatIndent2(&UE->dlsch_tc_intl1_stats,"turbo internal interleaver", UE->dlsch_tc_init_stats.trials); + printStatIndent2(&UE->dlsch_tc_intl2_stats,"intl2+HardDecode+CRC", UE->dlsch_tc_init_stats.trials); + } if ((transmission_mode != 3) && (transmission_mode != 4)) { @@ -2399,7 +2197,7 @@ int main(int argc, char **argv) eNB->dlsch_modulation_stats.trials, eNB->dlsch_scrambling_stats.trials, eNB->dlsch_encoding_stats.trials, - UE->phy_proc_rx[UE->current_thread_id[subframe]].trials, + phy_proc_rx_tot.trials, UE->ofdm_demod_stats.trials, UE->dlsch_rx_pdcch_stats.trials, UE->dlsch_llr_stats.trials, @@ -2412,7 +2210,7 @@ int main(int argc, char **argv) get_time_meas_us(&eNB->dlsch_modulation_stats), get_time_meas_us(&eNB->dlsch_scrambling_stats), get_time_meas_us(&eNB->dlsch_encoding_stats), - get_time_meas_us(&UE->phy_proc_rx[UE->current_thread_id[subframe]]), + get_time_meas_us(&phy_proc_rx_tot), nsymb*get_time_meas_us(&UE->ofdm_demod_stats), get_time_meas_us(&UE->dlsch_rx_pdcch_stats), 3*get_time_meas_us(&UE->dlsch_llr_stats), @@ -2420,45 +2218,36 @@ int main(int argc, char **argv) get_time_meas_us(&UE->dlsch_decoding_stats[UE->current_thread_id[subframe]]) ); //fprintf(time_meas_fd,"eNB_PROC_TX_STD;eNB_PROC_TX_MAX;eNB_PROC_TX_MIN;eNB_PROC_TX_MED;eNB_PROC_TX_Q1;eNB_PROC_TX_Q3;eNB_PROC_TX_DROPPED;\n"); - fprintf(time_meas_fd,"%f;%f;%f;%f;%f;%f;%d;", std_phy_proc_tx, t_tx_max, t_tx_min, tx_median, tx_q1, tx_q3, n_tx_dropped); - + fprintf(time_meas_fd,"%f;%f;%f;%f;%f;%f;%d;",squareRoot(&UE->phy_proc_tx), t_tx_max, t_tx_min, median(table_tx), q1(table_tx), q3(table_tx), n_tx_dropped); //fprintf(time_meas_fd,"IFFT;\n"); - fprintf(time_meas_fd,"%f;%f;%f;%f;", std_phy_proc_tx_ifft, tx_ifft_median, tx_ifft_q1, tx_ifft_q3); - + fprintf(time_meas_fd,"%f;%f;%f;%f;", + squareRoot(&eNB->ofdm_mod_stats), + median(table_tx_ifft),q1(table_tx_ifft),q3(table_tx_ifft)); //fprintf(time_meas_fd,"MOD;\n"); - fprintf(time_meas_fd,"%f;%f;%f;%f;", std_phy_proc_tx_mod, tx_mod_median, tx_mod_q1, tx_mod_q3); - + fprintf(time_meas_fd,"%f;%f;%f;%f;", + squareRoot(&eNB->dlsch_modulation_stats), + median(table_tx_mod), q1(table_tx_mod), q3(table_tx_mod)); //fprintf(time_meas_fd,"ENC;\n"); - fprintf(time_meas_fd,"%f;%f;%f;%f;", std_phy_proc_tx_enc, tx_enc_median, tx_enc_q1, tx_enc_q3); - - - //fprintf(time_meas_fd,"UE_PROC_RX_STD;UE_PROC_RX_MAX;UE_PROC_RX_MIN;UE_PROC_RX_MED;UE_PROC_RX_Q1;UE_PROC_RX_Q3;UE_PROC_RX_DROPPED;\n"); - fprintf(time_meas_fd,"%f;%f;%f;%f;%f;%f;%d;", std_phy_proc_rx, t_rx_max, t_rx_min, rx_median, rx_q1, rx_q3, n_rx_dropped); - + fprintf(time_meas_fd,"%f;%f;%f;%f;", + squareRoot(&eNB->dlsch_encoding_stats), + median(table_tx_enc),q1(table_tx_enc),q3(table_tx_enc)); + //fprintf(time_meas_fd,"eNB_PROC_RX_STD;eNB_PROC_RX_MAX;eNB_PROC_RX_MIN;eNB_PROC_RX_MED;eNB_PROC_RX_Q1;eNB_PROC_RX_Q3;eNB_PROC_RX_DROPPED;\n"); + fprintf(time_meas_fd,"%f;%f;%f;%f;%f;%f;%d;", + squareRoot(&phy_proc_rx_tot), t_rx_max, t_rx_min, + median(table_rx), q1(table_rx), q3(table_rx), n_rx_dropped); //fprintf(time_meas_fd,"FFT;\n"); - fprintf(time_meas_fd,"%f;%f;%f;%f;", std_phy_proc_rx_fft, rx_fft_median, rx_fft_q1, rx_fft_q3); - + fprintf(time_meas_fd,"%f;%f;%f;%f;", + squareRoot(&UE->ofdm_demod_stats), + median(table_rx_fft), q1(table_rx_fft), q3(table_rx_fft)); //fprintf(time_meas_fd,"DEMOD;\n"); - fprintf(time_meas_fd,"%f;%f;%f;%f;", std_phy_proc_rx_demod,rx_demod_median, rx_demod_q1, rx_demod_q3); - + fprintf(time_meas_fd,"%f;%f;%f;%f;", + squareRoot(&UE->dlsch_demodulation_stats), + median(table_rx_demod), q1(table_rx_demod), q3(table_rx_demod)); //fprintf(time_meas_fd,"DEC;\n"); - fprintf(time_meas_fd,"%f;%f;%f;%f\n", std_phy_proc_rx_dec, rx_dec_median, rx_dec_q1, rx_dec_q3); + fprintf(time_meas_fd,"%f;%f;%f;%f\n", + squareRoot(&UE->dlsch_decoding_stats[subframe]), + median(table_rx_dec), q1(table_rx_dec), q3(table_rx_dec)); - - /* - fprintf(time_meas_fd,"%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;%d;", - eNB->phy_proc_tx.trials, - eNB->ofdm_mod_stats.trials, - eNB->dlsch_modulation_stats.trials, - eNB->dlsch_scrambling_stats.trials, - eNB->dlsch_encoding_stats.trials, - UE->phy_proc_rx[UE->current_thread_id[subframe]].trials, - UE->ofdm_demod_stats.trials, - UE->dlsch_rx_pdcch_stats.trials, - UE->dlsch_llr_stats.trials, - UE->dlsch_unscrambling_stats.trials, - UE->dlsch_decoding_stats[UE->current_thread_id[subframe]].trials); - */ printf("[passed] effective rate : %f (%2.1f%%,%f)): log and break \n",rate*effective_rate, 100*effective_rate, rate ); test_passed = 1; break; diff --git a/openair1/SIMULATION/LTE_PHY/ulsim.c b/openair1/SIMULATION/LTE_PHY/ulsim.c index 8c09da1daf..c015063b60 100644 --- a/openair1/SIMULATION/LTE_PHY/ulsim.c +++ b/openair1/SIMULATION/LTE_PHY/ulsim.c @@ -1,23 +1,23 @@ /* - Licensed to the OpenAirInterface (OAI) Software Alliance under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The OpenAirInterface Software Alliance licenses this file to You under - the OAI Public License, Version 1.1 (the "License"); you may not use this file - except in compliance with the License. - You may obtain a copy of the License at - - http://www.openairinterface.org/?page_id=698 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - ------------------------------------------------------------------------------- - For more information about the OpenAirInterface (OAI) Software Alliance: - contact@openairinterface.org -*/ + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ /*! \file ulsim.c \brief Top-level UL simulator @@ -60,32 +60,7 @@ double cpuf; #define inMicroS(a) (((double)(a))/(cpu_freq_GHz*1000.0)) //#define MCS_COUNT 23//added for PHY abstraction -static int cmpdouble(const void *p1, const void *p2) { - return *(double *)p1 > *(double *)p2; -} - -double median(varArray_t *input) { - return *(double *)((uint8_t *)(input+1)+(input->size/2)*input->atomSize); -} - -double q1(varArray_t *input) { - return *(double *)((uint8_t *)(input+1)+(input->size/4)*input->atomSize); -} - -double q3(varArray_t *input) { - return *(double *)((uint8_t *)(input+1)+(3*input->size/4)*input->atomSize); -} - -void dumpVarArray(varArray_t *input) { - double *ptr=dataArray(input); - printf("dumping size=%ld\n", input->size); - - for (int i=0; i < input->size; i++) - printf("%.1f:", *ptr++); - - printf("\n"); -} - +#include channel_desc_t *eNB2UE[NUMBER_OF_eNB_MAX][NUMBER_OF_UE_MAX]; channel_desc_t *UE2eNB[NUMBER_OF_UE_MAX][NUMBER_OF_eNB_MAX]; //Added for PHY abstractionopenair1/PHY/TOOLS/lte_phy_scope.h @@ -348,48 +323,8 @@ void fill_ulsch_dci(PHY_VARS_eNB *eNB, ul_req->tl.tag = NFAPI_UL_CONFIG_REQUEST_BODY_TAG; } -void printStatIndent(time_stats_t *ptr, char *txt) { - printf("|__ %-50s %.2f us (%d trials)\n", - txt, - inMicroS(ptr->diff/ptr->trials), - ptr->trials); -} - -void printStatIndent2(time_stats_t *ptr, char *txt, int turbo_iter) { - double timeBase=1/(1000*cpu_freq_GHz); - printf(" |__ %-45s %.2f us (cycles/block %7g, %5d trials)\n", - txt, - ((double)ptr->diff)/ptr->trials*timeBase, - round(((double)ptr->diff)/turbo_iter), - ptr->trials); -} - -double squareRoot(time_stats_t *ptr) { - double timeBase=1/(1000*cpu_freq_GHz); - return sqrt((double)ptr->diff_square*pow(timeBase,2)/ptr->trials - - pow((double)ptr->diff/ptr->trials*timeBase,2)); -} - -void printDistribution(time_stats_t *ptr, varArray_t *sortedList, char *txt) { - double timeBase=1/(1000*cpu_freq_GHz); - printf("%-50s :%.2f us (%d trials)\n", - txt, - (double)ptr->diff/ptr->trials*timeBase, - ptr->trials); - printf("|__ Statistics std=%.2f, median=%.2f, q1=%.2f, q3=%.2f µs (on %ld trials)\n", - squareRoot(ptr), median(sortedList),q1(sortedList),q3(sortedList), sortedList->size); -} - -void logDistribution(FILE* fd, time_stats_t *ptr, varArray_t *sortedList, int dropped) { - fprintf(fd,"%f;%f;%f;%f;%f;%f;%d;", - squareRoot(ptr), - (double)ptr->max, *(double*)dataArray(sortedList), - median(sortedList),q1(sortedList),q3(sortedList), - dropped); -} - enum eTypes { eBool, eInt, eFloat, eText }; -static int verbose,disable_bundling=0,cqi_flag=0, extended_prefix_flag=0, test_perf=0, subframe=3, transmission_m=1,n_rx=1; +static int verbose,help,disable_bundling=0,cqi_flag=0, extended_prefix_flag=0, test_perf=0, subframe=3, transmission_m=1,n_rx=1; int main(int argc, char **argv) { int i,j,aa,u; @@ -505,13 +440,13 @@ int main(int argc, char **argv) { //set_glog(LOG_DEBUG,LOG_MED); //hapZEbm:n:Y:X:x:s:w:e:q:d:D:O:c:r:i:f:y:c:oA:C:R:g:N:l:S:T:QB:PI:LF static paramdef_t options[] = { - { "awgn", "Additive white gaussian noise", PARAMFLAG_BOOL, strptr:NULL, defintval:0, TYPE_INT, 0, NULL, NULL }, + { "awgn", "Use AWGN channel and not multipath", PARAMFLAG_BOOL, strptr:NULL, defintval:0, TYPE_INT, 0, NULL, NULL }, { "BnbRBs", "The LTE bandwith in RBs (100 is 20MHz)",0, iptr:&N_RB_DL, defintval:25, TYPE_INT, 0 }, { "mcs", "The MCS to use", 0, iptr:&mcs, defintval:10, TYPE_INT, 0 }, { "nb_frame", "number of frame in a test",0, iptr:&n_frames, defintval:1, TYPE_INT, 0 }, { "snr", "starting snr", 0, dblptr:&snr0, defdblval:-2.9, TYPE_DOUBLE, 0 }, { "wsnrInterrupt", "snr int ?", 0, dblptr:&snr_int, defdblval:30, TYPE_DOUBLE, 0 }, - { "e_snr_step", "step increasint snr",0, dblptr:&input_snr_step, defdblval:0.2, TYPE_DOUBLE, 0 }, + { "e_snr_step", "step increasing snr",0, dblptr:&input_snr_step, defdblval:0.2, TYPE_DOUBLE, 0 }, { "rb_dynamic", "number of rb in dynamic allocation",0, iptr:NULL, defintval:0, TYPE_INT, 0 }, { "first_rb", "first rb used in dynamic allocation",0, iptr:&first_rb, defintval:0, TYPE_INT, 0 }, { "osrs", "enable srs generation",PARAMFLAG_BOOL, iptr:&srs_flag, defintval:0, TYPE_INT, 0 }, @@ -538,37 +473,12 @@ int main(int argc, char **argv) { { "bundling_disable", "bundling disable",PARAMFLAG_BOOL, iptr:&disable_bundling, defintval:0, TYPE_INT, 0 }, { "Y", "n_ch_rlz",0, iptr:&n_ch_rlz, defintval:1, TYPE_INT, 0 }, { "X", "abstx", PARAMFLAG_BOOL, iptr:&abstx, defintval:0, TYPE_INT, 0 }, - { "Operf", "test perf mode ?",0, iptr:&test_perf, defintval:0, TYPE_INT, 0 }, + { "Operf", "Set the percentage of effective rate to testbench the modem performance (typically 30 and 70, range 1-100)",0, iptr:&test_perf, defintval:0, TYPE_INT, 0 }, { "verbose", "display debug text", PARAMFLAG_BOOL, iptr:&verbose, defintval:0, TYPE_INT, 0 }, + { "help", "display help and exit", PARAMFLAG_BOOL, iptr:&help, defintval:0, TYPE_INT, 0 }, { "", "",0, iptr:NULL, defintval:0, TYPE_INT, 0 }, }; - int l; - - for(l=0; options[l].optname[0]!=0; l++) {}; - - struct option *long_options=calloc(sizeof(struct option),l); - - for(int i=0; options[i].optname[0]!=0; i++) { - long_options[i].name=options[i].optname; - long_options[i].has_arg=options[i].paramflags==PARAMFLAG_BOOL?no_argument:required_argument; - - if ( options[i].voidptr) - switch (options[i].type) { - case TYPE_INT: - *options[i].iptr=options[i].defintval; - break; - - case TYPE_DOUBLE: - *options[i].dblptr=options[i].defdblval; - break; - - default: - printf("not parsed type for default value %s\n", options[i].optname ); - exit(1); - } - - continue; - }; + struct option * long_options = parse_oai_options(options); int option_index; @@ -579,113 +489,121 @@ int main(int argc, char **argv) { if (long_options[option_index].has_arg==no_argument) *(bool *)options[option_index].iptr=1; else switch (options[option_index].type) { - case TYPE_INT: - *(int *)options[option_index].iptr=atoi(optarg); - break; + case TYPE_INT: + *(int *)options[option_index].iptr=atoi(optarg); + break; - case TYPE_DOUBLE: - *(double *)options[option_index].dblptr=atof(optarg); - break; + case TYPE_DOUBLE: + *(double *)options[option_index].dblptr=atof(optarg); + break; - default: - printf("not decoded type.\n"); - exit(1); + case TYPE_UINT8: + *(uint8_t *)options[option_index].dblptr=atoi(optarg); + break; + + case TYPE_UINT16: + *(uint16_t *)options[option_index].dblptr=atoi(optarg); + break; + + default: + printf("not decoded type.\n"); + exit(1); } continue; } switch (long_options[option_index].name[0]) { - case 'T': - tdd_config=atoi(optarg); - frame_type=TDD; - break; + case 'T': + tdd_config=atoi(optarg); + frame_type=TDD; + break; - case 'a': - channel_model = AWGN; - chMod = 1; - break; + case 'a': + channel_model = AWGN; + chMod = 1; + break; - case 'g': - strncpy(channel_model_input,optarg,9); - struct tmp { - char opt; - int m; - int M; - } - tmp[]= { - {'A',SCM_A,2}, - {'B',SCM_B,3}, - {'C',SCM_C,4}, - {'D',SCM_D,5}, - {'E',EPA,6}, - {'G',ETU,8}, - {'H',Rayleigh8,9}, - {'I',Rayleigh1,10}, - {'J',Rayleigh1_corr,11}, - {'K',Rayleigh1_anticorr,12}, - {'L',Rice8,13}, - {'M',Rice1,14}, - {'N',AWGN,1}, - {0,0,0} - }; - struct tmp *ptr; + case 'g': + strncpy(channel_model_input,optarg,9); + struct tmp { + char opt; + int m; + int M; + } + tmp[]= { + {'A',SCM_A,2}, + {'B',SCM_B,3}, + {'C',SCM_C,4}, + {'D',SCM_D,5}, + {'E',EPA,6}, + {'G',ETU,8}, + {'H',Rayleigh8,9}, + {'I',Rayleigh1,10}, + {'J',Rayleigh1_corr,11}, + {'K',Rayleigh1_anticorr,12}, + {'L',Rice8,13}, + {'M',Rice1,14}, + {'N',AWGN,1}, + {0,0,0} + }; + struct tmp *ptr; - for (ptr=tmp; ptr->opt!=0; ptr++) - if ( ptr->opt == optarg[0] ) { - channel_model=ptr->m; - chMod=ptr->M; - break; - } + for (ptr=tmp; ptr->opt!=0; ptr++) + if ( ptr->opt == optarg[0] ) { + channel_model=ptr->m; + chMod=ptr->M; + break; + } - AssertFatal(ptr->opt != 0, "Unsupported channel model: %s !\n", optarg ); - break; + AssertFatal(ptr->opt != 0, "Unsupported channel model: %s !\n", optarg ); + break; - case 'x': - transmission_m=atoi(optarg); - AssertFatal(transmission_m==1 || transmission_m==2, - "Unsupported transmission mode %d\n",transmission_m); - break; + case 'x': + transmission_m=atoi(optarg); + AssertFatal(transmission_m==1 || transmission_m==2, + "Unsupported transmission mode %d\n",transmission_m); + break; - case 'r': - nb_rb = atoi(optarg); - nb_rb_set = 1; - break; + case 'r': + nb_rb = atoi(optarg); + nb_rb_set = 1; + break; //case 'c': // cyclic_shift = atoi(optarg); // break; - case 'i': - input_fdUL = fopen(optarg,"r"); - printf("Reading in %s (%p)\n",optarg,input_fdUL); - AssertFatal(input_fdUL != (FILE *)NULL,"Unknown file %s\n",optarg); - break; + case 'i': + input_fdUL = fopen(optarg,"r"); + printf("Reading in %s (%p)\n",optarg,input_fdUL); + AssertFatal(input_fdUL != (FILE *)NULL,"Unknown file %s\n",optarg); + break; - case 'A': - beta_ACK = atoi(optarg); - AssertFatal(beta_ACK>15,"beta_ack must be in (0..15)\n"); - break; + case 'A': + beta_ACK = atoi(optarg); + AssertFatal(beta_ACK>15,"beta_ack must be in (0..15)\n"); + break; - case 'C': - beta_CQI = atoi(optarg); - AssertFatal((beta_CQI>15)||(beta_CQI<2),"beta_cqi must be in (2..15)\n"); - break; + case 'C': + beta_CQI = atoi(optarg); + AssertFatal((beta_CQI>15)||(beta_CQI<2),"beta_cqi must be in (2..15)\n"); + break; - case 'R': - beta_RI = atoi(optarg); - AssertFatal((beta_RI>15)||(beta_RI<2),"beta_ri must be in (0..13)\n"); - break; + case 'R': + beta_RI = atoi(optarg); + AssertFatal((beta_RI>15)||(beta_RI<2),"beta_ri must be in (0..13)\n"); + break; - case 'P': - dump_perf=1; - opp_enabled=1; - break; + case 'P': + dump_perf=1; + opp_enabled=1; + break; - default: - printf("Wrong option\n"); - exit(1); - break; + default: + printf("Wrong option: %s\n",long_options[option_index].name); + exit(1); + break; } } @@ -694,34 +612,12 @@ int main(int argc, char **argv) { exit(1); } - paramdef_t *ptr=options ; - for( ptr=options; ptr->optname[0]!=0; ptr++) { - char varText[256]="need specific display"; - - if (ptr->voidptr != NULL) { - if ( (ptr->paramflags & PARAMFLAG_BOOL) ) - strcpy(varText, *(bool *)ptr->iptr ? "True": "False" ); - else switch (ptr->type) { - case TYPE_INT: - sprintf(varText,"%d",*ptr->iptr); - break; - - case TYPE_DOUBLE: - sprintf(varText,"%.2f",*ptr->dblptr); - break; - - default: - printf("not decoded type\n"); - exit(1); - } - } - - printf("Option: %20s set to %s\n",ptr->optname, varText); - - if (verbose) - printf("%s\n",ptr->helpstr); - } + if (help || verbose ) + display_options_values(options, true); + if (help) + exit(0); + set_parallel_conf("PARALLEL_RU_L1_TRX_SPLIT"); set_worker_conf("WORKER_ENABLE"); RC.nb_L1_inst = 1; From 63d3bf148ec8088fead694cb0f612342e292df90 Mon Sep 17 00:00:00 2001 From: laurent Date: Fri, 12 Oct 2018 19:29:58 +0200 Subject: [PATCH 009/233] a printf with a removed variable in last commit --- targets/RT/USER/lte-enb.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/targets/RT/USER/lte-enb.c b/targets/RT/USER/lte-enb.c index e2415e1156..0b0cc8ea0a 100644 --- a/targets/RT/USER/lte-enb.c +++ b/targets/RT/USER/lte-enb.c @@ -257,9 +257,8 @@ static inline int rxtx(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc, char *thread_nam LOG_D(PHY,"%s() Exit proc[rx:%d%d tx:%d%d]\n", __FUNCTION__, proc->frame_rx, proc->subframe_rx, proc->frame_tx, proc->subframe_tx); - LOG_D(PHY, "rxtx:%lld nfapi:%lld phy:%lld tx:%lld rx:%lld prach:%lld ofdm:%lld ", + LOG_D(PHY, "rxtx:%lld nfapi:%lld tx:%lld rx:%lld prach:%lld ofdm:%lld ", softmodem_stats_rxtx_sf.p_time, nfapi_meas.p_time, - TICK_TO_US(eNB->phy_proc), TICK_TO_US(eNB->phy_proc_tx), TICK_TO_US(eNB->phy_proc_rx), TICK_TO_US(eNB->rx_prach), From 97ac7809723c91b426196f6dcc41b8325a8f626e Mon Sep 17 00:00:00 2001 From: laurent Date: Mon, 15 Oct 2018 10:39:28 +0200 Subject: [PATCH 010/233] fix test case options style for getopts_long() --- cmake_targets/autotests/test_case_list.xml | 28 +++++++++++----------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/cmake_targets/autotests/test_case_list.xml b/cmake_targets/autotests/test_case_list.xml index e7f274c2d0..fc4567269e 100644 --- a/cmake_targets/autotests/test_case_list.xml +++ b/cmake_targets/autotests/test_case_list.xml @@ -956,20 +956,20 @@ $OPENAIR_DIR/cmake_targets/autotests/tools/free_mem.bash $OPENAIR_DIR/targets/bin/dlsim.Rel14 - -m5 -gF -s-1 -w1.0 -f.2 -n500 -B50 -c2 -z2 -O60 - -m4 -gF -s0 -w1.0 -f.2 -n500 -B6 -c4 -z2 -O60 - -m15 -gF -s6.7 -w1.0 -f.2 -n500 -B50 -c2 -z2 -O60 - -m15 -gF -s6.7 -w1.0 -f.2 -n500 -B25 -c2 -z2 -O60 - -m15 -gG -s1.4 -w1.0 -f.2 -n500 -B50 -c2 -z2 -O25 - -m15 -gG -s1.4 -w1.0 -f.2 -n500 -B25 -c2 -z2 -O25 - -m25 -gF -s17.4 -w1.0 -f.2 -n500 -B25 -c3 -z2 -O60 - -m25 -gF -s17.5 -w1.0 -f.2 -n500 -B25 -c3 -z2 -r1022 -O60 - -m26 -gF -s17.7 -w1.0 -f.2 -n500 -B50 -c2 -z2 -O60 - -m26 -gF -s17.6 -w1.0 -f.2 -n500 -B100 -c2 -z2 -O60 - -m26 -gF -s17.3 -w1.0 -f.2 -n500 -B100 -c2 -z2 -r1600 -O60 - -m26 -gF -s16.6 -w1.0 -f.2 -n500 -B100 -c2 -z2 -r1899 -O60 - -m14 -gF -s6.8 -w1.0 -f.2 -n500 -B50 -c2 -x2 -y2 -z2 -O60 - -m13 -gF -s5.9 -w1.0 -f.2 -n500 -B25 -c3 -x2 -y2 -z2 -O60 + -m=5 -g=F -s=-1= -w=1.0 -f=.2 -n=500 -B=50 -c=2 -z=2 -O=60 + -m=4 -g=F -s=0 -w=1.0 -f=.2 -n=500 -B=6 -c=4 -z=2 -O=60 + -m=15 -g=F -s=6.7 -w=1.0 -f=.2 -n=500 -B=50 -c=2 -z=2 -O=60 + -m=15 -g=F -s=6.7 -w=1.0 -f=.2 -n=500 -B=25 -c=2 -z=2 -O=60 + -m=15 -g=G -s=1.4 -w=1.0 -f=.2 -n=500 -B=50 -c=2 -z=2 -O=25 + -m=15 -g=G -s=1.4 -w=1.0 -f=.2 -n=500 -B=25 -c=2 -z=2 -O=25 + -m=25 -g=F -s=17.4 -w=1.0 -f=.2 -n=500 -B=25 -c=3 -z=2 -O=60 + -m=25 -g=F -s=17.5 -w=1.0 -f=.2 -n=500 -B=25 -c=3 -z=2 -r=1022 -O=60 + -m=26 -g=F -s=17.7 -w=1.0 -f=.2 -n=500 -B=50 -c=2 -z=2 -O=60 + -m=26 -g=F -s=17.6 -w=1.0 -f=.2 -n=500 -B=100 -c=2 -z=2 -O=60 + -m=26 -g=F -s=17.3 -w=1.0 -f=.2 -n=500 -B=100 -c=2 -z=2 -r=1600 -O=60 + -m=26 -g=F -s=16.6 -w=1.0 -f=.2 -n=500 -B=100 -c=2 -z=2 -r=1899 -O=60 + -m=14 -g=F -s=6.8 -w=1.0 -f=.2 -n=500 -B=50 -c=2 -x=2 -y=2 -z=2 -O=60 + -m=13 -g=F -s=5.9 -w=1.0 -f=.2 -n=500 -B=25 -c=3 -x=2 -y=2 -z=2 -O=60 dlsim.test1 dlsim.test5 dlsim.test6 dlsim.test6b dlsim.test7 dlsim.test7b dlsim.test10 dlsim.test10b dlsim.test11 dlsim.TM2_test1 dlsim.TM2_test1b "passed" segmentation fault|assertion|exiting|fatal From 0d58ed224fed53ed3a7f96c7c3adfea81d52bece Mon Sep 17 00:00:00 2001 From: Y_Tomita Date: Wed, 17 Oct 2018 09:48:15 +0900 Subject: [PATCH 011/233] Change type for 256UEs test , abnormal exit and add definition of UE's thread ID for multiple UEs simulation. --- openair2/LAYER2/MAC/mac_extern.h | 2 +- openair2/LAYER2/MAC/mac_vars.h | 5 +++-- openair2/LAYER2/PDCP_v10.1.0/pdcp.c | 1 + openair2/LAYER2/PDCP_v10.1.0/pdcp.h | 2 +- openair2/RRC/LTE/rrc_extern.h | 2 +- openair2/RRC/LTE/rrc_vars.h | 2 +- 6 files changed, 8 insertions(+), 6 deletions(-) mode change 100644 => 100755 openair2/LAYER2/MAC/mac_extern.h mode change 100644 => 100755 openair2/LAYER2/MAC/mac_vars.h mode change 100644 => 100755 openair2/LAYER2/PDCP_v10.1.0/pdcp.c mode change 100644 => 100755 openair2/LAYER2/PDCP_v10.1.0/pdcp.h mode change 100644 => 100755 openair2/RRC/LTE/rrc_extern.h mode change 100644 => 100755 openair2/RRC/LTE/rrc_vars.h diff --git a/openair2/LAYER2/MAC/mac_extern.h b/openair2/LAYER2/MAC/mac_extern.h old mode 100644 new mode 100755 index ca72882471..10822465f1 --- a/openair2/LAYER2/MAC/mac_extern.h +++ b/openair2/LAYER2/MAC/mac_extern.h @@ -64,7 +64,7 @@ extern eNB_DLSCH_INFO eNB_dlsch_info[NUMBER_OF_eNB_MAX][MAX_NUM_CCs][MAX_MOBILES extern unsigned char NB_INST; #endif extern unsigned char NB_eNB_INST; -extern unsigned char NB_UE_INST; +extern uint16_t NB_UE_INST; extern unsigned char NB_RN_INST; extern unsigned short NODE_ID[1]; diff --git a/openair2/LAYER2/MAC/mac_vars.h b/openair2/LAYER2/MAC/mac_vars.h old mode 100644 new mode 100755 index 76842afd38..071ed7391d --- a/openair2/LAYER2/MAC/mac_vars.h +++ b/openair2/LAYER2/MAC/mac_vars.h @@ -95,7 +95,7 @@ const uint8_t cqi2fmt2x_agg[MAX_SUPPORTED_BW][CQI_VALUE_RANGE] = { uint32_t RRC_CONNECTION_FLAG; -UE_MAC_INST *UE_mac_inst; //[NB_MODULE_MAX]; +UE_MAC_INST *UE_mac_inst = NULL; //[NB_MODULE_MAX]; MAC_RLC_XFACE *Mac_rlc_xface; /// Primary component carrier index of eNB @@ -109,7 +109,8 @@ eNB_DLSCH_INFO eNB_dlsch_info[NUMBER_OF_eNB_MAX][MAX_NUM_CCs][MAX_MOBILES_PER_EN #ifdef OPENAIR2 unsigned char NB_eNB_INST = 0; -unsigned char NB_UE_INST = 0; +uint16_t NB_UE_INST = 0; +uint16_t NB_THREAD_INST = 0; unsigned char NB_RN_INST = 0; unsigned char NB_INST = 0; #endif diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp.c b/openair2/LAYER2/PDCP_v10.1.0/pdcp.c old mode 100644 new mode 100755 index 05ddb4151f..15b970b319 --- a/openair2/LAYER2/PDCP_v10.1.0/pdcp.c +++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp.c @@ -67,6 +67,7 @@ extern int otg_enabled; #include "common/ran_context.h" extern RAN_CONTEXT_t RC; +hash_table_t *pdcp_coll_p = NULL; #ifdef MBMS_MULTICAST_OUT # include diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp.h b/openair2/LAYER2/PDCP_v10.1.0/pdcp.h old mode 100644 new mode 100755 index 054bb5fac4..75754664e9 --- a/openair2/LAYER2/PDCP_v10.1.0/pdcp.h +++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp.h @@ -542,7 +542,7 @@ sdu_size_t pdcp_input_sdu_remaining_size_to_read; (((hash_key_t)(sESSION_ID)) << 37) | \ (((hash_key_t)(0x0000000000000001)) << 63)) -hash_table_t *pdcp_coll_p; +extern hash_table_t *pdcp_coll_p; #endif /*@}*/ diff --git a/openair2/RRC/LTE/rrc_extern.h b/openair2/RRC/LTE/rrc_extern.h old mode 100644 new mode 100755 index 59200fb9cc..67504cb245 --- a/openair2/RRC/LTE/rrc_extern.h +++ b/openair2/RRC/LTE/rrc_extern.h @@ -51,7 +51,7 @@ extern LogicalChannelConfig_t SRB2_logicalChannelConfig_defaultValue; extern unsigned char NB_INST; #endif extern unsigned char NB_eNB_INST; -extern unsigned char NB_UE_INST; +extern uint16_t NB_UE_INST; extern unsigned short NODE_ID[1]; extern void* bigphys_malloc(int); #endif diff --git a/openair2/RRC/LTE/rrc_vars.h b/openair2/RRC/LTE/rrc_vars.h old mode 100644 new mode 100755 index 028a59f7d9..732be74aa1 --- a/openair2/RRC/LTE/rrc_vars.h +++ b/openair2/RRC/LTE/rrc_vars.h @@ -38,7 +38,7 @@ UE_PF_PO_t UE_PF_PO[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB]; pthread_mutex_t ue_pf_po_mutex; -UE_RRC_INST *UE_rrc_inst; +UE_RRC_INST *UE_rrc_inst = NULL; #include "LAYER2/MAC/mac_extern.h" #define MAX_U32 0xFFFFFFFF From 1791574de5b4771f7ea21e21e0546b6fac371390 Mon Sep 17 00:00:00 2001 From: Y_Tomita Date: Wed, 17 Oct 2018 09:52:53 +0900 Subject: [PATCH 012/233] Missing RRC_VERSION and sourceL2Id, destinationL2Id. --- openair2/NETWORK_DRIVER/MESH/local.h | 10 ++++++++++ 1 file changed, 10 insertions(+) mode change 100644 => 100755 openair2/NETWORK_DRIVER/MESH/local.h diff --git a/openair2/NETWORK_DRIVER/MESH/local.h b/openair2/NETWORK_DRIVER/MESH/local.h old mode 100644 new mode 100755 index e23188d357..82dfc0ac88 --- a/openair2/NETWORK_DRIVER/MESH/local.h +++ b/openair2/NETWORK_DRIVER/MESH/local.h @@ -64,6 +64,8 @@ #include "rrc_nas_primitives.h" #include "COMMON/platform_types.h" +#define MAKE_VERSION(a,b,c) ((a)*256+(b)*16+(c)) + struct rb_entity { nasRadioBearerId_t rab_id; nasSapId_t sapi; @@ -160,6 +162,10 @@ typedef struct pdcp_data_req_header_s { sdu_size_t data_size; signed int inst; ip_traffic_type_t traffic_type; +#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + uint32_t sourceL2Id; + uint32_t destinationL2Id; +#endif } pdcp_data_req_header_t; typedef struct pdcp_data_ind_header_s { @@ -167,6 +173,10 @@ typedef struct pdcp_data_ind_header_s { sdu_size_t data_size; signed int inst; ip_traffic_type_t dummy_traffic_type; +#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + uint32_t sourceL2Id; + uint32_t destinationL2Id; +#endif } pdcp_data_ind_header_t; extern struct net_device *nasdev[NB_INSTANCES_MAX]; From 1f4a9f343940aaf025cab1a3b20e5c2be0369263 Mon Sep 17 00:00:00 2001 From: Y_Tomita Date: Wed, 17 Oct 2018 09:54:08 +0900 Subject: [PATCH 013/233] Fix for abnormal exit because L2sim doesn't use pointer of D2D test. --- openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c | 38 ++++++++++++++++++++++-- 1 file changed, 35 insertions(+), 3 deletions(-) mode change 100644 => 100755 openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c b/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c old mode 100644 new mode 100755 index 92409d96dc..96a0ad26ce --- a/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c +++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c @@ -85,7 +85,7 @@ unsigned char pdcp_read_state_g = 0; #endif extern Packet_OTG_List_t *otg_pdcp_buffer; - +extern uint8_t nfapi_mode; #if defined(LINK_ENB_PDCP_TO_GTPV1U) # include "gtpv1u_eNB_task.h" # include "gtpv1u_eNB_defs.h" @@ -1072,7 +1072,22 @@ int pdcp_fifo_read_input_sdus (const protocol_ctxt_t* const ctxt_pP) pdcp_read_header_g.rb_id, rab_id, pdcp_read_header_g.data_size); - + if(nfapi_mode == 3){ + pdcp_data_req( + &ctxt, + SRB_FLAG_NO, + rab_id, + RLC_MUI_UNDEFINED, + RLC_SDU_CONFIRM_NO, + pdcp_read_header_g.data_size, + (unsigned char *)NLMSG_DATA(nas_nlh_rx), + PDCP_TRANSMISSION_MODE_DATA +#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + ,NULL + ,NULL +#endif + ); + }else{ pdcp_data_req( &ctxt, SRB_FLAG_NO, @@ -1087,6 +1102,7 @@ int pdcp_fifo_read_input_sdus (const protocol_ctxt_t* const ctxt_pP) ,&pdcp_read_header_g.destinationL2Id #endif ); + } } else { MSC_LOG_RX_DISCARDED_MESSAGE( (ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_PDCP_ENB:MSC_PDCP_UE, @@ -1130,7 +1146,22 @@ int pdcp_fifo_read_input_sdus (const protocol_ctxt_t* const ctxt_pP) pdcp_read_header_g.rb_id, DEFAULT_RAB_ID, pdcp_read_header_g.data_size); - + if(nfapi_mode == 3){ + pdcp_data_req ( + &ctxt, + SRB_FLAG_NO, + DEFAULT_RAB_ID, + RLC_MUI_UNDEFINED, + RLC_SDU_CONFIRM_NO, + pdcp_read_header_g.data_size, + (unsigned char *)NLMSG_DATA(nas_nlh_rx), + PDCP_TRANSMISSION_MODE_DATA +#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + ,NULL + ,NULL +#endif + ); + }else{ pdcp_data_req ( &ctxt, SRB_FLAG_NO, @@ -1145,6 +1176,7 @@ int pdcp_fifo_read_input_sdus (const protocol_ctxt_t* const ctxt_pP) ,&pdcp_read_header_g.destinationL2Id #endif ); + } } } From 53d6f992c92ab4760d64042ab670db52189f8d46 Mon Sep 17 00:00:00 2001 From: Y_Tomita Date: Wed, 17 Oct 2018 09:55:27 +0900 Subject: [PATCH 014/233] Fix for problems that eNB keeps waiting for signal of unused thread and eNB_thread_rxtx isn't created. --- targets/RT/USER/lte-enb.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) mode change 100644 => 100755 targets/RT/USER/lte-enb.c diff --git a/targets/RT/USER/lte-enb.c b/targets/RT/USER/lte-enb.c old mode 100644 new mode 100755 index e2415e1156..9ac7da46e7 --- a/targets/RT/USER/lte-enb.c +++ b/targets/RT/USER/lte-enb.c @@ -222,7 +222,7 @@ static inline int rxtx(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc, char *thread_nam } VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ULSCH_SCHEDULER , 1 ); - if(get_thread_parallel_conf() == PARALLEL_RU_L1_TRX_SPLIT){ + if(get_thread_parallel_conf() == PARALLEL_RU_L1_TRX_SPLIT && nfapi_mode != 2){ if(wait_on_condition(&proc[1].mutex_rxtx,&proc[1].cond_rxtx,&proc[1].pipe_ready,"wakeup_tx")<0) { LOG_E(PHY,"Frame %d, subframe %d: TX1 not ready\n",proc[1].frame_rx,proc[1].subframe_rx); return(-1); @@ -965,6 +965,10 @@ void init_eNB_proc(int inst) { pthread_create( &proc_rxtx[0].pthread_rxtx, attr0, eNB_thread_rxtx, proc ); pthread_create( &proc_rxtx[1].pthread_rxtx, attr1, tx_thread, proc); } + else if (nfapi_mode == 2) { + pthread_create( &proc_rxtx[0].pthread_rxtx, attr0, eNB_thread_rxtx, &proc_rxtx[0] ); + pthread_create( &proc_rxtx[1].pthread_rxtx, attr1, eNB_thread_rxtx, &proc_rxtx[1] ); + } pthread_create( &proc->pthread_prach, attr_prach, eNB_thread_prach, eNB ); #if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) pthread_create( &proc->pthread_prach_br, attr_prach_br, eNB_thread_prach_br, eNB ); From 33e8577f941360e2f3dd29748478be073ce194e2 Mon Sep 17 00:00:00 2001 From: Y_Tomita Date: Wed, 17 Oct 2018 10:01:05 +0900 Subject: [PATCH 015/233] Fix for problems that L2sim finishes in case of multiple UEs and UE L2sim keeps wating for a signal. --- targets/RT/USER/lte-uesoftmodem.c | 35 +++++++++++++++++++++++++++++-- 1 file changed, 33 insertions(+), 2 deletions(-) mode change 100644 => 100755 targets/RT/USER/lte-uesoftmodem.c diff --git a/targets/RT/USER/lte-uesoftmodem.c b/targets/RT/USER/lte-uesoftmodem.c old mode 100644 new mode 100755 index 69556b19f2..0081e7be8b --- a/targets/RT/USER/lte-uesoftmodem.c +++ b/targets/RT/USER/lte-uesoftmodem.c @@ -852,7 +852,7 @@ printf("~~~~~~~~~~~~~~~~~~~~successfully get the parallel config[%d], worker con printf("Running with %d UE instances\n",NB_UE_INST); - if (NB_UE_INST > 1 && simL1flag != 1) { + if (NB_UE_INST > 1 && simL1flag != 1 && nfapi_mode != 3) { printf("Running with more than 1 UE instance and simL1 is not active, this will result in undefined behaviour for now, exiting.\n"); abort(); } @@ -971,6 +971,8 @@ printf("~~~~~~~~~~~~~~~~~~~~successfully get the parallel config[%d], worker con RCConfig_sim(); } +// source code written in below moved to later to avoid keeping waiting for nfapi_sync_cond in wait_nfapi_init. +/* // start the main UE threads int eMBMS_active = 0; @@ -1001,7 +1003,7 @@ printf("~~~~~~~~~~~~~~~~~~~~successfully get the parallel config[%d], worker con PHY_vars_UE_g[0][CC_id]->rf_map.chain=CC_id+chain_offset; } } - +*/ cpuf=get_cpu_freq_GHz(); @@ -1090,7 +1092,36 @@ printf("~~~~~~~~~~~~~~~~~~~~successfully get the parallel config[%d], worker con } printf("NFAPI MODE:%s\n", nfapi_mode_str); + // start the main UE threads + int eMBMS_active = 0; + if (nfapi_mode==3) // UE-STUB-PNF + { + config_sync_var=0; + wait_nfapi_init("main?"); + //Panos: Temporarily we will be using single set of threads for multiple UEs. + //init_UE_stub(1,eMBMS_active,uecap_xer_in,emul_iface); + init_UE_stub_single_thread(NB_UE_INST,eMBMS_active,uecap_xer_in,emul_iface); + } + else { + init_UE(NB_UE_INST,eMBMS_active,uecap_xer_in,0,phy_test,UE_scan,UE_scan_carrier,mode,(int)rx_gain[0][0],tx_max_power[0], + frame_parms[0]); + } + + + if (phy_test==0) { + printf("Filling UE band info\n"); + fill_ue_band_info(); + dl_phy_sync_success (0, 0, 0, 1); + } + + if (nfapi_mode!=3){ + number_of_cards = 1; + for(CC_id=0; CC_idrf_map.card=0; + PHY_vars_UE_g[0][CC_id]->rf_map.chain=CC_id+chain_offset; + } + } // connect the TX/RX buffers From 4249ebbf8ba61391e896b9e0bcf92a156641423c Mon Sep 17 00:00:00 2001 From: Y_Tomita Date: Wed, 17 Oct 2018 10:05:41 +0900 Subject: [PATCH 016/233] Add function to create pre_scd_thread in case of L2sim. --- targets/RT/USER/lte-enb.c | 32 +++++++++ targets/RT/USER/lte-ru.c | 114 ++++++++++++++++++++++++++++++++ targets/RT/USER/lte-softmodem.c | 7 ++ targets/RT/USER/lte-softmodem.h | 1 + 4 files changed, 154 insertions(+) mode change 100644 => 100755 targets/RT/USER/lte-ru.c mode change 100644 => 100755 targets/RT/USER/lte-softmodem.c mode change 100644 => 100755 targets/RT/USER/lte-softmodem.h diff --git a/targets/RT/USER/lte-enb.c b/targets/RT/USER/lte-enb.c index 9ac7da46e7..a93a52a1a9 100755 --- a/targets/RT/USER/lte-enb.c +++ b/targets/RT/USER/lte-enb.c @@ -165,6 +165,8 @@ static inline int rxtx(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc, char *thread_nam // ******************************************************************* + RU_t *ru = RC.ru[0]; + if (nfapi_mode == 1) { // I am a PNF and I need to let nFAPI know that we have a (sub)frame tick @@ -230,6 +232,36 @@ static inline int rxtx(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc, char *thread_nam if (release_thread(&proc[1].mutex_rxtx,&proc[1].pipe_ready,"wakeup_tx")<0) return(-1); } +#if defined(PRE_SCD_THREAD) + if (nfapi_mode == 2){ + new_dlsch_ue_select_tbl_in_use = dlsch_ue_select_tbl_in_use; + dlsch_ue_select_tbl_in_use = !dlsch_ue_select_tbl_in_use; + memcpy(&pre_scd_eNB_UE_stats,&RC.mac[ru->eNB_list[0]->Mod_id]->UE_list.eNB_UE_stats, sizeof(eNB_UE_STATS)*MAX_NUM_CCs*NUMBER_OF_UE_MAX); + memcpy(&pre_scd_activeUE, &RC.mac[ru->eNB_list[0]->Mod_id]->UE_list.active, sizeof(boolean_t)*NUMBER_OF_UE_MAX); + if (pthread_mutex_lock(&ru->proc.mutex_pre_scd)!= 0) { + LOG_E( PHY, "[eNB] error locking proc mutex for eNB pre scd\n"); + exit_fun("error locking mutex_time"); + } + + ru->proc.instance_pre_scd++; + + if (ru->proc.instance_pre_scd == 0) { + if (pthread_cond_signal(&ru->proc.cond_pre_scd) != 0) { + LOG_E( PHY, "[eNB] ERROR pthread_cond_signal for eNB pre scd\n" ); + exit_fun( "ERROR pthread_cond_signal cond_pre_scd" ); + } + }else{ + LOG_E( PHY, "[eNB] frame %d subframe %d rxtx busy instance_pre_scd %d\n", + proc->frame_rx,proc->subframe_rx,ru->proc.instance_pre_scd ); + } + + if (pthread_mutex_unlock(&ru->proc.mutex_pre_scd)!= 0) { + LOG_E( PHY, "[eNB] error unlocking mutex_pre_scd mutex for eNB pre scd\n"); + exit_fun("error unlocking mutex_pre_scd"); + } + } +#endif + pthread_mutex_lock(&eNB->UL_INFO_mutex); eNB->UL_INFO.frame = proc->frame_rx; diff --git a/targets/RT/USER/lte-ru.c b/targets/RT/USER/lte-ru.c old mode 100644 new mode 100755 index 7002bc4ebd..750d8239da --- a/targets/RT/USER/lte-ru.c +++ b/targets/RT/USER/lte-ru.c @@ -120,6 +120,7 @@ extern volatile int oai_exit; extern int emulate_rf; extern int numerology; extern clock_source_t clock_source; +extern uint8_t dlsch_ue_select_tbl_in_use; extern PARALLEL_CONF_t get_thread_parallel_conf(void); extern WORKER_CONF_t get_thread_worker_conf(void); @@ -142,6 +143,11 @@ int connect_rau(RU_t *ru); extern uint16_t sf_ahead; +#if defined(PRE_SCD_THREAD) +void init_ru_vnf(void); +#endif + + /*************************************************************/ /* Functions to attach and configure RRU */ @@ -2798,6 +2804,114 @@ void stop_RU(int nb_ru) } } +//Some of the member of ru pointer is used in pre_scd. +//This funtion is for initializing ru pointer for L2 FAPI simulator. +#if defined(PRE_SCD_THREAD) +void init_ru_vnf(void) { + + int ru_id; + RU_t *ru; + RU_proc_t *proc; +// PHY_VARS_eNB *eNB0= (PHY_VARS_eNB *)NULL; + int i; + int CC_id; + + + dlsch_ue_select_tbl_in_use = 1; + + + // create status mask + RC.ru_mask = 0; + pthread_mutex_init(&RC.ru_mutex,NULL); + pthread_cond_init(&RC.ru_cond,NULL); + + // read in configuration file) + printf("configuring RU from file\n"); + RCconfig_RU(); + LOG_I(PHY,"number of L1 instances %d, number of RU %d, number of CPU cores %d\n",RC.nb_L1_inst,RC.nb_RU,get_nprocs()); + + if (RC.nb_CC != 0) + for (i=0;inum_RU=0; + + LOG_D(PHY,"Process RUs RC.nb_RU:%d\n",RC.nb_RU); + for (ru_id=0;ru_idrf_config_file = rf_config_file; + ru->idx = ru_id; + ru->ts_offset = 0; + // use eNB_list[0] as a reference for RU frame parameters + // NOTE: multiple CC_id are not handled here yet! + + if (ru->num_eNB > 0) { +// LOG_D(PHY, "%s() RC.ru[%d].num_eNB:%d ru->eNB_list[0]:%p RC.eNB[0][0]:%p rf_config_file:%s\n", __FUNCTION__, ru_id, ru->num_eNB, ru->eNB_list[0], RC.eNB[0][0], ru->rf_config_file); + + if (ru->eNB_list[0] == 0) + { + LOG_E(PHY,"%s() DJP - ru->eNB_list ru->num_eNB are not initialized - so do it manually\n", __FUNCTION__); + ru->eNB_list[0] = RC.eNB[0][0]; + ru->num_eNB=1; + // + // DJP - feptx_prec() / feptx_ofdm() parses the eNB_list (based on num_eNB) and copies the txdata_F to txdata in RU + // + } + else + { + LOG_E(PHY,"DJP - delete code above this %s:%d\n", __FILE__, __LINE__); + } + } + +// frame_parms is not used in L2 FAPI simulator +/* + eNB0 = ru->eNB_list[0]; + LOG_D(PHY, "RU FUnction:%d ru->if_south:%d\n", ru->function, ru->if_south); + LOG_D(PHY, "eNB0:%p\n", eNB0); + if (eNB0) + { + if ((ru->function != NGFI_RRU_IF5) && (ru->function != NGFI_RRU_IF4p5)) + AssertFatal(eNB0!=NULL,"eNB0 is null!\n"); + + if (eNB0) { + LOG_I(PHY,"Copying frame parms from eNB %d to ru %d\n",eNB0->Mod_id,ru->idx); + memcpy((void*)&ru->frame_parms,(void*)&eNB0->frame_parms,sizeof(LTE_DL_FRAME_PARMS)); + + // attach all RU to all eNBs in its list/ + LOG_D(PHY,"ru->num_eNB:%d eNB0->num_RU:%d\n", ru->num_eNB, eNB0->num_RU); + for (i=0;inum_eNB;i++) { + eNB0 = ru->eNB_list[i]; + eNB0->RU_list[eNB0->num_RU++] = ru; + } + } + } +*/ + LOG_I(PHY,"Initializing RRU descriptor %d : (%s,%s,%d)\n",ru_id,ru_if_types[ru->if_south],eNB_timing[ru->if_timing],ru->function); + +// set_function_spec_param(ru); + LOG_I(PHY,"Starting ru_thread %d\n",ru_id); + +// init_RU_proc(ru); + + proc = &ru->proc; + memset((void*)proc,0,sizeof(RU_proc_t)); + + proc->instance_pre_scd = -1; + pthread_mutex_init( &proc->mutex_pre_scd, NULL); + pthread_cond_init( &proc->cond_pre_scd, NULL); + pthread_create(&proc->pthread_pre_scd, NULL, pre_scd_thread, (void*)ru); + pthread_setname_np(proc->pthread_pre_scd, "pre_scd_thread"); + + } // for ru_id + + + + // sleep(1); + LOG_D(HW,"[lte-softmodem.c] RU threads created\n"); + + +} +#endif + /* --------------------------------------------------------*/ /* from here function to use configuration module */ diff --git a/targets/RT/USER/lte-softmodem.c b/targets/RT/USER/lte-softmodem.c old mode 100644 new mode 100755 index 03a461454f..101f8fa0a8 --- a/targets/RT/USER/lte-softmodem.c +++ b/targets/RT/USER/lte-softmodem.c @@ -1063,6 +1063,13 @@ int main( int argc, char **argv ) } } + +#if defined(PRE_SCD_THREAD) + if (nfapi_mode==2) { // ru pointer is necessary for pre_scd. + init_ru_vnf(); + } +#endif + config_sync_var=0; if (nfapi_mode==1) { // PNF diff --git a/targets/RT/USER/lte-softmodem.h b/targets/RT/USER/lte-softmodem.h old mode 100644 new mode 100755 index 96ab799c3d..bd71e0877f --- a/targets/RT/USER/lte-softmodem.h +++ b/targets/RT/USER/lte-softmodem.h @@ -255,6 +255,7 @@ extern void kill_eNB_proc(int inst); // In lte-ru.c extern void init_RU(const char*); extern void stop_ru(RU_t *ru); +extern void init_ru_vnf(void); extern void init_RU_proc(RU_t *ru); extern void stop_RU(int nb_ru); extern void kill_RU_proc(RU_t *ru); From f58ad3c39f04ca7305202749a7dad2b25ef6b942 Mon Sep 17 00:00:00 2001 From: "Bi-Ruei, Chiu" Date: Wed, 17 Oct 2018 15:46:12 +0800 Subject: [PATCH 017/233] Add prefix LTE_ to LTE-RRC generated data types by ASN1C_PREFIX=LTE_ 1. Modify all expressions using original LTE-RRC data types for new generated ones 2. Does not change any program logic --- cmake_targets/CMakeLists.txt | 24 +- openair1/PHY/INIT/defs_NB_IoT.h | 2 +- openair1/PHY/INIT/lte_init.c | 26 +- openair1/PHY/INIT/lte_init_ru.c | 12 +- openair1/PHY/INIT/lte_init_ue.c | 64 +- openair1/PHY/INIT/phy_init.h | 62 +- openair1/PHY/LTE_TRANSPORT/dci.c | 2 +- openair1/PHY/LTE_TRANSPORT/dlsch_scrambling.c | 6 +- openair1/PHY/LTE_TRANSPORT/edci.c | 2 +- openair1/PHY/LTE_TRANSPORT/if4_tools.c | 8 +- openair1/PHY/LTE_TRANSPORT/prach.c | 22 +- openair1/PHY/LTE_TRANSPORT/prach_common.c | 2 +- openair1/PHY/LTE_TRANSPORT/transport_common.h | 6 +- openair1/PHY/LTE_TRANSPORT/transport_eNB.h | 6 +- openair1/PHY/LTE_TRANSPORT/transport_proto.h | 2 +- openair1/PHY/LTE_UE_TRANSPORT/dci_tools_ue.c | 2 +- openair1/PHY/defs_L1_NB_IoT.h | 2 +- openair1/PHY/defs_common.h | 6 +- openair1/PHY/defs_eNB.h | 48 +- openair1/SCHED/fapi_l1.c | 16 +- openair1/SCHED/phy_procedures_lte_eNb.c | 4 +- openair1/SCHED/prach_procedures.c | 10 +- openair1/SCHED/sched_common.h | 4 +- openair1/SCHED/sched_eNB.h | 2 +- openair1/SCHED_UE/phy_procedures_lte_ue.c | 8 +- openair2/COMMON/gtpv1_u_messages_types.h | 4 +- openair2/COMMON/mac_rrc_primitives.h | 38 +- openair2/COMMON/platform_constants.h | 12 +- openair2/COMMON/rrc_messages_types.h | 66 +- openair2/COMMON/x2ap_messages_types.h | 6 +- .../CONTROL_MODULES/RRC/flexran_agent_rrc.c | 2 +- .../CONTROL_MODULES/RRC/flexran_agent_rrc.h | 2 +- .../RRC/flexran_agent_rrc_defs.h | 4 +- openair2/ENB_APP/RRC_config_tools.c | 6 +- openair2/ENB_APP/RRC_paramsvalues.h | 12 +- openair2/ENB_APP/enb_config.c | 508 ++-- openair2/ENB_APP/enb_config.h | 4 +- openair2/ENB_APP/enb_paramdef.h | 2 +- openair2/ENB_APP/flexran_agent_ran_api.c | 40 +- openair2/ENB_APP/flexran_agent_ran_api.h | 8 +- openair2/LAYER2/MAC/config.c | 136 +- openair2/LAYER2/MAC/config_ue.c | 108 +- openair2/LAYER2/MAC/eNB_scheduler.c | 22 +- openair2/LAYER2/MAC/eNB_scheduler_RA.c | 46 +- openair2/LAYER2/MAC/eNB_scheduler_bch.c | 24 +- openair2/LAYER2/MAC/eNB_scheduler_dlsch.c | 16 +- openair2/LAYER2/MAC/eNB_scheduler_fairRR.c | 18 +- openair2/LAYER2/MAC/eNB_scheduler_mch.c | 12 +- openair2/LAYER2/MAC/eNB_scheduler_phytest.c | 4 +- .../LAYER2/MAC/eNB_scheduler_primitives.c | 124 +- openair2/LAYER2/MAC/eNB_scheduler_ulsch.c | 6 +- openair2/LAYER2/MAC/l1_helpers.c | 2 +- openair2/LAYER2/MAC/mac.h | 130 +- openair2/LAYER2/MAC/mac_proto.h | 106 +- openair2/LAYER2/MAC/mac_vars.h | 2 +- openair2/LAYER2/MAC/pre_processor.c | 2 +- openair2/LAYER2/MAC/ra_procedures.c | 34 +- openair2/LAYER2/MAC/rar_tools.c | 2 +- openair2/LAYER2/MAC/ue_procedures.c | 110 +- openair2/LAYER2/PDCP_v10.1.0/pdcp.c | 104 +- openair2/LAYER2/PDCP_v10.1.0/pdcp.h | 40 +- openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c | 70 +- .../LAYER2/PDCP_v10.1.0/pdcp_proto_extern.h | 2 +- openair2/LAYER2/PDCP_v10.1.0/pdcp_security.c | 4 +- openair2/LAYER2/RLC/AM_v9.3.0/rlc_am.c | 42 +- openair2/LAYER2/RLC/AM_v9.3.0/rlc_am.h | 4 +- .../RLC/UM_v9.3.0/rlc_um_control_primitives.c | 24 +- .../RLC/UM_v9.3.0/rlc_um_control_primitives.h | 10 +- openair2/LAYER2/RLC/rlc.c | 18 +- openair2/LAYER2/RLC/rlc.h | 48 +- openair2/LAYER2/RLC/rlc_mac.c | 8 +- openair2/LAYER2/RLC/rlc_mpls.c | 2 +- openair2/LAYER2/RLC/rlc_rrc.c | 142 +- openair2/NETWORK_DRIVER/UE_IP/common.c | 2 +- openair2/NETWORK_DRIVER/UE_IP/local.h | 4 +- openair2/PHY_INTERFACE/IF_Module.c | 4 +- openair2/PHY_INTERFACE/IF_Module.h | 2 +- openair2/PHY_INTERFACE/IF_Module_NB_IoT.h | 4 +- openair2/RRC/LTE/L2_interface.c | 10 +- openair2/RRC/LTE/L2_interface_ue.c | 8 +- openair2/RRC/LTE/MESSAGES/asn1_msg.c | 954 +++---- openair2/RRC/LTE/MESSAGES/asn1_msg.h | 60 +- openair2/RRC/LTE/MESSAGES/asn1_msg_NB_IoT.c | 382 +-- openair2/RRC/LTE/defs_NB_IoT.h | 74 +- openair2/RRC/LTE/extern_NB_IoT.h | 6 +- openair2/RRC/LTE/proto_NB_IoT.h | 2 +- openair2/RRC/LTE/rrc_UE.c | 1268 ++++----- openair2/RRC/LTE/rrc_defs.h | 226 +- openair2/RRC/LTE/rrc_eNB.c | 2264 ++++++++--------- openair2/RRC/LTE/rrc_eNB_S1AP.c | 96 +- openair2/RRC/LTE/rrc_eNB_S1AP.h | 8 +- openair2/RRC/LTE/rrc_extern.h | 4 +- openair2/RRC/LTE/rrc_proto.h | 40 +- openair2/RRC/LTE/rrc_vars.h | 20 +- openair3/GTPV1-U/gtpv1u_eNB.c | 4 +- openair3/GTPV1-U/gtpv1u_eNB_defs.h | 4 +- targets/RT/USER/lte-enb.c | 28 +- targets/RT/USER/lte-ru.c | 30 +- targets/RT/USER/lte-ue.c | 2 +- targets/RT/USER/lte-uesoftmodem.c | 2 +- 100 files changed, 3996 insertions(+), 3996 deletions(-) diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt index 23d96afc54..f205e3f5fa 100644 --- a/cmake_targets/CMakeLists.txt +++ b/cmake_targets/CMakeLists.txt @@ -290,36 +290,36 @@ set(protobuf_generated_dir ${OPENAIR_BIN_DIR}) add_list2_option(RRC_ASN1_VERSION "Rel14" "ASN.1 version of RRC interface" "Rel8" "Rel10" "Rel14" "CBA") if (${RRC_ASN1_VERSION} STREQUAL "Rel8") - make_version(RRC_VERSION 8 6 0) + make_version(LTE_RRC_VERSION 8 6 0) set (RRC_GRAMMAR ${OPENAIR2_DIR}/RRC/LTE/MESSAGES/asn1c/ASN1_files/EUTRA-RRC-Definitions-86.asn) elseif (${RRC_ASN1_VERSION} STREQUAL "CBA") - make_version(RRC_VERSION 10 2 0) + make_version(LTE_RRC_VERSION 10 2 0) add_definitions(-DCBA) set (RRC_GRAMMAR ${OPENAIR2_DIR}/RRC/LTE/MESSAGES/asn1c/ASN1_files/EUTRA-RRC-Definitions-a20-lola.asn) elseif (${RRC_ASN1_VERSION} STREQUAL "Rel10") - make_version(RRC_VERSION 10 2 0) + make_version(LTE_RRC_VERSION 10 2 0) set (RRC_GRAMMAR ${OPENAIR2_DIR}/RRC/LTE/MESSAGES/asn1c/ASN1_files/EUTRA-RRC-Definitions-a20.asn) elseif (${RRC_ASN1_VERSION} STREQUAL "Rel11") - make_version(RRC_VERSION 11 18 0) + make_version(LTE_RRC_VERSION 11 18 0) set (RRC_GRAMMAR ${OPENAIR2_DIR}/RRC/LTE/MESSAGES/asn1c/ASN1_files/lte-rrc-11.18.0.asn1) elseif (${RRC_ASN1_VERSION} STREQUAL "Rel12") - make_version(RRC_VERSION 12 16 0) + make_version(LTE_RRC_VERSION 12 16 0) set (RRC_GRAMMAR ${OPENAIR2_DIR}/RRC/LTE/MESSAGES/asn1c/ASN1_files/lte-rrc-12.16.0.asn1) elseif (${RRC_ASN1_VERSION} STREQUAL "Rel13") - make_version(RRC_VERSION 13 9 1) + make_version(LTE_RRC_VERSION 13 9 1) set (RRC_GRAMMAR ${OPENAIR2_DIR}/RRC/LTE/MESSAGES/asn1c/ASN1_files/lte-rrc-13.9.1.asn1) elseif (${RRC_ASN1_VERSION} STREQUAL "Rel14") - make_version(RRC_VERSION 14 7 0) + make_version(LTE_RRC_VERSION 14 7 0) set (RRC_GRAMMAR ${OPENAIR2_DIR}/RRC/LTE/MESSAGES/asn1c/ASN1_files/lte-rrc-14.7.0.asn1) elseif (${RRC_ASN1_VERSION} STREQUAL "Rel15") - make_version(RRC_VERSION 15 2 2) + make_version(LTE_RRC_VERSION 15 2 2) set (RRC_GRAMMAR ${OPENAIR2_DIR}/RRC/LTE/MESSAGES/asn1c/ASN1_files/lte-rrc-15.2.2.asn1) endif (${RRC_ASN1_VERSION} STREQUAL "Rel8") -add_definitions(-DRRC_VERSION=${RRC_VERSION}) +add_definitions(-DLTE_RRC_VERSION=${LTE_RRC_VERSION}) set (RRC_FULL_DIR ${asn1_generated_dir}/RRC_${RRC_ASN1_VERSION}) -message("calling asn1c -pdu=all -fcompound-names -gen-PER -no-gen-OER -no-gen-example -D ${RRC_FULL_DIR} ${RRC_GRAMMAR}") +message("calling ASN1C_PREFIX=LTE_ asn1c -pdu=all -fcompound-names -gen-PER -no-gen-OER -no-gen-example -D ${RRC_FULL_DIR} ${RRC_GRAMMAR}") execute_process(COMMAND mkdir -p ${RRC_FULL_DIR} - COMMAND env asn1c -pdu=all -fcompound-names -gen-PER -no-gen-OER -no-gen-example -D ${RRC_FULL_DIR} ${RRC_GRAMMAR} + COMMAND env "ASN1C_PREFIX=LTE_" asn1c -pdu=all -fcompound-names -gen-PER -no-gen-OER -no-gen-example -D ${RRC_FULL_DIR} ${RRC_GRAMMAR} RESULT_VARIABLE ret) if (NOT ${ret} STREQUAL 0) message(FATAL_ERROR "${ret}: error") @@ -339,7 +339,7 @@ include_directories ("${RRC_FULL_DIR}") add_custom_command ( OUTPUT ${RRC_FULL_DIR}/asn_constant.h COMMAND mkdir -p ${RRC_FULL_DIR} - COMMAND env asn1c -pdu=all -fcompound-names -gen-PER -no-gen-OER -no-gen-example -D ${RRC_FULL_DIR} ${RRC_GRAMMAR} + COMMAND env "ASN1C_PREFIX=LTE_" asn1c -pdu=all -fcompound-names -gen-PER -no-gen-OER -no-gen-example -D ${RRC_FULL_DIR} ${RRC_GRAMMAR} DEPENDS ${RRC_GRAMMAR} ) diff --git a/openair1/PHY/INIT/defs_NB_IoT.h b/openair1/PHY/INIT/defs_NB_IoT.h index b49936770f..d115a57f10 100644 --- a/openair1/PHY/INIT/defs_NB_IoT.h +++ b/openair1/PHY/INIT/defs_NB_IoT.h @@ -33,7 +33,7 @@ //#include "TDD-Config.h" //#include "MBSFN-SubframeConfigList.h" //#include "MobilityControlInfo.h" -//#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) +//#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) //#include "SCellToAddMod-r10.h" //#endif diff --git a/openair1/PHY/INIT/lte_init.c b/openair1/PHY/INIT/lte_init.c index bec0873276..93a43e48eb 100644 --- a/openair1/PHY/INIT/lte_init.c +++ b/openair1/PHY/INIT/lte_init.c @@ -27,10 +27,10 @@ #include "PHY/LTE_UE_TRANSPORT/transport_proto_ue.h" #include "PHY/LTE_REFSIG/lte_refsig.h" #include "SIMULATION/TOOLS/sim.h" -#include "RadioResourceConfigCommonSIB.h" -#include "RadioResourceConfigDedicated.h" -#include "TDD-Config.h" -#include "MBSFN-SubframeConfigList.h" +#include "LTE_RadioResourceConfigCommonSIB.h" +#include "LTE_RadioResourceConfigDedicated.h" +#include "LTE_TDD-Config.h" +#include "LTE_MBSFN-SubframeConfigList.h" #include "common/utils/LOG/vcd_signal_dumper.h" #include "assertions.h" #include @@ -182,7 +182,7 @@ void phy_config_request(PHY_Config_t *phy_config) { fp->frame_type, RC.eNB[Mod_id][CC_id]->X_u); -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) fp->prach_emtc_config_common.prach_Config_enabled=1; fp->prach_emtc_config_common.rootSequenceIndex = cfg->emtc_config.prach_catm_root_sequence_index.value; @@ -487,7 +487,7 @@ void phy_config_sib13_eNB(module_id_t Mod_id,int CC_id,int mbsfn_Area_idx, void phy_config_dedicated_eNB_step2(PHY_VARS_eNB *eNB) { uint16_t UE_id; - struct PhysicalConfigDedicated *physicalConfigDedicated; + struct LTE_PhysicalConfigDedicated *physicalConfigDedicated; LTE_DL_FRAME_PARMS *fp=&eNB->frame_parms; for (UE_id=0; UE_idpucch_ConfigDedicated) { - if (physicalConfigDedicated->pucch_ConfigDedicated->ackNackRepetition.present==PUCCH_ConfigDedicated__ackNackRepetition_PR_release) + if (physicalConfigDedicated->pucch_ConfigDedicated->ackNackRepetition.present==LTE_PUCCH_ConfigDedicated__ackNackRepetition_PR_release) eNB->pucch_config_dedicated[UE_id].ackNackRepetition=0; else { eNB->pucch_config_dedicated[UE_id].ackNackRepetition=1; @@ -563,7 +563,7 @@ void phy_config_dedicated_eNB_step2(PHY_VARS_eNB *eNB) } if (physicalConfigDedicated->schedulingRequestConfig) { - if (physicalConfigDedicated->schedulingRequestConfig->present == SchedulingRequestConfig_PR_setup) { + if (physicalConfigDedicated->schedulingRequestConfig->present == LTE_SchedulingRequestConfig_PR_setup) { eNB->scheduling_request_config[UE_id].sr_PUCCH_ResourceIndex = physicalConfigDedicated->schedulingRequestConfig->choice.setup.sr_PUCCH_ResourceIndex; eNB->scheduling_request_config[UE_id].sr_ConfigIndex=physicalConfigDedicated->schedulingRequestConfig->choice.setup.sr_ConfigIndex; eNB->scheduling_request_config[UE_id].dsr_TransMax=physicalConfigDedicated->schedulingRequestConfig->choice.setup.dsr_TransMax; @@ -578,7 +578,7 @@ void phy_config_dedicated_eNB_step2(PHY_VARS_eNB *eNB) } if (physicalConfigDedicated->soundingRS_UL_ConfigDedicated) { - if (physicalConfigDedicated->soundingRS_UL_ConfigDedicated->present == SoundingRS_UL_ConfigDedicated_PR_setup) { + if (physicalConfigDedicated->soundingRS_UL_ConfigDedicated->present == LTE_SoundingRS_UL_ConfigDedicated_PR_setup) { eNB->soundingrs_ul_config_dedicated[UE_id].srsConfigDedicatedSetup = 1; eNB->soundingrs_ul_config_dedicated[UE_id].duration = physicalConfigDedicated->soundingRS_UL_ConfigDedicated->choice.setup.duration; @@ -729,7 +729,7 @@ int phy_init_lte_eNB(PHY_VARS_eNB *eNB, LTE_eNB_PUSCH** const pusch_vars = eNB->pusch_vars; LTE_eNB_SRS* const srs_vars = eNB->srs_vars; LTE_eNB_PRACH* const prach_vars = &eNB->prach_vars; -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) LTE_eNB_PRACH* const prach_vars_br = &eNB->prach_vars_br; #endif int i, UE_id; @@ -825,7 +825,7 @@ int phy_init_lte_eNB(PHY_VARS_eNB *eNB, prach_vars->rxsigF[0] = (int16_t**)malloc16_clear(64*sizeof(int16_t*)); // PRACH BR -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) prach_vars_br->prachF = (int16_t*)malloc16_clear( 1024*2*sizeof(int32_t) ); // assume maximum of 64 RX antennas for PRACH receiver @@ -893,7 +893,7 @@ void phy_free_lte_eNB(PHY_VARS_eNB *eNB) LTE_eNB_PUSCH** const pusch_vars = eNB->pusch_vars; LTE_eNB_SRS* const srs_vars = eNB->srs_vars; LTE_eNB_PRACH* const prach_vars = &eNB->prach_vars; -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) LTE_eNB_PRACH* const prach_vars_br = &eNB->prach_vars_br; #endif int i, UE_id; @@ -926,7 +926,7 @@ void phy_free_lte_eNB(PHY_VARS_eNB *eNB) for (i = 0; i < 64; i++) free_and_zero(prach_vars->prach_ifft[0][i]); free_and_zero(prach_vars->prach_ifft[0]); -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) for (int ce_level = 0; ce_level < 4; ce_level++) { for (i = 0; i < 64; i++) free_and_zero(prach_vars_br->prach_ifft[ce_level][i]); free_and_zero(prach_vars_br->prach_ifft[ce_level]); diff --git a/openair1/PHY/INIT/lte_init_ru.c b/openair1/PHY/INIT/lte_init_ru.c index 3a1364620e..e2f6259447 100644 --- a/openair1/PHY/INIT/lte_init_ru.c +++ b/openair1/PHY/INIT/lte_init_ru.c @@ -23,10 +23,10 @@ #include "SCHED/sched_eNB.h" #include "PHY/phy_extern.h" #include "SIMULATION/TOOLS/sim.h" -#include "RadioResourceConfigCommonSIB.h" -#include "RadioResourceConfigDedicated.h" -#include "TDD-Config.h" -#include "MBSFN-SubframeConfigList.h" +#include "LTE_RadioResourceConfigCommonSIB.h" +#include "LTE_RadioResourceConfigDedicated.h" +#include "LTE_TDD-Config.h" +#include "LTE_MBSFN-SubframeConfigList.h" #include "common/utils/LOG/vcd_signal_dumper.h" #include "assertions.h" #include @@ -101,7 +101,7 @@ int phy_init_RU(RU_t *ru) { for (i=0; inb_rx; i++) { ru->prach_rxsigF[i] = (int16_t*)malloc16_clear( fp->ofdm_symbol_size*12*2*sizeof(int16_t) ); LOG_D(PHY,"[INIT] prach_vars->rxsigF[%d] = %p\n",i,ru->prach_rxsigF[i]); -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) for (j=0;j<4;j++) { ru->prach_rxsigF_br[j][i] = (int16_t*)malloc16_clear( fp->ofdm_symbol_size*12*2*sizeof(int16_t) ); LOG_D(PHY,"[INIT] prach_vars_br->rxsigF[%d] = %p\n",i,ru->prach_rxsigF_br[j][i]); @@ -179,7 +179,7 @@ void phy_free_RU(RU_t *ru) for (i = 0; i < ru->nb_rx; i++) { free_and_zero(ru->prach_rxsigF[i]); -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) for (j = 0; j < 4; j++) free_and_zero(ru->prach_rxsigF_br[j][i]); #endif } diff --git a/openair1/PHY/INIT/lte_init_ue.c b/openair1/PHY/INIT/lte_init_ue.c index bcdd782073..31c37e4669 100644 --- a/openair1/PHY/INIT/lte_init_ue.c +++ b/openair1/PHY/INIT/lte_init_ue.c @@ -23,10 +23,10 @@ #include "SCHED_UE/sched_UE.h" #include "PHY/phy_extern_ue.h" #include "SIMULATION/TOOLS/sim.h" -#include "RadioResourceConfigCommonSIB.h" -#include "RadioResourceConfigDedicated.h" -#include "TDD-Config.h" -#include "MBSFN-SubframeConfigList.h" +#include "LTE_RadioResourceConfigCommonSIB.h" +#include "LTE_RadioResourceConfigDedicated.h" +#include "LTE_TDD-Config.h" +#include "LTE_MBSFN-SubframeConfigList.h" #include "common/utils/LOG/vcd_signal_dumper.h" #include "assertions.h" #include @@ -41,7 +41,7 @@ extern uint8_t nfapi_mode; void phy_config_sib1_ue(module_id_t Mod_id,int CC_id, uint8_t eNB_id, - TDD_Config_t *tdd_Config, + LTE_TDD_Config_t *tdd_Config, uint8_t SIwindowsize, uint16_t SIperiod) { @@ -59,11 +59,11 @@ void phy_config_sib1_ue(module_id_t Mod_id,int CC_id, void phy_config_sib2_ue(module_id_t Mod_id,int CC_id, uint8_t eNB_id, - RadioResourceConfigCommonSIB_t *radioResourceConfigCommon, - ARFCN_ValueEUTRA_t *ul_CarrierFreq, + LTE_RadioResourceConfigCommonSIB_t *radioResourceConfigCommon, + LTE_ARFCN_ValueEUTRA_t *ul_CarrierFreq, long *ul_Bandwidth, - AdditionalSpectrumEmission_t *additionalSpectrumEmission, - struct MBSFN_SubframeConfigList *mbsfn_SubframeConfigList) + LTE_AdditionalSpectrumEmission_t *additionalSpectrumEmission, + struct LTE_MBSFN_SubframeConfigList *mbsfn_SubframeConfigList) { PHY_VARS_UE *ue = PHY_vars_UE_g[Mod_id][CC_id]; @@ -114,7 +114,7 @@ void phy_config_sib2_ue(module_id_t Mod_id,int CC_id, init_ul_hopping(fp); fp->soundingrs_ul_config_common.enabled_flag = 0; - if (radioResourceConfigCommon->soundingRS_UL_ConfigCommon.present==SoundingRS_UL_ConfigCommon_PR_setup) { + if (radioResourceConfigCommon->soundingRS_UL_ConfigCommon.present == LTE_SoundingRS_UL_ConfigCommon_PR_setup) { fp->soundingrs_ul_config_common.enabled_flag = 1; fp->soundingrs_ul_config_common.srs_BandwidthConfig = radioResourceConfigCommon->soundingRS_UL_ConfigCommon.choice.setup.srs_BandwidthConfig; fp->soundingrs_ul_config_common.srs_SubframeConfig = radioResourceConfigCommon->soundingRS_UL_ConfigCommon.choice.setup.srs_SubframeConfig; @@ -159,19 +159,19 @@ void phy_config_sib2_ue(module_id_t Mod_id,int CC_id, fp->MBSFN_config[i].radioframeAllocationPeriod = mbsfn_SubframeConfigList->list.array[i]->radioframeAllocationPeriod; fp->MBSFN_config[i].radioframeAllocationOffset = mbsfn_SubframeConfigList->list.array[i]->radioframeAllocationOffset; - if (mbsfn_SubframeConfigList->list.array[i]->subframeAllocation.present == MBSFN_SubframeConfig__subframeAllocation_PR_oneFrame) { + if (mbsfn_SubframeConfigList->list.array[i]->subframeAllocation.present == LTE_MBSFN_SubframeConfig__subframeAllocation_PR_oneFrame) { fp->MBSFN_config[i].fourFrames_flag = 0; fp->MBSFN_config[i].mbsfn_SubframeConfig = mbsfn_SubframeConfigList->list.array[i]->subframeAllocation.choice.oneFrame.buf[0]; // 6-bit subframe configuration - LOG_I(PHY, "[CONFIG] MBSFN_SubframeConfig[%d] pattern is %d\n", i, + LOG_I(PHY, "[CONFIG] LTE_MBSFN_SubframeConfig[%d] pattern is %d\n", i, fp->MBSFN_config[i].mbsfn_SubframeConfig); - } else if (mbsfn_SubframeConfigList->list.array[i]->subframeAllocation.present == MBSFN_SubframeConfig__subframeAllocation_PR_fourFrames) { // 24-bit subframe configuration + } else if (mbsfn_SubframeConfigList->list.array[i]->subframeAllocation.present == LTE_MBSFN_SubframeConfig__subframeAllocation_PR_fourFrames) { // 24-bit subframe configuration fp->MBSFN_config[i].fourFrames_flag = 1; fp->MBSFN_config[i].mbsfn_SubframeConfig = mbsfn_SubframeConfigList->list.array[i]->subframeAllocation.choice.oneFrame.buf[2]| (mbsfn_SubframeConfigList->list.array[i]->subframeAllocation.choice.oneFrame.buf[1]<<8)| (mbsfn_SubframeConfigList->list.array[i]->subframeAllocation.choice.oneFrame.buf[0]<<16); - LOG_I(PHY, "[CONFIG] MBSFN_SubframeConfig[%d] pattern is %x\n", i, + LOG_I(PHY, "[CONFIG] LTE_MBSFN_SubframeConfig[%d] pattern is %x\n", i, fp->MBSFN_config[i].mbsfn_SubframeConfig); } } @@ -203,11 +203,11 @@ void phy_config_sib13_ue(module_id_t Mod_id,int CC_id,uint8_t eNB_id,int mbsfn_A /* * Configures UE MAC and PHY with radioResourceCommon received in mobilityControlInfo IE during Handover */ -void phy_config_afterHO_ue(module_id_t Mod_id,uint8_t CC_id,uint8_t eNB_id, MobilityControlInfo_t *mobilityControlInfo, uint8_t ho_failed) +void phy_config_afterHO_ue(module_id_t Mod_id,uint8_t CC_id,uint8_t eNB_id, LTE_MobilityControlInfo_t *mobilityControlInfo, uint8_t ho_failed) { if(mobilityControlInfo!=NULL) { - RadioResourceConfigCommon_t *radioResourceConfigCommon = &mobilityControlInfo->radioResourceConfigCommon; + LTE_RadioResourceConfigCommon_t *radioResourceConfigCommon = &mobilityControlInfo->radioResourceConfigCommon; LOG_I(PHY,"radioResourceConfigCommon %p\n", radioResourceConfigCommon); memcpy((void *)&PHY_vars_UE_g[Mod_id][CC_id]->frame_parms_before_ho, (void *)&PHY_vars_UE_g[Mod_id][CC_id]->frame_parms, @@ -264,7 +264,7 @@ void phy_config_afterHO_ue(module_id_t Mod_id,uint8_t CC_id,uint8_t eNB_id, Mobi init_ul_hopping(fp); fp->soundingrs_ul_config_common.enabled_flag = 0; - if (radioResourceConfigCommon->soundingRS_UL_ConfigCommon->present==SoundingRS_UL_ConfigCommon_PR_setup) { + if (radioResourceConfigCommon->soundingRS_UL_ConfigCommon->present == LTE_SoundingRS_UL_ConfigCommon_PR_setup) { fp->soundingrs_ul_config_common.enabled_flag = 1; fp->soundingrs_ul_config_common.srs_BandwidthConfig = radioResourceConfigCommon->soundingRS_UL_ConfigCommon->choice.setup.srs_BandwidthConfig; fp->soundingrs_ul_config_common.srs_SubframeConfig = radioResourceConfigCommon->soundingRS_UL_ConfigCommon->choice.setup.srs_SubframeConfig; @@ -344,10 +344,10 @@ void phy_config_meas_ue(module_id_t Mod_id,uint8_t CC_id,uint8_t eNB_index,uint8 } -#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) void phy_config_dedicated_scell_ue(uint8_t Mod_id, uint8_t eNB_index, - SCellToAddMod_r10_t *sCellToAddMod_r10, + LTE_SCellToAddMod_r10_t *sCellToAddMod_r10, int CC_id) { @@ -366,7 +366,7 @@ void phy_config_harq_ue(module_id_t Mod_id,int CC_id,uint8_t eNB_id, extern uint16_t beta_cqi[16]; void phy_config_dedicated_ue(module_id_t Mod_id,int CC_id,uint8_t eNB_id, - struct PhysicalConfigDedicated *physicalConfigDedicated ) + struct LTE_PhysicalConfigDedicated *physicalConfigDedicated ) { static uint8_t first_dedicated_configuration = 0; @@ -396,7 +396,7 @@ void phy_config_dedicated_ue(module_id_t Mod_id,int CC_id,uint8_t eNB_id, } if (physicalConfigDedicated->pucch_ConfigDedicated) { - if (physicalConfigDedicated->pucch_ConfigDedicated->ackNackRepetition.present==PUCCH_ConfigDedicated__ackNackRepetition_PR_release) + if (physicalConfigDedicated->pucch_ConfigDedicated->ackNackRepetition.present == LTE_PUCCH_ConfigDedicated__ackNackRepetition_PR_release) phy_vars_ue->pucch_config_dedicated[eNB_id].ackNackRepetition=0; else { phy_vars_ue->pucch_config_dedicated[eNB_id].ackNackRepetition=1; @@ -448,25 +448,25 @@ void phy_config_dedicated_ue(module_id_t Mod_id,int CC_id,uint8_t eNB_id, phy_vars_ue->transmission_mode[eNB_id] = 1+(physicalConfigDedicated->antennaInfo->choice.explicitValue.transmissionMode); LOG_I(PHY,"Transmission Mode %d\n",phy_vars_ue->transmission_mode[eNB_id]); switch(physicalConfigDedicated->antennaInfo->choice.explicitValue.transmissionMode) { - case AntennaInfoDedicated__transmissionMode_tm1: + case LTE_AntennaInfoDedicated__transmissionMode_tm1: phy_vars_ue->transmission_mode[eNB_id] = 1; break; - case AntennaInfoDedicated__transmissionMode_tm2: + case LTE_AntennaInfoDedicated__transmissionMode_tm2: phy_vars_ue->transmission_mode[eNB_id] = 2; break; - case AntennaInfoDedicated__transmissionMode_tm3: + case LTE_AntennaInfoDedicated__transmissionMode_tm3: phy_vars_ue->transmission_mode[eNB_id] = 3; break; - case AntennaInfoDedicated__transmissionMode_tm4: + case LTE_AntennaInfoDedicated__transmissionMode_tm4: phy_vars_ue->transmission_mode[eNB_id] = 4; break; - case AntennaInfoDedicated__transmissionMode_tm5: + case LTE_AntennaInfoDedicated__transmissionMode_tm5: phy_vars_ue->transmission_mode[eNB_id] = 5; break; - case AntennaInfoDedicated__transmissionMode_tm6: + case LTE_AntennaInfoDedicated__transmissionMode_tm6: phy_vars_ue->transmission_mode[eNB_id] = 6; break; - case AntennaInfoDedicated__transmissionMode_tm7: + case LTE_AntennaInfoDedicated__transmissionMode_tm7: lte_gold_ue_spec_port5(phy_vars_ue->lte_gold_uespec_port5_table, phy_vars_ue->frame_parms.Nid_cell, phy_vars_ue->pdcch_vars[0][eNB_id]->crnti); phy_vars_ue->transmission_mode[eNB_id] = 7; break; @@ -479,7 +479,7 @@ void phy_config_dedicated_ue(module_id_t Mod_id,int CC_id,uint8_t eNB_id, } if (physicalConfigDedicated->schedulingRequestConfig) { - if (physicalConfigDedicated->schedulingRequestConfig->present == SchedulingRequestConfig_PR_setup) { + if (physicalConfigDedicated->schedulingRequestConfig->present == LTE_SchedulingRequestConfig_PR_setup) { phy_vars_ue->scheduling_request_config[eNB_id].sr_PUCCH_ResourceIndex = physicalConfigDedicated->schedulingRequestConfig->choice.setup.sr_PUCCH_ResourceIndex; phy_vars_ue->scheduling_request_config[eNB_id].sr_ConfigIndex=physicalConfigDedicated->schedulingRequestConfig->choice.setup.sr_ConfigIndex; phy_vars_ue->scheduling_request_config[eNB_id].dsr_TransMax=physicalConfigDedicated->schedulingRequestConfig->choice.setup.dsr_TransMax; @@ -496,7 +496,7 @@ void phy_config_dedicated_ue(module_id_t Mod_id,int CC_id,uint8_t eNB_id, if (physicalConfigDedicated->soundingRS_UL_ConfigDedicated) { phy_vars_ue->soundingrs_ul_config_dedicated[eNB_id].srsConfigDedicatedSetup = 0; - if (physicalConfigDedicated->soundingRS_UL_ConfigDedicated->present == SoundingRS_UL_ConfigDedicated_PR_setup) { + if (physicalConfigDedicated->soundingRS_UL_ConfigDedicated->present == LTE_SoundingRS_UL_ConfigDedicated_PR_setup) { phy_vars_ue->soundingrs_ul_config_dedicated[eNB_id].srsConfigDedicatedSetup = 1; phy_vars_ue->soundingrs_ul_config_dedicated[eNB_id].duration = physicalConfigDedicated->soundingRS_UL_ConfigDedicated->choice.setup.duration; phy_vars_ue->soundingrs_ul_config_dedicated[eNB_id].cyclicShift = physicalConfigDedicated->soundingRS_UL_ConfigDedicated->choice.setup.cyclicShift; @@ -525,14 +525,14 @@ void phy_config_dedicated_ue(module_id_t Mod_id,int CC_id,uint8_t eNB_id, LOG_E(PHY,"Unsupported Aperiodic CQI Feedback Mode : %d\n",phy_vars_ue->cqi_report_config[eNB_id].cqi_ReportModeAperiodic); } if (physicalConfigDedicated->cqi_ReportConfig->cqi_ReportPeriodic) { - if (physicalConfigDedicated->cqi_ReportConfig->cqi_ReportPeriodic->present == CQI_ReportPeriodic_PR_setup) { + if (physicalConfigDedicated->cqi_ReportConfig->cqi_ReportPeriodic->present == LTE_CQI_ReportPeriodic_PR_setup) { // configure PUCCH CQI reporting phy_vars_ue->cqi_report_config[eNB_id].CQI_ReportPeriodic.cqi_PUCCH_ResourceIndex = physicalConfigDedicated->cqi_ReportConfig->cqi_ReportPeriodic->choice.setup.cqi_PUCCH_ResourceIndex; phy_vars_ue->cqi_report_config[eNB_id].CQI_ReportPeriodic.cqi_PMI_ConfigIndex = physicalConfigDedicated->cqi_ReportConfig->cqi_ReportPeriodic->choice.setup.cqi_pmi_ConfigIndex; if (physicalConfigDedicated->cqi_ReportConfig->cqi_ReportPeriodic->choice.setup.ri_ConfigIndex) phy_vars_ue->cqi_report_config[eNB_id].CQI_ReportPeriodic.ri_ConfigIndex = *physicalConfigDedicated->cqi_ReportConfig->cqi_ReportPeriodic->choice.setup.ri_ConfigIndex; } - else if (physicalConfigDedicated->cqi_ReportConfig->cqi_ReportPeriodic->present == CQI_ReportPeriodic_PR_release) { + else if (physicalConfigDedicated->cqi_ReportConfig->cqi_ReportPeriodic->present == LTE_CQI_ReportPeriodic_PR_release) { // handle release phy_vars_ue->cqi_report_config[eNB_id].CQI_ReportPeriodic.ri_ConfigIndex = -1; phy_vars_ue->cqi_report_config[eNB_id].CQI_ReportPeriodic.cqi_PMI_ConfigIndex = -1; diff --git a/openair1/PHY/INIT/phy_init.h b/openair1/PHY/INIT/phy_init.h index da4050c848..9e08dabba2 100644 --- a/openair1/PHY/INIT/phy_init.h +++ b/openair1/PHY/INIT/phy_init.h @@ -25,15 +25,15 @@ #include "PHY/defs_eNB.h" #include "PHY/defs_UE.h" -#include "SystemInformationBlockType2.h" +#include "LTE_SystemInformationBlockType2.h" //#include "RadioResourceConfigCommonSIB.h" -#include "RadioResourceConfigDedicated.h" -#include "TDD-Config.h" -#include "PHICH-Config.h" -#include "MBSFN-SubframeConfigList.h" -#include "MobilityControlInfo.h" -#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) -#include "SCellToAddMod-r10.h" +#include "LTE_RadioResourceConfigDedicated.h" +#include "LTE_TDD-Config.h" +#include "LTE_PHICH-Config.h" +#include "LTE_MBSFN-SubframeConfigList.h" +#include "LTE_MobilityControlInfo.h" +#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) +#include "LTE_SCellToAddMod-r10.h" #endif /** @addtogroup _PHY_STRUCTURES_ * @{ @@ -110,7 +110,7 @@ void phy_config_mib_eNB(int Mod_id, int CC_id, int eutra_band, int N_RB_DL, - PHICH_Config_t *phich_config, + LTE_PHICH_Config_t *phich_config, int Nid_cell, int Ncp, int p_eNB, @@ -128,7 +128,7 @@ void phy_config_mib_eNB(int Mod_id, @param SIperiod Periodicity of System Information Messages (in multiples of a frame)*/ void phy_config_sib1_eNB(module_id_t Mod_id, int CC_id, - TDD_Config_t *tdd_Config, + LTE_TDD_Config_t *tdd_Config, uint8_t SIwindowsize, uint16_t SIperiod); @@ -143,7 +143,7 @@ void phy_config_sib1_eNB(module_id_t Mod_id, void phy_config_sib1_ue(module_id_t Mod_id, int CC_id, uint8_t CH_index, - TDD_Config_t *tdd_Config, + LTE_TDD_Config_t *tdd_Config, uint8_t SIwindowsize, uint16_t SIperiod); @@ -166,14 +166,14 @@ void phy_config_sib1_ue(module_id_t Mod_id, @param additionalSpectrumEmission UL parameter (see 36.101) @param mbsfn_SubframeConfigList MBSFN subframe configuration */ -void phy_config_sib2_ue(module_id_t Mod_id, - int CC_id, - uint8_t CH_index, - RadioResourceConfigCommonSIB_t *radioResourceConfigCommon, - ARFCN_ValueEUTRA_t *ul_CArrierFreq, - long *ul_Bandwidth, - AdditionalSpectrumEmission_t *additionalSpectrumEmission, - struct MBSFN_SubframeConfigList *mbsfn_SubframeConfigList); +void phy_config_sib2_ue(module_id_t Mod_id, + int CC_id, + uint8_t CH_index, + LTE_RadioResourceConfigCommonSIB_t *radioResourceConfigCommon, + LTE_ARFCN_ValueEUTRA_t *ul_CArrierFreq, + long *ul_Bandwidth, + LTE_AdditionalSpectrumEmission_t *additionalSpectrumEmission, + struct LTE_MBSFN_SubframeConfigList *mbsfn_SubframeConfigList); /*! @@ -188,7 +188,7 @@ void phy_config_sib2_ue(module_id_t Mod_id, void phy_config_afterHO_ue(module_id_t Mod_id, uint8_t CC_id, uint8_t eNB_index, - MobilityControlInfo_t *mobilityControlInfo, + LTE_MobilityControlInfo_t *mobilityControlInfo, uint8_t ho_failed); /*! \fn void phy_config_sib2_eNB(module_id_t Mod_id, @@ -206,13 +206,13 @@ void phy_config_afterHO_ue(module_id_t Mod_id, @param additionalSpectrumEmission UL parameter (see 36.101) @param mbsfn_SubframeConfigList MBSFN subframe configuration */ -void phy_config_sib2_eNB(module_id_t Mod_id, - int CC_id, - RadioResourceConfigCommonSIB_t *radioResourceConfigCommon, - ARFCN_ValueEUTRA_t *ul_CArrierFreq, +void phy_config_sib2_eNB(module_id_t Mod_id, + int CC_id, + LTE_RadioResourceConfigCommonSIB_t *radioResourceConfigCommon, + LTE_ARFCN_ValueEUTRA_t *ul_CArrierFreq, long *ul_Bandwidth, - AdditionalSpectrumEmission_t *additionalSpectrumEmission, - struct MBSFN_SubframeConfigList *mbsfn_SubframeConfigList); + LTE_AdditionalSpectrumEmission_t *additionalSpectrumEmission, + struct LTE_MBSFN_SubframeConfigList *mbsfn_SubframeConfigList); /*! @@ -229,7 +229,7 @@ void phy_config_sib2_eNB(module_id_t Mod_id, void phy_config_dedicated_ue(module_id_t Mod_id, int CC_id, uint8_t CH_index, - struct PhysicalConfigDedicated *physicalConfigDedicated); + struct LTE_PhysicalConfigDedicated *physicalConfigDedicated); /*! \fn void phy_config_harq_ue(module_id_t Mod_id,uint8_t CC_id,uint8_t CH_index, @@ -308,7 +308,7 @@ void phy_config_meas_ue(module_id_t Mod_id, void phy_config_dedicated_eNB(module_id_t Mod_id, int CC_id, rnti_t rnti, - struct PhysicalConfigDedicated *physicalConfigDedicated); + struct LTE_PhysicalConfigDedicated *physicalConfigDedicated); /*! \fn void phy_config_dedicated_eNB_step2(PHY_VARS_eNB *phy_vars_eNB) @@ -349,15 +349,15 @@ void lte_param_init(PHY_VARS_eNB **eNBp, uint32_t perfect_ce); -#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) void phy_config_dedicated_scell_ue(uint8_t Mod_id, uint8_t eNB_index, - SCellToAddMod_r10_t *sCellToAddMod_r10, + LTE_SCellToAddMod_r10_t *sCellToAddMod_r10, int CC_id); void phy_config_dedicated_scell_eNB(uint8_t Mod_id, uint16_t rnti, - SCellToAddMod_r10_t *sCellToAddMod_r10, + LTE_SCellToAddMod_r10_t *sCellToAddMod_r10, int CC_id); #endif diff --git a/openair1/PHY/LTE_TRANSPORT/dci.c b/openair1/PHY/LTE_TRANSPORT/dci.c index 520488664d..a7131ad1fb 100755 --- a/openair1/PHY/LTE_TRANSPORT/dci.c +++ b/openair1/PHY/LTE_TRANSPORT/dci.c @@ -121,7 +121,7 @@ uint8_t *generate_dci0(uint8_t *dci, (aggregation_level==2) || (aggregation_level==4) || (aggregation_level==8) -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) // Added for EPDCCH/MPDCCH +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) // Added for EPDCCH/MPDCCH || (aggregation_level==16) || (aggregation_level==24) || diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_scrambling.c b/openair1/PHY/LTE_TRANSPORT/dlsch_scrambling.c index 9aacdd079d..1a83508cee 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_scrambling.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_scrambling.c @@ -60,7 +60,7 @@ void dlsch_scrambling(LTE_DL_FRAME_PARMS *frame_parms, VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_SCRAMBLING, VCD_FUNCTION_IN); -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) // Rule for accumulation of subframes for BL/CE UEs uint8_t Nacc=4; uint16_t j0,j,idelta; @@ -97,7 +97,7 @@ void dlsch_scrambling(LTE_DL_FRAME_PARMS *frame_parms, // reset = 1; // x1 is set in lte_gold_generic if (mbsfn_flag == 0) { -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) #ifdef PHY_TX_THREAD if (dlsch->harq_processes[harq_pid]->i0 != 0xFFFF) { #else @@ -115,7 +115,7 @@ void dlsch_scrambling(LTE_DL_FRAME_PARMS *frame_parms, } #ifdef DEBUG_SCRAMBLING -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) printf("scrambling: i0 %d rnti %x, q %d, Ns %d, Nid_cell %d, G %d x2 %x\n",dlsch->i0,dlsch->rnti,q,Ns,frame_parms->Nid_cell, G, x2); #else printf("scrambling: rnti %x, q %d, Ns %d, Nid_cell %d, G %d x2 %x\n",dlsch->rnti,q,Ns,frame_parms->Nid_cell, G, x2); diff --git a/openair1/PHY/LTE_TRANSPORT/edci.c b/openair1/PHY/LTE_TRANSPORT/edci.c index fc82fd0137..06bd5aecd5 100755 --- a/openair1/PHY/LTE_TRANSPORT/edci.c +++ b/openair1/PHY/LTE_TRANSPORT/edci.c @@ -47,7 +47,7 @@ //#define DEBUG_DCI_DECODING 1 //#define DEBUG_PHY -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) void generate_edci_top(PHY_VARS_eNB *eNB, int frame, int subframe) { } diff --git a/openair1/PHY/LTE_TRANSPORT/if4_tools.c b/openair1/PHY/LTE_TRANSPORT/if4_tools.c index 8a56105f67..127471dcb6 100644 --- a/openair1/PHY/LTE_TRANSPORT/if4_tools.c +++ b/openair1/PHY/LTE_TRANSPORT/if4_tools.c @@ -47,7 +47,7 @@ void send_IF4p5(RU_t *ru, int frame, int subframe, uint16_t packet_type) { int32_t **txdataF = ru->common.txdataF_BF; int32_t **rxdataF = ru->common.rxdataF; int16_t **prach_rxsigF = ru->prach_rxsigF; -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) int16_t ***prach_rxsigF_br = ru->prach_rxsigF_br; #endif void *tx_buffer = ru->ifbuffer.tx[subframe&1]; @@ -221,7 +221,7 @@ void send_IF4p5(RU_t *ru, int frame, int subframe, uint16_t packet_type) { int16_t *rxF; -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) if (packet_type > IF4p5_PRACH) rxF = &prach_rxsigF_br[packet_type - IF4p5_PRACH - 1][0][0]; else @@ -262,7 +262,7 @@ void recv_IF4p5(RU_t *ru, int *frame, int *subframe, uint16_t *packet_type, uint int32_t **txdataF = ru->common.txdataF_BF; int32_t **rxdataF = ru->common.rxdataF; int16_t **prach_rxsigF = ru->prach_rxsigF; -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) int16_t ***prach_rxsigF_br = ru->prach_rxsigF_br; #endif void *rx_buffer = ru->ifbuffer.rx; @@ -359,7 +359,7 @@ void recv_IF4p5(RU_t *ru, int *frame, int *subframe, uint16_t *packet_type, uint int16_t *rxF; -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) if (*packet_type > IF4p5_PRACH) rxF = &prach_rxsigF_br[*packet_type - IF4p5_PRACH - 1][0][0]; else diff --git a/openair1/PHY/LTE_TRANSPORT/prach.c b/openair1/PHY/LTE_TRANSPORT/prach.c index ec0b7db4ad..42d217130a 100644 --- a/openair1/PHY/LTE_TRANSPORT/prach.c +++ b/openair1/PHY/LTE_TRANSPORT/prach.c @@ -38,7 +38,7 @@ #include "common/utils/LOG/vcd_signal_dumper.h" #include "prach_extern.h" -#if (RRC_VERSION < MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION < MAKE_VERSION(14, 0, 0)) #define rx_prach0 rx_prach #endif @@ -49,7 +49,7 @@ void rx_prach0(PHY_VARS_eNB *eNB, uint16_t *max_preamble_delay, uint16_t Nf, uint8_t tdd_mapindex -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) ,uint8_t br_flag, uint8_t ce_level #endif @@ -95,7 +95,7 @@ void rx_prach0(PHY_VARS_eNB *eNB, int16_t prach_ifft_tmp[2048*2] __attribute__((aligned(32))); int32_t *prach_ifft=(int32_t*)NULL; int32_t **prach_ifftp=(int32_t **)NULL; -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) int prach_ifft_cnt=0; #endif @@ -112,7 +112,7 @@ void rx_prach0(PHY_VARS_eNB *eNB, frame_type = fp->frame_type; -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) if (br_flag == 1) { AssertFatal(fp->prach_emtc_config_common.prach_Config_enabled==1, "emtc prach_Config is not enabled\n"); @@ -147,7 +147,7 @@ void rx_prach0(PHY_VARS_eNB *eNB, uint16_t N_ZC = (prach_fmt <4)?839:139; if (eNB) { -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) if (br_flag == 1) { prach_ifftp = eNB->prach_vars_br.prach_ifft[ce_level]; subframe = eNB->proc.subframe_prach_br; @@ -174,7 +174,7 @@ void rx_prach0(PHY_VARS_eNB *eNB, } } else { -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) if (br_flag == 1) { subframe = ru->proc.subframe_prach_br; rxsigF = ru->prach_rxsigF_br[ce_level]; @@ -425,7 +425,7 @@ void rx_prach0(PHY_VARS_eNB *eNB, if ((eNB==NULL) && (ru!=NULL) && ru->function == NGFI_RRU_IF4p5) { /// **** send_IF4 of rxsigF to RAU **** /// -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) if (br_flag == 1) send_IF4p5(ru, ru->proc.frame_prach, ru->proc.subframe_prach, IF4p5_PRACH+1+ce_level); else @@ -570,7 +570,7 @@ void rx_prach0(PHY_VARS_eNB *eNB, if (new_dft == 1) { new_dft = 0; -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) if (br_flag == 1) { Xu=(int16_t*)eNB->X_u_br[ce_level][preamble_offset-first_nonzero_root_idx]; prach_ifft = prach_ifftp[prach_ifft_cnt++]; @@ -627,7 +627,7 @@ void rx_prach0(PHY_VARS_eNB *eNB, } // new dft // check energy in nth time shift, for -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) if ((br_flag==0) || (eNB->prach_vars_br.repetition_number[ce_level]== eNB->frame_parms.prach_emtc_config_common.prach_ConfigInfo.prach_numRepetitionPerPreambleAttempt[ce_level])) @@ -694,7 +694,7 @@ void rx_prach0(PHY_VARS_eNB *eNB, } -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) void rx_prach(PHY_VARS_eNB *eNB, RU_t *ru, @@ -736,4 +736,4 @@ void rx_prach(PHY_VARS_eNB *eNB, } } -#endif /* #if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) */ +#endif /* #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) */ diff --git a/openair1/PHY/LTE_TRANSPORT/prach_common.c b/openair1/PHY/LTE_TRANSPORT/prach_common.c index 475a97ca0c..4962f6a7f9 100644 --- a/openair1/PHY/LTE_TRANSPORT/prach_common.c +++ b/openair1/PHY/LTE_TRANSPORT/prach_common.c @@ -570,7 +570,7 @@ int is_prach_subframe(LTE_DL_FRAME_PARMS *frame_parms,uint32_t frame, uint8_t su uint8_t prach_ConfigIndex = frame_parms->prach_config_common.prach_ConfigInfo.prach_ConfigIndex; int prach_mask = is_prach_subframe0(frame_parms,prach_ConfigIndex,frame,subframe); -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) int i; for (i=0;i<4;i++) { diff --git a/openair1/PHY/LTE_TRANSPORT/transport_common.h b/openair1/PHY/LTE_TRANSPORT/transport_common.h index 130c973774..c1104cd290 100644 --- a/openair1/PHY/LTE_TRANSPORT/transport_common.h +++ b/openair1/PHY/LTE_TRANSPORT/transport_common.h @@ -105,7 +105,7 @@ typedef enum { -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) typedef enum { CEmodeA = 0, CEmodeB = 1 @@ -138,7 +138,7 @@ typedef enum { HARQ_SR_CQI } UCI_type_t; -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) typedef enum { NOCE, CEMODEA, @@ -183,7 +183,7 @@ typedef struct { PRACH_TDD_PREAMBLE_MAP_elem map[6]; } PRACH_TDD_PREAMBLE_MAP; -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) typedef struct { uint16_t slss_id; diff --git a/openair1/PHY/LTE_TRANSPORT/transport_eNB.h b/openair1/PHY/LTE_TRANSPORT/transport_eNB.h index d1dd595d35..7df39e038c 100644 --- a/openair1/PHY/LTE_TRANSPORT/transport_eNB.h +++ b/openair1/PHY/LTE_TRANSPORT/transport_eNB.h @@ -126,7 +126,7 @@ typedef struct { /// codeword this transport block is mapped to uint8_t codeword; #ifdef PHY_TX_THREAD -#ifdef Rel14 +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) /// indicator that this DLSCH corresponds to SIB1-BR, needed for c_init for scrambling uint8_t sib1_br_flag; /// initial absolute subframe (see 36.211 Section 6.3.1), needed for c_init for scrambling @@ -183,7 +183,7 @@ typedef struct { /// amplitude of PDSCH (compared to RS) in symbols containing pilots int16_t sqrt_rho_b; #ifndef PHY_TX_THREAD -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) /// indicator that this DLSCH corresponds to SIB1-BR, needed for c_init for scrambling uint8_t sib1_br_flag; /// initial absolute subframe (see 36.211 Section 6.3.1), needed for c_init for scrambling @@ -348,7 +348,7 @@ typedef struct { uint8_t tdd_bundling; /// Received Energy uint32_t stat; -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) /// non BL/CE, CEmodeA, CEmodeB UE_type_t ue_type; /// Indicates the symbols that are left empty due to eMTC retuning. diff --git a/openair1/PHY/LTE_TRANSPORT/transport_proto.h b/openair1/PHY/LTE_TRANSPORT/transport_proto.h index 37ac335d02..f3c55b85e6 100644 --- a/openair1/PHY/LTE_TRANSPORT/transport_proto.h +++ b/openair1/PHY/LTE_TRANSPORT/transport_proto.h @@ -578,7 +578,7 @@ void rx_prach(PHY_VARS_eNB *phy_vars_eNB,RU_t *ru, uint16_t *max_preamble_energy, uint16_t *max_preamble_delay, uint16_t Nf, uint8_t tdd_mapindex -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) , uint8_t br_flag #endif diff --git a/openair1/PHY/LTE_UE_TRANSPORT/dci_tools_ue.c b/openair1/PHY/LTE_UE_TRANSPORT/dci_tools_ue.c index e0ea796a82..76176d346e 100644 --- a/openair1/PHY/LTE_UE_TRANSPORT/dci_tools_ue.c +++ b/openair1/PHY/LTE_UE_TRANSPORT/dci_tools_ue.c @@ -3593,7 +3593,7 @@ int generate_ue_ulsch_params_from_dci(void *dci_pdu, if (cqi_req == 1) { - if( (AntennaInfoDedicated__transmissionMode_tm3 == transmission_mode) || (AntennaInfoDedicated__transmissionMode_tm4 == transmission_mode) ) + if( (LTE_AntennaInfoDedicated__transmissionMode_tm3 == transmission_mode) || (LTE_AntennaInfoDedicated__transmissionMode_tm4 == transmission_mode) ) { ulsch->O_RI = 1; } diff --git a/openair1/PHY/defs_L1_NB_IoT.h b/openair1/PHY/defs_L1_NB_IoT.h index 8a7c853df5..0a34d9f12b 100644 --- a/openair1/PHY/defs_L1_NB_IoT.h +++ b/openair1/PHY/defs_L1_NB_IoT.h @@ -425,7 +425,7 @@ typedef struct eNB_proc_NB_IoT_t_s { int RU_mask; /// mask for RUs serving nbiot (PRACH) int RU_mask_prach; -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) /// mask for RUs serving eNB (PRACH) int RU_mask_prach_br; #endif diff --git a/openair1/PHY/defs_common.h b/openair1/PHY/defs_common.h index 9a735b038f..ae0168b53c 100644 --- a/openair1/PHY/defs_common.h +++ b/openair1/PHY/defs_common.h @@ -159,7 +159,7 @@ typedef struct { PRACH_CONFIG_INFO prach_ConfigInfo; } PRACH_CONFIG_COMMON; -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) /// PRACH-eMTC-Config from 36.331 RRC spec typedef struct { @@ -192,7 +192,7 @@ typedef struct { /// prach_Config_enabled=1 means enabled. \vr{[0..1]} uint8_t prach_Config_enabled; /// PRACH Configuration Information -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) PRACH_eMTC_CONFIG_INFO prach_ConfigInfo; #endif } PRACH_eMTC_CONFIG_COMMON; @@ -644,7 +644,7 @@ typedef struct { uint8_t nb_antenna_ports_eNB; /// PRACH_CONFIG PRACH_CONFIG_COMMON prach_config_common; -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) /// PRACH_eMTC_CONFIG PRACH_eMTC_CONFIG_COMMON prach_emtc_config_common; #endif diff --git a/openair1/PHY/defs_eNB.h b/openair1/PHY/defs_eNB.h index f23485cad8..8406aaa2ff 100644 --- a/openair1/PHY/defs_eNB.h +++ b/openair1/PHY/defs_eNB.h @@ -85,7 +85,7 @@ typedef struct RU_proc_t_s { int subframe_tx; /// subframe to act upon for reception of prach int subframe_prach; -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) /// subframe to act upon for reception of prach BL/CE UEs int subframe_prach_br; #endif @@ -97,7 +97,7 @@ typedef struct RU_proc_t_s { int frame_tx_unwrap; /// frame to act upon for reception of prach int frame_prach; -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) /// frame to act upon for reception of prach int frame_prach_br; #endif @@ -109,7 +109,7 @@ typedef struct RU_proc_t_s { int instance_cnt_FH1; /// \internal This variable is protected by \ref mutex_prach. int instance_cnt_prach; -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) /// \internal This variable is protected by \ref mutex_prach. int instance_cnt_prach_br; #endif @@ -131,7 +131,7 @@ typedef struct RU_proc_t_s { pthread_t pthread_FH1; /// pthread structure for RU prach processing thread pthread_t pthread_prach; -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) /// pthread structure for RU prach processing thread BL/CE UEs pthread_t pthread_prach_br; #endif @@ -154,7 +154,7 @@ typedef struct RU_proc_t_s { pthread_attr_t attr_FH1; /// pthread attributes for RU prach pthread_attr_t attr_prach; -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) /// pthread attributes for RU prach BL/CE UEs pthread_attr_t attr_prach_br; #endif @@ -173,7 +173,7 @@ typedef struct RU_proc_t_s { struct sched_param sched_param_FH1; /// scheduling parameters for RU prach thread struct sched_param sched_param_prach; -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) /// scheduling parameters for RU prach thread BL/CE UEs struct sched_param sched_param_prach_br; #endif @@ -186,7 +186,7 @@ typedef struct RU_proc_t_s { pthread_cond_t cond_FH1; /// condition variable for RU prach thread pthread_cond_t cond_prach; -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) /// condition variable for RU prach thread BL/CE UEs pthread_cond_t cond_prach_br; #endif @@ -207,7 +207,7 @@ typedef struct RU_proc_t_s { pthread_mutex_t mutex_FH1; /// mutex for RU prach pthread_mutex_t mutex_prach; -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) /// mutex for RU prach BL/CE UEs pthread_mutex_t mutex_prach_br; #endif @@ -359,7 +359,7 @@ typedef struct RU_t_s{ int (*wakeup_rxtx)(struct PHY_VARS_eNB_s *eNB, struct RU_t_s *ru); /// function pointer to wakeup routine in lte-enb. void (*wakeup_prach_eNB)(struct PHY_VARS_eNB_s *eNB,struct RU_t_s *ru,int frame,int subframe); -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) /// function pointer to wakeup routine in lte-enb. void (*wakeup_prach_eNB_br)(struct PHY_VARS_eNB_s *eNB,struct RU_t_s *ru,int frame,int subframe); #endif @@ -484,7 +484,7 @@ typedef struct RRU_config_s { int prach_FreqOffset[MAX_BANDS_PER_RRU]; /// prach_ConfigIndex for IF4p5 int prach_ConfigIndex[MAX_BANDS_PER_RRU]; -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) int emtc_prach_CElevel_enable[MAX_BANDS_PER_RRU][4]; /// emtc_prach_FreqOffset for IF4p5 per CE Level int emtc_prach_FreqOffset[MAX_BANDS_PER_RRU][4]; @@ -619,7 +619,7 @@ typedef struct { int32_t **prach_ifft[4]; /// repetition number -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) /// indicator of first frame in a group of PRACH repetitions int first_frame[4]; /// current repetition for each CE level @@ -706,7 +706,7 @@ typedef struct eNB_proc_t_s { int subframe_rx; /// subframe to act upon for PRACH int subframe_prach; -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) /// subframe to act upon for reception of prach BL/CE UEs int subframe_prach_br; #endif @@ -716,7 +716,7 @@ typedef struct eNB_proc_t_s { int frame_tx; /// frame to act upon for PRACH int frame_prach; -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) /// frame to act upon for PRACH BL/CE UEs int frame_prach_br; #endif @@ -726,7 +726,7 @@ typedef struct eNB_proc_t_s { int instance_cnt_te; /// \internal This variable is protected by \ref mutex_prach. int instance_cnt_prach; -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) /// \internal This variable is protected by \ref mutex_prach for BL/CE UEs. int instance_cnt_prach_br; #endif @@ -748,7 +748,7 @@ typedef struct eNB_proc_t_s { pthread_attr_t attr_single; /// pthread attributes for prach processing thread pthread_attr_t attr_prach; -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) /// pthread attributes for prach processing thread BL/CE UEs pthread_attr_t attr_prach_br; #endif @@ -762,7 +762,7 @@ typedef struct eNB_proc_t_s { struct sched_param sched_param_single; /// scheduling parameters for prach thread struct sched_param sched_param_prach; -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) /// scheduling parameters for prach thread struct sched_param sched_param_prach_br; #endif @@ -774,7 +774,7 @@ typedef struct eNB_proc_t_s { pthread_t pthread_te; /// pthread structure for PRACH thread pthread_t pthread_prach; -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) /// pthread structure for PRACH thread BL/CE UEs pthread_t pthread_prach_br; #endif @@ -784,7 +784,7 @@ typedef struct eNB_proc_t_s { pthread_cond_t cond_te; /// condition variable for PRACH processing thread; pthread_cond_t cond_prach; -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) /// condition variable for PRACH processing thread BL/CE UEs; pthread_cond_t cond_prach_br; #endif @@ -796,7 +796,7 @@ typedef struct eNB_proc_t_s { pthread_mutex_t mutex_te; /// mutex for PRACH thread pthread_mutex_t mutex_prach; -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) /// mutex for PRACH thread for BL/CE UEs pthread_mutex_t mutex_prach_br; #endif @@ -812,7 +812,7 @@ typedef struct eNB_proc_t_s { int RU_mask; /// mask for RUs serving eNB (PRACH) int RU_mask_prach; -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) /// mask for RUs serving eNB (PRACH) int RU_mask_prach_br; #endif @@ -927,14 +927,14 @@ typedef struct PHY_VARS_eNB_s { nfapi_cqi_indication_raw_pdu_t cqi_raw_pdu_list[NFAPI_CQI_IND_MAX_PDU]; /// NFAPI PRACH information nfapi_preamble_pdu_t preamble_list[MAX_NUM_RX_PRACH_PREAMBLES]; -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) /// NFAPI PRACH information BL/CE UEs nfapi_preamble_pdu_t preamble_list_br[MAX_NUM_RX_PRACH_PREAMBLES]; #endif Sched_Rsp_t Sched_INFO; LTE_eNB_PDCCH pdcch_vars[2]; LTE_eNB_PHICH phich_vars[2]; -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) LTE_eNB_EPDCCH epdcch_vars[2]; LTE_eNB_MPDCCH mpdcch_vars[2]; LTE_eNB_PRACH prach_vars_br; @@ -966,7 +966,7 @@ typedef struct PHY_VARS_eNB_s { uint32_t lte_gold_mbsfn_table[10][3][42]; uint32_t X_u[64][839]; -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) uint32_t X_u_br[4][64][839]; #endif uint8_t pbch_configured; @@ -1037,7 +1037,7 @@ typedef struct PHY_VARS_eNB_s { uint8_t cba_last_reception[4]; // Pointers for active physicalConfigDedicated to be applied in current subframe - struct PhysicalConfigDedicated *physicalConfigDedicated[NUMBER_OF_UE_MAX]; + struct LTE_PhysicalConfigDedicated *physicalConfigDedicated[NUMBER_OF_UE_MAX]; uint32_t rb_mask_ul[4]; diff --git a/openair1/SCHED/fapi_l1.c b/openair1/SCHED/fapi_l1.c index ad72c3d9f5..ec14b32ac2 100644 --- a/openair1/SCHED/fapi_l1.c +++ b/openair1/SCHED/fapi_l1.c @@ -63,7 +63,7 @@ void handle_nfapi_dci_dl_pdu(PHY_VARS_eNB *eNB, LOG_D(PHY,"Frame %d, Subframe %d: DCI processing - populated pdcch_vars->dci_alloc[%d] proc:subframe_tx:%d idx:%d pdcch_vars->num_dci:%d\n",proc->frame_tx,proc->subframe_tx, pdcch_vars->num_dci, proc->subframe_tx, idx, pdcch_vars->num_dci); } -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) void handle_nfapi_mpdcch_pdu(PHY_VARS_eNB *eNB, eNB_rxtx_proc_t *proc, @@ -128,7 +128,7 @@ void handle_nfapi_bch_pdu(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc, // adjust transmit amplitude here based on NFAPI info } -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) extern uint32_t localRIV2alloc_LUT6[32]; extern uint32_t localRIV2alloc_LUT25[512]; extern uint32_t localRIV2alloc_LUT50_0[1600]; @@ -145,10 +145,10 @@ void handle_nfapi_dlsch_pdu(PHY_VARS_eNB *eNB,int frame,int subframe,eNB_rxtx_pr uint8_t *sdu) { nfapi_dl_config_dlsch_pdu_rel8_t *rel8 = &dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8; -#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) nfapi_dl_config_dlsch_pdu_rel10_t *rel10 = &dl_config_pdu->dlsch_pdu.dlsch_pdu_rel10; #endif -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) nfapi_dl_config_dlsch_pdu_rel13_t *rel13 = &dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13; #endif LTE_eNB_DLSCH_t *dlsch0=NULL,*dlsch1=NULL; @@ -167,7 +167,7 @@ void handle_nfapi_dlsch_pdu(PHY_VARS_eNB *eNB,int frame,int subframe,eNB_rxtx_pr dlsch0 = eNB->dlsch[UE_id][0]; dlsch1 = eNB->dlsch[UE_id][1]; -#if (RRC_VERSION >= MAKE_VERSION(13, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(13, 0, 0)) if ((rel13->pdsch_payload_type < 2) && (rel13->ue_type>0)) dlsch0->harq_ids[frame%2][subframe] = 0; #endif @@ -236,7 +236,7 @@ void handle_nfapi_dlsch_pdu(PHY_VARS_eNB *eNB,int frame,int subframe,eNB_rxtx_pr rel8->rnti,UE_id,harq_pid); } -#if (RRC_VERSION >= MAKE_VERSION(13, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(13, 0, 0)) #ifdef PHY_TX_THREAD dlsch0_harq->sib1_br_flag=0; #else @@ -307,7 +307,7 @@ void handle_nfapi_dlsch_pdu(PHY_VARS_eNB *eNB,int frame,int subframe,eNB_rxtx_pr #endif -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) LOG_D(PHY,"dlsch->i0:%04x dlsch0_harq[pdsch_start:%d nb_rb:%d vrb_type:%d rvidx:%d Nl:%d mimo_mode:%d dl_power_off:%d round:%d status:%d TBS:%d Qm:%d codeword:%d rb_alloc:%d] rel8[length:%d]\n", #ifdef PHY_TX_THREAD dlsch0_harq->i0, @@ -823,7 +823,7 @@ void schedule_response(Sched_Rsp_t *Sched_INFO) case NFAPI_DL_CONFIG_EPDCCH_DL_PDU_TYPE: // handle_nfapi_epdcch_pdu(eNB,dl_config_pdu); break; -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) case NFAPI_DL_CONFIG_MPDCCH_PDU_TYPE: handle_nfapi_mpdcch_pdu(eNB,proc,dl_config_pdu); eNB->mpdcch_vars[subframe&1].num_dci++; diff --git a/openair1/SCHED/phy_procedures_lte_eNb.c b/openair1/SCHED/phy_procedures_lte_eNb.c index 276006ec3b..4525b93d72 100644 --- a/openair1/SCHED/phy_procedures_lte_eNb.c +++ b/openair1/SCHED/phy_procedures_lte_eNb.c @@ -136,7 +136,7 @@ lte_subframe_t get_subframe_direction(uint8_t Mod_id,uint8_t CC_id,uint8_t subfr void pmch_procedures(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc) { -#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) MCH_PDU *mch_pduP=NULL; // uint8_t sync_area=255; #endif @@ -152,7 +152,7 @@ void pmch_procedures(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc) { subframe<<1,1); -#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) // if mcch is active, send regardless of the node type: eNB or RN // when mcch is active, MAC sched does not allow MCCH and MTCH multiplexing /* diff --git a/openair1/SCHED/prach_procedures.c b/openair1/SCHED/prach_procedures.c index 0c45b9ad80..1dead0ee57 100644 --- a/openair1/SCHED/prach_procedures.c +++ b/openair1/SCHED/prach_procedures.c @@ -54,7 +54,7 @@ extern uint32_t nfapi_mode; extern int oai_nfapi_rach_ind(nfapi_rach_indication_t *rach_ind); void prach_procedures(PHY_VARS_eNB *eNB -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) , int br_flag #endif @@ -63,7 +63,7 @@ void prach_procedures(PHY_VARS_eNB *eNB uint16_t i; int frame,subframe; -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) if (br_flag==1) { subframe = eNB->proc.subframe_prach_br; frame = eNB->proc.frame_prach_br; @@ -93,7 +93,7 @@ void prach_procedures(PHY_VARS_eNB *eNB ru=eNB->RU_list[i]; for (ru_aa=0,aa=0;ru_aanb_rx;ru_aa++,aa++) { eNB->prach_vars.rxsigF[0][aa] = eNB->RU_list[i]->prach_rxsigF[ru_aa]; -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) int ce_level; if (br_flag==1) @@ -109,7 +109,7 @@ void prach_procedures(PHY_VARS_eNB *eNB &max_preamble_delay[0], frame, 0 -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) ,br_flag #endif ); @@ -121,7 +121,7 @@ void prach_procedures(PHY_VARS_eNB *eNB max_preamble_delay[0], eNB->prach_energy_counter); -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) if (br_flag==1) { eNB->UL_INFO.rach_ind_br.rach_indication_body.preamble_list = eNB->preamble_list_br; diff --git a/openair1/SCHED/sched_common.h b/openair1/SCHED/sched_common.h index e579110a78..3e1455e67c 100644 --- a/openair1/SCHED/sched_common.h +++ b/openair1/SCHED/sched_common.h @@ -30,7 +30,7 @@ #include "PHY/defs_eNB.h" #include "PHY/defs_UE.h" -#include "TDD-Config.h" +#include "LTE_TDD-Config.h" /*! \brief Function to compute subframe Number(DL and S) as a function of Frame type and TDD Configuration @param frame_parms Pointer to DL frame parameter descriptor @returns Subframe Number (DL,S) @@ -346,7 +346,7 @@ void compute_srs_pos(lte_frame_type_t frameType,uint16_t isrs,uint16_t *psrsPeri int ul_ACK_subframe2_dl_frame(LTE_DL_FRAME_PARMS *frame_parms,int frame, unsigned char subframe,unsigned char subframe_tx); -void get_retransmission_timing(TDD_Config_t *tdd_Config, frame_t *frameP, sub_frame_t *subframeP); +void get_retransmission_timing(LTE_TDD_Config_t *tdd_Config, frame_t *frameP, sub_frame_t *subframeP); /*@}*/ diff --git a/openair1/SCHED/sched_eNB.h b/openair1/SCHED/sched_eNB.h index cf6c5815f2..9815f25574 100644 --- a/openair1/SCHED/sched_eNB.h +++ b/openair1/SCHED/sched_eNB.h @@ -127,7 +127,7 @@ void phy_procedures_eNB_S_RX(PHY_VARS_eNB *phy_vars_eNB,eNB_rxtx_proc_t *proc); @param phy_vars_eNB Pointer to eNB variables on which to act @param br_flag indicator for eMTC PRACH */ -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) void prach_procedures(PHY_VARS_eNB *eNB, int br_flag); #else diff --git a/openair1/SCHED_UE/phy_procedures_lte_ue.c b/openair1/SCHED_UE/phy_procedures_lte_ue.c index b7d05ba006..9872fe5a0d 100644 --- a/openair1/SCHED_UE/phy_procedures_lte_ue.c +++ b/openair1/SCHED_UE/phy_procedures_lte_ue.c @@ -3110,7 +3110,7 @@ void ue_pmch_procedures(PHY_VARS_UE *ue, UE_rxtx_proc_t *proc,int eNB_id,int abs int subframe_rx = proc->subframe_rx; int frame_rx = proc->frame_rx; int pmch_mcs=-1; -#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) int CC_id = ue->CC_id; #endif uint8_t sync_area=255; @@ -3123,7 +3123,7 @@ void ue_pmch_procedures(PHY_VARS_UE *ue, UE_rxtx_proc_t *proc,int eNB_id,int abs LOG_D(PHY,"[UE %d] Frame %d, subframe %d: Querying for PMCH demodulation\n", ue->Mod_id,frame_rx,subframe_rx); -#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) pmch_mcs = ue_query_mch(ue->Mod_id, CC_id, @@ -3222,7 +3222,7 @@ void ue_pmch_procedures(PHY_VARS_UE *ue, UE_rxtx_proc_t *proc,int eNB_id,int abs // if (subframe_rx==9) // mac_xface->macphy_exit("Why are we exiting here?"); } else { // decoding successful -#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) ue_send_mch_sdu(ue->Mod_id, CC_id, @@ -3244,7 +3244,7 @@ void ue_pmch_procedures(PHY_VARS_UE *ue, UE_rxtx_proc_t *proc,int eNB_id,int abs ue->dlsch_mch_received_sf[subframe_rx][0]=1; } -#endif // #if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) +#endif // #if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) } // decoding sucessful } // pmch_mcs>=0 } // is_pmch_subframe=true diff --git a/openair2/COMMON/gtpv1_u_messages_types.h b/openair2/COMMON/gtpv1_u_messages_types.h index 0118a78f6d..c398b55e3e 100644 --- a/openair2/COMMON/gtpv1_u_messages_types.h +++ b/openair2/COMMON/gtpv1_u_messages_types.h @@ -22,10 +22,10 @@ #ifndef GTPV1_U_MESSAGES_TYPES_H_ #define GTPV1_U_MESSAGES_TYPES_H_ -#include "asn_constant.h" +#include "LTE_asn_constant.h" -#define GTPV1U_MAX_BEARERS_PER_UE max_val_DRB_Identity +#define GTPV1U_MAX_BEARERS_PER_UE max_val_LTE_DRB_Identity #define GTPV1U_ENB_UPDATE_TUNNEL_REQ(mSGpTR) (mSGpTR)->ittiMsg.Gtpv1uUpdateTunnelReq #define GTPV1U_ENB_UPDATE_TUNNEL_RESP(mSGpTR) (mSGpTR)->ittiMsg.Gtpv1uUpdateTunnelResp diff --git a/openair2/COMMON/mac_rrc_primitives.h b/openair2/COMMON/mac_rrc_primitives.h index d902de15d9..0141220235 100644 --- a/openair2/COMMON/mac_rrc_primitives.h +++ b/openair2/COMMON/mac_rrc_primitives.h @@ -30,13 +30,13 @@ #include "COMMON/platform_types.h" #include "COMMON/platform_constants.h" -#include "RadioResourceConfigCommonSIB.h" -#include "RadioResourceConfigDedicated.h" -#include "MeasGapConfig.h" -#include "TDD-Config.h" -#if (RRC_VERSION >= MAKE_VERSION(9, 0, 0)) -#include "MBSFN-AreaInfoList-r9.h" -#include "MBSFN-SubframeConfigList.h" +#include "LTE_RadioResourceConfigCommonSIB.h" +#include "LTE_RadioResourceConfigDedicated.h" +#include "LTE_MeasGapConfig.h" +#include "LTE_TDD-Config.h" +#if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) +#include "LTE_MBSFN-AreaInfoList-r9.h" +#include "LTE_MBSFN-SubframeConfigList.h" #endif //#include "rrm_config_structs.h" //#include "platform_types.h" @@ -347,25 +347,25 @@ typedef struct { void (*pdcp_data_req)(module_id_t, rb_id_t, sdu_size_t, char*); signed int (*rrc_rlc_config_req)(unsigned int, unsigned int, unsigned int, unsigned int, rlc_info_t ); int (*rrc_mac_config_req)(uint8_t Mod_id,uint8_t eNB_flag,uint8_t UE_id,uint8_t eNB_index, - RadioResourceConfigCommonSIB_t *radioResourceConfigCommon, - struct PhysicalConfigDedicated *physicalConfigDedicated, - MAC_MainConfig_t *mac_MainConfig, + LTE_RadioResourceConfigCommonSIB_t *radioResourceConfigCommon, + struct LTE_PhysicalConfigDedicated *physicalConfigDedicated, + LTE_MAC_MainConfig_t *mac_MainConfig, long logicalChannelIdentity, - LogicalChannelConfig_t *logicalChannelConfig, - MeasGapConfig_t *measGapConfig, - TDD_Config_t *tdd_Config, + LTE_LogicalChannelConfig_t *logicalChannelConfig, + LTE_MeasGapConfig_t *measGapConfig, + LTE_TDD_Config_t *tdd_Config, uint8_t *SIwindowsize, uint16_t *SIperiod -#if (RRC_VERSION >= MAKE_VERSION(9, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) , MBMS_flag_t MBMS_Flag, - struct MBSFN_SubframeConfigList *mbsfn_SubframeConfigList, - MBSFN_AreaInfoList_r9_t *mbsfn_AreaInfoList, - struct PMCH_InfoList_r9 *pmch_InfoList + struct LTE_MBSFN_SubframeConfigList *mbsfn_SubframeConfigList, + LTE_MBSFN_AreaInfoList_r9_t *mbsfn_AreaInfoList, + struct LTE_PMCH_InfoList_r9 *pmch_InfoList #endif ); unsigned int (*mac_rlc_data_req)(module_id_t, unsigned int, const unsigned int,char* -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) ,uint32_t ,uint32_t #endif @@ -373,7 +373,7 @@ typedef struct { void (*mac_rlc_data_ind)(module_id_t, logical_chan_id_t, char*, tb_size_t, num_tb_t, crc_t* ); mac_rlc_status_resp_t (*mac_rlc_status_ind) (module_id_t enb_mod_idP, module_id_t ue_mod_idP, frame_t frameP, sub_frame_t subframeP, eNB_flag_t eNB_flagP, MBMS_flag_t MBMS_flagP, logical_chan_id_t channel_idP, tb_size_t tb_sizeP -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) ,uint32_t sourceL2Id ,uint32_t destinationL2Id #endif diff --git a/openair2/COMMON/platform_constants.h b/openair2/COMMON/platform_constants.h index 9aa912a01e..b00e08588a 100644 --- a/openair2/COMMON/platform_constants.h +++ b/openair2/COMMON/platform_constants.h @@ -29,7 +29,7 @@ ***************************************************************************/ #ifdef CMAKER -#include "asn_constant.h" +#include "LTE_asn_constant.h" #else #include "RRC/LTE/MESSAGES/asn1_constants.h" #endif @@ -87,19 +87,19 @@ #define MAX_MANAGED_ENB_PER_MOBILE 2 ///NB-IOT -#define NB_RB_MAX_NB_IOT (maxDRB_NB_r13 + 3) //MP: NB_IoT --> 2(DRB)+3(SRBs - 2 is not used) = 5 +#define NB_RB_MAX_NB_IOT (LTE_maxDRB_NB_r13 + 3) //MP: NB_IoT --> 2(DRB)+3(SRBs - 2 is not used) = 5 #define DEFAULT_RAB_ID 1 -#define NB_RB_MAX (maxDRB + 3) /* was 11, now 14, maxDRB comes from asn1_constants.h, + 3 because of 3 SRB, one invisible id 0, then id 1 and 2 */ -#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) -#define NB_RB_MBMS_MAX (maxSessionPerPMCH*maxServiceCount) +#define NB_RB_MAX (LTE_maxDRB + 3) /* was 11, now 14, maxDRB comes from asn1_constants.h, + 3 because of 3 SRB, one invisible id 0, then id 1 and 2 */ +#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) +#define NB_RB_MBMS_MAX (LTE_maxSessionPerPMCH*LTE_maxServiceCount) #else // Do not allocate unused memory #define NB_RB_MBMS_MAX 1 #endif -#define NB_RAB_MAX maxDRB /* was 8, now 11 */ +#define NB_RAB_MAX LTE_maxDRB /* was 8, now 11 */ #define RAB_SHIFT1 9 #define RAB_SHIFT2 3 #define RAB_OFFSET 0x0007 diff --git a/openair2/COMMON/rrc_messages_types.h b/openair2/COMMON/rrc_messages_types.h index 12a06f7c65..aeacd09fde 100644 --- a/openair2/COMMON/rrc_messages_types.h +++ b/openair2/COMMON/rrc_messages_types.h @@ -33,26 +33,26 @@ #include "rrc_types.h" #include "s1ap_messages_types.h" #ifdef CMAKER -#include "SystemInformationBlockType2.h" +#include "LTE_SystemInformationBlockType2.h" #else -#include "RRC/LTE/MESSAGES/SystemInformationBlockType2.h" +#include "RRC/LTE/MESSAGES/LTE_SystemInformationBlockType2.h" #endif -#include "SL-OffsetIndicator-r12.h" -#include "SubframeBitmapSL-r12.h" -#include "SL-CP-Len-r12.h" -#include "SL-PeriodComm-r12.h" -#include "SL-DiscResourcePool-r12.h" +#include "LTE_SL-OffsetIndicator-r12.h" +#include "LTE_SubframeBitmapSL-r12.h" +#include "LTE_SL-CP-Len-r12.h" +#include "LTE_SL-PeriodComm-r12.h" +#include "LTE_SL-DiscResourcePool-r12.h" //-------------------------------------------------------------------------------------------// // Messages for RRC logging #if defined(DISABLE_ITTI_XER_PRINT) -#include "BCCH-DL-SCH-Message.h" -#include "DL-CCCH-Message.h" -#include "DL-DCCH-Message.h" -#include "UE-EUTRA-Capability.h" -#include "UL-CCCH-Message.h" -#include "UL-DCCH-Message.h" +#include "LTE_BCCH-DL-SCH-Message.h" +#include "LTE_DL-CCCH-Message.h" +#include "LTE_DL-DCCH-Message.h" +#include "LTE_UE-EUTRA-Capability.h" +#include "LTE_UL-CCCH-Message.h" +#include "LTE_UL-DCCH-Message.h" typedef BCCH_DL_SCH_Message_t RrcDlBcchMessage; typedef DL_CCCH_Message_t RrcDlCcchMessage; @@ -124,7 +124,7 @@ typedef struct RrcConfigurationReq_s { long pucch_delta_shift[MAX_NUM_CCs]; long pucch_nRB_CQI[MAX_NUM_CCs]; long pucch_nCS_AN[MAX_NUM_CCs]; -//#if (RRC_VERSION < MAKE_VERSION(10, 0, 0)) +//#if (LTE_RRC_VERSION < MAKE_VERSION(10, 0, 0)) long pucch_n1_AN[MAX_NUM_CCs]; //#endif long pdsch_referenceSignalPower[MAX_NUM_CCs]; @@ -149,16 +149,16 @@ typedef struct RrcConfigurationReq_s { long pucch_p0_Nominal[MAX_NUM_CCs]; long msg3_delta_Preamble[MAX_NUM_CCs]; long ul_CyclicPrefixLength[MAX_NUM_CCs]; - e_DeltaFList_PUCCH__deltaF_PUCCH_Format1 pucch_deltaF_Format1[MAX_NUM_CCs]; - e_DeltaFList_PUCCH__deltaF_PUCCH_Format1b pucch_deltaF_Format1b[MAX_NUM_CCs]; - e_DeltaFList_PUCCH__deltaF_PUCCH_Format2 pucch_deltaF_Format2[MAX_NUM_CCs]; - e_DeltaFList_PUCCH__deltaF_PUCCH_Format2a pucch_deltaF_Format2a[MAX_NUM_CCs]; - e_DeltaFList_PUCCH__deltaF_PUCCH_Format2b pucch_deltaF_Format2b[MAX_NUM_CCs]; + e_LTE_DeltaFList_PUCCH__deltaF_PUCCH_Format1 pucch_deltaF_Format1[MAX_NUM_CCs]; + e_LTE_DeltaFList_PUCCH__deltaF_PUCCH_Format1b pucch_deltaF_Format1b[MAX_NUM_CCs]; + e_LTE_DeltaFList_PUCCH__deltaF_PUCCH_Format2 pucch_deltaF_Format2[MAX_NUM_CCs]; + e_LTE_DeltaFList_PUCCH__deltaF_PUCCH_Format2a pucch_deltaF_Format2a[MAX_NUM_CCs]; + e_LTE_DeltaFList_PUCCH__deltaF_PUCCH_Format2b pucch_deltaF_Format2b[MAX_NUM_CCs]; long rach_numberOfRA_Preambles[MAX_NUM_CCs]; BOOLEAN_t rach_preamblesGroupAConfig[MAX_NUM_CCs]; long rach_sizeOfRA_PreamblesGroupA[MAX_NUM_CCs]; long rach_messageSizeGroupA[MAX_NUM_CCs]; - e_RACH_ConfigCommon__preambleInfo__preamblesGroupAConfig__messagePowerOffsetGroupB rach_messagePowerOffsetGroupB[MAX_NUM_CCs]; + e_LTE_RACH_ConfigCommon__preambleInfo__preamblesGroupAConfig__messagePowerOffsetGroupB rach_messagePowerOffsetGroupB[MAX_NUM_CCs]; long rach_powerRampingStep[MAX_NUM_CCs]; long rach_preambleInitialReceivedTargetPower[MAX_NUM_CCs]; long rach_preambleTransMax[MAX_NUM_CCs]; @@ -179,45 +179,45 @@ typedef struct RrcConfigurationReq_s { //TTN - for D2D //SIB18 - e_SL_CP_Len_r12 rxPool_sc_CP_Len[MAX_NUM_CCs]; - e_SL_PeriodComm_r12 rxPool_sc_Period[MAX_NUM_CCs]; - e_SL_CP_Len_r12 rxPool_data_CP_Len[MAX_NUM_CCs]; + e_LTE_SL_CP_Len_r12 rxPool_sc_CP_Len[MAX_NUM_CCs]; + e_LTE_SL_PeriodComm_r12 rxPool_sc_Period[MAX_NUM_CCs]; + e_LTE_SL_CP_Len_r12 rxPool_data_CP_Len[MAX_NUM_CCs]; long rxPool_ResourceConfig_prb_Num[MAX_NUM_CCs]; long rxPool_ResourceConfig_prb_Start[MAX_NUM_CCs]; long rxPool_ResourceConfig_prb_End[MAX_NUM_CCs]; - SL_OffsetIndicator_r12_PR rxPool_ResourceConfig_offsetIndicator_present[MAX_NUM_CCs]; + LTE_SL_OffsetIndicator_r12_PR rxPool_ResourceConfig_offsetIndicator_present[MAX_NUM_CCs]; long rxPool_ResourceConfig_offsetIndicator_choice[MAX_NUM_CCs]; - SubframeBitmapSL_r12_PR rxPool_ResourceConfig_subframeBitmap_present[MAX_NUM_CCs]; + LTE_SubframeBitmapSL_r12_PR rxPool_ResourceConfig_subframeBitmap_present[MAX_NUM_CCs]; char* rxPool_ResourceConfig_subframeBitmap_choice_bs_buf[MAX_NUM_CCs]; long rxPool_ResourceConfig_subframeBitmap_choice_bs_size[MAX_NUM_CCs]; long rxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused[MAX_NUM_CCs]; //SIB19 //for discRxPool - SL_CP_Len_r12_t discRxPool_cp_Len[MAX_NUM_CCs]; - e_SL_DiscResourcePool_r12__discPeriod_r12 discRxPool_discPeriod[MAX_NUM_CCs]; + LTE_SL_CP_Len_r12_t discRxPool_cp_Len[MAX_NUM_CCs]; + e_LTE_SL_DiscResourcePool_r12__discPeriod_r12 discRxPool_discPeriod[MAX_NUM_CCs]; long discRxPool_numRetx[MAX_NUM_CCs]; long discRxPool_numRepetition[MAX_NUM_CCs]; long discRxPool_ResourceConfig_prb_Num[MAX_NUM_CCs]; long discRxPool_ResourceConfig_prb_Start[MAX_NUM_CCs]; long discRxPool_ResourceConfig_prb_End[MAX_NUM_CCs]; - SL_OffsetIndicator_r12_PR discRxPool_ResourceConfig_offsetIndicator_present[MAX_NUM_CCs]; + LTE_SL_OffsetIndicator_r12_PR discRxPool_ResourceConfig_offsetIndicator_present[MAX_NUM_CCs]; long discRxPool_ResourceConfig_offsetIndicator_choice[MAX_NUM_CCs]; - SubframeBitmapSL_r12_PR discRxPool_ResourceConfig_subframeBitmap_present[MAX_NUM_CCs]; + LTE_SubframeBitmapSL_r12_PR discRxPool_ResourceConfig_subframeBitmap_present[MAX_NUM_CCs]; char* discRxPool_ResourceConfig_subframeBitmap_choice_bs_buf[MAX_NUM_CCs]; long discRxPool_ResourceConfig_subframeBitmap_choice_bs_size[MAX_NUM_CCs]; long discRxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused[MAX_NUM_CCs]; //for discRxPoolPS - SL_CP_Len_r12_t discRxPoolPS_cp_Len[MAX_NUM_CCs]; - e_SL_DiscResourcePool_r12__discPeriod_r12 discRxPoolPS_discPeriod[MAX_NUM_CCs]; + LTE_SL_CP_Len_r12_t discRxPoolPS_cp_Len[MAX_NUM_CCs]; + e_LTE_SL_DiscResourcePool_r12__discPeriod_r12 discRxPoolPS_discPeriod[MAX_NUM_CCs]; long discRxPoolPS_numRetx[MAX_NUM_CCs]; long discRxPoolPS_numRepetition[MAX_NUM_CCs]; long discRxPoolPS_ResourceConfig_prb_Num[MAX_NUM_CCs]; long discRxPoolPS_ResourceConfig_prb_Start[MAX_NUM_CCs]; long discRxPoolPS_ResourceConfig_prb_End[MAX_NUM_CCs]; - SL_OffsetIndicator_r12_PR discRxPoolPS_ResourceConfig_offsetIndicator_present[MAX_NUM_CCs]; + LTE_SL_OffsetIndicator_r12_PR discRxPoolPS_ResourceConfig_offsetIndicator_present[MAX_NUM_CCs]; long discRxPoolPS_ResourceConfig_offsetIndicator_choice[MAX_NUM_CCs]; - SubframeBitmapSL_r12_PR discRxPoolPS_ResourceConfig_subframeBitmap_present[MAX_NUM_CCs]; + LTE_SubframeBitmapSL_r12_PR discRxPoolPS_ResourceConfig_subframeBitmap_present[MAX_NUM_CCs]; char* discRxPoolPS_ResourceConfig_subframeBitmap_choice_bs_buf[MAX_NUM_CCs]; long discRxPoolPS_ResourceConfig_subframeBitmap_choice_bs_size[MAX_NUM_CCs]; long discRxPoolPS_ResourceConfig_subframeBitmap_choice_bs_bits_unused[MAX_NUM_CCs]; diff --git a/openair2/COMMON/x2ap_messages_types.h b/openair2/COMMON/x2ap_messages_types.h index c74a826ff8..9b744ded6b 100644 --- a/openair2/COMMON/x2ap_messages_types.h +++ b/openair2/COMMON/x2ap_messages_types.h @@ -22,7 +22,7 @@ #ifndef X2AP_MESSAGES_TYPES_H_ #define X2AP_MESSAGES_TYPES_H_ -#include "PhysCellId.h" +#include "LTE_PhysCellId.h" //-------------------------------------------------------------------------------------------// // Defines to access message fields. @@ -122,7 +122,7 @@ typedef struct x2ap_lastvisitedcell_info_s { uint16_t mcc; uint16_t mnc; uint8_t mnc_len; - PhysCellId_t target_physCellId; + LTE_PhysCellId_t target_physCellId; cell_type_t cell_type; uint64_t time_UE_StayedInCell; }x2ap_lastvisitedcell_info_t; @@ -134,7 +134,7 @@ typedef struct x2ap_handover_req_s { unsigned old_eNB_ue_s1ap_id:24; - PhysCellId_t target_physCellId; + LTE_PhysCellId_t target_physCellId; x2ap_gummei_t ue_gummei; diff --git a/openair2/ENB_APP/CONTROL_MODULES/RRC/flexran_agent_rrc.c b/openair2/ENB_APP/CONTROL_MODULES/RRC/flexran_agent_rrc.c index b79ad88417..7d7f48a610 100644 --- a/openair2/ENB_APP/CONTROL_MODULES/RRC/flexran_agent_rrc.c +++ b/openair2/ENB_APP/CONTROL_MODULES/RRC/flexran_agent_rrc.c @@ -262,7 +262,7 @@ int flexran_agent_destroy_ue_state_change(Protocol__FlexranMessage *msg) { } /* this is called by RRC as a part of rrc xface . The controller previously requested this*/ -void flexran_trigger_rrc_measurements (mid_t mod_id, MeasResults_t* measResults) { +void flexran_trigger_rrc_measurements (mid_t mod_id, LTE_MeasResults_t* measResults) { //int i; // int priority = 0; // Warning Preventing diff --git a/openair2/ENB_APP/CONTROL_MODULES/RRC/flexran_agent_rrc.h b/openair2/ENB_APP/CONTROL_MODULES/RRC/flexran_agent_rrc.h index 780976893e..b6cb674ce9 100644 --- a/openair2/ENB_APP/CONTROL_MODULES/RRC/flexran_agent_rrc.h +++ b/openair2/ENB_APP/CONTROL_MODULES/RRC/flexran_agent_rrc.h @@ -55,7 +55,7 @@ int flexran_agent_destroy_ue_state_change(Protocol__FlexranMessage *msg); // void flexran_agent_send_update_rrc_stats(mid_t mod_id); /* this is called by RRC as a part of rrc xface . The controller previously requested this*/ -void flexran_trigger_rrc_measurements (mid_t mod_id, MeasResults_t *); +void flexran_trigger_rrc_measurements (mid_t mod_id, LTE_MeasResults_t *); /* Statistics reply protocol message constructor and destructor */ int flexran_agent_rrc_stats_reply(mid_t mod_id, const report_config_t *report_config, Protocol__FlexUeStatsReport **ue_report, Protocol__FlexCellStatsReport **cell_report); diff --git a/openair2/ENB_APP/CONTROL_MODULES/RRC/flexran_agent_rrc_defs.h b/openair2/ENB_APP/CONTROL_MODULES/RRC/flexran_agent_rrc_defs.h index 8c336abef1..5f6432732f 100644 --- a/openair2/ENB_APP/CONTROL_MODULES/RRC/flexran_agent_rrc_defs.h +++ b/openair2/ENB_APP/CONTROL_MODULES/RRC/flexran_agent_rrc_defs.h @@ -34,7 +34,7 @@ #include "flexran_agent_defs.h" #include "flexran.pb-c.h" #include "header.pb-c.h" -#include "MeasResults.h" +#include "LTE_MeasResults.h" #define RINGBUFFER_SIZE 100 @@ -62,7 +62,7 @@ typedef struct { void (*flexran_agent_notify_ue_state_change)(mid_t mod_id, uint32_t rnti, uint8_t state_change); - void (*flexran_trigger_rrc_measurements)(mid_t mod_id, MeasResults_t* measResults); + void (*flexran_trigger_rrc_measurements)(mid_t mod_id, LTE_MeasResults_t* measResults); } AGENT_RRC_xface; diff --git a/openair2/ENB_APP/RRC_config_tools.c b/openair2/ENB_APP/RRC_config_tools.c index c7c75c13d4..e778439d3d 100644 --- a/openair2/ENB_APP/RRC_config_tools.c +++ b/openair2/ENB_APP/RRC_config_tools.c @@ -40,11 +40,11 @@ # include "sctp_eNB_task.h" # endif #endif -#include "SystemInformationBlockType2.h" +#include "LTE_SystemInformationBlockType2.h" #include "common/config/config_userapi.h" #include "RRC_config_tools.h" -#include "DL-GapConfig-NB-r13.h" -#include "NPRACH-Parameters-NB-r13.h" +#include "LTE_DL-GapConfig-NB-r13.h" +#include "LTE_NPRACH-Parameters-NB-r13.h" static const eutra_band_t eutra_bands[] = { { 1, 1920 * MHz, 1980 * MHz, 2110 * MHz, 2170 * MHz, FDD}, diff --git a/openair2/ENB_APP/RRC_paramsvalues.h b/openair2/ENB_APP/RRC_paramsvalues.h index 06fee0e172..cfab58b451 100644 --- a/openair2/ENB_APP/RRC_paramsvalues.h +++ b/openair2/ENB_APP/RRC_paramsvalues.h @@ -68,27 +68,27 @@ #define NRBDL_OKVALUES {6,15,25,50,75,100} #define UETIMER_T300_OKVALUES {100,200,300,400,600,1000,1500,2000} -#define UETT300(A) UE_TimersAndConstants__t300_ ## A +#define UETT300(A) LTE_UE_TimersAndConstants__t300_ ## A #define UETIMER_T300_MODVALUES { UETT300(ms100), UETT300(ms200),UETT300(ms300),UETT300(ms400),UETT300(ms600),UETT300(ms1000),UETT300(ms1500),UETT300(ms2000)} #define UETIMER_T301_OKVALUES {100,200,300,400,600,1000,1500,2000} -#define UETT301(A) UE_TimersAndConstants__t301_ ## A +#define UETT301(A) LTE_UE_TimersAndConstants__t301_ ## A #define UETIMER_T301_MODVALUES { UETT301(ms100), UETT301(ms200),UETT301(ms300),UETT301(ms400),UETT301(ms600),UETT301(ms1000),UETT301(ms1500),UETT301(ms2000)} #define UETIMER_T310_OKVALUES {0,50,100,200,500,1000,2000} -#define UETT310(A) UE_TimersAndConstants__t310_ ## A +#define UETT310(A) LTE_UE_TimersAndConstants__t310_ ## A #define UETIMER_T310_MODVALUES { UETT310(ms0), UETT310(ms50),UETT310(ms100),UETT310(ms200),UETT310(ms500),UETT310(ms1000),UETT310(ms2000)} #define UETIMER_T311_OKVALUES {1000,3110,5000,10000,15000,20000,31100} -#define UETT311(A) UE_TimersAndConstants__t311_ ## A +#define UETT311(A) LTE_UE_TimersAndConstants__t311_ ## A #define UETIMER_T311_MODVALUES { UETT311(ms1000), UETT311(ms3000),UETT311(ms5000),UETT311(ms10000),UETT311(ms15000),UETT311(ms20000),UETT311(ms30000)} #define UETIMER_N310_OKVALUES {1,2,3,4,6,8,10,20} -#define UETN310(A) UE_TimersAndConstants__n310_ ## A +#define UETN310(A) LTE_UE_TimersAndConstants__n310_ ## A #define UETIMER_N310_MODVALUES { UETN310(n1), UETN310(n2),UETN310(n3),UETN310(n4),UETN310(n6),UETN310(n8),UETN310(n10),UETN310(n20)} #define UETIMER_N311_OKVALUES {1,2,3,4,5,6,8,10} -#define UETN311(A) UE_TimersAndConstants__n311_ ## A +#define UETN311(A) LTE_UE_TimersAndConstants__n311_ ## A #define UETIMER_N311_MODVALUES { UETN311(n1), UETN311(n2),UETN311(n3),UETN311(n4),UETN311(n5),UETN311(n6),UETN311(n8),UETN311(n10)} #endif diff --git a/openair2/ENB_APP/enb_config.c b/openair2/ENB_APP/enb_config.c index 2675e4454c..74494ba818 100644 --- a/openair2/ENB_APP/enb_config.c +++ b/openair2/ENB_APP/enb_config.c @@ -45,7 +45,7 @@ #endif #endif #include "sctp_default_values.h" -#include "SystemInformationBlockType2.h" +#include "LTE_SystemInformationBlockType2.h" #include "LAYER2/MAC/mac_extern.h" #include "LAYER2/MAC/mac_proto.h" #include "PHY/phy_extern.h" @@ -409,7 +409,7 @@ int RCconfig_RRC(MessageDef *msg_p, uint32_t i, eNB_RRC_INST *rrc) { int32_t pucch_delta_shift = 0; int32_t pucch_nRB_CQI = 0; int32_t pucch_nCS_AN = 0; - //#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) + //#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) int32_t pucch_n1_AN = 0; //#endif int32_t pdsch_referenceSignalPower = 0; @@ -568,7 +568,7 @@ int RCconfig_RRC(MessageDef *msg_p, uint32_t i, eNB_RRC_INST *rrc) { // search if in active list for (k=0; k = MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) if (!pbch_repetition) AssertFatal (0, @@ -691,13 +691,13 @@ int RCconfig_RRC(MessageDef *msg_p, uint32_t i, eNB_RRC_INST *rrc) { } RRC_CONFIGURATION_REQ (msg_p).tdd_config[j] = tdd_config; - AssertFatal (tdd_config <= TDD_Config__subframeAssignment_sa6, + AssertFatal (tdd_config <= LTE_TDD_Config__subframeAssignment_sa6, "Failed to parse eNB configuration file %s, enb %d illegal tdd_config %d (should be 0-%d)!", - RC.config_file_name, i, tdd_config, TDD_Config__subframeAssignment_sa6); + RC.config_file_name, i, tdd_config, LTE_TDD_Config__subframeAssignment_sa6); RRC_CONFIGURATION_REQ (msg_p).tdd_config_s[j] = tdd_config_s; - AssertFatal (tdd_config_s <= TDD_Config__specialSubframePatterns_ssp8, + AssertFatal (tdd_config_s <= LTE_TDD_Config__specialSubframePatterns_ssp8, "Failed to parse eNB configuration file %s, enb %d illegal tdd_config_s %d (should be 0-%d)!", - RC.config_file_name, i, tdd_config_s, TDD_Config__specialSubframePatterns_ssp8); + RC.config_file_name, i, tdd_config_s, LTE_TDD_Config__specialSubframePatterns_ssp8); if (!prefix_type) AssertFatal (0, @@ -795,7 +795,7 @@ int RCconfig_RRC(MessageDef *msg_p, uint32_t i, eNB_RRC_INST *rrc) { "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for pucch_nCS_AN choice: 0..7!\n", RC.config_file_name, i, pucch_nCS_AN); - //#if (RRC_VERSION < MAKE_VERSION(10, 0, 0)) + //#if (LTE_RRC_VERSION < MAKE_VERSION(10, 0, 0)) RRC_CONFIGURATION_REQ (msg_p).pucch_n1_AN[j] = pucch_n1_AN; if ((pucch_n1_AN <0) || (pucch_n1_AN > 2047)) @@ -830,9 +830,9 @@ int RCconfig_RRC(MessageDef *msg_p, uint32_t i, eNB_RRC_INST *rrc) { "Failed to parse eNB configuration file %s, enb %d define %s: interSubframe,intraAndInterSubframe!\n", RC.config_file_name, i, ENB_CONFIG_STRING_PUSCH_HOPPINGMODE); else if (strcmp(pusch_hoppingMode,"interSubFrame")==0) { - RRC_CONFIGURATION_REQ (msg_p).pusch_hoppingMode[j] = PUSCH_ConfigCommon__pusch_ConfigBasic__hoppingMode_interSubFrame; + RRC_CONFIGURATION_REQ (msg_p).pusch_hoppingMode[j] = LTE_PUSCH_ConfigCommon__pusch_ConfigBasic__hoppingMode_interSubFrame; } else if (strcmp(pusch_hoppingMode,"intraAndInterSubFrame")==0) { - RRC_CONFIGURATION_REQ (msg_p).pusch_hoppingMode[j] = PUSCH_ConfigCommon__pusch_ConfigBasic__hoppingMode_intraAndInterSubFrame; + RRC_CONFIGURATION_REQ (msg_p).pusch_hoppingMode[j] = LTE_PUSCH_ConfigCommon__pusch_ConfigBasic__hoppingMode_intraAndInterSubFrame; } else AssertFatal (0, "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for pusch_hoppingMode choice: interSubframe,intraAndInterSubframe!\n", @@ -899,22 +899,22 @@ int RCconfig_RRC(MessageDef *msg_p, uint32_t i, eNB_RRC_INST *rrc) { RC.config_file_name, i, pusch_nDMRS1); if (strcmp(phich_duration,"NORMAL")==0) { - RRC_CONFIGURATION_REQ (msg_p).phich_duration[j] = PHICH_Config__phich_Duration_normal; + RRC_CONFIGURATION_REQ (msg_p).phich_duration[j] = LTE_PHICH_Config__phich_Duration_normal; } else if (strcmp(phich_duration,"EXTENDED")==0) { - RRC_CONFIGURATION_REQ (msg_p).phich_duration[j] = PHICH_Config__phich_Duration_extended; + RRC_CONFIGURATION_REQ (msg_p).phich_duration[j] = LTE_PHICH_Config__phich_Duration_extended; } else AssertFatal (0, "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for phich_duration choice: NORMAL,EXTENDED!\n", RC.config_file_name, i, phich_duration); if (strcmp(phich_resource,"ONESIXTH")==0) { - RRC_CONFIGURATION_REQ (msg_p).phich_resource[j] = PHICH_Config__phich_Resource_oneSixth ; + RRC_CONFIGURATION_REQ (msg_p).phich_resource[j] = LTE_PHICH_Config__phich_Resource_oneSixth ; } else if (strcmp(phich_resource,"HALF")==0) { - RRC_CONFIGURATION_REQ (msg_p).phich_resource[j] = PHICH_Config__phich_Resource_half; + RRC_CONFIGURATION_REQ (msg_p).phich_resource[j] = LTE_PHICH_Config__phich_Resource_half; } else if (strcmp(phich_resource,"ONE")==0) { - RRC_CONFIGURATION_REQ (msg_p).phich_resource[j] = PHICH_Config__phich_Resource_one; + RRC_CONFIGURATION_REQ (msg_p).phich_resource[j] = LTE_PHICH_Config__phich_Resource_one; } else if (strcmp(phich_resource,"TWO")==0) { - RRC_CONFIGURATION_REQ (msg_p).phich_resource[j] = PHICH_Config__phich_Resource_two; + RRC_CONFIGURATION_REQ (msg_p).phich_resource[j] = LTE_PHICH_Config__phich_Resource_two; } else AssertFatal (0, "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for phich_resource choice: ONESIXTH,HALF,ONE,TWO!\n", @@ -973,45 +973,45 @@ int RCconfig_RRC(MessageDef *msg_p, uint32_t i, eNB_RRC_INST *rrc) { "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for pusch_p0_Nominal choice: -126..24 !\n", RC.config_file_name, i, pusch_p0_Nominal); -#if (RRC_VERSION <= MAKE_VERSION(12, 0, 0)) +#if (LTE_RRC_VERSION <= MAKE_VERSION(12, 0, 0)) if (strcmp(pusch_alpha,"AL0")==0) { - RRC_CONFIGURATION_REQ (msg_p).pusch_alpha[j] = UplinkPowerControlCommon__alpha_al0; + RRC_CONFIGURATION_REQ (msg_p).pusch_alpha[j] = LTE_UplinkPowerControlCommon__alpha_al0; } else if (strcmp(pusch_alpha,"AL04")==0) { - RRC_CONFIGURATION_REQ (msg_p).pusch_alpha[j] = UplinkPowerControlCommon__alpha_al04; + RRC_CONFIGURATION_REQ (msg_p).pusch_alpha[j] = LTE_UplinkPowerControlCommon__alpha_al04; } else if (strcmp(pusch_alpha,"AL05")==0) { - RRC_CONFIGURATION_REQ (msg_p).pusch_alpha[j] = UplinkPowerControlCommon__alpha_al05; + RRC_CONFIGURATION_REQ (msg_p).pusch_alpha[j] = LTE_UplinkPowerControlCommon__alpha_al05; } else if (strcmp(pusch_alpha,"AL06")==0) { - RRC_CONFIGURATION_REQ (msg_p).pusch_alpha[j] = UplinkPowerControlCommon__alpha_al06; + RRC_CONFIGURATION_REQ (msg_p).pusch_alpha[j] = LTE_UplinkPowerControlCommon__alpha_al06; } else if (strcmp(pusch_alpha,"AL07")==0) { - RRC_CONFIGURATION_REQ (msg_p).pusch_alpha[j] = UplinkPowerControlCommon__alpha_al07; + RRC_CONFIGURATION_REQ (msg_p).pusch_alpha[j] = LTE_UplinkPowerControlCommon__alpha_al07; } else if (strcmp(pusch_alpha,"AL08")==0) { - RRC_CONFIGURATION_REQ (msg_p).pusch_alpha[j] = UplinkPowerControlCommon__alpha_al08; + RRC_CONFIGURATION_REQ (msg_p).pusch_alpha[j] = LTE_UplinkPowerControlCommon__alpha_al08; } else if (strcmp(pusch_alpha,"AL09")==0) { - RRC_CONFIGURATION_REQ (msg_p).pusch_alpha[j] = UplinkPowerControlCommon__alpha_al09; + RRC_CONFIGURATION_REQ (msg_p).pusch_alpha[j] = LTE_UplinkPowerControlCommon__alpha_al09; } else if (strcmp(pusch_alpha,"AL1")==0) { - RRC_CONFIGURATION_REQ (msg_p).pusch_alpha[j] = UplinkPowerControlCommon__alpha_al1; + RRC_CONFIGURATION_REQ (msg_p).pusch_alpha[j] = LTE_UplinkPowerControlCommon__alpha_al1; } #endif -#if (RRC_VERSION >= MAKE_VERSION(12, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(12, 0, 0)) if (strcmp(pusch_alpha,"AL0")==0) { - RRC_CONFIGURATION_REQ (msg_p).pusch_alpha[j] = Alpha_r12_al0; + RRC_CONFIGURATION_REQ (msg_p).pusch_alpha[j] = LTE_Alpha_r12_al0; } else if (strcmp(pusch_alpha,"AL04")==0) { - RRC_CONFIGURATION_REQ (msg_p).pusch_alpha[j] = Alpha_r12_al04; + RRC_CONFIGURATION_REQ (msg_p).pusch_alpha[j] = LTE_Alpha_r12_al04; } else if (strcmp(pusch_alpha,"AL05")==0) { - RRC_CONFIGURATION_REQ (msg_p).pusch_alpha[j] = Alpha_r12_al05; + RRC_CONFIGURATION_REQ (msg_p).pusch_alpha[j] = LTE_Alpha_r12_al05; } else if (strcmp(pusch_alpha,"AL06")==0) { - RRC_CONFIGURATION_REQ (msg_p).pusch_alpha[j] = Alpha_r12_al06; + RRC_CONFIGURATION_REQ (msg_p).pusch_alpha[j] = LTE_Alpha_r12_al06; } else if (strcmp(pusch_alpha,"AL07")==0) { - RRC_CONFIGURATION_REQ (msg_p).pusch_alpha[j] = Alpha_r12_al07; + RRC_CONFIGURATION_REQ (msg_p).pusch_alpha[j] = LTE_Alpha_r12_al07; } else if (strcmp(pusch_alpha,"AL08")==0) { - RRC_CONFIGURATION_REQ (msg_p).pusch_alpha[j] = Alpha_r12_al08; + RRC_CONFIGURATION_REQ (msg_p).pusch_alpha[j] = LTE_Alpha_r12_al08; } else if (strcmp(pusch_alpha,"AL09")==0) { - RRC_CONFIGURATION_REQ (msg_p).pusch_alpha[j] = Alpha_r12_al09; + RRC_CONFIGURATION_REQ (msg_p).pusch_alpha[j] = LTE_Alpha_r12_al09; } else if (strcmp(pusch_alpha,"AL1")==0) { - RRC_CONFIGURATION_REQ (msg_p).pusch_alpha[j] = Alpha_r12_al1; + RRC_CONFIGURATION_REQ (msg_p).pusch_alpha[j] = LTE_Alpha_r12_al1; } #endif @@ -1035,57 +1035,57 @@ int RCconfig_RRC(MessageDef *msg_p, uint32_t i, eNB_RRC_INST *rrc) { RC.config_file_name, i, msg3_delta_Preamble); if (strcmp(pucch_deltaF_Format1,"deltaF_2")==0) { - RRC_CONFIGURATION_REQ (msg_p).pucch_deltaF_Format1[j] = DeltaFList_PUCCH__deltaF_PUCCH_Format1_deltaF_2; + RRC_CONFIGURATION_REQ (msg_p).pucch_deltaF_Format1[j] = LTE_DeltaFList_PUCCH__deltaF_PUCCH_Format1_deltaF_2; } else if (strcmp(pucch_deltaF_Format1,"deltaF0")==0) { - RRC_CONFIGURATION_REQ (msg_p).pucch_deltaF_Format1[j] = DeltaFList_PUCCH__deltaF_PUCCH_Format1_deltaF0; + RRC_CONFIGURATION_REQ (msg_p).pucch_deltaF_Format1[j] = LTE_DeltaFList_PUCCH__deltaF_PUCCH_Format1_deltaF0; } else if (strcmp(pucch_deltaF_Format1,"deltaF2")==0) { - RRC_CONFIGURATION_REQ (msg_p).pucch_deltaF_Format1[j] = DeltaFList_PUCCH__deltaF_PUCCH_Format1_deltaF2; + RRC_CONFIGURATION_REQ (msg_p).pucch_deltaF_Format1[j] = LTE_DeltaFList_PUCCH__deltaF_PUCCH_Format1_deltaF2; } else AssertFatal (0, "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for pucch_deltaF_Format1 choice: deltaF_2,dltaF0,deltaF2!\n", RC.config_file_name, i, pucch_deltaF_Format1); if (strcmp(pucch_deltaF_Format1b,"deltaF1")==0) { - RRC_CONFIGURATION_REQ (msg_p).pucch_deltaF_Format1b[j] = DeltaFList_PUCCH__deltaF_PUCCH_Format1b_deltaF1; + RRC_CONFIGURATION_REQ (msg_p).pucch_deltaF_Format1b[j] = LTE_DeltaFList_PUCCH__deltaF_PUCCH_Format1b_deltaF1; } else if (strcmp(pucch_deltaF_Format1b,"deltaF3")==0) { - RRC_CONFIGURATION_REQ (msg_p).pucch_deltaF_Format1b[j] = DeltaFList_PUCCH__deltaF_PUCCH_Format1b_deltaF3; + RRC_CONFIGURATION_REQ (msg_p).pucch_deltaF_Format1b[j] = LTE_DeltaFList_PUCCH__deltaF_PUCCH_Format1b_deltaF3; } else if (strcmp(pucch_deltaF_Format1b,"deltaF5")==0) { - RRC_CONFIGURATION_REQ (msg_p).pucch_deltaF_Format1b[j] = DeltaFList_PUCCH__deltaF_PUCCH_Format1b_deltaF5; + RRC_CONFIGURATION_REQ (msg_p).pucch_deltaF_Format1b[j] = LTE_DeltaFList_PUCCH__deltaF_PUCCH_Format1b_deltaF5; } else AssertFatal (0, "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for pucch_deltaF_Format1b choice: deltaF1,dltaF3,deltaF5!\n", RC.config_file_name, i, pucch_deltaF_Format1b); if (strcmp(pucch_deltaF_Format2,"deltaF_2")==0) { - RRC_CONFIGURATION_REQ (msg_p).pucch_deltaF_Format2[j] = DeltaFList_PUCCH__deltaF_PUCCH_Format2_deltaF_2; + RRC_CONFIGURATION_REQ (msg_p).pucch_deltaF_Format2[j] = LTE_DeltaFList_PUCCH__deltaF_PUCCH_Format2_deltaF_2; } else if (strcmp(pucch_deltaF_Format2,"deltaF0")==0) { - RRC_CONFIGURATION_REQ (msg_p).pucch_deltaF_Format2[j] = DeltaFList_PUCCH__deltaF_PUCCH_Format2_deltaF0; + RRC_CONFIGURATION_REQ (msg_p).pucch_deltaF_Format2[j] = LTE_DeltaFList_PUCCH__deltaF_PUCCH_Format2_deltaF0; } else if (strcmp(pucch_deltaF_Format2,"deltaF1")==0) { - RRC_CONFIGURATION_REQ (msg_p).pucch_deltaF_Format2[j] = DeltaFList_PUCCH__deltaF_PUCCH_Format2_deltaF1; + RRC_CONFIGURATION_REQ (msg_p).pucch_deltaF_Format2[j] = LTE_DeltaFList_PUCCH__deltaF_PUCCH_Format2_deltaF1; } else if (strcmp(pucch_deltaF_Format2,"deltaF2")==0) { - RRC_CONFIGURATION_REQ (msg_p).pucch_deltaF_Format2[j] = DeltaFList_PUCCH__deltaF_PUCCH_Format2_deltaF2; + RRC_CONFIGURATION_REQ (msg_p).pucch_deltaF_Format2[j] = LTE_DeltaFList_PUCCH__deltaF_PUCCH_Format2_deltaF2; } else AssertFatal (0, "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for pucch_deltaF_Format2 choice: deltaF_2,dltaF0,deltaF1,deltaF2!\n", RC.config_file_name, i, pucch_deltaF_Format2); if (strcmp(pucch_deltaF_Format2a,"deltaF_2")==0) { - RRC_CONFIGURATION_REQ (msg_p).pucch_deltaF_Format2a[j] = DeltaFList_PUCCH__deltaF_PUCCH_Format2a_deltaF_2; + RRC_CONFIGURATION_REQ (msg_p).pucch_deltaF_Format2a[j] = LTE_DeltaFList_PUCCH__deltaF_PUCCH_Format2a_deltaF_2; } else if (strcmp(pucch_deltaF_Format2a,"deltaF0")==0) { - RRC_CONFIGURATION_REQ (msg_p).pucch_deltaF_Format2a[j] = DeltaFList_PUCCH__deltaF_PUCCH_Format2a_deltaF0; + RRC_CONFIGURATION_REQ (msg_p).pucch_deltaF_Format2a[j] = LTE_DeltaFList_PUCCH__deltaF_PUCCH_Format2a_deltaF0; } else if (strcmp(pucch_deltaF_Format2a,"deltaF2")==0) { - RRC_CONFIGURATION_REQ (msg_p).pucch_deltaF_Format2a[j] = DeltaFList_PUCCH__deltaF_PUCCH_Format2a_deltaF2; + RRC_CONFIGURATION_REQ (msg_p).pucch_deltaF_Format2a[j] = LTE_DeltaFList_PUCCH__deltaF_PUCCH_Format2a_deltaF2; } else AssertFatal (0, "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for pucch_deltaF_Format2a choice: deltaF_2,dltaF0,deltaF2!\n", RC.config_file_name, i, pucch_deltaF_Format2a); if (strcmp(pucch_deltaF_Format2b,"deltaF_2")==0) { - RRC_CONFIGURATION_REQ (msg_p).pucch_deltaF_Format2b[j] = DeltaFList_PUCCH__deltaF_PUCCH_Format2b_deltaF_2; + RRC_CONFIGURATION_REQ (msg_p).pucch_deltaF_Format2b[j] = LTE_DeltaFList_PUCCH__deltaF_PUCCH_Format2b_deltaF_2; } else if (strcmp(pucch_deltaF_Format2b,"deltaF0")==0) { - RRC_CONFIGURATION_REQ (msg_p).pucch_deltaF_Format2b[j] = DeltaFList_PUCCH__deltaF_PUCCH_Format2b_deltaF0; + RRC_CONFIGURATION_REQ (msg_p).pucch_deltaF_Format2b[j] = LTE_DeltaFList_PUCCH__deltaF_PUCCH_Format2b_deltaF0; } else if (strcmp(pucch_deltaF_Format2b,"deltaF2")==0) { - RRC_CONFIGURATION_REQ (msg_p).pucch_deltaF_Format2b[j] = DeltaFList_PUCCH__deltaF_PUCCH_Format2b_deltaF2; + RRC_CONFIGURATION_REQ (msg_p).pucch_deltaF_Format2b[j] = LTE_DeltaFList_PUCCH__deltaF_PUCCH_Format2b_deltaF2; } else AssertFatal (0, "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for pucch_deltaF_Format2b choice: deltaF_2,dltaF0,deltaF2!\n", @@ -1109,19 +1109,19 @@ int RCconfig_RRC(MessageDef *msg_p, uint32_t i, eNB_RRC_INST *rrc) { switch (rach_messageSizeGroupA) { case 56: - RRC_CONFIGURATION_REQ (msg_p).rach_messageSizeGroupA[j] = RACH_ConfigCommon__preambleInfo__preamblesGroupAConfig__messageSizeGroupA_b56; + RRC_CONFIGURATION_REQ (msg_p).rach_messageSizeGroupA[j] = LTE_RACH_ConfigCommon__preambleInfo__preamblesGroupAConfig__messageSizeGroupA_b56; break; case 144: - RRC_CONFIGURATION_REQ (msg_p).rach_messageSizeGroupA[j] = RACH_ConfigCommon__preambleInfo__preamblesGroupAConfig__messageSizeGroupA_b144; + RRC_CONFIGURATION_REQ (msg_p).rach_messageSizeGroupA[j] = LTE_RACH_ConfigCommon__preambleInfo__preamblesGroupAConfig__messageSizeGroupA_b144; break; case 208: - RRC_CONFIGURATION_REQ (msg_p).rach_messageSizeGroupA[j] = RACH_ConfigCommon__preambleInfo__preamblesGroupAConfig__messageSizeGroupA_b208; + RRC_CONFIGURATION_REQ (msg_p).rach_messageSizeGroupA[j] = LTE_RACH_ConfigCommon__preambleInfo__preamblesGroupAConfig__messageSizeGroupA_b208; break; case 256: - RRC_CONFIGURATION_REQ (msg_p).rach_messageSizeGroupA[j] = RACH_ConfigCommon__preambleInfo__preamblesGroupAConfig__messageSizeGroupA_b256; + RRC_CONFIGURATION_REQ (msg_p).rach_messageSizeGroupA[j] = LTE_RACH_ConfigCommon__preambleInfo__preamblesGroupAConfig__messageSizeGroupA_b256; break; default: @@ -1132,21 +1132,21 @@ int RCconfig_RRC(MessageDef *msg_p, uint32_t i, eNB_RRC_INST *rrc) { } if (strcmp(rach_messagePowerOffsetGroupB,"minusinfinity")==0) { - RRC_CONFIGURATION_REQ (msg_p).rach_messagePowerOffsetGroupB[j] = RACH_ConfigCommon__preambleInfo__preamblesGroupAConfig__messagePowerOffsetGroupB_minusinfinity; + RRC_CONFIGURATION_REQ (msg_p).rach_messagePowerOffsetGroupB[j] = LTE_RACH_ConfigCommon__preambleInfo__preamblesGroupAConfig__messagePowerOffsetGroupB_minusinfinity; } else if (strcmp(rach_messagePowerOffsetGroupB,"dB0")==0) { - RRC_CONFIGURATION_REQ (msg_p).rach_messagePowerOffsetGroupB[j] = RACH_ConfigCommon__preambleInfo__preamblesGroupAConfig__messagePowerOffsetGroupB_dB0; + RRC_CONFIGURATION_REQ (msg_p).rach_messagePowerOffsetGroupB[j] = LTE_RACH_ConfigCommon__preambleInfo__preamblesGroupAConfig__messagePowerOffsetGroupB_dB0; } else if (strcmp(rach_messagePowerOffsetGroupB,"dB5")==0) { - RRC_CONFIGURATION_REQ (msg_p).rach_messagePowerOffsetGroupB[j] = RACH_ConfigCommon__preambleInfo__preamblesGroupAConfig__messagePowerOffsetGroupB_dB5; + RRC_CONFIGURATION_REQ (msg_p).rach_messagePowerOffsetGroupB[j] = LTE_RACH_ConfigCommon__preambleInfo__preamblesGroupAConfig__messagePowerOffsetGroupB_dB5; } else if (strcmp(rach_messagePowerOffsetGroupB,"dB8")==0) { - RRC_CONFIGURATION_REQ (msg_p).rach_messagePowerOffsetGroupB[j] = RACH_ConfigCommon__preambleInfo__preamblesGroupAConfig__messagePowerOffsetGroupB_dB8; + RRC_CONFIGURATION_REQ (msg_p).rach_messagePowerOffsetGroupB[j] = LTE_RACH_ConfigCommon__preambleInfo__preamblesGroupAConfig__messagePowerOffsetGroupB_dB8; } else if (strcmp(rach_messagePowerOffsetGroupB,"dB10")==0) { - RRC_CONFIGURATION_REQ (msg_p).rach_messagePowerOffsetGroupB[j] = RACH_ConfigCommon__preambleInfo__preamblesGroupAConfig__messagePowerOffsetGroupB_dB10; + RRC_CONFIGURATION_REQ (msg_p).rach_messagePowerOffsetGroupB[j] = LTE_RACH_ConfigCommon__preambleInfo__preamblesGroupAConfig__messagePowerOffsetGroupB_dB10; } else if (strcmp(rach_messagePowerOffsetGroupB,"dB12")==0) { - RRC_CONFIGURATION_REQ (msg_p).rach_messagePowerOffsetGroupB[j] = RACH_ConfigCommon__preambleInfo__preamblesGroupAConfig__messagePowerOffsetGroupB_dB12; + RRC_CONFIGURATION_REQ (msg_p).rach_messagePowerOffsetGroupB[j] = LTE_RACH_ConfigCommon__preambleInfo__preamblesGroupAConfig__messagePowerOffsetGroupB_dB12; } else if (strcmp(rach_messagePowerOffsetGroupB,"dB15")==0) { - RRC_CONFIGURATION_REQ (msg_p).rach_messagePowerOffsetGroupB[j] = RACH_ConfigCommon__preambleInfo__preamblesGroupAConfig__messagePowerOffsetGroupB_dB15; + RRC_CONFIGURATION_REQ (msg_p).rach_messagePowerOffsetGroupB[j] = LTE_RACH_ConfigCommon__preambleInfo__preamblesGroupAConfig__messagePowerOffsetGroupB_dB15; } else if (strcmp(rach_messagePowerOffsetGroupB,"dB18")==0) { - RRC_CONFIGURATION_REQ (msg_p).rach_messagePowerOffsetGroupB[j] = RACH_ConfigCommon__preambleInfo__preamblesGroupAConfig__messagePowerOffsetGroupB_dB18; + RRC_CONFIGURATION_REQ (msg_p).rach_messagePowerOffsetGroupB[j] = LTE_RACH_ConfigCommon__preambleInfo__preamblesGroupAConfig__messagePowerOffsetGroupB_dB18; } else AssertFatal (0, "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for rach_messagePowerOffsetGroupB choice: minusinfinity,dB0,dB5,dB8,dB10,dB12,dB15,dB18!\n", @@ -1173,95 +1173,95 @@ int RCconfig_RRC(MessageDef *msg_p, uint32_t i, eNB_RRC_INST *rrc) { RC.config_file_name, i, rach_powerRampingStep); switch (rach_preambleTransMax) { -#if (RRC_VERSION < MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION < MAKE_VERSION(14, 0, 0)) case 3: - RRC_CONFIGURATION_REQ (msg_p).rach_preambleTransMax[j] = RACH_ConfigCommon__ra_SupervisionInfo__preambleTransMax_n3; + RRC_CONFIGURATION_REQ (msg_p).rach_preambleTransMax[j] = LTE_RACH_ConfigCommon__ra_SupervisionInfo__preambleTransMax_n3; break; case 4: - RRC_CONFIGURATION_REQ (msg_p).rach_preambleTransMax[j] = RACH_ConfigCommon__ra_SupervisionInfo__preambleTransMax_n4; + RRC_CONFIGURATION_REQ (msg_p).rach_preambleTransMax[j] = LTE_RACH_ConfigCommon__ra_SupervisionInfo__preambleTransMax_n4; break; case 5: - RRC_CONFIGURATION_REQ (msg_p).rach_preambleTransMax[j] = RACH_ConfigCommon__ra_SupervisionInfo__preambleTransMax_n5; + RRC_CONFIGURATION_REQ (msg_p).rach_preambleTransMax[j] = LTE_RACH_ConfigCommon__ra_SupervisionInfo__preambleTransMax_n5; break; case 6: - RRC_CONFIGURATION_REQ (msg_p).rach_preambleTransMax[j] = RACH_ConfigCommon__ra_SupervisionInfo__preambleTransMax_n6; + RRC_CONFIGURATION_REQ (msg_p).rach_preambleTransMax[j] = LTE_RACH_ConfigCommon__ra_SupervisionInfo__preambleTransMax_n6; break; case 7: - RRC_CONFIGURATION_REQ (msg_p).rach_preambleTransMax[j] = RACH_ConfigCommon__ra_SupervisionInfo__preambleTransMax_n7; + RRC_CONFIGURATION_REQ (msg_p).rach_preambleTransMax[j] = LTE_RACH_ConfigCommon__ra_SupervisionInfo__preambleTransMax_n7; break; case 8: - RRC_CONFIGURATION_REQ (msg_p).rach_preambleTransMax[j] = RACH_ConfigCommon__ra_SupervisionInfo__preambleTransMax_n8; + RRC_CONFIGURATION_REQ (msg_p).rach_preambleTransMax[j] = LTE_RACH_ConfigCommon__ra_SupervisionInfo__preambleTransMax_n8; break; case 10: - RRC_CONFIGURATION_REQ (msg_p).rach_preambleTransMax[j] = RACH_ConfigCommon__ra_SupervisionInfo__preambleTransMax_n10; + RRC_CONFIGURATION_REQ (msg_p).rach_preambleTransMax[j] = LTE_RACH_ConfigCommon__ra_SupervisionInfo__preambleTransMax_n10; break; case 20: - RRC_CONFIGURATION_REQ (msg_p).rach_preambleTransMax[j] = RACH_ConfigCommon__ra_SupervisionInfo__preambleTransMax_n20; + RRC_CONFIGURATION_REQ (msg_p).rach_preambleTransMax[j] = LTE_RACH_ConfigCommon__ra_SupervisionInfo__preambleTransMax_n20; break; case 50: - RRC_CONFIGURATION_REQ (msg_p).rach_preambleTransMax[j] = RACH_ConfigCommon__ra_SupervisionInfo__preambleTransMax_n50; + RRC_CONFIGURATION_REQ (msg_p).rach_preambleTransMax[j] = LTE_RACH_ConfigCommon__ra_SupervisionInfo__preambleTransMax_n50; break; case 100: - RRC_CONFIGURATION_REQ (msg_p).rach_preambleTransMax[j] = RACH_ConfigCommon__ra_SupervisionInfo__preambleTransMax_n100; + RRC_CONFIGURATION_REQ (msg_p).rach_preambleTransMax[j] = LTE_RACH_ConfigCommon__ra_SupervisionInfo__preambleTransMax_n100; break; case 200: - RRC_CONFIGURATION_REQ (msg_p).rach_preambleTransMax[j] = RACH_ConfigCommon__ra_SupervisionInfo__preambleTransMax_n200; + RRC_CONFIGURATION_REQ (msg_p).rach_preambleTransMax[j] = LTE_RACH_ConfigCommon__ra_SupervisionInfo__preambleTransMax_n200; break; #else case 3: - RRC_CONFIGURATION_REQ (msg_p).rach_preambleTransMax[j] = PreambleTransMax_n3; + RRC_CONFIGURATION_REQ (msg_p).rach_preambleTransMax[j] = LTE_PreambleTransMax_n3; break; case 4: - RRC_CONFIGURATION_REQ (msg_p).rach_preambleTransMax[j] = PreambleTransMax_n4; + RRC_CONFIGURATION_REQ (msg_p).rach_preambleTransMax[j] = LTE_PreambleTransMax_n4; break; case 5: - RRC_CONFIGURATION_REQ (msg_p).rach_preambleTransMax[j] = PreambleTransMax_n5; + RRC_CONFIGURATION_REQ (msg_p).rach_preambleTransMax[j] = LTE_PreambleTransMax_n5; break; case 6: - RRC_CONFIGURATION_REQ (msg_p).rach_preambleTransMax[j] = PreambleTransMax_n6; + RRC_CONFIGURATION_REQ (msg_p).rach_preambleTransMax[j] = LTE_PreambleTransMax_n6; break; case 7: - RRC_CONFIGURATION_REQ (msg_p).rach_preambleTransMax[j] = PreambleTransMax_n7; + RRC_CONFIGURATION_REQ (msg_p).rach_preambleTransMax[j] = LTE_PreambleTransMax_n7; break; case 8: - RRC_CONFIGURATION_REQ (msg_p).rach_preambleTransMax[j] = PreambleTransMax_n8; + RRC_CONFIGURATION_REQ (msg_p).rach_preambleTransMax[j] = LTE_PreambleTransMax_n8; break; case 10: - RRC_CONFIGURATION_REQ (msg_p).rach_preambleTransMax[j] = PreambleTransMax_n10; + RRC_CONFIGURATION_REQ (msg_p).rach_preambleTransMax[j] = LTE_PreambleTransMax_n10; break; case 20: - RRC_CONFIGURATION_REQ (msg_p).rach_preambleTransMax[j] = PreambleTransMax_n20; + RRC_CONFIGURATION_REQ (msg_p).rach_preambleTransMax[j] = LTE_PreambleTransMax_n20; break; case 50: - RRC_CONFIGURATION_REQ (msg_p).rach_preambleTransMax[j] = PreambleTransMax_n50; + RRC_CONFIGURATION_REQ (msg_p).rach_preambleTransMax[j] = LTE_PreambleTransMax_n50; break; case 100: - RRC_CONFIGURATION_REQ (msg_p).rach_preambleTransMax[j] = PreambleTransMax_n100; + RRC_CONFIGURATION_REQ (msg_p).rach_preambleTransMax[j] = LTE_PreambleTransMax_n100; break; case 200: - RRC_CONFIGURATION_REQ (msg_p).rach_preambleTransMax[j] = PreambleTransMax_n200; + RRC_CONFIGURATION_REQ (msg_p).rach_preambleTransMax[j] = LTE_PreambleTransMax_n200; break; #endif @@ -1295,19 +1295,19 @@ int RCconfig_RRC(MessageDef *msg_p, uint32_t i, eNB_RRC_INST *rrc) { switch (pcch_defaultPagingCycle) { case 32: - RRC_CONFIGURATION_REQ (msg_p).pcch_defaultPagingCycle[j] = PCCH_Config__defaultPagingCycle_rf32; + RRC_CONFIGURATION_REQ (msg_p).pcch_defaultPagingCycle[j] = LTE_PCCH_Config__defaultPagingCycle_rf32; break; case 64: - RRC_CONFIGURATION_REQ (msg_p).pcch_defaultPagingCycle[j] = PCCH_Config__defaultPagingCycle_rf64; + RRC_CONFIGURATION_REQ (msg_p).pcch_defaultPagingCycle[j] = LTE_PCCH_Config__defaultPagingCycle_rf64; break; case 128: - RRC_CONFIGURATION_REQ (msg_p).pcch_defaultPagingCycle[j] = PCCH_Config__defaultPagingCycle_rf128; + RRC_CONFIGURATION_REQ (msg_p).pcch_defaultPagingCycle[j] = LTE_PCCH_Config__defaultPagingCycle_rf128; break; case 256: - RRC_CONFIGURATION_REQ (msg_p).pcch_defaultPagingCycle[j] = PCCH_Config__defaultPagingCycle_rf256; + RRC_CONFIGURATION_REQ (msg_p).pcch_defaultPagingCycle[j] = LTE_PCCH_Config__defaultPagingCycle_rf256; break; default: @@ -1318,21 +1318,21 @@ int RCconfig_RRC(MessageDef *msg_p, uint32_t i, eNB_RRC_INST *rrc) { } if (strcmp(pcch_nB, "fourT") == 0) { - RRC_CONFIGURATION_REQ (msg_p).pcch_nB[j] = PCCH_Config__nB_fourT; + RRC_CONFIGURATION_REQ (msg_p).pcch_nB[j] = LTE_PCCH_Config__nB_fourT; } else if (strcmp(pcch_nB, "twoT") == 0) { - RRC_CONFIGURATION_REQ (msg_p).pcch_nB[j] = PCCH_Config__nB_twoT; + RRC_CONFIGURATION_REQ (msg_p).pcch_nB[j] = LTE_PCCH_Config__nB_twoT; } else if (strcmp(pcch_nB, "oneT") == 0) { - RRC_CONFIGURATION_REQ (msg_p).pcch_nB[j] = PCCH_Config__nB_oneT; + RRC_CONFIGURATION_REQ (msg_p).pcch_nB[j] = LTE_PCCH_Config__nB_oneT; } else if (strcmp(pcch_nB, "halfT") == 0) { - RRC_CONFIGURATION_REQ (msg_p).pcch_nB[j] = PCCH_Config__nB_halfT; + RRC_CONFIGURATION_REQ (msg_p).pcch_nB[j] = LTE_PCCH_Config__nB_halfT; } else if (strcmp(pcch_nB, "quarterT") == 0) { - RRC_CONFIGURATION_REQ (msg_p).pcch_nB[j] = PCCH_Config__nB_quarterT; + RRC_CONFIGURATION_REQ (msg_p).pcch_nB[j] = LTE_PCCH_Config__nB_quarterT; } else if (strcmp(pcch_nB, "oneEighthT") == 0) { - RRC_CONFIGURATION_REQ (msg_p).pcch_nB[j] = PCCH_Config__nB_oneEighthT; + RRC_CONFIGURATION_REQ (msg_p).pcch_nB[j] = LTE_PCCH_Config__nB_oneEighthT; } else if (strcmp(pcch_nB, "oneSixteenthT") == 0) { - RRC_CONFIGURATION_REQ (msg_p).pcch_nB[j] = PCCH_Config__nB_oneSixteenthT; + RRC_CONFIGURATION_REQ (msg_p).pcch_nB[j] = LTE_PCCH_Config__nB_oneSixteenthT; } else if (strcmp(pcch_nB, "oneThirtySecondT") == 0) { - RRC_CONFIGURATION_REQ (msg_p).pcch_nB[j] = PCCH_Config__nB_oneThirtySecondT; + RRC_CONFIGURATION_REQ (msg_p).pcch_nB[j] = LTE_PCCH_Config__nB_oneThirtySecondT; } else AssertFatal (0, "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for pcch_nB choice: fourT,twoT,oneT,halfT,quarterT,oneighthT,oneSixteenthT,oneThirtySecondT !\n", @@ -1340,19 +1340,19 @@ int RCconfig_RRC(MessageDef *msg_p, uint32_t i, eNB_RRC_INST *rrc) { switch (bcch_modificationPeriodCoeff) { case 2: - RRC_CONFIGURATION_REQ (msg_p).bcch_modificationPeriodCoeff[j] = BCCH_Config__modificationPeriodCoeff_n2; + RRC_CONFIGURATION_REQ (msg_p).bcch_modificationPeriodCoeff[j] = LTE_BCCH_Config__modificationPeriodCoeff_n2; break; case 4: - RRC_CONFIGURATION_REQ (msg_p).bcch_modificationPeriodCoeff[j] = BCCH_Config__modificationPeriodCoeff_n4; + RRC_CONFIGURATION_REQ (msg_p).bcch_modificationPeriodCoeff[j] = LTE_BCCH_Config__modificationPeriodCoeff_n4; break; case 8: - RRC_CONFIGURATION_REQ (msg_p).bcch_modificationPeriodCoeff[j] = BCCH_Config__modificationPeriodCoeff_n8; + RRC_CONFIGURATION_REQ (msg_p).bcch_modificationPeriodCoeff[j] = LTE_BCCH_Config__modificationPeriodCoeff_n8; break; case 16: - RRC_CONFIGURATION_REQ (msg_p).bcch_modificationPeriodCoeff[j] = BCCH_Config__modificationPeriodCoeff_n16; + RRC_CONFIGURATION_REQ (msg_p).bcch_modificationPeriodCoeff[j] = LTE_BCCH_Config__modificationPeriodCoeff_n16; break; default: @@ -1371,31 +1371,31 @@ int RCconfig_RRC(MessageDef *msg_p, uint32_t i, eNB_RRC_INST *rrc) { switch (ue_TransmissionMode) { case 1: - RRC_CONFIGURATION_REQ (msg_p).ue_TransmissionMode[j] = AntennaInfoDedicated__transmissionMode_tm1; + RRC_CONFIGURATION_REQ (msg_p).ue_TransmissionMode[j] = LTE_AntennaInfoDedicated__transmissionMode_tm1; break; case 2: - RRC_CONFIGURATION_REQ (msg_p).ue_TransmissionMode[j] = AntennaInfoDedicated__transmissionMode_tm2; + RRC_CONFIGURATION_REQ (msg_p).ue_TransmissionMode[j] = LTE_AntennaInfoDedicated__transmissionMode_tm2; break; case 3: - RRC_CONFIGURATION_REQ (msg_p).ue_TransmissionMode[j] = AntennaInfoDedicated__transmissionMode_tm3; + RRC_CONFIGURATION_REQ (msg_p).ue_TransmissionMode[j] = LTE_AntennaInfoDedicated__transmissionMode_tm3; break; case 4: - RRC_CONFIGURATION_REQ (msg_p).ue_TransmissionMode[j] = AntennaInfoDedicated__transmissionMode_tm4; + RRC_CONFIGURATION_REQ (msg_p).ue_TransmissionMode[j] = LTE_AntennaInfoDedicated__transmissionMode_tm4; break; case 5: - RRC_CONFIGURATION_REQ (msg_p).ue_TransmissionMode[j] = AntennaInfoDedicated__transmissionMode_tm5; + RRC_CONFIGURATION_REQ (msg_p).ue_TransmissionMode[j] = LTE_AntennaInfoDedicated__transmissionMode_tm5; break; case 6: - RRC_CONFIGURATION_REQ (msg_p).ue_TransmissionMode[j] = AntennaInfoDedicated__transmissionMode_tm6; + RRC_CONFIGURATION_REQ (msg_p).ue_TransmissionMode[j] = LTE_AntennaInfoDedicated__transmissionMode_tm6; break; case 7: - RRC_CONFIGURATION_REQ (msg_p).ue_TransmissionMode[j] = AntennaInfoDedicated__transmissionMode_tm7; + RRC_CONFIGURATION_REQ (msg_p).ue_TransmissionMode[j] = LTE_AntennaInfoDedicated__transmissionMode_tm7; break; default: @@ -1442,55 +1442,55 @@ int RCconfig_RRC(MessageDef *msg_p, uint32_t i, eNB_RRC_INST *rrc) { //TTN - for D2D //SIB18 if (strcmp(rxPool_sc_CP_Len,"normal")==0) { - RRC_CONFIGURATION_REQ (msg_p).rxPool_sc_CP_Len[j] = SL_CP_Len_r12_normal; + RRC_CONFIGURATION_REQ (msg_p).rxPool_sc_CP_Len[j] = LTE_SL_CP_Len_r12_normal; } else if (strcmp(rxPool_sc_CP_Len,"extended")==0) { - RRC_CONFIGURATION_REQ (msg_p).rxPool_sc_CP_Len[j] = SL_CP_Len_r12_extended; + RRC_CONFIGURATION_REQ (msg_p).rxPool_sc_CP_Len[j] = LTE_SL_CP_Len_r12_extended; } else AssertFatal (0, "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for rxPool_sc_CP_Len choice: normal,extended!\n", RC.config_file_name, i, rxPool_sc_CP_Len); if (strcmp(rxPool_sc_Period,"sf40")==0) { - RRC_CONFIGURATION_REQ (msg_p).rxPool_sc_Period[j] = SL_PeriodComm_r12_sf40; + RRC_CONFIGURATION_REQ (msg_p).rxPool_sc_Period[j] = LTE_SL_PeriodComm_r12_sf40; } else if (strcmp(rxPool_sc_Period,"sf60")==0) { - RRC_CONFIGURATION_REQ (msg_p).rxPool_sc_Period[j] = SL_PeriodComm_r12_sf60; + RRC_CONFIGURATION_REQ (msg_p).rxPool_sc_Period[j] = LTE_SL_PeriodComm_r12_sf60; } else if (strcmp(rxPool_sc_Period,"sf70")==0) { - RRC_CONFIGURATION_REQ (msg_p).rxPool_sc_Period[j] = SL_PeriodComm_r12_sf70; + RRC_CONFIGURATION_REQ (msg_p).rxPool_sc_Period[j] = LTE_SL_PeriodComm_r12_sf70; } else if (strcmp(rxPool_sc_Period,"sf80")==0) { - RRC_CONFIGURATION_REQ (msg_p).rxPool_sc_Period[j] = SL_PeriodComm_r12_sf80; + RRC_CONFIGURATION_REQ (msg_p).rxPool_sc_Period[j] = LTE_SL_PeriodComm_r12_sf80; } else if (strcmp(rxPool_sc_Period,"sf120")==0) { - RRC_CONFIGURATION_REQ (msg_p).rxPool_sc_Period[j] = SL_PeriodComm_r12_sf120; + RRC_CONFIGURATION_REQ (msg_p).rxPool_sc_Period[j] = LTE_SL_PeriodComm_r12_sf120; } else if (strcmp(rxPool_sc_Period,"sf140")==0) { - RRC_CONFIGURATION_REQ (msg_p).rxPool_sc_Period[j] = SL_PeriodComm_r12_sf140; + RRC_CONFIGURATION_REQ (msg_p).rxPool_sc_Period[j] = LTE_SL_PeriodComm_r12_sf140; } else if (strcmp(rxPool_sc_Period,"sf160")==0) { - RRC_CONFIGURATION_REQ (msg_p).rxPool_sc_Period[j] = SL_PeriodComm_r12_sf160; + RRC_CONFIGURATION_REQ (msg_p).rxPool_sc_Period[j] = LTE_SL_PeriodComm_r12_sf160; } else if (strcmp(rxPool_sc_Period,"sf240")==0) { - RRC_CONFIGURATION_REQ (msg_p).rxPool_sc_Period[j] = SL_PeriodComm_r12_sf240; + RRC_CONFIGURATION_REQ (msg_p).rxPool_sc_Period[j] = LTE_SL_PeriodComm_r12_sf240; } else if (strcmp(rxPool_sc_Period,"sf280")==0) { - RRC_CONFIGURATION_REQ (msg_p).rxPool_sc_Period[j] = SL_PeriodComm_r12_sf280; + RRC_CONFIGURATION_REQ (msg_p).rxPool_sc_Period[j] = LTE_SL_PeriodComm_r12_sf280; } else if (strcmp(rxPool_sc_Period,"sf320")==0) { - RRC_CONFIGURATION_REQ (msg_p).rxPool_sc_Period[j] = SL_PeriodComm_r12_sf320; + RRC_CONFIGURATION_REQ (msg_p).rxPool_sc_Period[j] = LTE_SL_PeriodComm_r12_sf320; } else if (strcmp(rxPool_sc_Period,"spare6")==0) { - RRC_CONFIGURATION_REQ (msg_p).rxPool_sc_Period[j] = SL_PeriodComm_r12_spare6; + RRC_CONFIGURATION_REQ (msg_p).rxPool_sc_Period[j] = LTE_SL_PeriodComm_r12_spare6; } else if (strcmp(rxPool_sc_Period,"spare5")==0) { - RRC_CONFIGURATION_REQ (msg_p).rxPool_sc_Period[j] = SL_PeriodComm_r12_spare5; + RRC_CONFIGURATION_REQ (msg_p).rxPool_sc_Period[j] = LTE_SL_PeriodComm_r12_spare5; } else if (strcmp(rxPool_sc_Period,"spare4")==0) { - RRC_CONFIGURATION_REQ (msg_p).rxPool_sc_Period[j] = SL_PeriodComm_r12_spare4; + RRC_CONFIGURATION_REQ (msg_p).rxPool_sc_Period[j] = LTE_SL_PeriodComm_r12_spare4; } else if (strcmp(rxPool_sc_Period,"spare3")==0) { - RRC_CONFIGURATION_REQ (msg_p).rxPool_sc_Period[j] = SL_PeriodComm_r12_spare3; + RRC_CONFIGURATION_REQ (msg_p).rxPool_sc_Period[j] = LTE_SL_PeriodComm_r12_spare3; } else if (strcmp(rxPool_sc_Period,"spare2")==0) { - RRC_CONFIGURATION_REQ (msg_p).rxPool_sc_Period[j] = SL_PeriodComm_r12_spare2; + RRC_CONFIGURATION_REQ (msg_p).rxPool_sc_Period[j] = LTE_SL_PeriodComm_r12_spare2; } else if (strcmp(rxPool_sc_Period,"spare")==0) { - RRC_CONFIGURATION_REQ (msg_p).rxPool_sc_Period[j] = SL_PeriodComm_r12_spare; + RRC_CONFIGURATION_REQ (msg_p).rxPool_sc_Period[j] = LTE_SL_PeriodComm_r12_spare; } else AssertFatal (0, "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for rxPool_sc_Period choice: sf40,sf60,sf70,sf80,sf120,sf140,sf160,sf240,sf280,sf320,spare6,spare5,spare4,spare3,spare2,spare!\n", RC.config_file_name, i, rxPool_sc_Period); if (strcmp(rxPool_data_CP_Len,"normal")==0) { - RRC_CONFIGURATION_REQ (msg_p).rxPool_data_CP_Len[j] = SL_CP_Len_r12_normal; + RRC_CONFIGURATION_REQ (msg_p).rxPool_data_CP_Len[j] = LTE_SL_CP_Len_r12_normal; } else if (strcmp(rxPool_data_CP_Len,"extended")==0) { - RRC_CONFIGURATION_REQ (msg_p).rxPool_data_CP_Len[j] = SL_CP_Len_r12_extended; + RRC_CONFIGURATION_REQ (msg_p).rxPool_data_CP_Len[j] = LTE_SL_CP_Len_r12_extended; } else AssertFatal (0, "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for rxPool_data_CP_Len choice: normal,extended!\n", @@ -1501,11 +1501,11 @@ int RCconfig_RRC(MessageDef *msg_p, uint32_t i, eNB_RRC_INST *rrc) { RRC_CONFIGURATION_REQ (msg_p).rxPool_ResourceConfig_prb_End[j] = rxPool_ResourceConfig_prb_End; if (strcmp(rxPool_ResourceConfig_offsetIndicator_present,"prNothing")==0) { - RRC_CONFIGURATION_REQ (msg_p).rxPool_ResourceConfig_offsetIndicator_present[j] = SL_OffsetIndicator_r12_PR_NOTHING; + RRC_CONFIGURATION_REQ (msg_p).rxPool_ResourceConfig_offsetIndicator_present[j] = LTE_SL_OffsetIndicator_r12_PR_NOTHING; } else if (strcmp(rxPool_ResourceConfig_offsetIndicator_present,"prSmall")==0) { - RRC_CONFIGURATION_REQ (msg_p).rxPool_ResourceConfig_offsetIndicator_present[j] = SL_OffsetIndicator_r12_PR_small_r12; + RRC_CONFIGURATION_REQ (msg_p).rxPool_ResourceConfig_offsetIndicator_present[j] = LTE_SL_OffsetIndicator_r12_PR_small_r12; } else if (strcmp(rxPool_ResourceConfig_offsetIndicator_present,"prLarge")==0) { - RRC_CONFIGURATION_REQ (msg_p).rxPool_ResourceConfig_offsetIndicator_present[j] = SL_OffsetIndicator_r12_PR_large_r12; + RRC_CONFIGURATION_REQ (msg_p).rxPool_ResourceConfig_offsetIndicator_present[j] = LTE_SL_OffsetIndicator_r12_PR_large_r12; } else AssertFatal (0, "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for rxPool_ResourceConfig_offsetIndicator_present choice: prNothing,prSmal,prLarge!\n", @@ -1514,21 +1514,21 @@ int RCconfig_RRC(MessageDef *msg_p, uint32_t i, eNB_RRC_INST *rrc) { RRC_CONFIGURATION_REQ (msg_p).rxPool_ResourceConfig_offsetIndicator_choice[j] = rxPool_ResourceConfig_offsetIndicator_choice; if (strcmp(rxPool_ResourceConfig_subframeBitmap_present,"prNothing")==0) { - RRC_CONFIGURATION_REQ (msg_p).rxPool_ResourceConfig_subframeBitmap_present[j] = SubframeBitmapSL_r12_PR_NOTHING; + RRC_CONFIGURATION_REQ (msg_p).rxPool_ResourceConfig_subframeBitmap_present[j] = LTE_SubframeBitmapSL_r12_PR_NOTHING; } else if (strcmp(rxPool_ResourceConfig_subframeBitmap_present,"prBs4")==0) { - RRC_CONFIGURATION_REQ (msg_p).rxPool_ResourceConfig_subframeBitmap_present[j] = SubframeBitmapSL_r12_PR_bs4_r12; + RRC_CONFIGURATION_REQ (msg_p).rxPool_ResourceConfig_subframeBitmap_present[j] = LTE_SubframeBitmapSL_r12_PR_bs4_r12; } else if (strcmp(rxPool_ResourceConfig_subframeBitmap_present,"prBs8")==0) { - RRC_CONFIGURATION_REQ (msg_p).rxPool_ResourceConfig_subframeBitmap_present[j] = SubframeBitmapSL_r12_PR_bs8_r12; + RRC_CONFIGURATION_REQ (msg_p).rxPool_ResourceConfig_subframeBitmap_present[j] = LTE_SubframeBitmapSL_r12_PR_bs8_r12; } else if (strcmp(rxPool_ResourceConfig_subframeBitmap_present,"prBs12")==0) { - RRC_CONFIGURATION_REQ (msg_p).rxPool_ResourceConfig_subframeBitmap_present[j] = SubframeBitmapSL_r12_PR_bs12_r12; + RRC_CONFIGURATION_REQ (msg_p).rxPool_ResourceConfig_subframeBitmap_present[j] = LTE_SubframeBitmapSL_r12_PR_bs12_r12; } else if (strcmp(rxPool_ResourceConfig_subframeBitmap_present,"prBs16")==0) { - RRC_CONFIGURATION_REQ (msg_p).rxPool_ResourceConfig_subframeBitmap_present[j] = SubframeBitmapSL_r12_PR_bs16_r12; + RRC_CONFIGURATION_REQ (msg_p).rxPool_ResourceConfig_subframeBitmap_present[j] = LTE_SubframeBitmapSL_r12_PR_bs16_r12; } else if (strcmp(rxPool_ResourceConfig_subframeBitmap_present,"prBs30")==0) { - RRC_CONFIGURATION_REQ (msg_p).rxPool_ResourceConfig_subframeBitmap_present[j] = SubframeBitmapSL_r12_PR_bs30_r12; + RRC_CONFIGURATION_REQ (msg_p).rxPool_ResourceConfig_subframeBitmap_present[j] = LTE_SubframeBitmapSL_r12_PR_bs30_r12; } else if (strcmp(rxPool_ResourceConfig_subframeBitmap_present,"prBs40")==0) { - RRC_CONFIGURATION_REQ (msg_p).rxPool_ResourceConfig_subframeBitmap_present[j] = SubframeBitmapSL_r12_PR_bs40_r12; + RRC_CONFIGURATION_REQ (msg_p).rxPool_ResourceConfig_subframeBitmap_present[j] = LTE_SubframeBitmapSL_r12_PR_bs40_r12; } else if (strcmp(rxPool_ResourceConfig_subframeBitmap_present,"prBs42")==0) { - RRC_CONFIGURATION_REQ (msg_p).rxPool_ResourceConfig_subframeBitmap_present[j] = SubframeBitmapSL_r12_PR_bs42_r12; + RRC_CONFIGURATION_REQ (msg_p).rxPool_ResourceConfig_subframeBitmap_present[j] = LTE_SubframeBitmapSL_r12_PR_bs42_r12; } else AssertFatal (0, "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for rxPool_ResourceConfig_subframeBitmap_present choice: prNothing,prBs4,prBs8,prBs12,prBs16,prBs30,prBs40,prBs42!\n", @@ -1540,30 +1540,30 @@ int RCconfig_RRC(MessageDef *msg_p, uint32_t i, eNB_RRC_INST *rrc) { //SIB19 - for discRxPool if (strcmp(discRxPool_cp_Len,"normal")==0) { - RRC_CONFIGURATION_REQ (msg_p).discRxPool_cp_Len[j] = SL_CP_Len_r12_normal; + RRC_CONFIGURATION_REQ (msg_p).discRxPool_cp_Len[j] = LTE_SL_CP_Len_r12_normal; } else if (strcmp(discRxPool_cp_Len,"extended")==0) { - RRC_CONFIGURATION_REQ (msg_p).discRxPool_cp_Len[j] = SL_CP_Len_r12_extended; + RRC_CONFIGURATION_REQ (msg_p).discRxPool_cp_Len[j] = LTE_SL_CP_Len_r12_extended; } else AssertFatal (0, "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for discRxPool_cp_Len choice: normal,extended!\n", RC.config_file_name, i, discRxPool_cp_Len); if (strcmp(discRxPool_discPeriod,"rf32")==0) { - RRC_CONFIGURATION_REQ (msg_p).discRxPool_discPeriod[j] = SL_DiscResourcePool_r12__discPeriod_r12_rf32; + RRC_CONFIGURATION_REQ (msg_p).discRxPool_discPeriod[j] = LTE_SL_DiscResourcePool_r12__discPeriod_r12_rf32; } else if (strcmp(discRxPool_discPeriod,"rf64")==0) { - RRC_CONFIGURATION_REQ (msg_p).discRxPool_discPeriod[j] = SL_DiscResourcePool_r12__discPeriod_r12_rf64; + RRC_CONFIGURATION_REQ (msg_p).discRxPool_discPeriod[j] = LTE_SL_DiscResourcePool_r12__discPeriod_r12_rf64; } else if (strcmp(discRxPool_discPeriod,"rf128")==0) { - RRC_CONFIGURATION_REQ (msg_p).discRxPool_discPeriod[j] = SL_DiscResourcePool_r12__discPeriod_r12_rf128; + RRC_CONFIGURATION_REQ (msg_p).discRxPool_discPeriod[j] = LTE_SL_DiscResourcePool_r12__discPeriod_r12_rf128; } else if (strcmp(discRxPool_discPeriod,"rf256")==0) { - RRC_CONFIGURATION_REQ (msg_p).discRxPool_discPeriod[j] = SL_DiscResourcePool_r12__discPeriod_r12_rf256; + RRC_CONFIGURATION_REQ (msg_p).discRxPool_discPeriod[j] = LTE_SL_DiscResourcePool_r12__discPeriod_r12_rf256; } else if (strcmp(discRxPool_discPeriod,"rf512")==0) { - RRC_CONFIGURATION_REQ (msg_p).discRxPool_discPeriod[j] = SL_DiscResourcePool_r12__discPeriod_r12_rf512; + RRC_CONFIGURATION_REQ (msg_p).discRxPool_discPeriod[j] = LTE_SL_DiscResourcePool_r12__discPeriod_r12_rf512; } else if (strcmp(discRxPool_discPeriod,"rf1024")==0) { - RRC_CONFIGURATION_REQ (msg_p).discRxPool_discPeriod[j] = SL_DiscResourcePool_r12__discPeriod_r12_rf1024; + RRC_CONFIGURATION_REQ (msg_p).discRxPool_discPeriod[j] = LTE_SL_DiscResourcePool_r12__discPeriod_r12_rf1024; } else if (strcmp(discRxPool_discPeriod,"rf16")==0) { - RRC_CONFIGURATION_REQ (msg_p).discRxPool_discPeriod[j] = SL_DiscResourcePool_r12__discPeriod_r12_rf16_v1310; + RRC_CONFIGURATION_REQ (msg_p).discRxPool_discPeriod[j] = LTE_SL_DiscResourcePool_r12__discPeriod_r12_rf16_v1310; } else if (strcmp(discRxPool_discPeriod,"spare")==0) { - RRC_CONFIGURATION_REQ (msg_p).discRxPool_discPeriod[j] = SL_DiscResourcePool_r12__discPeriod_r12_spare; + RRC_CONFIGURATION_REQ (msg_p).discRxPool_discPeriod[j] = LTE_SL_DiscResourcePool_r12__discPeriod_r12_spare; } else AssertFatal (0, "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for discRxPool_discPeriod choice: rf32,rf64,rf128,rf512,rf1024,rf16,spare!\n", @@ -1576,11 +1576,11 @@ int RCconfig_RRC(MessageDef *msg_p, uint32_t i, eNB_RRC_INST *rrc) { RRC_CONFIGURATION_REQ (msg_p).discRxPool_ResourceConfig_prb_End[j] = discRxPool_ResourceConfig_prb_End; if (strcmp(discRxPool_ResourceConfig_offsetIndicator_present,"prNothing")==0) { - RRC_CONFIGURATION_REQ (msg_p).discRxPool_ResourceConfig_offsetIndicator_present[j] = SL_OffsetIndicator_r12_PR_NOTHING; + RRC_CONFIGURATION_REQ (msg_p).discRxPool_ResourceConfig_offsetIndicator_present[j] = LTE_SL_OffsetIndicator_r12_PR_NOTHING; } else if (strcmp(discRxPool_ResourceConfig_offsetIndicator_present,"prSmall")==0) { - RRC_CONFIGURATION_REQ (msg_p).discRxPool_ResourceConfig_offsetIndicator_present[j] = SL_OffsetIndicator_r12_PR_small_r12; + RRC_CONFIGURATION_REQ (msg_p).discRxPool_ResourceConfig_offsetIndicator_present[j] = LTE_SL_OffsetIndicator_r12_PR_small_r12; } else if (strcmp(discRxPool_ResourceConfig_offsetIndicator_present,"prLarge")==0) { - RRC_CONFIGURATION_REQ (msg_p).discRxPool_ResourceConfig_offsetIndicator_present[j] = SL_OffsetIndicator_r12_PR_large_r12; + RRC_CONFIGURATION_REQ (msg_p).discRxPool_ResourceConfig_offsetIndicator_present[j] = LTE_SL_OffsetIndicator_r12_PR_large_r12; } else AssertFatal (0, "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for discRxPool_ResourceConfig_offsetIndicator_present choice: prNothing,prSmal,prLarge!\n", @@ -1589,21 +1589,21 @@ int RCconfig_RRC(MessageDef *msg_p, uint32_t i, eNB_RRC_INST *rrc) { RRC_CONFIGURATION_REQ (msg_p).discRxPool_ResourceConfig_offsetIndicator_choice[j] = discRxPool_ResourceConfig_offsetIndicator_choice; if (strcmp(discRxPool_ResourceConfig_subframeBitmap_present,"prNothing")==0) { - RRC_CONFIGURATION_REQ (msg_p).discRxPool_ResourceConfig_subframeBitmap_present[j] = SubframeBitmapSL_r12_PR_NOTHING; + RRC_CONFIGURATION_REQ (msg_p).discRxPool_ResourceConfig_subframeBitmap_present[j] = LTE_SubframeBitmapSL_r12_PR_NOTHING; } else if (strcmp(discRxPool_ResourceConfig_subframeBitmap_present,"prBs4")==0) { - RRC_CONFIGURATION_REQ (msg_p).discRxPool_ResourceConfig_subframeBitmap_present[j] = SubframeBitmapSL_r12_PR_bs4_r12; + RRC_CONFIGURATION_REQ (msg_p).discRxPool_ResourceConfig_subframeBitmap_present[j] = LTE_SubframeBitmapSL_r12_PR_bs4_r12; } else if (strcmp(discRxPool_ResourceConfig_subframeBitmap_present,"prBs8")==0) { - RRC_CONFIGURATION_REQ (msg_p).discRxPool_ResourceConfig_subframeBitmap_present[j] = SubframeBitmapSL_r12_PR_bs8_r12; + RRC_CONFIGURATION_REQ (msg_p).discRxPool_ResourceConfig_subframeBitmap_present[j] = LTE_SubframeBitmapSL_r12_PR_bs8_r12; } else if (strcmp(discRxPool_ResourceConfig_subframeBitmap_present,"prBs12")==0) { - RRC_CONFIGURATION_REQ (msg_p).discRxPool_ResourceConfig_subframeBitmap_present[j] = SubframeBitmapSL_r12_PR_bs12_r12; + RRC_CONFIGURATION_REQ (msg_p).discRxPool_ResourceConfig_subframeBitmap_present[j] = LTE_SubframeBitmapSL_r12_PR_bs12_r12; } else if (strcmp(discRxPool_ResourceConfig_subframeBitmap_present,"prBs16")==0) { - RRC_CONFIGURATION_REQ (msg_p).discRxPool_ResourceConfig_subframeBitmap_present[j] = SubframeBitmapSL_r12_PR_bs16_r12; + RRC_CONFIGURATION_REQ (msg_p).discRxPool_ResourceConfig_subframeBitmap_present[j] = LTE_SubframeBitmapSL_r12_PR_bs16_r12; } else if (strcmp(discRxPool_ResourceConfig_subframeBitmap_present,"prBs30")==0) { - RRC_CONFIGURATION_REQ (msg_p).discRxPool_ResourceConfig_subframeBitmap_present[j] = SubframeBitmapSL_r12_PR_bs30_r12; + RRC_CONFIGURATION_REQ (msg_p).discRxPool_ResourceConfig_subframeBitmap_present[j] = LTE_SubframeBitmapSL_r12_PR_bs30_r12; } else if (strcmp(discRxPool_ResourceConfig_subframeBitmap_present,"prBs40")==0) { - RRC_CONFIGURATION_REQ (msg_p).discRxPool_ResourceConfig_subframeBitmap_present[j] = SubframeBitmapSL_r12_PR_bs40_r12; + RRC_CONFIGURATION_REQ (msg_p).discRxPool_ResourceConfig_subframeBitmap_present[j] = LTE_SubframeBitmapSL_r12_PR_bs40_r12; } else if (strcmp(discRxPool_ResourceConfig_subframeBitmap_present,"prBs42")==0) { - RRC_CONFIGURATION_REQ (msg_p).discRxPool_ResourceConfig_subframeBitmap_present[j] = SubframeBitmapSL_r12_PR_bs42_r12; + RRC_CONFIGURATION_REQ (msg_p).discRxPool_ResourceConfig_subframeBitmap_present[j] = LTE_SubframeBitmapSL_r12_PR_bs42_r12; } else AssertFatal (0, "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for discRxPool_ResourceConfig_subframeBitmap_present choice: prNothing,prBs4,prBs8,prBs12,prBs16,prBs30,prBs40,prBs42!\n", @@ -1615,30 +1615,30 @@ int RCconfig_RRC(MessageDef *msg_p, uint32_t i, eNB_RRC_INST *rrc) { //SIB19 - For discRxPoolPS if (strcmp(discRxPoolPS_cp_Len,"normal")==0) { - RRC_CONFIGURATION_REQ (msg_p).discRxPoolPS_cp_Len[j] = SL_CP_Len_r12_normal; + RRC_CONFIGURATION_REQ (msg_p).discRxPoolPS_cp_Len[j] = LTE_SL_CP_Len_r12_normal; } else if (strcmp(discRxPoolPS_cp_Len,"extended")==0) { - RRC_CONFIGURATION_REQ (msg_p).discRxPoolPS_cp_Len[j] = SL_CP_Len_r12_extended; + RRC_CONFIGURATION_REQ (msg_p).discRxPoolPS_cp_Len[j] = LTE_SL_CP_Len_r12_extended; } else AssertFatal (0, "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for discRxPoolPS_cp_Len choice: normal,extended!\n", RC.config_file_name, i, discRxPoolPS_cp_Len); if (strcmp(discRxPoolPS_discPeriod,"rf32")==0) { - RRC_CONFIGURATION_REQ (msg_p).discRxPoolPS_discPeriod[j] = SL_DiscResourcePool_r12__discPeriod_r12_rf32; + RRC_CONFIGURATION_REQ (msg_p).discRxPoolPS_discPeriod[j] = LTE_SL_DiscResourcePool_r12__discPeriod_r12_rf32; } else if (strcmp(discRxPoolPS_discPeriod,"rf64")==0) { - RRC_CONFIGURATION_REQ (msg_p).discRxPoolPS_discPeriod[j] = SL_DiscResourcePool_r12__discPeriod_r12_rf64; + RRC_CONFIGURATION_REQ (msg_p).discRxPoolPS_discPeriod[j] = LTE_SL_DiscResourcePool_r12__discPeriod_r12_rf64; } else if (strcmp(discRxPoolPS_discPeriod,"rf128")==0) { - RRC_CONFIGURATION_REQ (msg_p).discRxPoolPS_discPeriod[j] = SL_DiscResourcePool_r12__discPeriod_r12_rf128; + RRC_CONFIGURATION_REQ (msg_p).discRxPoolPS_discPeriod[j] = LTE_SL_DiscResourcePool_r12__discPeriod_r12_rf128; } else if (strcmp(discRxPoolPS_discPeriod,"rf256")==0) { - RRC_CONFIGURATION_REQ (msg_p).discRxPoolPS_discPeriod[j] = SL_DiscResourcePool_r12__discPeriod_r12_rf256; + RRC_CONFIGURATION_REQ (msg_p).discRxPoolPS_discPeriod[j] = LTE_SL_DiscResourcePool_r12__discPeriod_r12_rf256; } else if (strcmp(discRxPoolPS_discPeriod,"rf512")==0) { - RRC_CONFIGURATION_REQ (msg_p).discRxPoolPS_discPeriod[j] = SL_DiscResourcePool_r12__discPeriod_r12_rf512; + RRC_CONFIGURATION_REQ (msg_p).discRxPoolPS_discPeriod[j] = LTE_SL_DiscResourcePool_r12__discPeriod_r12_rf512; } else if (strcmp(discRxPoolPS_discPeriod,"rf1024")==0) { - RRC_CONFIGURATION_REQ (msg_p).discRxPoolPS_discPeriod[j] = SL_DiscResourcePool_r12__discPeriod_r12_rf1024; + RRC_CONFIGURATION_REQ (msg_p).discRxPoolPS_discPeriod[j] = LTE_SL_DiscResourcePool_r12__discPeriod_r12_rf1024; } else if (strcmp(discRxPoolPS_discPeriod,"rf16")==0) { - RRC_CONFIGURATION_REQ (msg_p).discRxPoolPS_discPeriod[j] = SL_DiscResourcePool_r12__discPeriod_r12_rf16_v1310; + RRC_CONFIGURATION_REQ (msg_p).discRxPoolPS_discPeriod[j] = LTE_SL_DiscResourcePool_r12__discPeriod_r12_rf16_v1310; } else if (strcmp(discRxPoolPS_discPeriod,"spare")==0) { - RRC_CONFIGURATION_REQ (msg_p).discRxPoolPS_discPeriod[j] = SL_DiscResourcePool_r12__discPeriod_r12_spare; + RRC_CONFIGURATION_REQ (msg_p).discRxPoolPS_discPeriod[j] = LTE_SL_DiscResourcePool_r12__discPeriod_r12_spare; } else AssertFatal (0, "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for discRxPoolPS_discPeriod choice: rf32,rf64,rf128,rf512,rf1024,rf16,spare!\n", @@ -1651,11 +1651,11 @@ int RCconfig_RRC(MessageDef *msg_p, uint32_t i, eNB_RRC_INST *rrc) { RRC_CONFIGURATION_REQ (msg_p).discRxPoolPS_ResourceConfig_prb_End[j] = discRxPoolPS_ResourceConfig_prb_End; if (strcmp(discRxPoolPS_ResourceConfig_offsetIndicator_present,"prNothing")==0) { - RRC_CONFIGURATION_REQ (msg_p).discRxPoolPS_ResourceConfig_offsetIndicator_present[j] = SL_OffsetIndicator_r12_PR_NOTHING; + RRC_CONFIGURATION_REQ (msg_p).discRxPoolPS_ResourceConfig_offsetIndicator_present[j] = LTE_SL_OffsetIndicator_r12_PR_NOTHING; } else if (strcmp(discRxPoolPS_ResourceConfig_offsetIndicator_present,"prSmall")==0) { - RRC_CONFIGURATION_REQ (msg_p).discRxPoolPS_ResourceConfig_offsetIndicator_present[j] = SL_OffsetIndicator_r12_PR_small_r12; + RRC_CONFIGURATION_REQ (msg_p).discRxPoolPS_ResourceConfig_offsetIndicator_present[j] = LTE_SL_OffsetIndicator_r12_PR_small_r12; } else if (strcmp(discRxPoolPS_ResourceConfig_offsetIndicator_present,"prLarge")==0) { - RRC_CONFIGURATION_REQ (msg_p).discRxPoolPS_ResourceConfig_offsetIndicator_present[j] = SL_OffsetIndicator_r12_PR_large_r12; + RRC_CONFIGURATION_REQ (msg_p).discRxPoolPS_ResourceConfig_offsetIndicator_present[j] = LTE_SL_OffsetIndicator_r12_PR_large_r12; } else AssertFatal (0, "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for discRxPoolPS_ResourceConfig_offsetIndicator_present choice: prNothing,prSmal,prLarge!\n", @@ -1664,21 +1664,21 @@ int RCconfig_RRC(MessageDef *msg_p, uint32_t i, eNB_RRC_INST *rrc) { RRC_CONFIGURATION_REQ (msg_p).discRxPoolPS_ResourceConfig_offsetIndicator_choice[j] = discRxPoolPS_ResourceConfig_offsetIndicator_choice; if (strcmp(discRxPoolPS_ResourceConfig_subframeBitmap_present,"prNothing")==0) { - RRC_CONFIGURATION_REQ (msg_p).discRxPoolPS_ResourceConfig_subframeBitmap_present[j] = SubframeBitmapSL_r12_PR_NOTHING; + RRC_CONFIGURATION_REQ (msg_p).discRxPoolPS_ResourceConfig_subframeBitmap_present[j] = LTE_SubframeBitmapSL_r12_PR_NOTHING; } else if (strcmp(discRxPoolPS_ResourceConfig_subframeBitmap_present,"prBs4")==0) { - RRC_CONFIGURATION_REQ (msg_p).discRxPoolPS_ResourceConfig_subframeBitmap_present[j] = SubframeBitmapSL_r12_PR_bs4_r12; + RRC_CONFIGURATION_REQ (msg_p).discRxPoolPS_ResourceConfig_subframeBitmap_present[j] = LTE_SubframeBitmapSL_r12_PR_bs4_r12; } else if (strcmp(discRxPoolPS_ResourceConfig_subframeBitmap_present,"prBs8")==0) { - RRC_CONFIGURATION_REQ (msg_p).discRxPoolPS_ResourceConfig_subframeBitmap_present[j] = SubframeBitmapSL_r12_PR_bs8_r12; + RRC_CONFIGURATION_REQ (msg_p).discRxPoolPS_ResourceConfig_subframeBitmap_present[j] = LTE_SubframeBitmapSL_r12_PR_bs8_r12; } else if (strcmp(discRxPoolPS_ResourceConfig_subframeBitmap_present,"prBs12")==0) { - RRC_CONFIGURATION_REQ (msg_p).discRxPoolPS_ResourceConfig_subframeBitmap_present[j] = SubframeBitmapSL_r12_PR_bs12_r12; + RRC_CONFIGURATION_REQ (msg_p).discRxPoolPS_ResourceConfig_subframeBitmap_present[j] = LTE_SubframeBitmapSL_r12_PR_bs12_r12; } else if (strcmp(discRxPoolPS_ResourceConfig_subframeBitmap_present,"prBs16")==0) { - RRC_CONFIGURATION_REQ (msg_p).discRxPoolPS_ResourceConfig_subframeBitmap_present[j] = SubframeBitmapSL_r12_PR_bs16_r12; + RRC_CONFIGURATION_REQ (msg_p).discRxPoolPS_ResourceConfig_subframeBitmap_present[j] = LTE_SubframeBitmapSL_r12_PR_bs16_r12; } else if (strcmp(discRxPoolPS_ResourceConfig_subframeBitmap_present,"prBs30")==0) { - RRC_CONFIGURATION_REQ (msg_p).discRxPoolPS_ResourceConfig_subframeBitmap_present[j] = SubframeBitmapSL_r12_PR_bs30_r12; + RRC_CONFIGURATION_REQ (msg_p).discRxPoolPS_ResourceConfig_subframeBitmap_present[j] = LTE_SubframeBitmapSL_r12_PR_bs30_r12; } else if (strcmp(discRxPoolPS_ResourceConfig_subframeBitmap_present,"prBs40")==0) { - RRC_CONFIGURATION_REQ (msg_p).discRxPoolPS_ResourceConfig_subframeBitmap_present[j] = SubframeBitmapSL_r12_PR_bs40_r12; + RRC_CONFIGURATION_REQ (msg_p).discRxPoolPS_ResourceConfig_subframeBitmap_present[j] = LTE_SubframeBitmapSL_r12_PR_bs40_r12; } else if (strcmp(discRxPoolPS_ResourceConfig_subframeBitmap_present,"prBs42")==0) { - RRC_CONFIGURATION_REQ (msg_p).discRxPoolPS_ResourceConfig_subframeBitmap_present[j] = SubframeBitmapSL_r12_PR_bs42_r12; + RRC_CONFIGURATION_REQ (msg_p).discRxPoolPS_ResourceConfig_subframeBitmap_present[j] = LTE_SubframeBitmapSL_r12_PR_bs42_r12; } else AssertFatal (0, "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for discRxPoolPS_ResourceConfig_subframeBitmap_present choice: prNothing,prBs4,prBs8,prBs12,prBs16,prBs30,prBs40,prBs42!\n", @@ -1697,35 +1697,35 @@ int RCconfig_RRC(MessageDef *msg_p, uint32_t i, eNB_RRC_INST *rrc) { if (npar == sizeof(SRB1Params)/sizeof(paramdef_t)) { switch (srb1_max_retx_threshold) { case 1: - rrc->srb1_max_retx_threshold = UL_AM_RLC__maxRetxThreshold_t1; + rrc->srb1_max_retx_threshold = LTE_UL_AM_RLC__maxRetxThreshold_t1; break; case 2: - rrc->srb1_max_retx_threshold = UL_AM_RLC__maxRetxThreshold_t2; + rrc->srb1_max_retx_threshold = LTE_UL_AM_RLC__maxRetxThreshold_t2; break; case 3: - rrc->srb1_max_retx_threshold = UL_AM_RLC__maxRetxThreshold_t3; + rrc->srb1_max_retx_threshold = LTE_UL_AM_RLC__maxRetxThreshold_t3; break; case 4: - rrc->srb1_max_retx_threshold = UL_AM_RLC__maxRetxThreshold_t4; + rrc->srb1_max_retx_threshold = LTE_UL_AM_RLC__maxRetxThreshold_t4; break; case 6: - rrc->srb1_max_retx_threshold = UL_AM_RLC__maxRetxThreshold_t6; + rrc->srb1_max_retx_threshold = LTE_UL_AM_RLC__maxRetxThreshold_t6; break; case 8: - rrc->srb1_max_retx_threshold = UL_AM_RLC__maxRetxThreshold_t8; + rrc->srb1_max_retx_threshold = LTE_UL_AM_RLC__maxRetxThreshold_t8; break; case 16: - rrc->srb1_max_retx_threshold = UL_AM_RLC__maxRetxThreshold_t16; + rrc->srb1_max_retx_threshold = LTE_UL_AM_RLC__maxRetxThreshold_t16; break; case 32: - rrc->srb1_max_retx_threshold = UL_AM_RLC__maxRetxThreshold_t32; + rrc->srb1_max_retx_threshold = LTE_UL_AM_RLC__maxRetxThreshold_t32; break; default: @@ -1736,36 +1736,36 @@ int RCconfig_RRC(MessageDef *msg_p, uint32_t i, eNB_RRC_INST *rrc) { switch (srb1_poll_pdu) { case 4: - rrc->srb1_poll_pdu = PollPDU_p4; + rrc->srb1_poll_pdu = LTE_PollPDU_p4; break; case 8: - rrc->srb1_poll_pdu = PollPDU_p8; + rrc->srb1_poll_pdu = LTE_PollPDU_p8; break; case 16: - rrc->srb1_poll_pdu = PollPDU_p16; + rrc->srb1_poll_pdu = LTE_PollPDU_p16; break; case 32: - rrc->srb1_poll_pdu = PollPDU_p32; + rrc->srb1_poll_pdu = LTE_PollPDU_p32; break; case 64: - rrc->srb1_poll_pdu = PollPDU_p64; + rrc->srb1_poll_pdu = LTE_PollPDU_p64; break; case 128: - rrc->srb1_poll_pdu = PollPDU_p128; + rrc->srb1_poll_pdu = LTE_PollPDU_p128; break; case 256: - rrc->srb1_poll_pdu = PollPDU_p256; + rrc->srb1_poll_pdu = LTE_PollPDU_p256; break; default: if (srb1_poll_pdu >= 10000) - rrc->srb1_poll_pdu = PollPDU_pInfinity; + rrc->srb1_poll_pdu = LTE_PollPDU_pInfinity; else AssertFatal (0, "Bad config value when parsing eNB configuration file %s, enb %d srb1_poll_pdu %u!\n", @@ -1776,64 +1776,64 @@ int RCconfig_RRC(MessageDef *msg_p, uint32_t i, eNB_RRC_INST *rrc) { switch (srb1_poll_byte) { case 25: - rrc->srb1_poll_byte = PollByte_kB25; + rrc->srb1_poll_byte = LTE_PollByte_kB25; break; case 50: - rrc->srb1_poll_byte = PollByte_kB50; + rrc->srb1_poll_byte = LTE_PollByte_kB50; break; case 75: - rrc->srb1_poll_byte = PollByte_kB75; + rrc->srb1_poll_byte = LTE_PollByte_kB75; break; case 100: - rrc->srb1_poll_byte = PollByte_kB100; + rrc->srb1_poll_byte = LTE_PollByte_kB100; break; case 125: - rrc->srb1_poll_byte = PollByte_kB125; + rrc->srb1_poll_byte = LTE_PollByte_kB125; break; case 250: - rrc->srb1_poll_byte = PollByte_kB250; + rrc->srb1_poll_byte = LTE_PollByte_kB250; break; case 375: - rrc->srb1_poll_byte = PollByte_kB375; + rrc->srb1_poll_byte = LTE_PollByte_kB375; break; case 500: - rrc->srb1_poll_byte = PollByte_kB500; + rrc->srb1_poll_byte = LTE_PollByte_kB500; break; case 750: - rrc->srb1_poll_byte = PollByte_kB750; + rrc->srb1_poll_byte = LTE_PollByte_kB750; break; case 1000: - rrc->srb1_poll_byte = PollByte_kB1000; + rrc->srb1_poll_byte = LTE_PollByte_kB1000; break; case 1250: - rrc->srb1_poll_byte = PollByte_kB1250; + rrc->srb1_poll_byte = LTE_PollByte_kB1250; break; case 1500: - rrc->srb1_poll_byte = PollByte_kB1500; + rrc->srb1_poll_byte = LTE_PollByte_kB1500; break; case 2000: - rrc->srb1_poll_byte = PollByte_kB2000; + rrc->srb1_poll_byte = LTE_PollByte_kB2000; break; case 3000: - rrc->srb1_poll_byte = PollByte_kB3000; + rrc->srb1_poll_byte = LTE_PollByte_kB3000; break; default: if (srb1_poll_byte >= 10000) - rrc->srb1_poll_byte = PollByte_kBinfinity; + rrc->srb1_poll_byte = LTE_PollByte_kBinfinity; else AssertFatal (0, "Bad config value when parsing eNB configuration file %s, enb %d srb1_poll_byte %u!\n", @@ -1862,127 +1862,127 @@ int RCconfig_RRC(MessageDef *msg_p, uint32_t i, eNB_RRC_INST *rrc) { switch (srb1_timer_reordering) { case 0: - rrc->srb1_timer_reordering = T_Reordering_ms0; + rrc->srb1_timer_reordering = LTE_T_Reordering_ms0; break; case 5: - rrc->srb1_timer_reordering = T_Reordering_ms5; + rrc->srb1_timer_reordering = LTE_T_Reordering_ms5; break; case 10: - rrc->srb1_timer_reordering = T_Reordering_ms10; + rrc->srb1_timer_reordering = LTE_T_Reordering_ms10; break; case 15: - rrc->srb1_timer_reordering = T_Reordering_ms15; + rrc->srb1_timer_reordering = LTE_T_Reordering_ms15; break; case 20: - rrc->srb1_timer_reordering = T_Reordering_ms20; + rrc->srb1_timer_reordering = LTE_T_Reordering_ms20; break; case 25: - rrc->srb1_timer_reordering = T_Reordering_ms25; + rrc->srb1_timer_reordering = LTE_T_Reordering_ms25; break; case 30: - rrc->srb1_timer_reordering = T_Reordering_ms30; + rrc->srb1_timer_reordering = LTE_T_Reordering_ms30; break; case 35: - rrc->srb1_timer_reordering = T_Reordering_ms35; + rrc->srb1_timer_reordering = LTE_T_Reordering_ms35; break; case 40: - rrc->srb1_timer_reordering = T_Reordering_ms40; + rrc->srb1_timer_reordering = LTE_T_Reordering_ms40; break; case 45: - rrc->srb1_timer_reordering = T_Reordering_ms45; + rrc->srb1_timer_reordering = LTE_T_Reordering_ms45; break; case 50: - rrc->srb1_timer_reordering = T_Reordering_ms50; + rrc->srb1_timer_reordering = LTE_T_Reordering_ms50; break; case 55: - rrc->srb1_timer_reordering = T_Reordering_ms55; + rrc->srb1_timer_reordering = LTE_T_Reordering_ms55; break; case 60: - rrc->srb1_timer_reordering = T_Reordering_ms60; + rrc->srb1_timer_reordering = LTE_T_Reordering_ms60; break; case 65: - rrc->srb1_timer_reordering = T_Reordering_ms65; + rrc->srb1_timer_reordering = LTE_T_Reordering_ms65; break; case 70: - rrc->srb1_timer_reordering = T_Reordering_ms70; + rrc->srb1_timer_reordering = LTE_T_Reordering_ms70; break; case 75: - rrc->srb1_timer_reordering = T_Reordering_ms75; + rrc->srb1_timer_reordering = LTE_T_Reordering_ms75; break; case 80: - rrc->srb1_timer_reordering = T_Reordering_ms80; + rrc->srb1_timer_reordering = LTE_T_Reordering_ms80; break; case 85: - rrc->srb1_timer_reordering = T_Reordering_ms85; + rrc->srb1_timer_reordering = LTE_T_Reordering_ms85; break; case 90: - rrc->srb1_timer_reordering = T_Reordering_ms90; + rrc->srb1_timer_reordering = LTE_T_Reordering_ms90; break; case 95: - rrc->srb1_timer_reordering = T_Reordering_ms95; + rrc->srb1_timer_reordering = LTE_T_Reordering_ms95; break; case 100: - rrc->srb1_timer_reordering = T_Reordering_ms100; + rrc->srb1_timer_reordering = LTE_T_Reordering_ms100; break; case 110: - rrc->srb1_timer_reordering = T_Reordering_ms110; + rrc->srb1_timer_reordering = LTE_T_Reordering_ms110; break; case 120: - rrc->srb1_timer_reordering = T_Reordering_ms120; + rrc->srb1_timer_reordering = LTE_T_Reordering_ms120; break; case 130: - rrc->srb1_timer_reordering = T_Reordering_ms130; + rrc->srb1_timer_reordering = LTE_T_Reordering_ms130; break; case 140: - rrc->srb1_timer_reordering = T_Reordering_ms140; + rrc->srb1_timer_reordering = LTE_T_Reordering_ms140; break; case 150: - rrc->srb1_timer_reordering = T_Reordering_ms150; + rrc->srb1_timer_reordering = LTE_T_Reordering_ms150; break; case 160: - rrc->srb1_timer_reordering = T_Reordering_ms160; + rrc->srb1_timer_reordering = LTE_T_Reordering_ms160; break; case 170: - rrc->srb1_timer_reordering = T_Reordering_ms170; + rrc->srb1_timer_reordering = LTE_T_Reordering_ms170; break; case 180: - rrc->srb1_timer_reordering = T_Reordering_ms180; + rrc->srb1_timer_reordering = LTE_T_Reordering_ms180; break; case 190: - rrc->srb1_timer_reordering = T_Reordering_ms190; + rrc->srb1_timer_reordering = LTE_T_Reordering_ms190; break; case 200: - rrc->srb1_timer_reordering = T_Reordering_ms200; + rrc->srb1_timer_reordering = LTE_T_Reordering_ms200; break; default: @@ -1991,12 +1991,12 @@ int RCconfig_RRC(MessageDef *msg_p, uint32_t i, eNB_RRC_INST *rrc) { RC.config_file_name, i, srb1_timer_reordering); } } else { - rrc->srb1_timer_poll_retransmit = T_PollRetransmit_ms80; - rrc->srb1_timer_reordering = T_Reordering_ms35; - rrc->srb1_timer_status_prohibit = T_StatusProhibit_ms0; - rrc->srb1_poll_pdu = PollPDU_p4; - rrc->srb1_poll_byte = PollByte_kBinfinity; - rrc->srb1_max_retx_threshold = UL_AM_RLC__maxRetxThreshold_t8; + rrc->srb1_timer_poll_retransmit = LTE_T_PollRetransmit_ms80; + rrc->srb1_timer_reordering = LTE_T_Reordering_ms35; + rrc->srb1_timer_status_prohibit = LTE_T_StatusProhibit_ms0; + rrc->srb1_poll_pdu = LTE_PollPDU_p4; + rrc->srb1_poll_byte = LTE_PollByte_kBinfinity; + rrc->srb1_max_retx_threshold = LTE_UL_AM_RLC__maxRetxThreshold_t8; } break; diff --git a/openair2/ENB_APP/enb_config.h b/openair2/ENB_APP/enb_config.h index ed1b4aeaa2..1b47a112cf 100644 --- a/openair2/ENB_APP/enb_config.h +++ b/openair2/ENB_APP/enb_config.h @@ -41,10 +41,10 @@ #include "PHY/defs_eNB.h" #include "s1ap_messages_types.h" #ifdef CMAKER -#include "SystemInformationBlockType2.h" +#include "LTE_SystemInformationBlockType2.h" #include "rrc_messages_types.h" #else -#include "RRC/LTE/MESSAGES/SystemInformationBlockType2.h" +#include "RRC/LTE/MESSAGES/LTE_SystemInformationBlockType2.h" #endif #include "RRC/LTE/rrc_defs.h" #include diff --git a/openair2/ENB_APP/enb_paramdef.h b/openair2/ENB_APP/enb_paramdef.h index 524daac43d..576a9bf0a2 100755 --- a/openair2/ENB_APP/enb_paramdef.h +++ b/openair2/ENB_APP/enb_paramdef.h @@ -296,7 +296,7 @@ typedef enum { #define ENB_CONFIG_STRING_PUCCH_DELTA_SHIFT "pucch_delta_shift" #define ENB_CONFIG_STRING_PUCCH_NRB_CQI "pucch_nRB_CQI" #define ENB_CONFIG_STRING_PUCCH_NCS_AN "pucch_nCS_AN" -//#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +//#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) #define ENB_CONFIG_STRING_PUCCH_N1_AN "pucch_n1_AN" //#endif #define ENB_CONFIG_STRING_PDSCH_RS_EPRE "pdsch_referenceSignalPower" diff --git a/openair2/ENB_APP/flexran_agent_ran_api.c b/openair2/ENB_APP/flexran_agent_ran_api.c index 973d322a5f..20ab7cda50 100644 --- a/openair2/ENB_APP/flexran_agent_ran_api.c +++ b/openair2/ENB_APP/flexran_agent_ran_api.c @@ -157,7 +157,7 @@ rlc_buffer_occupancy_t flexran_get_tx_queue_size(mid_t mod_id, mid_t ue_id, logi frame_t frame = flexran_get_current_frame(mod_id); sub_frame_t subframe = flexran_get_current_subframe(mod_id); mac_rlc_status_resp_t rlc_status = mac_rlc_status_ind(mod_id,rnti, mod_id, frame, subframe, ENB_FLAG_YES,MBMS_FLAG_NO, channel_id, 0 -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) ,0, 0 #endif ); @@ -170,7 +170,7 @@ rlc_buffer_occupancy_t flexran_get_num_pdus_buffer(mid_t mod_id, mid_t ue_id, lo frame_t frame = flexran_get_current_frame(mod_id); sub_frame_t subframe = flexran_get_current_subframe(mod_id); mac_rlc_status_resp_t rlc_status = mac_rlc_status_ind(mod_id,rnti, mod_id, frame, subframe, ENB_FLAG_YES,MBMS_FLAG_NO, channel_id, 0 -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) ,0, 0 #endif ); @@ -183,7 +183,7 @@ frame_t flexran_get_hol_delay(mid_t mod_id, mid_t ue_id, logical_chan_id_t chann frame_t frame = flexran_get_current_frame(mod_id); sub_frame_t subframe = flexran_get_current_subframe(mod_id); mac_rlc_status_resp_t rlc_status = mac_rlc_status_ind(mod_id, rnti, mod_id, frame, subframe, ENB_FLAG_YES, MBMS_FLAG_NO, channel_id, 0 -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) ,0, 0 #endif ); @@ -719,7 +719,7 @@ uint8_t flexran_get_num_pdcch_symb(mid_t mod_id, uint8_t cc_id) */ -TimeAlignmentTimer_t flexran_get_time_alignment_timer(mid_t mod_id, mid_t ue_id) +LTE_TimeAlignmentTimer_t flexran_get_time_alignment_timer(mid_t mod_id, mid_t ue_id) { if (!rrc_is_present(mod_id)) return -1; @@ -740,11 +740,11 @@ Protocol__FlexMeasGapConfigPattern flexran_get_meas_gap_config(mid_t mod_id, mid if (!ue_context_p) return -1; if (!ue_context_p->ue_context.measGapConfig) return -1; - if (ue_context_p->ue_context.measGapConfig->present != MeasGapConfig_PR_setup) return -1; + if (ue_context_p->ue_context.measGapConfig->present != LTE_MeasGapConfig_PR_setup) return -1; switch (ue_context_p->ue_context.measGapConfig->choice.setup.gapOffset.present) { - case MeasGapConfig__setup__gapOffset_PR_gp0: + case LTE_MeasGapConfig__setup__gapOffset_PR_gp0: return PROTOCOL__FLEX_MEAS_GAP_CONFIG_PATTERN__FLMGCP_GP1; - case MeasGapConfig__setup__gapOffset_PR_gp1: + case LTE_MeasGapConfig__setup__gapOffset_PR_gp1: return PROTOCOL__FLEX_MEAS_GAP_CONFIG_PATTERN__FLMGCP_GP2; default: return PROTOCOL__FLEX_MEAS_GAP_CONFIG_PATTERN__FLMGCP_OFF; @@ -761,11 +761,11 @@ long flexran_get_meas_gap_config_offset(mid_t mod_id, mid_t ue_id) if (!ue_context_p) return -1; if (!ue_context_p->ue_context.measGapConfig) return -1; - if (ue_context_p->ue_context.measGapConfig->present != MeasGapConfig_PR_setup) return -1; + if (ue_context_p->ue_context.measGapConfig->present != LTE_MeasGapConfig_PR_setup) return -1; switch (ue_context_p->ue_context.measGapConfig->choice.setup.gapOffset.present) { - case MeasGapConfig__setup__gapOffset_PR_gp0: + case LTE_MeasGapConfig__setup__gapOffset_PR_gp0: return ue_context_p->ue_context.measGapConfig->choice.setup.gapOffset.choice.gp0; - case MeasGapConfig__setup__gapOffset_PR_gp1: + case LTE_MeasGapConfig__setup__gapOffset_PR_gp1: return ue_context_p->ue_context.measGapConfig->choice.setup.gapOffset.choice.gp1; default: return -1; @@ -804,7 +804,7 @@ int flexran_get_half_duplex(mid_t mod_id, mid_t ue_id) if (!ue_context_p) return -1; if (!ue_context_p->ue_context.UE_Capability) return -1; - SupportedBandListEUTRA_t *bands = &ue_context_p->ue_context.UE_Capability->rf_Parameters.supportedBandListEUTRA; + LTE_SupportedBandListEUTRA_t *bands = &ue_context_p->ue_context.UE_Capability->rf_Parameters.supportedBandListEUTRA; for (int i = 0; i < bands->list.count; i++) { if (bands->list.array[i]->halfDuplex > 0) return 1; } @@ -976,7 +976,7 @@ BOOLEAN_t flexran_get_ack_nack_simultaneous_trans(mid_t mod_id, mid_t ue_id, uin return RC.rrc[mod_id]->carrier[cc_id].sib2->radioResourceConfigCommon.soundingRS_UL_ConfigCommon.choice.setup.ackNackSRS_SimultaneousTransmission; } -CQI_ReportModeAperiodic_t flexran_get_aperiodic_cqi_rep_mode(mid_t mod_id,mid_t ue_id) +LTE_CQI_ReportModeAperiodic_t flexran_get_aperiodic_cqi_rep_mode(mid_t mod_id,mid_t ue_id) { if (!rrc_is_present(mod_id)) return -1; @@ -1041,9 +1041,9 @@ int flexran_get_ue_transmission_antenna(mid_t mod_id, mid_t ue_id) if (!ue_context_p->ue_context.physicalConfigDedicated) return -1; if (!ue_context_p->ue_context.physicalConfigDedicated->antennaInfo) return -1; switch (ue_context_p->ue_context.physicalConfigDedicated->antennaInfo->choice.explicitValue.ue_TransmitAntennaSelection.choice.setup) { - case AntennaInfoDedicated__ue_TransmitAntennaSelection__setup_closedLoop: + case LTE_AntennaInfoDedicated__ue_TransmitAntennaSelection__setup_closedLoop: return 2; - case AntennaInfoDedicated__ue_TransmitAntennaSelection__setup_openLoop: + case LTE_AntennaInfoDedicated__ue_TransmitAntennaSelection__setup_openLoop: return 1; default: return 0; @@ -1365,7 +1365,7 @@ uint32_t flexran_get_pdcp_rx_oo(mid_t mod_id, mid_t ue_id, lcid_t lcid) /******************** RRC *****************************/ -MeasId_t flexran_get_rrc_pcell_measid(mid_t mod_id, mid_t ue_id) +LTE_MeasId_t flexran_get_rrc_pcell_measid(mid_t mod_id, mid_t ue_id) { if (!rrc_is_present(mod_id)) return -1; @@ -1412,11 +1412,11 @@ int flexran_get_rrc_num_ncell(mid_t mod_id, mid_t ue_id) if (!ue_context_p) return 0; if (!ue_context_p->ue_context.measResults) return 0; if (!ue_context_p->ue_context.measResults->measResultNeighCells) return 0; - if (ue_context_p->ue_context.measResults->measResultNeighCells->present != MeasResults__measResultNeighCells_PR_measResultListEUTRA) return 0; + if (ue_context_p->ue_context.measResults->measResultNeighCells->present != LTE_MeasResults__measResultNeighCells_PR_measResultListEUTRA) return 0; return ue_context_p->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.count; } -PhysCellId_t flexran_get_rrc_neigh_phy_cell_id(mid_t mod_id, mid_t ue_id, int cell_id) +LTE_PhysCellId_t flexran_get_rrc_neigh_phy_cell_id(mid_t mod_id, mid_t ue_id, int cell_id) { if (!rrc_is_present(mod_id)) return -1; @@ -1426,7 +1426,7 @@ PhysCellId_t flexran_get_rrc_neigh_phy_cell_id(mid_t mod_id, mid_t ue_id, int ce if (!ue_context_p) return -1; if (!ue_context_p->ue_context.measResults) return -1; if (!ue_context_p->ue_context.measResults->measResultNeighCells) return -1; - if (ue_context_p->ue_context.measResults->measResultNeighCells->present != MeasResults__measResultNeighCells_PR_measResultListEUTRA) return -1; + if (ue_context_p->ue_context.measResults->measResultNeighCells->present != LTE_MeasResults__measResultNeighCells_PR_measResultListEUTRA) return -1; if (!ue_context_p->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.array[cell_id]) return -1; return ue_context_p->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.array[cell_id]->physCellId; } @@ -1441,7 +1441,7 @@ float flexran_get_rrc_neigh_rsrp(mid_t mod_id, mid_t ue_id, int cell_id) if (!ue_context_p) return -1; if (!ue_context_p->ue_context.measResults) return -1; if (!ue_context_p->ue_context.measResults->measResultNeighCells) return -1; - if (ue_context_p->ue_context.measResults->measResultNeighCells->present != MeasResults__measResultNeighCells_PR_measResultListEUTRA) return -1; + if (ue_context_p->ue_context.measResults->measResultNeighCells->present != LTE_MeasResults__measResultNeighCells_PR_measResultListEUTRA) return -1; if (!ue_context_p->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.array[cell_id]) return -1; if (!ue_context_p->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.array[cell_id]->measResult.rsrpResult) return 0; return RSRP_meas_mapping[*(ue_context_p->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.array[cell_id]->measResult.rsrpResult)]; @@ -1457,7 +1457,7 @@ float flexran_get_rrc_neigh_rsrq(mid_t mod_id, mid_t ue_id, int cell_id) if (!ue_context_p) return -1; if (!ue_context_p->ue_context.measResults) return -1; if (!ue_context_p->ue_context.measResults->measResultNeighCells) return -1; - if (ue_context_p->ue_context.measResults->measResultNeighCells->present != MeasResults__measResultNeighCells_PR_measResultListEUTRA) return -1; + if (ue_context_p->ue_context.measResults->measResultNeighCells->present != LTE_MeasResults__measResultNeighCells_PR_measResultListEUTRA) return -1; if (!ue_context_p->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.array[cell_id]->measResult.rsrqResult) return 0; return RSRQ_meas_mapping[*(ue_context_p->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.array[cell_id]->measResult.rsrqResult)]; } diff --git a/openair2/ENB_APP/flexran_agent_ran_api.h b/openair2/ENB_APP/flexran_agent_ran_api.h index 37bdaae170..4fa05fd2f6 100644 --- a/openair2/ENB_APP/flexran_agent_ran_api.h +++ b/openair2/ENB_APP/flexran_agent_ran_api.h @@ -308,7 +308,7 @@ PHICH_DURATION_t flexran_get_phich_duration(mid_t mod_id, uint8_t cc_id); /* Get timer in subframes. Controls the synchronization status of the UE, not the actual timing advance procedure. See TS 36.321 */ -TimeAlignmentTimer_t flexran_get_time_alignment_timer(mid_t mod_id, mid_t ue_id); +LTE_TimeAlignmentTimer_t flexran_get_time_alignment_timer(mid_t mod_id, mid_t ue_id); /* Get measurement gap configuration. See TS 36.133 */ Protocol__FlexMeasGapConfigPattern flexran_get_meas_gap_config(mid_t mod_id, mid_t ue_id); @@ -365,7 +365,7 @@ BOOLEAN_t flexran_get_simultaneous_ack_nack_cqi(mid_t mod_id, mid_t ue_id); BOOLEAN_t flexran_get_ack_nack_simultaneous_trans(mid_t mod_id, mid_t ue_id, uint8_t cc_id); /* Get aperiodic CQI report mode */ -CQI_ReportModeAperiodic_t flexran_get_aperiodic_cqi_rep_mode(mid_t mod_id,mid_t ue_id); +LTE_CQI_ReportModeAperiodic_t flexran_get_aperiodic_cqi_rep_mode(mid_t mod_id,mid_t ue_id); /* Get ACK/NACK feedback mode. TDD only */ long flexran_get_tdd_ack_nack_feedback_mode(mid_t mod_id, mid_t ue_id); @@ -481,7 +481,7 @@ uint32_t flexran_get_pdcp_rx_oo(mid_t mod_id, mid_t ue_id, lcid_t lcid); /*********************RRC**********************/ /*Get primary cell measuremeant id flexRAN*/ -MeasId_t flexran_get_rrc_pcell_measid(mid_t mod_id, mid_t ue_id); +LTE_MeasId_t flexran_get_rrc_pcell_measid(mid_t mod_id, mid_t ue_id); /*Get primary cell RSRP measurement flexRAN*/ float flexran_get_rrc_pcell_rsrp(mid_t mod_id, mid_t ue_id); @@ -493,7 +493,7 @@ float flexran_get_rrc_pcell_rsrq(mid_t mod_id, mid_t ue_id); int flexran_get_rrc_num_ncell(mid_t mod_id, mid_t ue_id); /*Get physical cell id*/ -PhysCellId_t flexran_get_rrc_neigh_phy_cell_id(mid_t mod_id, mid_t ue_id, int cell_id); +LTE_PhysCellId_t flexran_get_rrc_neigh_phy_cell_id(mid_t mod_id, mid_t ue_id, int cell_id); /*Get RSRP of neighbouring Cell*/ float flexran_get_rrc_neigh_rsrp(mid_t mod_id, mid_t ue_id, int cell_id); diff --git a/openair2/LAYER2/MAC/config.c b/openair2/LAYER2/MAC/config.c index 0b4f05a56e..ac5c4a5de3 100644 --- a/openair2/LAYER2/MAC/config.c +++ b/openair2/LAYER2/MAC/config.c @@ -32,16 +32,16 @@ #include "COMMON/platform_types.h" #include "COMMON/platform_constants.h" -#include "SystemInformationBlockType2.h" +#include "LTE_SystemInformationBlockType2.h" //#include "RadioResourceConfigCommonSIB.h" -#include "RadioResourceConfigDedicated.h" -#if (RRC_VERSION >= MAKE_VERSION(13, 0, 0)) -#include "PRACH-ConfigSIB-v1310.h" +#include "LTE_RadioResourceConfigDedicated.h" +#if (LTE_RRC_VERSION >= MAKE_VERSION(13, 0, 0)) +#include "LTE_PRACH-ConfigSIB-v1310.h" #endif -#include "MeasGapConfig.h" -#include "MeasObjectToAddModList.h" -#include "TDD-Config.h" -#include "MAC-MainConfig.h" +#include "LTE_MeasGapConfig.h" +#include "LTE_MeasObjectToAddModList.h" +#include "LTE_TDD-Config.h" +#include "LTE_MAC-MainConfig.h" #include "mac.h" #include "mac_proto.h" #include "mac_extern.h" @@ -49,11 +49,11 @@ #include "common/utils/LOG/vcd_signal_dumper.h" #include "common/ran_context.h" -#if (RRC_VERSION >= MAKE_VERSION(9, 0, 0)) -#include "MBSFN-AreaInfoList-r9.h" -#include "MBSFN-AreaInfo-r9.h" -#include "MBSFN-SubframeConfigList.h" -#include "PMCH-InfoList-r9.h" +#if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) +#include "LTE_MBSFN-AreaInfoList-r9.h" +#include "LTE_MBSFN-AreaInfo-r9.h" +#include "LTE_MBSFN-SubframeConfigList.h" +#include "LTE_PMCH-InfoList-r9.h" #endif extern RAN_CONTEXT_t RC; @@ -239,13 +239,13 @@ void config_mib(int Mod_idP, int CC_idP, int eutra_bandP, int dl_BandwidthP, - PHICH_Config_t *phich_configP, + LTE_PHICH_Config_t *phich_configP, int Nid_cellP, int NcpP, int p_eNBP, uint32_t dl_CarrierFreqP, uint32_t ul_CarrierFreqP -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) , uint32_t pbch_repetitionP #endif @@ -317,14 +317,14 @@ void config_mib(int Mod_idP, cfg->sch_config.physical_cell_id.tl.tag = NFAPI_SCH_CONFIG_PHYSICAL_CELL_ID_TAG; cfg->num_tlv++; -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) cfg->emtc_config.pbch_repetitions_enable_r13.value = pbch_repetitionP; cfg->emtc_config.pbch_repetitions_enable_r13.tl.tag = NFAPI_EMTC_CONFIG_PBCH_REPETITIONS_ENABLE_R13_TAG; cfg->num_tlv++; #endif LOG_I(MAC, "%s() NFAPI_CONFIG_REQUEST(num_tlv:%u) DL_BW:%u UL_BW:%u Ncp %d,p_eNB %d,earfcn %d,band %d,phich_resource %u phich_duration %u phich_power_offset %u PSS %d SSS %d PCI %d" -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) " PBCH repetition %d" #endif @@ -342,13 +342,13 @@ void config_mib(int Mod_idP, ,cfg->sch_config.primary_synchronization_signal_epre_eprers.value ,cfg->sch_config.secondary_synchronization_signal_epre_eprers.value ,cfg->sch_config.physical_cell_id.value -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) ,cfg->emtc_config.pbch_repetitions_enable_r13.value #endif ); } -void config_sib1(int Mod_idP, int CC_idP, TDD_Config_t * tdd_ConfigP) +void config_sib1(int Mod_idP, int CC_idP, LTE_TDD_Config_t * tdd_ConfigP) { @@ -380,14 +380,14 @@ int power_off_dB[6] = { 78, 118, 140, 170, 188, 200 }; void config_sib2(int Mod_idP, int CC_idP, - RadioResourceConfigCommonSIB_t * radioResourceConfigCommonP, -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - RadioResourceConfigCommonSIB_t * radioResourceConfigCommon_BRP, + LTE_RadioResourceConfigCommonSIB_t * radioResourceConfigCommonP, +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + LTE_RadioResourceConfigCommonSIB_t * radioResourceConfigCommon_BRP, #endif - ARFCN_ValueEUTRA_t *ul_CArrierFreqP, + LTE_ARFCN_ValueEUTRA_t *ul_CArrierFreqP, long *ul_BandwidthP, - AdditionalSpectrumEmission_t *additionalSpectrumEmissionP, - struct MBSFN_SubframeConfigList *mbsfn_SubframeConfigListP) { + LTE_AdditionalSpectrumEmission_t *additionalSpectrumEmissionP, + struct LTE_MBSFN_SubframeConfigList *mbsfn_SubframeConfigListP) { nfapi_config_request_t *cfg = &RC.mac[Mod_idP]->config[CC_idP]; @@ -474,7 +474,7 @@ config_sib2(int Mod_idP, // how to enable/disable SRS? - if (radioResourceConfigCommonP->soundingRS_UL_ConfigCommon.present==SoundingRS_UL_ConfigCommon_PR_setup) { + if (radioResourceConfigCommonP->soundingRS_UL_ConfigCommon.present== LTE_SoundingRS_UL_ConfigCommon_PR_setup) { cfg->srs_config.bandwidth_configuration.value = radioResourceConfigCommonP->soundingRS_UL_ConfigCommon.choice.setup.srs_BandwidthConfig; cfg->srs_config.bandwidth_configuration.tl.tag = NFAPI_SRS_CONFIG_BANDWIDTH_CONFIGURATION_TAG; cfg->num_tlv++; @@ -497,7 +497,7 @@ config_sib2(int Mod_idP, cfg->num_tlv++; } -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) if (RC.mac[Mod_idP]->common_channels[CC_idP].mib->message.schedulingInfoSIB1_BR_r13 > 0) { AssertFatal(radioResourceConfigCommon_BRP != NULL, "radioResource rou is missing\n"); AssertFatal(radioResourceConfigCommon_BRP->ext4 != NULL, "ext4 is missing\n"); @@ -513,11 +513,11 @@ config_sib2(int Mod_idP, cfg->emtc_config.prach_catm_high_speed_flag.tl.tag = NFAPI_EMTC_CONFIG_PRACH_CATM_HIGH_SPEED_FLAG; cfg->num_tlv++; - struct PRACH_ConfigSIB_v1310 *ext4_prach = radioResourceConfigCommon_BRP->ext4->prach_ConfigCommon_v1310; + struct LTE_PRACH_ConfigSIB_v1310 *ext4_prach = radioResourceConfigCommon_BRP->ext4->prach_ConfigCommon_v1310; - PRACH_ParametersListCE_r13_t *prach_ParametersListCE_r13 = &ext4_prach->prach_ParametersListCE_r13; + LTE_PRACH_ParametersListCE_r13_t *prach_ParametersListCE_r13 = &ext4_prach->prach_ParametersListCE_r13; - PRACH_ParametersCE_r13_t *p; + LTE_PRACH_ParametersCE_r13_t *p; cfg->emtc_config.prach_ce_level_0_enable.value = 0; cfg->emtc_config.prach_ce_level_0_enable.tl.tag=NFAPI_EMTC_CONFIG_PRACH_CE_LEVEL_0_ENABLE_TAG; cfg->num_tlv++; @@ -664,18 +664,18 @@ config_sib2(int Mod_idP, cfg->num_tlv++; } - struct FreqHoppingParameters_r13 *ext4_freqHoppingParameters = radioResourceConfigCommonP->ext4->freqHoppingParameters_r13; + struct LTE_FreqHoppingParameters_r13 *ext4_freqHoppingParameters = radioResourceConfigCommonP->ext4->freqHoppingParameters_r13; if ((ext4_freqHoppingParameters) && (ext4_freqHoppingParameters->interval_ULHoppingConfigCommonModeA_r13)){ switch(ext4_freqHoppingParameters->interval_ULHoppingConfigCommonModeA_r13->present) { - case FreqHoppingParameters_r13__interval_ULHoppingConfigCommonModeA_r13_PR_NOTHING: /* No components present */ + case LTE_FreqHoppingParameters_r13__interval_ULHoppingConfigCommonModeA_r13_PR_NOTHING: /* No components present */ break; - case FreqHoppingParameters_r13__interval_ULHoppingConfigCommonModeA_r13_PR_interval_FDD_r13: + case LTE_FreqHoppingParameters_r13__interval_ULHoppingConfigCommonModeA_r13_PR_interval_FDD_r13: cfg->emtc_config.pucch_interval_ulhoppingconfigcommonmodea.value = ext4_freqHoppingParameters->interval_ULHoppingConfigCommonModeA_r13->choice.interval_FDD_r13; cfg->emtc_config.pucch_interval_ulhoppingconfigcommonmodea.tl.tag = NFAPI_EMTC_CONFIG_PUCCH_INTERVAL_ULHOPPINGCONFIGCOMMONMODEA_TAG; cfg->num_tlv++; break; - case FreqHoppingParameters_r13__interval_ULHoppingConfigCommonModeA_r13_PR_interval_TDD_r13: + case LTE_FreqHoppingParameters_r13__interval_ULHoppingConfigCommonModeA_r13_PR_interval_TDD_r13: cfg->emtc_config.pucch_interval_ulhoppingconfigcommonmodea.value = ext4_freqHoppingParameters->interval_ULHoppingConfigCommonModeA_r13->choice.interval_TDD_r13; cfg->emtc_config.pucch_interval_ulhoppingconfigcommonmodea.tl.tag = NFAPI_EMTC_CONFIG_PUCCH_INTERVAL_ULHOPPINGCONFIGCOMMONMODEA_TAG; cfg->num_tlv++; @@ -685,14 +685,14 @@ config_sib2(int Mod_idP, if ((ext4_freqHoppingParameters) && (ext4_freqHoppingParameters->interval_ULHoppingConfigCommonModeB_r13)){ switch(ext4_freqHoppingParameters->interval_ULHoppingConfigCommonModeB_r13->present) { - case FreqHoppingParameters_r13__interval_ULHoppingConfigCommonModeB_r13_PR_NOTHING: /* No components present */ + case LTE_FreqHoppingParameters_r13__interval_ULHoppingConfigCommonModeB_r13_PR_NOTHING: /* No components present */ break; - case FreqHoppingParameters_r13__interval_ULHoppingConfigCommonModeB_r13_PR_interval_FDD_r13: + case LTE_FreqHoppingParameters_r13__interval_ULHoppingConfigCommonModeB_r13_PR_interval_FDD_r13: cfg->emtc_config.pucch_interval_ulhoppingconfigcommonmodeb.value = ext4_freqHoppingParameters->interval_ULHoppingConfigCommonModeB_r13->choice.interval_FDD_r13; cfg->emtc_config.pucch_interval_ulhoppingconfigcommonmodeb.tl.tag = NFAPI_EMTC_CONFIG_PUCCH_INTERVAL_ULHOPPINGCONFIGCOMMONMODEB_TAG; cfg->num_tlv++; break; - case FreqHoppingParameters_r13__interval_ULHoppingConfigCommonModeB_r13_PR_interval_TDD_r13: + case LTE_FreqHoppingParameters_r13__interval_ULHoppingConfigCommonModeB_r13_PR_interval_TDD_r13: cfg->emtc_config.pucch_interval_ulhoppingconfigcommonmodeb.value = ext4_freqHoppingParameters->interval_ULHoppingConfigCommonModeB_r13->choice.interval_TDD_r13; cfg->emtc_config.pucch_interval_ulhoppingconfigcommonmodeb.tl.tag = NFAPI_EMTC_CONFIG_PUCCH_INTERVAL_ULHOPPINGCONFIGCOMMONMODEB_TAG; cfg->num_tlv++; @@ -708,7 +708,7 @@ void config_dedicated(int Mod_idP, int CC_idP, uint16_t rnti, - struct PhysicalConfigDedicated *physicalConfigDedicated) + struct LTE_PhysicalConfigDedicated *physicalConfigDedicated) { } @@ -716,7 +716,7 @@ config_dedicated(int Mod_idP, void config_dedicated_scell(int Mod_idP, uint16_t rnti, - SCellToAddMod_r10_t * sCellToAddMod_r10) + LTE_SCellToAddMod_r10_t * sCellToAddMod_r10) { } @@ -728,45 +728,45 @@ rrc_mac_config_req_eNB(module_id_t Mod_idP, int physCellId, int p_eNB, int Ncp, int eutra_band, uint32_t dl_CarrierFreq, -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) int pbch_repetition, #endif rnti_t rntiP, - BCCH_BCH_Message_t * mib, - RadioResourceConfigCommonSIB_t * + LTE_BCCH_BCH_Message_t * mib, + LTE_RadioResourceConfigCommonSIB_t * radioResourceConfigCommon, -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - RadioResourceConfigCommonSIB_t * +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + LTE_RadioResourceConfigCommonSIB_t * radioResourceConfigCommon_BR, #endif - struct PhysicalConfigDedicated + struct LTE_PhysicalConfigDedicated *physicalConfigDedicated, -#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) - SCellToAddMod_r10_t * sCellToAddMod_r10, - //struct PhysicalConfigDedicatedSCell_r10 *physicalConfigDedicatedSCell_r10, +#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) + LTE_SCellToAddMod_r10_t * sCellToAddMod_r10, + //struct LTE_PhysicalConfigDedicatedSCell_r10 *physicalConfigDedicatedSCell_r10, #endif - MeasObjectToAddMod_t ** measObj, - MAC_MainConfig_t * mac_MainConfig, + LTE_MeasObjectToAddMod_t ** measObj, + LTE_MAC_MainConfig_t * mac_MainConfig, long logicalChannelIdentity, - LogicalChannelConfig_t * logicalChannelConfig, - MeasGapConfig_t * measGapConfig, - TDD_Config_t * tdd_Config, - MobilityControlInfo_t * mobilityControlInfo, - SchedulingInfoList_t * schedulingInfoList, + LTE_LogicalChannelConfig_t * logicalChannelConfig, + LTE_MeasGapConfig_t * measGapConfig, + LTE_TDD_Config_t * tdd_Config, + LTE_MobilityControlInfo_t * mobilityControlInfo, + LTE_SchedulingInfoList_t * schedulingInfoList, uint32_t ul_CarrierFreq, long *ul_Bandwidth, - AdditionalSpectrumEmission_t * + LTE_AdditionalSpectrumEmission_t * additionalSpectrumEmission, - struct MBSFN_SubframeConfigList + struct LTE_MBSFN_SubframeConfigList *mbsfn_SubframeConfigList -#if (RRC_VERSION >= MAKE_VERSION(9, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) , uint8_t MBMS_Flag, - MBSFN_AreaInfoList_r9_t * mbsfn_AreaInfoList, - PMCH_InfoList_r9_t * pmch_InfoList + LTE_MBSFN_AreaInfoList_r9_t * mbsfn_AreaInfoList, + LTE_PMCH_InfoList_r9_t * pmch_InfoList #endif -#if (RRC_VERSION >= MAKE_VERSION(13, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(13, 0, 0)) , - SystemInformationBlockType1_v1310_IEs_t * + LTE_SystemInformationBlockType1_v1310_IEs_t * sib1_v13ext #endif ) { @@ -815,7 +815,7 @@ rrc_mac_config_req_eNB(module_id_t Mod_idP, p_eNB, dl_CarrierFreq, ul_CarrierFreq -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) , pbch_repetition #endif ); @@ -827,7 +827,7 @@ rrc_mac_config_req_eNB(module_id_t Mod_idP, RC.mac[Mod_idP]->common_channels[CC_idP].schedulingInfoList = schedulingInfoList; config_sib1(Mod_idP,CC_idP,tdd_Config); } -#if (RRC_VERSION >= MAKE_VERSION(13, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(13, 0, 0)) if (sib1_v13ext != NULL) { RC.mac[Mod_idP]->common_channels[CC_idP].sib1_v13ext = sib1_v13ext; } @@ -886,7 +886,7 @@ rrc_mac_config_req_eNB(module_id_t Mod_idP, dl_Bandwidth; config_sib2(Mod_idP, CC_idP, radioResourceConfigCommon, -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) radioResourceConfigCommon_BR, #endif NULL, ul_Bandwidth, additionalSpectrumEmission, @@ -933,7 +933,7 @@ rrc_mac_config_req_eNB(module_id_t Mod_idP, } -#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) if (sCellToAddMod_r10 != NULL) { UE_id = find_UE_id(Mod_idP, rntiP); @@ -966,11 +966,11 @@ rrc_mac_config_req_eNB(module_id_t Mod_idP, subframeAllocation.choice.oneFrame.buf[0]); } -#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) RC.mac[Mod_idP]->common_channels[0].MBMS_flag = MBMS_Flag; #endif } -#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) if (mbsfn_AreaInfoList != NULL) { // One eNB could be part of multiple mbsfn syc area, this could change over time so reset each time diff --git a/openair2/LAYER2/MAC/config_ue.c b/openair2/LAYER2/MAC/config_ue.c index c38c32a4de..bec39aa8dc 100644 --- a/openair2/LAYER2/MAC/config_ue.c +++ b/openair2/LAYER2/MAC/config_ue.c @@ -33,16 +33,16 @@ #include "COMMON/platform_types.h" #include "COMMON/platform_constants.h" #include "SCHED_UE/sched_UE.h" -#include "SystemInformationBlockType2.h" +#include "LTE_SystemInformationBlockType2.h" //#include "RadioResourceConfigCommonSIB.h" -#include "RadioResourceConfigDedicated.h" -#if (RRC_VERSION >= MAKE_VERSION(13, 0, 0)) -#include "PRACH-ConfigSIB-v1310.h" +#include "LTE_RadioResourceConfigDedicated.h" +#if (LTE_RRC_VERSION >= MAKE_VERSION(13, 0, 0)) +#include "LTE_PRACH-ConfigSIB-v1310.h" #endif -#include "MeasGapConfig.h" -#include "MeasObjectToAddModList.h" -#include "TDD-Config.h" -#include "MAC-MainConfig.h" +#include "LTE_MeasGapConfig.h" +#include "LTE_MeasObjectToAddModList.h" +#include "LTE_TDD-Config.h" +#include "LTE_MAC-MainConfig.h" #include "mac.h" #include "mac_proto.h" #include "mac_extern.h" @@ -51,11 +51,11 @@ #include "PHY/INIT/phy_init.h" #include "common/ran_context.h" -#if (RRC_VERSION >= MAKE_VERSION(9, 0, 0)) -#include "MBSFN-AreaInfoList-r9.h" -#include "MBSFN-AreaInfo-r9.h" -#include "MBSFN-SubframeConfigList.h" -#include "PMCH-InfoList-r9.h" +#if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) +#include "LTE_MBSFN-AreaInfoList-r9.h" +#include "LTE_MBSFN-AreaInfo-r9.h" +#include "LTE_MBSFN-SubframeConfigList.h" +#include "LTE_PMCH-InfoList-r9.h" #endif extern void mac_init_cell_params(int Mod_idP,int CC_idP); @@ -107,38 +107,38 @@ int rrc_mac_config_req_ue(module_id_t Mod_idP, int CC_idP, uint8_t eNB_index, - RadioResourceConfigCommonSIB_t * + LTE_RadioResourceConfigCommonSIB_t * radioResourceConfigCommon, - struct PhysicalConfigDedicated + struct LTE_PhysicalConfigDedicated *physicalConfigDedicated, -#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) - SCellToAddMod_r10_t * sCellToAddMod_r10, +#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) + LTE_SCellToAddMod_r10_t * sCellToAddMod_r10, //struct PhysicalConfigDedicatedSCell_r10 *physicalConfigDedicatedSCell_r10, #endif - MeasObjectToAddMod_t ** measObj, - MAC_MainConfig_t * mac_MainConfig, + LTE_MeasObjectToAddMod_t ** measObj, + LTE_MAC_MainConfig_t * mac_MainConfig, long logicalChannelIdentity, - LogicalChannelConfig_t * logicalChannelConfig, - MeasGapConfig_t * measGapConfig, - TDD_Config_t * tdd_Config, - MobilityControlInfo_t * mobilityControlInfo, + LTE_LogicalChannelConfig_t * logicalChannelConfig, + LTE_MeasGapConfig_t * measGapConfig, + LTE_TDD_Config_t * tdd_Config, + LTE_MobilityControlInfo_t * mobilityControlInfo, uint8_t * SIwindowsize, uint16_t * SIperiod, - ARFCN_ValueEUTRA_t * ul_CarrierFreq, + LTE_ARFCN_ValueEUTRA_t * ul_CarrierFreq, long *ul_Bandwidth, - AdditionalSpectrumEmission_t * + LTE_AdditionalSpectrumEmission_t * additionalSpectrumEmission, - struct MBSFN_SubframeConfigList + struct LTE_MBSFN_SubframeConfigList *mbsfn_SubframeConfigList -#if (RRC_VERSION >= MAKE_VERSION(9, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) , uint8_t MBMS_Flag, - MBSFN_AreaInfoList_r9_t * mbsfn_AreaInfoList, - PMCH_InfoList_r9_t * pmch_InfoList + LTE_MBSFN_AreaInfoList_r9_t * mbsfn_AreaInfoList, + LTE_PMCH_InfoList_r9_t * pmch_InfoList #endif #ifdef CBA , uint8_t num_active_cba_groups, uint16_t cba_rnti #endif -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) ,config_action_t config_action ,const uint32_t * const sourceL2Id ,const uint32_t * const destinationL2Id @@ -219,11 +219,11 @@ rrc_mac_config_req_ue(module_id_t Mod_idP, mac_MainConfig->ul_SCH_Config->periodicBSR_Timer; } else { UE_mac_inst[Mod_idP].scheduling_info.periodicBSR_Timer = -#if (RRC_VERSION < MAKE_VERSION(12, 0, 0)) +#if (LTE_RRC_VERSION < MAKE_VERSION(12, 0, 0)) (uint16_t) - MAC_MainConfig__ul_SCH_Config__periodicBSR_Timer_infinity + LTE_MAC_MainConfig__ul_SCH_Config__periodicBSR_Timer_infinity #else - (uint16_t) PeriodicBSR_Timer_r12_infinity; + (uint16_t) LTE_PeriodicBSR_Timer_r12_infinity; #endif ; } @@ -234,7 +234,7 @@ rrc_mac_config_req_ue(module_id_t Mod_idP, } else { UE_mac_inst[Mod_idP].scheduling_info.maxHARQ_Tx = (uint16_t) - MAC_MainConfig__ul_SCH_Config__maxHARQ_Tx_n5; + LTE_MAC_MainConfig__ul_SCH_Config__maxHARQ_Tx_n5; } if(nfapi_mode!=3) phy_config_harq_ue(Mod_idP, 0, eNB_index, @@ -246,17 +246,17 @@ rrc_mac_config_req_ue(module_id_t Mod_idP, (uint16_t) mac_MainConfig->ul_SCH_Config-> retxBSR_Timer; } else { -#if (RRC_VERSION < MAKE_VERSION(12, 0, 0)) +#if (LTE_RRC_VERSION < MAKE_VERSION(12, 0, 0)) UE_mac_inst[Mod_idP].scheduling_info.retxBSR_Timer = (uint16_t) - MAC_MainConfig__ul_SCH_Config__retxBSR_Timer_sf2560; + LTE_MAC_MainConfig__ul_SCH_Config__retxBSR_Timer_sf2560; #else UE_mac_inst[Mod_idP].scheduling_info.retxBSR_Timer = - (uint16_t) RetxBSR_Timer_r12_sf2560; + (uint16_t) LTE_RetxBSR_Timer_r12_sf2560; #endif } } -#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) if (mac_MainConfig->ext1 && mac_MainConfig->ext1->sr_ProhibitTimer_r9) { @@ -326,13 +326,13 @@ rrc_mac_config_req_ue(module_id_t Mod_idP, } else { UE_mac_inst[Mod_idP].PHR_reconfigured = 0; UE_mac_inst[Mod_idP].PHR_state = - MAC_MainConfig__phr_Config_PR_setup; + LTE_MAC_MainConfig__phr_Config_PR_setup; UE_mac_inst[Mod_idP].scheduling_info.periodicPHR_Timer = - MAC_MainConfig__phr_Config__setup__periodicPHR_Timer_sf20; + LTE_MAC_MainConfig__phr_Config__setup__periodicPHR_Timer_sf20; UE_mac_inst[Mod_idP].scheduling_info.prohibitPHR_Timer = - MAC_MainConfig__phr_Config__setup__prohibitPHR_Timer_sf20; + LTE_MAC_MainConfig__phr_Config__setup__prohibitPHR_Timer_sf20; UE_mac_inst[Mod_idP].scheduling_info.PathlossChange = - MAC_MainConfig__phr_Config__setup__dl_PathlossChange_dB1; + LTE_MAC_MainConfig__phr_Config__setup__dl_PathlossChange_dB1; } UE_mac_inst[Mod_idP].scheduling_info.periodicPHR_SF = @@ -362,7 +362,7 @@ rrc_mac_config_req_ue(module_id_t Mod_idP, physicalConfigDedicated); UE_mac_inst[Mod_idP].physicalConfigDedicated = physicalConfigDedicated; // for SR proc } -#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) if (sCellToAddMod_r10 != NULL) { @@ -410,14 +410,14 @@ rrc_mac_config_req_ue(module_id_t Mod_idP, rach_ConfigCommon, (void *) mobilityControlInfo-> radioResourceConfigCommon.rach_ConfigCommon, - sizeof(RACH_ConfigCommon_t)); + sizeof(LTE_RACH_ConfigCommon_t)); } memcpy((void *) &UE_mac_inst[Mod_idP]. radioResourceConfigCommon->prach_Config.prach_ConfigInfo, (void *) mobilityControlInfo-> radioResourceConfigCommon.prach_Config.prach_ConfigInfo, - sizeof(PRACH_ConfigInfo_t)); + sizeof(LTE_PRACH_ConfigInfo_t)); UE_mac_inst[Mod_idP].radioResourceConfigCommon-> prach_Config.rootSequenceIndex = mobilityControlInfo->radioResourceConfigCommon. @@ -430,19 +430,19 @@ rrc_mac_config_req_ue(module_id_t Mod_idP, pdsch_ConfigCommon, (void *) mobilityControlInfo-> radioResourceConfigCommon.pdsch_ConfigCommon, - sizeof(PDSCH_ConfigCommon_t)); + sizeof(LTE_PDSCH_ConfigCommon_t)); } // not a pointer: mobilityControlInfo->radioResourceConfigCommon.pusch_ConfigCommon memcpy((void *) &UE_mac_inst[Mod_idP]. radioResourceConfigCommon->pusch_ConfigCommon, (void *) &mobilityControlInfo-> radioResourceConfigCommon.pusch_ConfigCommon, - sizeof(PUSCH_ConfigCommon_t)); + sizeof(LTE_PUSCH_ConfigCommon_t)); if (mobilityControlInfo->radioResourceConfigCommon.phich_Config) { /* memcpy((void *)&UE_mac_inst[Mod_idP].radioResourceConfigCommon->phich_Config, (void *)mobilityControlInfo->radioResourceConfigCommon.phich_Config, - sizeof(PHICH_Config_t)); */ + sizeof(LTE_PHICH_Config_t)); */ } if (mobilityControlInfo->radioResourceConfigCommon. @@ -452,7 +452,7 @@ rrc_mac_config_req_ue(module_id_t Mod_idP, pucch_ConfigCommon, (void *) mobilityControlInfo-> radioResourceConfigCommon.pucch_ConfigCommon, - sizeof(PUCCH_ConfigCommon_t)); + sizeof(LTE_PUCCH_ConfigCommon_t)); } if (mobilityControlInfo-> @@ -462,7 +462,7 @@ rrc_mac_config_req_ue(module_id_t Mod_idP, soundingRS_UL_ConfigCommon, (void *) mobilityControlInfo-> radioResourceConfigCommon.soundingRS_UL_ConfigCommon, - sizeof(SoundingRS_UL_ConfigCommon_t)); + sizeof(LTE_SoundingRS_UL_ConfigCommon_t)); } if (mobilityControlInfo-> @@ -472,7 +472,7 @@ rrc_mac_config_req_ue(module_id_t Mod_idP, uplinkPowerControlCommon, (void *) mobilityControlInfo-> radioResourceConfigCommon.uplinkPowerControlCommon, - sizeof(UplinkPowerControlCommon_t)); + sizeof(LTE_UplinkPowerControlCommon_t)); } //configure antennaInfoCommon somewhere here.. if (mobilityControlInfo->radioResourceConfigCommon.p_Max) { @@ -491,7 +491,7 @@ rrc_mac_config_req_ue(module_id_t Mod_idP, ul_CyclicPrefixLength, (void *) mobilityControlInfo-> radioResourceConfigCommon.ul_CyclicPrefixLength, - sizeof(UL_CyclicPrefixLength_t)); + sizeof(LTE_UL_CyclicPrefixLength_t)); } // store the previous rnti in case of failure, and set thenew rnti UE_mac_inst[Mod_idP].crnti_before_ho = UE_mac_inst[Mod_idP].crnti; @@ -532,7 +532,7 @@ rrc_mac_config_req_ue(module_id_t Mod_idP, // UE_mac_inst[Mod_idP].mbsfn_SubframeConfig[i]->subframeAllocation.choice.oneFrame.buf[0]); } } -#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) if (mbsfn_AreaInfoList != NULL) { LOG_I(MAC, "[UE %d][CONFIG] Received %d MBSFN Area Info\n", @@ -590,7 +590,7 @@ rrc_mac_config_req_ue(module_id_t Mod_idP, VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME (VCD_SIGNAL_DUMPER_FUNCTIONS_RRC_MAC_CONFIG, VCD_FUNCTION_OUT); //for D2D - #if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) + #if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) switch (config_action) { case CONFIG_ACTION_ADD: if (sourceL2Id){ diff --git a/openair2/LAYER2/MAC/eNB_scheduler.c b/openair2/LAYER2/MAC/eNB_scheduler.c index 4dbf3cf36f..866855c456 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler.c +++ b/openair2/LAYER2/MAC/eNB_scheduler.c @@ -79,8 +79,8 @@ schedule_SRS(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP) nfapi_ul_config_request_body_t *ul_req; int CC_id, UE_id; COMMON_channels_t *cc = RC.mac[module_idP]->common_channels; - SoundingRS_UL_ConfigCommon_t *soundingRS_UL_ConfigCommon; - struct SoundingRS_UL_ConfigDedicated *soundingRS_UL_ConfigDedicated; + LTE_SoundingRS_UL_ConfigCommon_t *soundingRS_UL_ConfigCommon; + struct LTE_SoundingRS_UL_ConfigDedicated *soundingRS_UL_ConfigDedicated; uint8_t TSFC; uint16_t deltaTSFC; // bitmap uint8_t srs_SubframeConfig; @@ -119,7 +119,7 @@ schedule_SRS(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP) UE_id); if ((soundingRS_UL_ConfigDedicated = UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->soundingRS_UL_ConfigDedicated) != NULL) { - if (soundingRS_UL_ConfigDedicated->present == SoundingRS_UL_ConfigDedicated_PR_setup) { + if (soundingRS_UL_ConfigDedicated->present == LTE_SoundingRS_UL_ConfigDedicated_PR_setup) { get_srs_pos(&cc[CC_id], soundingRS_UL_ConfigDedicated->choice. setup.srs_ConfigIndex, @@ -162,7 +162,7 @@ schedule_CSI(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP) COMMON_channels_t *cc; nfapi_ul_config_request_body_t *ul_req; int CC_id, UE_id; - struct CQI_ReportPeriodic *cqi_ReportPeriodic; + struct LTE_CQI_ReportPeriodic *cqi_ReportPeriodic; uint16_t Npd, N_OFFSET_CQI; int H; @@ -185,7 +185,7 @@ schedule_CSI(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP) if (UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->cqi_ReportConfig) { if ((cqi_ReportPeriodic = UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->cqi_ReportConfig->cqi_ReportPeriodic) != NULL - && (cqi_ReportPeriodic->present != CQI_ReportPeriodic_PR_release)) { + && (cqi_ReportPeriodic->present != LTE_CQI_ReportPeriodic_PR_release)) { //Rel8 Periodic CQI/PMI/RI reporting get_csi_params(cc, cqi_ReportPeriodic, &Npd, @@ -209,7 +209,7 @@ schedule_CSI(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP) ul_req->number_of_pdus++; ul_req->tl.tag = NFAPI_UL_CONFIG_REQUEST_BODY_TAG; -#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) // PUT rel10-13 UCI options here #endif } else @@ -245,7 +245,7 @@ schedule_SR(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP) nfapi_ul_config_request_body_t *ul_req_body; int CC_id; int UE_id; - SchedulingRequestConfig_t *SRconfig; + LTE_SchedulingRequestConfig_t *SRconfig; int skip_ue; int is_harq; nfapi_ul_config_sr_information sr; @@ -269,7 +269,7 @@ schedule_SR(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP) UE_id); if ((SRconfig = UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->schedulingRequestConfig) != NULL) { - if (SRconfig->present == SchedulingRequestConfig_PR_setup) { + if (SRconfig->present == LTE_SchedulingRequestConfig_PR_setup) { if (SRconfig->choice.setup.sr_ConfigIndex <= 4) { // 5 ms SR period if ((subframeP % 5) != SRconfig->choice.setup.sr_ConfigIndex) continue; } else if (SRconfig->choice.setup.sr_ConfigIndex <= 14) { // 10 ms SR period @@ -312,7 +312,7 @@ schedule_SR(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP) LOG_D(MAC,"Frame %d, Subframe %d : Scheduling SR for UE %d/%x is_harq:%d\n",frameP,subframeP,UE_id,UE_list->UE_template[CC_id][UE_id].rnti, is_harq); // check Rel10 or Rel8 SR -#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) if ((UE_list-> UE_template[CC_id][UE_id].physicalConfigDedicated->ext2) && (UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->ext2->schedulingRequestConfig_v1020) && (UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->ext2->schedulingRequestConfig_v1020)) { @@ -517,7 +517,7 @@ eNB_dlsch_ulsch_scheduler(module_id_t module_idP, frame_t frameP, memset(cc[CC_id].vrb_map_UL, 0, 100); -#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) cc[CC_id].mcch_active = 0; #endif @@ -628,7 +628,7 @@ eNB_dlsch_ulsch_scheduler(module_id_t module_idP, frame_t frameP, rrc_rx_tx(&ctxt, CC_id); #endif -#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { if (cc[CC_id].MBMS_flag > 0) { diff --git a/openair2/LAYER2/MAC/eNB_scheduler_RA.c b/openair2/LAYER2/MAC/eNB_scheduler_RA.c index b637a92a96..1287b90585 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_RA.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_RA.c @@ -120,7 +120,7 @@ add_msg3(module_id_t module_idP, int CC_id, RA_t * ra, frame_t frameP, AssertFatal(ra->state != IDLE, "RA is not active for RA %X\n", ra->rnti); -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) if (ra->rach_resource_type > 0) { LOG_D(MAC, "[eNB %d][RAPROC] Frame %d, Subframe %d : CC_id %d CE level %d is active, Msg3 in (%d,%d)\n", @@ -272,16 +272,16 @@ generate_Msg2(module_id_t module_idP, int CC_idP, frame_t frameP, dl_config_pdu = &dl_req->dl_config_pdu_list[dl_req->number_pdu]; N_RB_DL = to_prb(cc[CC_idP].mib->message.dl_Bandwidth); -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) int rmax = 0; int rep = 0; int reps = 0; int num_nb = 0; first_rb = 0; - struct PRACH_ConfigSIB_v1310 *ext4_prach; - PRACH_ParametersListCE_r13_t *prach_ParametersListCE_r13; - PRACH_ParametersCE_r13_t *p[4] = { NULL, NULL, NULL, NULL }; + struct LTE_PRACH_ConfigSIB_v1310 *ext4_prach; + LTE_PRACH_ParametersListCE_r13_t *prach_ParametersListCE_r13; + LTE_PRACH_ParametersCE_r13_t *p[4] = { NULL, NULL, NULL, NULL }; uint16_t absSF = (10 * frameP) + subframeP; uint16_t absSF_Msg2 = (10 * ra->Msg2_frame) + ra->Msg2_subframe; @@ -631,18 +631,18 @@ generate_Msg4(module_id_t module_idP, int CC_idP, frame_t frameP, uint8_t offset; -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) int rmax = 0; int rep = 0; int reps = 0; first_rb = 0; - struct PRACH_ConfigSIB_v1310 *ext4_prach; - struct PUCCH_ConfigCommon_v1310 *ext4_pucch; - PRACH_ParametersListCE_r13_t *prach_ParametersListCE_r13; - struct N1PUCCH_AN_InfoList_r13 *pucch_N1PUCCH_AN_InfoList_r13; - PRACH_ParametersCE_r13_t *p[4] = { NULL, NULL, NULL, NULL }; + struct LTE_PRACH_ConfigSIB_v1310 *ext4_prach; + struct LTE_PUCCH_ConfigCommon_v1310 *ext4_pucch; + LTE_PRACH_ParametersListCE_r13_t *prach_ParametersListCE_r13; + struct LTE_N1PUCCH_AN_InfoList_r13 *pucch_N1PUCCH_AN_InfoList_r13; + LTE_PRACH_ParametersCE_r13_t *p[4] = { NULL, NULL, NULL, NULL }; int pucchreps[4] = { 1, 1, 1, 1 }; int n1pucchan[4] = { 0, 0, 0, 0 }; @@ -722,7 +722,7 @@ generate_Msg4(module_id_t module_idP, int CC_idP, frame_t frameP, module_idP, CC_idP, frameP, subframeP, UE_id, rrc_sdu_length);*/ -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) if (ra->rach_resource_type > 0) { // Generate DCI + repetitions first @@ -1232,7 +1232,7 @@ check_Msg4_retransmission(module_id_t module_idP, int CC_idP, int round; /* - #if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) COMMON_channels_t *cc = mac->common_channels; int rmax = 0; @@ -1285,7 +1285,7 @@ check_Msg4_retransmission(module_id_t module_idP, int CC_idP, if (round != 8) { -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) if (ra->rach_resource_type > 0) { AssertFatal(1 == 0, "Msg4 Retransmissions not handled yet for BL/CE UEs\n"); @@ -1442,7 +1442,7 @@ initiate_ra_proc(module_id_t module_idP, sub_frame_t subframeP, uint16_t preamble_index, int16_t timing_offset, uint16_t ra_rnti -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) , uint8_t rach_resource_type #endif ) @@ -1453,10 +1453,10 @@ initiate_ra_proc(module_id_t module_idP, COMMON_channels_t *cc = &RC.mac[module_idP]->common_channels[CC_id]; RA_t *ra = &cc->ra[0]; -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - struct PRACH_ConfigSIB_v1310 *ext4_prach = NULL; - PRACH_ParametersListCE_r13_t *prach_ParametersListCE_r13 = NULL; + struct LTE_PRACH_ConfigSIB_v1310 *ext4_prach = NULL; + LTE_PRACH_ParametersListCE_r13_t *prach_ParametersListCE_r13 = NULL; static uint8_t failure_cnt = 0; @@ -1466,12 +1466,12 @@ initiate_ra_proc(module_id_t module_idP, prach_ParametersListCE_r13 = &ext4_prach->prach_ParametersListCE_r13; } -#endif /* #if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) */ +#endif /* #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) */ LOG_D(MAC, "[eNB %d][RAPROC] CC_id %d Frame %d, Subframe %d Initiating RA procedure for preamble index %d\n", module_idP, CC_id, frameP, subframeP, preamble_index); -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) LOG_D(MAC, "[eNB %d][RAPROC] CC_id %d Frame %d, Subframe %d PRACH resource type %d\n", module_idP, CC_id, frameP, subframeP, rach_resource_type); @@ -1481,7 +1481,7 @@ initiate_ra_proc(module_id_t module_idP, uint16_t msg2_subframe = subframeP; int offset; -#if (RRC_VERSION >= MAKE_VERSION(13, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(13, 0, 0)) if (prach_ParametersListCE_r13 && prach_ParametersListCE_r13->list.count < rach_resource_type) { @@ -1492,7 +1492,7 @@ initiate_ra_proc(module_id_t module_idP, return; } -#endif /* #if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) */ +#endif /* #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) */ VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_INITIATE_RA_PROC, 1); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_INITIATE_RA_PROC, 0); @@ -1505,7 +1505,7 @@ initiate_ra_proc(module_id_t module_idP, ra[i].state = MSG2; ra[i].timing_offset = timing_offset; ra[i].preamble_subframe = subframeP; -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) ra[i].rach_resource_type = rach_resource_type; ra[i].msg2_mpdcch_repetition_cnt = 0; ra[i].msg4_mpdcch_repetition_cnt = 0; diff --git a/openair2/LAYER2/MAC/eNB_scheduler_bch.c b/openair2/LAYER2/MAC/eNB_scheduler_bch.c index b2b59691f8..370b2bedb0 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_bch.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_bch.c @@ -59,7 +59,7 @@ extern RAN_CONTEXT_t RC; // NEED TO ADD schedule_SI_BR for SIB1_BR and SIB23_BR // CCE_allocation_infeasible to be done for EPDCCH/MPDCCH -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) #define size_Sj25 2 int Sj25[size_Sj25] = { 0, 3 }; @@ -301,8 +301,8 @@ schedule_SIB1_BR(module_id_t module_idP, } } -int si_WindowLength_BR_r13tab[SystemInformationBlockType1_v1310_IEs__bandwidthReducedAccessRelatedInfo_r13__si_WindowLength_BR_r13_spare] = { 20, 40, 60, 80, 120, 160, 200 }; -int si_TBS_r13tab[SchedulingInfo_BR_r13__si_TBS_r13_b936 + 1] = { 152, 208, 256, 328, 408, 504, 600, 712, 808, 936 }; +int si_WindowLength_BR_r13tab[LTE_SystemInformationBlockType1_v1310_IEs__bandwidthReducedAccessRelatedInfo_r13__si_WindowLength_BR_r13_spare] = { 20, 40, 60, 80, 120, 160, 200 }; +int si_TBS_r13tab[LTE_SchedulingInfo_BR_r13__si_TBS_r13_b936 + 1] = { 152, 208, 256, 328, 408, 504, 600, 712, 808, 936 }; //------------------------------------------------------------------------------ void @@ -340,31 +340,31 @@ schedule_SI_BR(module_id_t module_idP, frame_t frameP, AssertFatal(cc->sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13 != NULL, "sib_v13ext->bandwidthReducedAccessRelatedInfo_r13 is null\n"); - SchedulingInfoList_BR_r13_t *schedulingInfoList_BR_r13 = cc->sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13->schedulingInfoList_BR_r13; + LTE_SchedulingInfoList_BR_r13_t *schedulingInfoList_BR_r13 = cc->sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13->schedulingInfoList_BR_r13; AssertFatal(schedulingInfoList_BR_r13 != NULL, "sib_v13ext->schedulingInfoList_BR_r13 is null\n"); - SchedulingInfoList_t *schedulingInfoList = cc->schedulingInfoList; + LTE_SchedulingInfoList_t *schedulingInfoList = cc->schedulingInfoList; AssertFatal(schedulingInfoList_BR_r13->list.count == schedulingInfoList->list.count, "schedulingInfolist_BR.r13->list.count %d != schedulingInfoList.list.count %d\n", schedulingInfoList_BR_r13->list.count, schedulingInfoList->list.count); - AssertFatal(cc->sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13->si_WindowLength_BR_r13<=SystemInformationBlockType1_v1310_IEs__bandwidthReducedAccessRelatedInfo_r13__si_WindowLength_BR_r13_ms200, + AssertFatal(cc->sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13->si_WindowLength_BR_r13<=LTE_SystemInformationBlockType1_v1310_IEs__bandwidthReducedAccessRelatedInfo_r13__si_WindowLength_BR_r13_ms200, "si_WindowLength_BR_r13 %d > %d\n", (int) cc->sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13->si_WindowLength_BR_r13, - SystemInformationBlockType1_v1310_IEs__bandwidthReducedAccessRelatedInfo_r13__si_WindowLength_BR_r13_ms200); + LTE_SystemInformationBlockType1_v1310_IEs__bandwidthReducedAccessRelatedInfo_r13__si_WindowLength_BR_r13_ms200); // check that SI frequency-hopping is disabled - AssertFatal(cc->sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13->si_HoppingConfigCommon_r13 == SystemInformationBlockType1_v1310_IEs__bandwidthReducedAccessRelatedInfo_r13__si_HoppingConfigCommon_r13_off, + AssertFatal(cc->sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13->si_HoppingConfigCommon_r13 == LTE_SystemInformationBlockType1_v1310_IEs__bandwidthReducedAccessRelatedInfo_r13__si_HoppingConfigCommon_r13_off, "Deactivate SI_HoppingConfigCommon_r13 in configuration file, not supported for now\n"); long si_WindowLength_BR_r13 = si_WindowLength_BR_r13tab[cc->sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13->si_WindowLength_BR_r13]; long si_RepetitionPattern_r13 = cc->sib1_v13ext->bandwidthReducedAccessRelatedInfo_r13->si_RepetitionPattern_r13; - AssertFatal(si_RepetitionPattern_r13<=SystemInformationBlockType1_v1310_IEs__bandwidthReducedAccessRelatedInfo_r13__si_RepetitionPattern_r13_every8thRF, + AssertFatal(si_RepetitionPattern_r13<=LTE_SystemInformationBlockType1_v1310_IEs__bandwidthReducedAccessRelatedInfo_r13__si_RepetitionPattern_r13_every8thRF, "si_RepetitionPattern_r13 %d > %d\n", (int) si_RepetitionPattern_r13, - SystemInformationBlockType1_v1310_IEs__bandwidthReducedAccessRelatedInfo_r13__si_RepetitionPattern_r13_every8thRF); + LTE_SystemInformationBlockType1_v1310_IEs__bandwidthReducedAccessRelatedInfo_r13__si_RepetitionPattern_r13_every8thRF); // cycle through SIB list for (i = 0; i < schedulingInfoList_BR_r13->list.count; i++) { @@ -533,7 +533,7 @@ schedule_mib(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP) LOG_D(MAC, "Frame %d, subframe %d: Adding BCH PDU in position %d (length %d)\n", frameP, subframeP, dl_req->number_pdu, mib_sdu_length); if ((frameP & 1023) < 40) -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) LOG_D(MAC, "[eNB %d] Frame %d : MIB->BCH CC_id %d, Received %d bytes (cc->mib->message.schedulingInfoSIB1_BR_r13 %d)\n", module_idP, frameP, CC_id, mib_sdu_length, @@ -789,7 +789,7 @@ schedule_SI(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP) } } } -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) schedule_SIB1_BR(module_idP, frameP, subframeP); schedule_SI_BR(module_idP, frameP, subframeP); #endif diff --git a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c index d4f7c04d03..6175005b44 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c @@ -866,7 +866,7 @@ schedule_ue_spec(module_id_t module_idP, int slice_idxP, if (TBS - ta_len - header_length_total - sdu_length_total - 3 > 0) { rlc_status = mac_rlc_status_ind(module_idP, rnti, module_idP, frameP, subframeP, ENB_FLAG_YES, MBMS_FLAG_NO, DCCH, TBS - ta_len - header_length_total - sdu_length_total - 3 -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) ,0, 0 #endif ); @@ -881,7 +881,7 @@ schedule_ue_spec(module_id_t module_idP, int slice_idxP, sdu_lengths[0] = mac_rlc_data_req(module_idP, rnti, module_idP, frameP, ENB_FLAG_YES, MBMS_FLAG_NO, DCCH, TBS, //not used (char *)&dlsch_buffer[0] -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) ,0, 0 #endif ); @@ -975,7 +975,7 @@ schedule_ue_spec(module_id_t module_idP, int slice_idxP, if (TBS - ta_len - header_length_total - sdu_length_total - 3 > 0) { rlc_status = mac_rlc_status_ind(module_idP, rnti, module_idP, frameP, subframeP, ENB_FLAG_YES, MBMS_FLAG_NO, DCCH + 1, TBS - ta_len - header_length_total - sdu_length_total - 3 -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) ,0, 0 #endif ); @@ -991,7 +991,7 @@ schedule_ue_spec(module_id_t module_idP, int slice_idxP, sdu_lengths[num_sdus] += mac_rlc_data_req(module_idP, rnti, module_idP, frameP, ENB_FLAG_YES, MBMS_FLAG_NO, DCCH + 1, TBS, //not used (char *)&dlsch_buffer[sdu_length_total] -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) ,0, 0 #endif ); @@ -1046,7 +1046,7 @@ schedule_ue_spec(module_id_t module_idP, int slice_idxP, MBMS_FLAG_NO, lcid, TBS - ta_len - header_length_total - sdu_length_total - 3 -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) ,0, 0 #endif ); @@ -1064,7 +1064,7 @@ schedule_ue_spec(module_id_t module_idP, int slice_idxP, sdu_lengths[num_sdus] = mac_rlc_data_req(module_idP, rnti, module_idP, frameP, ENB_FLAG_YES, MBMS_FLAG_NO, lcid, TBS, //not used (char *)&dlsch_buffer[sdu_length_total] -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) ,0, 0 #endif ); @@ -2104,11 +2104,11 @@ void schedule_PCH(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP) // dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.bf_vector = ; // Rel10 fields -#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) dl_config_pdu->dlsch_pdu.dlsch_pdu_rel10.pdsch_start = 3; #endif // Rel13 fields -#if (RRC_VERSION >= MAKE_VERSION(13, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(13, 0, 0)) dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.ue_type = 0; // regular UE dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.pdsch_payload_type = 2; // not BR dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.initial_transmission_sf_io = 0xFFFF; diff --git a/openair2/LAYER2/MAC/eNB_scheduler_fairRR.c b/openair2/LAYER2/MAC/eNB_scheduler_fairRR.c index 9ab4306000..7d87f92ece 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_fairRR.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_fairRR.c @@ -132,7 +132,7 @@ void pre_scd_nb_rbs_required( module_id_t module_idP, rlc_status = mac_rlc_status_ind(module_idP, rnti, module_idP, frameP, subframeP, ENB_FLAG_YES, MBMS_FLAG_NO, lc_id, 0 -#ifdef Rel14 +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) ,0, 0 #endif ); @@ -1246,7 +1246,7 @@ schedule_ue_spec_fairRR(module_id_t module_idP, if (TBS - ta_len - header_len_dcch > 0) { rlc_status = mac_rlc_status_ind(module_idP, rnti, module_idP, frameP, subframeP, ENB_FLAG_YES, MBMS_FLAG_NO, DCCH, (TBS - ta_len - header_len_dcch) -#ifdef Rel14 +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) ,0, 0 #endif ); // transport block set size @@ -1262,7 +1262,7 @@ schedule_ue_spec_fairRR(module_id_t module_idP, (char *) &dlsch_buffer [0] -#ifdef Rel14 +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) ,0, 0 #endif ); @@ -1351,7 +1351,7 @@ schedule_ue_spec_fairRR(module_id_t module_idP, // check for DCCH1 and update header information (assume 2 byte sub-header) if (TBS - ta_len - header_len_dcch - sdu_length_total > 0) { rlc_status = mac_rlc_status_ind(module_idP, rnti, module_idP, frameP, subframeP, ENB_FLAG_YES, MBMS_FLAG_NO, DCCH + 1, (TBS - ta_len - header_len_dcch - sdu_length_total) -#ifdef Rel14 +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) ,0, 0 #endif ); // transport block set size less allocations for timing advance and @@ -1367,7 +1367,7 @@ schedule_ue_spec_fairRR(module_id_t module_idP, (char *) &dlsch_buffer [sdu_length_total] -#ifdef Rel14 +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) ,0, 0 #endif ); @@ -1429,7 +1429,7 @@ schedule_ue_spec_fairRR(module_id_t module_idP, header_len_dcch - sdu_length_total - header_len_dtch -#ifdef Rel14 +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) ,0, 0 #endif ); @@ -1448,7 +1448,7 @@ schedule_ue_spec_fairRR(module_id_t module_idP, *) &dlsch_buffer [sdu_length_total] -#ifdef Rel14 +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) ,0, 0 #endif ); @@ -2867,7 +2867,7 @@ void schedule_ulsch_rnti_fairRR(module_id_t module_idP, get_TBS_UL(UE_template->mcs_UL[harq_pid], rb_table[rb_table_index]) ); -#ifdef Rel14 +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) if (UE_template->rach_resource_type>0) { // This is a BL/CE UE allocation fill_nfapi_ulsch_config_request_emtc(&ul_req_tmp->ul_config_pdu_list[ul_req_index], UE_template->rach_resource_type>2 ? 2 : 1, @@ -3013,7 +3013,7 @@ void schedule_ulsch_rnti_fairRR(module_id_t module_idP, 0, // n_srs UE_template->TBS_UL[harq_pid] ); -#ifdef Rel14 +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) if (UE_template->rach_resource_type>0) { // This is a BL/CE UE allocation fill_nfapi_ulsch_config_request_emtc(&ul_req_tmp->ul_config_pdu_list[ul_req_index], UE_template->rach_resource_type>2 ? 2 : 1, diff --git a/openair2/LAYER2/MAC/eNB_scheduler_mch.c b/openair2/LAYER2/MAC/eNB_scheduler_mch.c index 16953e958a..649f763f42 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_mch.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_mch.c @@ -59,7 +59,7 @@ extern RAN_CONTEXT_t RC; -#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) int8_t get_mbsfn_sf_alloction(module_id_t module_idP, uint8_t CC_id, uint8_t mbsfn_sync_area) @@ -151,7 +151,7 @@ schedule_MBMS(module_id_t module_idP, uint8_t CC_id, frame_t frameP, // 1st: Check the MBSFN subframes from SIB2 info (SF allocation pattern i, max 8 non-overlapping patterns exist) if (frameP % mbsfn_period == cc->mbsfn_SubframeConfig[j]->radioframeAllocationOffset) { // MBSFN frameP - if (cc->mbsfn_SubframeConfig[j]->subframeAllocation.present == MBSFN_SubframeConfig__subframeAllocation_PR_oneFrame) { // one-frameP format + if (cc->mbsfn_SubframeConfig[j]->subframeAllocation.present == LTE_MBSFN_SubframeConfig__subframeAllocation_PR_oneFrame) { // one-frameP format // Find the first subframeP in this MCH to transmit MSI if (frameP % mch_scheduling_period == @@ -585,7 +585,7 @@ schedule_MBMS(module_id_t module_idP, uint8_t CC_id, frame_t frameP, TBS = get_TBS_DL(cc->MCH_pdu.mcs, to_prb(cc->mib->message.dl_Bandwidth)); -#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) // do not let mcch and mtch multiplexing when relaying is active // for sync area 1, so not transmit data //if ((i == 0) && ((RC.mac[module_idP]->MBMS_flag != multicast_relay) || (RC.mac[module_idP]->mcch_active==0))) { @@ -633,7 +633,7 @@ schedule_MBMS(module_id_t module_idP, uint8_t CC_id, frame_t frameP, MTCH, TBS - header_len_mcch - header_len_msi - sdu_length_total - header_len_mtch -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) ,0, 0 #endif ); @@ -652,7 +652,7 @@ schedule_MBMS(module_id_t module_idP, uint8_t CC_id, frame_t frameP, sdu_lengths[num_sdus] = mac_rlc_data_req(module_idP, 0, module_idP, frameP, ENB_FLAG_YES, MBMS_FLAG_YES, MTCH, 0, //not used (char *) &mch_buffer[sdu_length_total] -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) ,0, 0 #endif @@ -676,7 +676,7 @@ schedule_MBMS(module_id_t module_idP, uint8_t CC_id, frame_t frameP, header_len_mtch = 0; } } -#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) // } #endif diff --git a/openair2/LAYER2/MAC/eNB_scheduler_phytest.c b/openair2/LAYER2/MAC/eNB_scheduler_phytest.c index 81c418c123..881359f274 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_phytest.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_phytest.c @@ -169,7 +169,7 @@ schedule_ue_spec_phy_test( 1, // number of subbands // uint8_t codebook_index, 4, // UE category capacity - PDSCH_ConfigDedicated__p_a_dB0, + LTE_PDSCH_ConfigDedicated__p_a_dB0, 0, // delta_power_offset for TM5 0, // ngap 0, // nprb @@ -347,7 +347,7 @@ void schedule_ulsch_phy_test(module_id_t module_idP,frame_t frameP,sub_frame_t s 0, // n_srs get_TBS_UL(mcs,nb_rb) ); -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) if (UE_template->rach_resource_type>0) { // This is a BL/CE UE allocation fill_nfapi_ulsch_config_request_emtc(&ul_req->ul_config_pdu_list[ul_req_index], UE_template->rach_resource_type>2 ? 2 : 1, diff --git a/openair2/LAYER2/MAC/eNB_scheduler_primitives.c b/openair2/LAYER2/MAC/eNB_scheduler_primitives.c index c9d3d9dbac..b43c34fe14 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_primitives.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_primitives.c @@ -788,7 +788,7 @@ get_srs_pos(COMMON_channels_t * cc, uint16_t isrs, void get_csi_params(COMMON_channels_t * cc, - struct CQI_ReportPeriodic *cqi_ReportPeriodic, + struct LTE_CQI_ReportPeriodic *cqi_ReportPeriodic, uint16_t * Npd, uint16_t * N_OFFSET_CQI, int *H) { uint16_t cqi_PMI_ConfigIndex = @@ -861,7 +861,7 @@ get_csi_params(COMMON_channels_t * cc, // get H if (cqi_ReportPeriodic->choice.setup.cqi_FormatIndicatorPeriodic. present == - CQI_ReportPeriodic__setup__cqi_FormatIndicatorPeriodic_PR_subbandCQI) + LTE_CQI_ReportPeriodic__setup__cqi_FormatIndicatorPeriodic_PR_subbandCQI) *H = 1 + (Jtab[cc->mib->message.dl_Bandwidth] * cqi_ReportPeriodic->choice.setup. @@ -873,7 +873,7 @@ get_csi_params(COMMON_channels_t * cc, uint8_t get_dl_cqi_pmi_size_pusch(COMMON_channels_t * cc, uint8_t tmode, uint8_t ri, - CQI_ReportModeAperiodic_t * + LTE_CQI_ReportModeAperiodic_t * cqi_ReportModeAperiodic) { int Ntab[6] = { 0, 4, 7, 9, 10, 13 }; @@ -885,7 +885,7 @@ get_dl_cqi_pmi_size_pusch(COMMON_channels_t * cc, uint8_t tmode, "cqi_ReportPeriodic is null!\n"); switch (*cqi_ReportModeAperiodic) { - case CQI_ReportModeAperiodic_rm12: + case LTE_CQI_ReportModeAperiodic_rm12: AssertFatal(tmode == 4 || tmode == 6 || tmode == 8 || tmode == 9 || tmode == 10, "Illegal TM (%d) for CQI_ReportModeAperiodic_rm12\n", @@ -901,7 +901,7 @@ get_dl_cqi_pmi_size_pusch(COMMON_channels_t * cc, uint8_t tmode, else if (ri > 1 && cc->p_eNB == 4) return (8 + (N << 2)); break; - case CQI_ReportModeAperiodic_rm20: + case LTE_CQI_ReportModeAperiodic_rm20: // Table 5.2.2.6.3-1 (36.212) AssertFatal(tmode == 1 || tmode == 2 || tmode == 3 || tmode == 7 || tmode == 9 @@ -913,7 +913,7 @@ get_dl_cqi_pmi_size_pusch(COMMON_channels_t * cc, uint8_t tmode, "TM9/10 will be handled later for CQI_ReportModeAperiodic_rm20\n"); return (4 + 2 + L); break; - case CQI_ReportModeAperiodic_rm22: + case LTE_CQI_ReportModeAperiodic_rm22: // Table 5.2.2.6.3-2 (36.212) AssertFatal(tmode == 4 || tmode == 6 || tmode == 8 || tmode == 9 || tmode == 10, @@ -931,7 +931,7 @@ get_dl_cqi_pmi_size_pusch(COMMON_channels_t * cc, uint8_t tmode, if (ri >= 2 && cc->p_eNB == 4) return (4 + 2 + 4 + 2 + L + 8); break; - case CQI_ReportModeAperiodic_rm30: + case LTE_CQI_ReportModeAperiodic_rm30: // Table 5.2.2.6.2-1 (36.212) AssertFatal(tmode == 1 || tmode == 2 || tmode == 3 || tmode == 7 || tmode == 8 || tmode == 9 @@ -943,7 +943,7 @@ get_dl_cqi_pmi_size_pusch(COMMON_channels_t * cc, uint8_t tmode, "TM8/9/10 will be handled later for CQI_ReportModeAperiodic_rm30\n"); return (4 + (N << 1)); break; - case CQI_ReportModeAperiodic_rm31: + case LTE_CQI_ReportModeAperiodic_rm31: // Table 5.2.2.6.2-2 (36.212) AssertFatal(tmode == 4 || tmode == 6 || tmode == 8 || tmode == 9 || tmode == 10, @@ -961,8 +961,8 @@ get_dl_cqi_pmi_size_pusch(COMMON_channels_t * cc, uint8_t tmode, else if (ri >= 2 && cc->p_eNB == 4) return (4 + (N << 1) + 4 + (N << 1) + 4); break; -#if (RRC_VERSION >= MAKE_VERSION(12, 5, 0)) - case CQI_ReportModeAperiodic_rm32_v1250: +#if (LTE_RRC_VERSION >= MAKE_VERSION(12, 5, 0)) + case LTE_CQI_ReportModeAperiodic_rm32_v1250: AssertFatal(tmode == 4 || tmode == 6 || tmode == 8 || tmode == 9 || tmode == 10, "Illegal TM (%d) for CQI_ReportModeAperiodic_rm32\n", @@ -970,14 +970,14 @@ get_dl_cqi_pmi_size_pusch(COMMON_channels_t * cc, uint8_t tmode, AssertFatal(1 == 0, "CQI_ReportModeAperiodic_rm32_v1250 not supported yet\n"); break; - case CQI_ReportModeAperiodic_rm10_v1310: + case LTE_CQI_ReportModeAperiodic_rm10_v1310: // Table 5.2.2.6.1-1F/G (36.212) if (ri == 1) return (4); // F else return (7); // G break; - case CQI_ReportModeAperiodic_rm11_v1310: + case LTE_CQI_ReportModeAperiodic_rm11_v1310: // Table 5.2.2.6.1-1H (36.212) AssertFatal(tmode == 4 || tmode == 6 || tmode == 8 || tmode == 9 || tmode == 10, @@ -995,7 +995,7 @@ get_dl_cqi_pmi_size_pusch(COMMON_channels_t * cc, uint8_t tmode, return (4 + 4 + 4); break; -#endif /* #if (RRC_VERSION >= MAKE_VERSION(12, 5, 0)) */ +#endif /* #if (LTE_RRC_VERSION >= MAKE_VERSION(12, 5, 0)) */ } AssertFatal(1 == 0, "Shouldn't get here\n"); return (0); @@ -1004,7 +1004,7 @@ get_dl_cqi_pmi_size_pusch(COMMON_channels_t * cc, uint8_t tmode, uint8_t get_rel8_dl_cqi_pmi_size(UE_sched_ctrl * sched_ctl, int CC_idP, COMMON_channels_t * cc, uint8_t tmode, - struct CQI_ReportPeriodic * cqi_ReportPeriodic) + struct LTE_CQI_ReportPeriodic * cqi_ReportPeriodic) { int no_pmi = 0; // Ltab[6] = {0,log2(15/4/2),log2(25/4/2),log2(50/6/3),log2(75/8/4),log2(100/8/4)}; @@ -1014,10 +1014,10 @@ get_rel8_dl_cqi_pmi_size(UE_sched_ctrl * sched_ctl, int CC_idP, AssertFatal(cqi_ReportPeriodic != NULL, "cqi_ReportPeriodic is null!\n"); - AssertFatal(cqi_ReportPeriodic->present != CQI_ReportPeriodic_PR_NOTHING, + AssertFatal(cqi_ReportPeriodic->present != LTE_CQI_ReportPeriodic_PR_NOTHING, "cqi_ReportPeriodic->present == CQI_ReportPeriodic_PR_NOTHING!\n"); AssertFatal(cqi_ReportPeriodic->choice. - setup.cqi_FormatIndicatorPeriodic.present != CQI_ReportPeriodic__setup__cqi_FormatIndicatorPeriodic_PR_NOTHING, + setup.cqi_FormatIndicatorPeriodic.present != LTE_CQI_ReportPeriodic__setup__cqi_FormatIndicatorPeriodic_PR_NOTHING, "cqi_ReportPeriodic->cqi_FormatIndicatorPeriodic.choice.setup.present == CQI_ReportPeriodic__setup__cqi_FormatIndicatorPeriodic_PR_NOTHING!\n"); switch (tmode) { @@ -1032,7 +1032,7 @@ get_rel8_dl_cqi_pmi_size(UE_sched_ctrl * sched_ctl, int CC_idP, no_pmi = 0; } - if ((cqi_ReportPeriodic->choice.setup.cqi_FormatIndicatorPeriodic.present == CQI_ReportPeriodic__setup__cqi_FormatIndicatorPeriodic_PR_widebandCQI) + if ((cqi_ReportPeriodic->choice.setup.cqi_FormatIndicatorPeriodic.present == LTE_CQI_ReportPeriodic__setup__cqi_FormatIndicatorPeriodic_PR_widebandCQI) || (sched_ctl->feedback_cnt[CC_idP] == 0)) { // send wideband report every opportunity if wideband reporting mode is selected, else every H opportunities if (no_pmi == 1) return (4); @@ -1044,7 +1044,7 @@ get_rel8_dl_cqi_pmi_size(UE_sched_ctrl * sched_ctl, int CC_idP, AssertFatal(1 == 0, "illegal combination p %d, ri %d, no_pmi %d\n", cc->p_eNB, ri, no_pmi); - } else if (cqi_ReportPeriodic->choice.setup.cqi_FormatIndicatorPeriodic.present == CQI_ReportPeriodic__setup__cqi_FormatIndicatorPeriodic_PR_subbandCQI) { + } else if (cqi_ReportPeriodic->choice.setup.cqi_FormatIndicatorPeriodic.present == LTE_CQI_ReportPeriodic__setup__cqi_FormatIndicatorPeriodic_PR_subbandCQI) { if ((no_pmi == 1) || ri == 1) return (4 + Ltab[cc->mib->message.dl_Bandwidth]); else return (7 + Ltab[cc->mib->message.dl_Bandwidth]); } @@ -1103,12 +1103,12 @@ program_dlsch_acknak(module_id_t module_idP, int CC_idP, int UE_idP, nfapi_ul_config_ulsch_harq_information *ulsch_harq_information = NULL; nfapi_ul_config_harq_information *harq_information = NULL; -#if (RRC_VERSION >= MAKE_VERSION(10, 2, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 2, 0)) if ((UE_list->UE_template[CC_idP][UE_idP].physicalConfigDedicated->ext2) && (UE_list->UE_template[CC_idP][UE_idP].physicalConfigDedicated->ext2->pucch_ConfigDedicated_v1020) && (UE_list->UE_template[CC_idP][UE_idP].physicalConfigDedicated->ext2->pucch_ConfigDedicated_v1020->simultaneousPUCCH_PUSCH_r10) - && (*UE_list->UE_template[CC_idP][UE_idP].physicalConfigDedicated->ext2->pucch_ConfigDedicated_v1020->simultaneousPUCCH_PUSCH_r10 == PUCCH_ConfigDedicated_v1020__simultaneousPUCCH_PUSCH_r10_true)) + && (*UE_list->UE_template[CC_idP][UE_idP].physicalConfigDedicated->ext2->pucch_ConfigDedicated_v1020->simultaneousPUCCH_PUSCH_r10 == LTE_PUCCH_ConfigDedicated_v1020__simultaneousPUCCH_PUSCH_r10_true)) use_simultaneous_pucch_pusch = 1; #endif @@ -1261,7 +1261,7 @@ fill_nfapi_ulsch_harq_information(module_id_t module_ int UE_id = find_UE_id(module_idP, rntiP); - PUSCH_ConfigDedicated_t *puschConfigDedicated; + LTE_PUSCH_ConfigDedicated_t *puschConfigDedicated; // PUSCH_ConfigDedicated_v1020_t *puschConfigDedicated_v1020; // PUSCH_ConfigDedicated_v1130_t *puschConfigDedicated_v1130; // PUSCH_ConfigDedicated_v1250_t *puschConfigDedicated_v1250; @@ -1270,17 +1270,17 @@ fill_nfapi_ulsch_harq_information(module_id_t module_ AssertFatal(UE_list != NULL, "UE_list is null\n"); AssertFatal(UE_list->UE_template[CC_idP][UE_id].physicalConfigDedicated != NULL, "physicalConfigDedicated for rnti %x is null\n", rntiP); - AssertFatal((puschConfigDedicated = (PUSCH_ConfigDedicated_t *) + AssertFatal((puschConfigDedicated = (LTE_PUSCH_ConfigDedicated_t *) UE_list->UE_template[CC_idP][UE_id].physicalConfigDedicated->pusch_ConfigDedicated) != NULL, "physicalConfigDedicated->puschConfigDedicated for rnti %x is null\n", rntiP); -#if (RRC_VERSION >= MAKE_VERSION(10, 2, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 2, 0)) /* if (UE_list->UE_template[CC_idP][UE_id].physicalConfigDedicated->ext2) puschConfigDedicated_v1020 = UE_list->UE_template[CC_idP][UE_id].physicalConfigDedicated->ext2->pusch_ConfigDedicated_v1020; #endif - #if (RRC_VERSION >= MAKE_VERSION(11, 3, 0)) + #if (LTE_RRC_VERSION >= MAKE_VERSION(11, 3, 0)) if (UE_list->UE_template[CC_idP][UE_id].physicalConfigDedicated->ext4) puschConfigDedicated_v1130 = UE_list->UE_template[CC_idP][UE_id].physicalConfigDedicated->ext4->pusch_ConfigDedicated_v1130; #endif - #if (RRC_VERSION >= MAKE_VERSION(12, 5, 0)) + #if (LTE_RRC_VERSION >= MAKE_VERSION(12, 5, 0)) if (UE_list->UE_template[CC_idP][UE_id].physicalConfigDedicated->ext5) puschConfigDedicated_v1250 = UE_list->UE_template[CC_idP][UE_id].physicalConfigDedicated->ext5->pusch_ConfigDedicated_v1250; #endif */ @@ -1289,7 +1289,7 @@ fill_nfapi_ulsch_harq_information(module_id_t module_ AssertFatal(UE_list->UE_template[CC_idP][UE_id].physicalConfigDedicated->pucch_ConfigDedicated != NULL, "pucch_ConfigDedicated is null!\n"); if ((UE_list->UE_template[CC_idP][UE_id].physicalConfigDedicated->pucch_ConfigDedicated->tdd_AckNackFeedbackMode != NULL) - && (*UE_list->UE_template[CC_idP][UE_id].physicalConfigDedicated->pucch_ConfigDedicated->tdd_AckNackFeedbackMode == PUCCH_ConfigDedicated__tdd_AckNackFeedbackMode_multiplexing)) + && (*UE_list->UE_template[CC_idP][UE_id].physicalConfigDedicated->pucch_ConfigDedicated->tdd_AckNackFeedbackMode == LTE_PUCCH_ConfigDedicated__tdd_AckNackFeedbackMode_multiplexing)) harq_information->harq_information_rel10.ack_nack_mode = 1; // multiplexing else harq_information->harq_information_rel10.ack_nack_mode = 0; // bundling @@ -1374,7 +1374,7 @@ fill_nfapi_harq_information(module_id_t module_idP, if (UE_list->UE_template[CC_idP][UE_id].physicalConfigDedicated != NULL && UE_list->UE_template[CC_idP][UE_id].physicalConfigDedicated->pucch_ConfigDedicated != NULL && (UE_list->UE_template[CC_idP][UE_id].physicalConfigDedicated->pucch_ConfigDedicated->tdd_AckNackFeedbackMode != NULL) - && (*UE_list->UE_template[CC_idP][UE_id].physicalConfigDedicated->pucch_ConfigDedicated->tdd_AckNackFeedbackMode == PUCCH_ConfigDedicated__tdd_AckNackFeedbackMode_multiplexing)) + && (*UE_list->UE_template[CC_idP][UE_id].physicalConfigDedicated->pucch_ConfigDedicated->tdd_AckNackFeedbackMode == LTE_PUCCH_ConfigDedicated__tdd_AckNackFeedbackMode_multiplexing)) { harq_information->harq_information_rel10_tdd.harq_size = 2; // 2-bit ACK/NAK harq_information->harq_information_rel10_tdd.ack_nack_mode = 1; // multiplexing @@ -1398,7 +1398,7 @@ fill_nfapi_harq_information(module_id_t module_idP, AssertFatal(UE_list->UE_template[CC_idP][UE_id].physicalConfigDedicated->pucch_ConfigDedicated != NULL, "pucch_ConfigDedicated is null for TDD!\n"); if ((UE_list->UE_template[CC_idP][UE_id].physicalConfigDedicated->pucch_ConfigDedicated->tdd_AckNackFeedbackMode != NULL) - && (*UE_list->UE_template[CC_idP][UE_id].physicalConfigDedicated->pucch_ConfigDedicated->tdd_AckNackFeedbackMode == PUCCH_ConfigDedicated__tdd_AckNackFeedbackMode_multiplexing)) { + && (*UE_list->UE_template[CC_idP][UE_id].physicalConfigDedicated->pucch_ConfigDedicated->tdd_AckNackFeedbackMode == LTE_PUCCH_ConfigDedicated__tdd_AckNackFeedbackMode_multiplexing)) { harq_information->harq_information_rel10_tdd.ack_nack_mode = 1; // multiplexing } else { harq_information->harq_information_rel10_tdd.ack_nack_mode = 0; // bundling @@ -1544,7 +1544,7 @@ void fill_nfapi_ulsch_config_request_rel8(nfapi_ul_config_request_pdu_t *ul_config_pdu, uint8_t cqi_req, COMMON_channels_t *cc, - struct PhysicalConfigDedicated *physicalConfigDedicated, + struct LTE_PhysicalConfigDedicated *physicalConfigDedicated, uint8_t tmode, uint32_t handle, uint16_t rnti, @@ -1615,7 +1615,7 @@ fill_nfapi_ulsch_config_request_rel8(nfapi_ul_config_request_pdu_t *ul_config_pd } } -#if (RRC_VERSION >= MAKE_VERSION(13, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(13, 0, 0)) void fill_nfapi_ulsch_config_request_emtc(nfapi_ul_config_request_pdu_t * ul_config_pdu, uint8_t ue_type, @@ -1658,12 +1658,12 @@ mpdcch_sf_condition(eNB_MAC_INST * eNB, int CC_id, frame_t frameP, sub_frame_t subframeP, int rmax, MPDCCH_TYPES_t mpdcch_type, int UE_id) { - struct PRACH_ConfigSIB_v1310 *ext4_prach = + struct LTE_PRACH_ConfigSIB_v1310 *ext4_prach = eNB->common_channels[CC_id].radioResourceConfigCommon_BR-> ext4->prach_ConfigCommon_v1310; int T; - EPDCCH_SetConfig_r11_t *epdcch_setconfig_r11; + LTE_EPDCCH_SetConfig_r11_t *epdcch_setconfig_r11; switch (mpdcch_type) { case TYPE0: @@ -1916,7 +1916,7 @@ void dump_ue_list(UE_list_t * listP, int ul_flag) } int add_new_ue(module_id_t mod_idP, int cc_idP, rnti_t rntiP, int harq_pidP -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) , uint8_t rach_resource_type #endif ) @@ -1950,7 +1950,7 @@ int add_new_ue(module_id_t mod_idP, int cc_idP, rnti_t rntiP, int harq_pidP UE_list->UE_template[cc_idP][UE_id].pre_assigned_mcs_ul = 0; #endif -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) UE_list->UE_template[cc_idP][UE_id].rach_resource_type = rach_resource_type; #endif @@ -2272,7 +2272,7 @@ uint8_t get_tmode(module_id_t module_idP, int CC_idP, int UE_idP) eNB_MAC_INST *eNB = RC.mac[module_idP]; COMMON_channels_t *cc = &eNB->common_channels[CC_idP]; - struct PhysicalConfigDedicated *physicalConfigDedicated = + struct LTE_PhysicalConfigDedicated *physicalConfigDedicated = eNB->UE_list.physicalConfigDedicated[CC_idP][UE_idP]; if (physicalConfigDedicated == NULL) { // RRCConnectionSetup not received by UE yet @@ -2285,16 +2285,16 @@ uint8_t get_tmode(module_id_t module_idP, int CC_idP, int UE_idP) UE_idP); AssertFatal(physicalConfigDedicated->antennaInfo->present != - PhysicalConfigDedicated__antennaInfo_PR_NOTHING, + LTE_PhysicalConfigDedicated__antennaInfo_PR_NOTHING, "antennaInfo (mod_id %d, CC_id %d) is set to NOTHING\n", module_idP, CC_idP); if (physicalConfigDedicated->antennaInfo->present == - PhysicalConfigDedicated__antennaInfo_PR_explicitValue) { + LTE_PhysicalConfigDedicated__antennaInfo_PR_explicitValue) { return (physicalConfigDedicated->antennaInfo-> choice.explicitValue.transmissionMode); } else if (physicalConfigDedicated->antennaInfo->present == - PhysicalConfigDedicated__antennaInfo_PR_defaultValue) { + LTE_PhysicalConfigDedicated__antennaInfo_PR_defaultValue) { AssertFatal(cc->p_eNB <= 2, "p_eNB is %d, should be <2\n", cc->p_eNB); return (cc->p_eNB); @@ -3310,7 +3310,7 @@ CCE_allocation_infeasible(int module_idP, return res; } -void get_retransmission_timing(TDD_Config_t *tdd_Config, frame_t *frameP, +void get_retransmission_timing(LTE_TDD_Config_t *tdd_Config, frame_t *frameP, sub_frame_t *subframeP) { @@ -3361,7 +3361,7 @@ uint8_t get_dl_subframe_count(int tdd_config_sfa, sub_frame_t subframeP){ return -1; } -uint8_t frame_subframe2_dl_harq_pid(TDD_Config_t *tdd_Config, int abs_frameP, sub_frame_t subframeP){ +uint8_t frame_subframe2_dl_harq_pid(LTE_TDD_Config_t *tdd_Config, int abs_frameP, sub_frame_t subframeP){ int harq_pid; if(tdd_Config){ @@ -3382,7 +3382,7 @@ uint8_t frame_subframe2_dl_harq_pid(TDD_Config_t *tdd_Config, int abs_frameP, su return -1; } -unsigned char ul_ACK_subframe2M(TDD_Config_t *tdd_Config,unsigned char subframe) +unsigned char ul_ACK_subframe2M(LTE_TDD_Config_t *tdd_Config,unsigned char subframe) { if (tdd_Config == NULL) { @@ -3447,7 +3447,7 @@ unsigned char ul_ACK_subframe2M(TDD_Config_t *tdd_Config,unsigned char subframe) return(0); } -unsigned char ul_ACK_subframe2dl_subframe(TDD_Config_t *tdd_Config,unsigned char subframe,unsigned char ACK_index) +unsigned char ul_ACK_subframe2dl_subframe(LTE_TDD_Config_t *tdd_Config,unsigned char subframe,unsigned char ACK_index) { if (tdd_Config == NULL) { @@ -3531,7 +3531,7 @@ extract_harq(module_id_t mod_idP, int CC_idP, int UE_id, int frame_tx; uint8_t harq_pid; -#if (RRC_VERSION >= MAKE_VERSION(13, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(13, 0, 0)) if (UE_list->UE_template[pCCid][UE_id].physicalConfigDedicated != NULL && UE_list->UE_template[pCCid][UE_id].physicalConfigDedicated->pucch_ConfigDedicated != NULL && (UE_list->UE_template[pCCid][UE_id].physicalConfigDedicated->ext7) @@ -4010,7 +4010,7 @@ extract_pucch_csi(module_id_t mod_idP, int CC_idP, int UE_id, UE_list_t *UE_list = &RC.mac[mod_idP]->UE_list; UE_sched_ctrl *sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; COMMON_channels_t *cc = &RC.mac[mod_idP]->common_channels[CC_idP]; - struct CQI_ReportPeriodic *cqi_ReportPeriodic; + struct LTE_CQI_ReportPeriodic *cqi_ReportPeriodic; int no_pmi; uint8_t Ltab[6] = { 0, 2, 4, 4, 4, 4 }; uint8_t Jtab[6] = { 0, 2, 2, 3, 4, 4 }; @@ -4025,10 +4025,10 @@ extract_pucch_csi(module_id_t mod_idP, int CC_idP, int UE_id, "cqi_ReportPeriodic is null for UE %d\n", UE_id); // determine feedback mode - AssertFatal(cqi_ReportPeriodic->present != CQI_ReportPeriodic_PR_NOTHING, - "cqi_ReportPeriodic->present == CQI_ReportPeriodic_PR_NOTHING!\n"); - AssertFatal(cqi_ReportPeriodic->choice.setup.cqi_FormatIndicatorPeriodic.present != CQI_ReportPeriodic__setup__cqi_FormatIndicatorPeriodic_PR_NOTHING, - "cqi_ReportPeriodic->cqi_FormatIndicatorPeriodic.choice.setup.present == CQI_ReportPeriodic__setup__cqi_FormatIndicatorPeriodic_PR_NOTHING!\n"); + AssertFatal(cqi_ReportPeriodic->present != LTE_CQI_ReportPeriodic_PR_NOTHING, + "cqi_ReportPeriodic->present == LTE_CQI_ReportPeriodic_PR_NOTHING!\n"); + AssertFatal(cqi_ReportPeriodic->choice.setup.cqi_FormatIndicatorPeriodic.present != LTE_CQI_ReportPeriodic__setup__cqi_FormatIndicatorPeriodic_PR_NOTHING, + "cqi_ReportPeriodic->cqi_FormatIndicatorPeriodic.choice.setup.present == LTE_CQI_ReportPeriodic__setup__cqi_FormatIndicatorPeriodic_PR_NOTHING!\n"); uint16_t Npd, N_OFFSET_CQI; int H, K, bandwidth_part, L, Lmask; @@ -4062,7 +4062,7 @@ extract_pucch_csi(module_id_t mod_idP, int CC_idP, int UE_id, no_pmi = 0; } - if ((cqi_ReportPeriodic->choice.setup.cqi_FormatIndicatorPeriodic.present == CQI_ReportPeriodic__setup__cqi_FormatIndicatorPeriodic_PR_widebandCQI) + if ((cqi_ReportPeriodic->choice.setup.cqi_FormatIndicatorPeriodic.present == LTE_CQI_ReportPeriodic__setup__cqi_FormatIndicatorPeriodic_PR_widebandCQI) || (feedback_cnt == 0)) { // Note: This implements only Tables: 5.3.3.1-1,5.3.3.1-1A and 5.3.3.1-2 from 36.213 (1,2,4 antenna ports Wideband CQI/PMI) @@ -4095,7 +4095,7 @@ extract_pucch_csi(module_id_t mod_idP, int CC_idP, int UE_id, AssertFatal(1 == 0, "illegal combination p %d, ri %d, no_pmi %d\n", cc->p_eNB, ri, no_pmi); - } else if (cqi_ReportPeriodic->choice.setup.cqi_FormatIndicatorPeriodic.present == CQI_ReportPeriodic__setup__cqi_FormatIndicatorPeriodic_PR_subbandCQI) + } else if (cqi_ReportPeriodic->choice.setup.cqi_FormatIndicatorPeriodic.present == LTE_CQI_ReportPeriodic__setup__cqi_FormatIndicatorPeriodic_PR_subbandCQI) { // This is Table 5.2.3.3.2-2 for 36.213 if (ri == 1) { @@ -4126,7 +4126,7 @@ extract_pusch_csi(module_id_t mod_idP, int CC_idP, int UE_id, int i; uint64_t p = *(uint64_t *) pdu; int curbyte, curbit; - CQI_ReportModeAperiodic_t *cqi_ReportModeAperiodic; + LTE_CQI_ReportModeAperiodic_t *cqi_ReportModeAperiodic; AssertFatal(UE_list->UE_template[CC_idP][UE_id].physicalConfigDedicated != NULL, "physicalConfigDedicated is null for UE %d\n", UE_id); @@ -4143,7 +4143,7 @@ extract_pusch_csi(module_id_t mod_idP, int CC_idP, int UE_id, int m; switch (*cqi_ReportModeAperiodic) { - case CQI_ReportModeAperiodic_rm12: + case LTE_CQI_ReportModeAperiodic_rm12: AssertFatal(0 == 1, "to be fixed, don't use p but pdu directly\n"); // wideband multiple PMI (TM4/6), Table 5.2.2.6.1-1 (for TM4/6) AssertFatal(tmode == 4 || tmode == 6 || tmode == 8 || tmode == 9 || tmode == 10, @@ -4192,7 +4192,7 @@ extract_pusch_csi(module_id_t mod_idP, int CC_idP, int UE_id, } break; - case CQI_ReportModeAperiodic_rm20: + case LTE_CQI_ReportModeAperiodic_rm20: AssertFatal(0 == 1, "to be fixed, don't use p but pdu directly\n"); // UE-selected subband CQI no PMI (TM1/2/3/7) , Table 5.2.2.6.3-1 from 36.213 AssertFatal(tmode == 1 || tmode == 2 || tmode == 3 @@ -4209,7 +4209,7 @@ extract_pusch_csi(module_id_t mod_idP, int CC_idP, int UE_id, for (m = 0; m < Mtab_uesel[bw]; m++) sched_ctl->aperiodic_subband_diffcqi0[CC_idP][v[m]] = diffcqi0; break; - case CQI_ReportModeAperiodic_rm22: + case LTE_CQI_ReportModeAperiodic_rm22: AssertFatal(0 == 1, "to be fixed, don't use p but pdu directly\n"); // UE-selected subband CQI multiple PMI (TM4/6) Table 5.2.2.6.3-2 from 36.213 @@ -4254,7 +4254,7 @@ extract_pusch_csi(module_id_t mod_idP, int CC_idP, int UE_id, sched_ctl->aperiodic_subband_pmi[CC_idP][v[m]] = pmi_uesel; } break; - case CQI_ReportModeAperiodic_rm30: + case LTE_CQI_ReportModeAperiodic_rm30: //subband CQI no PMI (TM1/2/3/7) AssertFatal(tmode == 1 || tmode == 2 || tmode == 3 || tmode == 7, @@ -4275,7 +4275,7 @@ extract_pusch_csi(module_id_t mod_idP, int CC_idP, int UE_id, sched_ctl->dl_cqi[CC_idP] = sched_ctl->aperiodic_wideband_cqi0[CC_idP]; break; - case CQI_ReportModeAperiodic_rm31: + case LTE_CQI_ReportModeAperiodic_rm31: AssertFatal(0 == 1, "to be fixed, don't use p but pdu directly\n"); //subband CQI single PMI (TM4/5/6) AssertFatal(tmode == 4 || tmode == 5 || tmode == 6 || tmode == 8 @@ -4346,8 +4346,8 @@ extract_pusch_csi(module_id_t mod_idP, int CC_idP, int UE_id, } break; -#if (RRC_VERSION >= MAKE_VERSION(12, 5, 0)) - case CQI_ReportModeAperiodic_rm32_v1250: +#if (LTE_RRC_VERSION >= MAKE_VERSION(12, 5, 0)) + case LTE_CQI_ReportModeAperiodic_rm32_v1250: AssertFatal(tmode == 4 || tmode == 5 || tmode == 6 || tmode == 8 || tmode == 9 || tmode == 10, @@ -4356,15 +4356,15 @@ extract_pusch_csi(module_id_t mod_idP, int CC_idP, int UE_id, AssertFatal(1 == 0, "CQI_ReportModeAperiodic_rm32 to be done\n"); break; #endif -#if (RRC_VERSION >= MAKE_VERSION(13, 1, 0)) - case CQI_ReportModeAperiodic_rm10_v1310: +#if (LTE_RRC_VERSION >= MAKE_VERSION(13, 1, 0)) + case LTE_CQI_ReportModeAperiodic_rm10_v1310: AssertFatal(tmode == 1 || tmode == 2 || tmode == 3 || tmode == 7, "Illegal transmission mode %d for CQI_ReportModeAperiodic_rm10\n", tmode); AssertFatal(1 == 0, "CQI_ReportModeAperiodic_rm10 to be done\n"); break; - case CQI_ReportModeAperiodic_rm11_v1310: + case LTE_CQI_ReportModeAperiodic_rm11_v1310: AssertFatal(tmode == 4 || tmode == 5 || tmode == 6 || tmode == 8 || tmode == 9 || tmode == 10, @@ -4372,7 +4372,7 @@ extract_pusch_csi(module_id_t mod_idP, int CC_idP, int UE_id, tmode); AssertFatal(1 == 0, "CQI_ReportModeAperiodic_rm11 to be done\n"); break; -#endif /* #if (RRC_VERSION >= MAKE_VERSION(13, 1, 0)) */ +#endif /* #if (LTE_RRC_VERSION >= MAKE_VERSION(13, 1, 0)) */ } } diff --git a/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c b/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c index 31c11e2c0a..2f32c801e3 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c @@ -561,7 +561,7 @@ rx_sdu(const module_id_t enb_mod_idP, if ((UE_id = add_new_ue(enb_mod_idP, CC_idP, mac->common_channels[CC_idP]. ra[ii].rnti, harq_pid -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) , mac->common_channels[CC_idP]. ra[ii].rach_resource_type @@ -1427,7 +1427,7 @@ schedule_ulsch_rnti(module_id_t module_idP, mcs_UL[harq_pid], rb_table [rb_table_index])); -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) if (UE_template->rach_resource_type > 0) { // This is a BL/CE UE allocation fill_nfapi_ulsch_config_request_emtc(&ul_req_tmp_body->ul_config_pdu_list[ul_req_index], UE_template->rach_resource_type > 2 ? 2 : 1, 1, //total_number_of_repetitions 1, //repetition_number @@ -1511,7 +1511,7 @@ schedule_ulsch_rnti(module_id_t module_idP, 0, // n_srs UE_template-> TBS_UL[harq_pid]); -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) if (UE_template->rach_resource_type > 0) { // This is a BL/CE UE allocation fill_nfapi_ulsch_config_request_emtc(&ul_req_tmp_body->ul_config_pdu_list[ul_req_index], UE_template->rach_resource_type > 2 ? 2 : 1, 1, //total_number_of_repetitions 1, //repetition_number diff --git a/openair2/LAYER2/MAC/l1_helpers.c b/openair2/LAYER2/MAC/l1_helpers.c index bd640a6c88..9b26413cb1 100644 --- a/openair2/LAYER2/MAC/l1_helpers.c +++ b/openair2/LAYER2/MAC/l1_helpers.c @@ -36,7 +36,7 @@ int8_t get_Po_NOMINAL_PUSCH(module_id_t module_idP, uint8_t CC_id) { - RACH_ConfigCommon_t *rach_ConfigCommon = NULL; + LTE_RACH_ConfigCommon_t *rach_ConfigCommon = NULL; AssertFatal(CC_id == 0, "Transmission on secondary CCs is not supported yet\n"); diff --git a/openair2/LAYER2/MAC/mac.h b/openair2/LAYER2/MAC/mac.h index ed6171dceb..0625a327eb 100644 --- a/openair2/LAYER2/MAC/mac.h +++ b/openair2/LAYER2/MAC/mac.h @@ -44,29 +44,29 @@ #include #include "COMMON/platform_constants.h" -#include "BCCH-BCH-Message.h" -#include "RadioResourceConfigCommon.h" -#include "RadioResourceConfigCommonSIB.h" -#include "RadioResourceConfigDedicated.h" -#include "MeasGapConfig.h" -#include "SchedulingInfoList.h" -#include "TDD-Config.h" -#include "RACH-ConfigCommon.h" -#include "MeasObjectToAddModList.h" -#include "MobilityControlInfo.h" -#if (RRC_VERSION >= MAKE_VERSION(9, 0, 0)) -#include "MBSFN-AreaInfoList-r9.h" -#include "MBSFN-SubframeConfigList.h" -#include "PMCH-InfoList-r9.h" +#include "LTE_BCCH-BCH-Message.h" +#include "LTE_RadioResourceConfigCommon.h" +#include "LTE_RadioResourceConfigCommonSIB.h" +#include "LTE_RadioResourceConfigDedicated.h" +#include "LTE_MeasGapConfig.h" +#include "LTE_SchedulingInfoList.h" +#include "LTE_TDD-Config.h" +#include "LTE_RACH-ConfigCommon.h" +#include "LTE_MeasObjectToAddModList.h" +#include "LTE_MobilityControlInfo.h" +#if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) +#include "LTE_MBSFN-AreaInfoList-r9.h" +#include "LTE_MBSFN-SubframeConfigList.h" +#include "LTE_PMCH-InfoList-r9.h" #endif -#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) -#include "SCellToAddMod-r10.h" +#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) +#include "LTE_SCellToAddMod-r10.h" #endif -#if (RRC_VERSION >= MAKE_VERSION(13, 0, 0)) -#include "SystemInformationBlockType1-v1310-IEs.h" -#include "SystemInformationBlockType18-r12.h" +#if (LTE_RRC_VERSION >= MAKE_VERSION(13, 0, 0)) +#include "LTE_SystemInformationBlockType1-v1310-IEs.h" +#include "LTE_SystemInformationBlockType18-r12.h" #endif -#include "RadioResourceConfigCommonSIB.h" +#include "LTE_RadioResourceConfigCommonSIB.h" #include "nfapi_interface.h" #include "PHY_INTERFACE/IF_Module.h" @@ -91,7 +91,7 @@ #define DCH_PAYLOAD_SIZE_MAX 4096 /// Logical channel ids from 36-311 (Note BCCH is not specified in 36-311, uses the same as first DRB) -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) // Mask for identifying subframe for MBMS #define MBSFN_TDD_SF3 0x80 // for TDD @@ -380,7 +380,7 @@ typedef struct { uint8_t payload[PCCH_PAYLOAD_SIZE_MAX]; } __attribute__ ((__packed__)) PCCH_PDU; -#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) /*! \brief MCCH payload */ typedef struct { uint8_t payload[MCCH_PAYLOAD_SIZE_MAX]; @@ -437,7 +437,7 @@ typedef struct { /*!\brief LCID of padding LCID for DLSCH */ #define SHORT_PADDING 31 -#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) // MCH LCHAN IDs (table6.2.1-4 TS36.321) /*!\brief LCID of MCCH for DL */ #define MCCH_LCHANID 0 @@ -900,14 +900,14 @@ typedef struct { eNB_UE_estimated_distances distance; #endif -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) uint8_t rach_resource_type; uint16_t mpdcch_repetition_cnt; frame_t Msg2_frame; #endif sub_frame_t Msg2_subframe; - PhysicalConfigDedicated_t *physicalConfigDedicated; + LTE_PhysicalConfigDedicated_t *physicalConfigDedicated; } UE_TEMPLATE; @@ -1047,7 +1047,7 @@ typedef struct { int msg4_TBsize; /// MCS used for Msg4 int msg4_mcs; -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) uint8_t rach_resource_type; uint8_t msg2_mpdcch_repetition_cnt; uint8_t msg4_mpdcch_repetition_cnt; @@ -1243,14 +1243,14 @@ typedef struct { int Ncp; int eutra_band; uint32_t dl_CarrierFreq; - BCCH_BCH_Message_t *mib; - RadioResourceConfigCommonSIB_t *radioResourceConfigCommon; -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - RadioResourceConfigCommonSIB_t *radioResourceConfigCommon_BR; + LTE_BCCH_BCH_Message_t *mib; + LTE_RadioResourceConfigCommonSIB_t *radioResourceConfigCommon; +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + LTE_RadioResourceConfigCommonSIB_t *radioResourceConfigCommon_BR; #endif - TDD_Config_t *tdd_Config; - SchedulingInfoList_t *schedulingInfoList; - ARFCN_ValueEUTRA_t ul_CarrierFreq; + LTE_TDD_Config_t *tdd_Config; + LTE_SchedulingInfoList_t *schedulingInfoList; + LTE_ARFCN_ValueEUTRA_t ul_CarrierFreq; long ul_Bandwidth; /// Outgoing MIB PDU for PHY MIB_PDU MIB_pdu; @@ -1273,10 +1273,10 @@ typedef struct { /// VRB map for common channels and retransmissions by PHICH uint8_t vrb_map_UL[100]; /// MBSFN SubframeConfig - struct MBSFN_SubframeConfig *mbsfn_SubframeConfig[8]; + struct LTE_MBSFN_SubframeConfig *mbsfn_SubframeConfig[8]; /// number of subframe allocation pattern available for MBSFN sync area uint8_t num_sf_allocation_pattern; -#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) /// MBMS Flag uint8_t MBMS_flag; /// Outgoing MCCH pdu for PHY @@ -1290,17 +1290,17 @@ typedef struct { /// number of active MBSFN area uint8_t num_active_mbsfn_area; /// MBSFN Area Info - struct MBSFN_AreaInfo_r9 *mbsfn_AreaInfo[MAX_MBSFN_AREA]; + struct LTE_MBSFN_AreaInfo_r9 *mbsfn_AreaInfo[MAX_MBSFN_AREA]; /// PMCH Config - struct PMCH_Config_r9 *pmch_Config[MAX_PMCH_perMBSFN]; + struct LTE_PMCH_Config_r9 *pmch_Config[MAX_PMCH_perMBSFN]; /// MBMS session info list - struct MBMS_SessionInfoList_r9 *mbms_SessionList[MAX_PMCH_perMBSFN]; + struct LTE_MBMS_SessionInfoList_r9 *mbms_SessionList[MAX_PMCH_perMBSFN]; /// Outgoing MCH pdu for PHY MCH_PDU MCH_pdu; #endif -#if (RRC_VERSION >= MAKE_VERSION(13, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(13, 0, 0)) /// Rel13 parameters from SIB1 - SystemInformationBlockType1_v1310_IEs_t *sib1_v13ext; + LTE_SystemInformationBlockType1_v1310_IEs_t *sib1_v13ext; /// Counter for SIB1-BR scheduling int SIB1_BR_cnt; /// Outgoing BCCH-BR pdu for PHY @@ -1454,9 +1454,9 @@ typedef struct { /// default value is false uint16_t ttiBundling; /// default value is release - struct DRX_Config *drx_config; + struct LTE_DRX_Config *drx_config; /// default value is release - struct MAC_MainConfig__phr_Config *phr_config; + struct LTE_MAC_MainConfig__phr_Config *phr_config; ///timer before triggering a periodic PHR uint16_t periodicPHR_Timer; ///timer before triggering a prohibit PHR @@ -1498,30 +1498,30 @@ typedef struct { /// uplink active flag uint8_t ul_active; /// pointer to RRC PHY configuration - RadioResourceConfigCommonSIB_t *radioResourceConfigCommon; + LTE_RadioResourceConfigCommonSIB_t *radioResourceConfigCommon; /// pointer to RACH_ConfigDedicated (NULL when not active, i.e. upon HO completion or T304 expiry) - struct RACH_ConfigDedicated *rach_ConfigDedicated; + struct LTE_RACH_ConfigDedicated *rach_ConfigDedicated; /// pointer to RRC PHY configuration - struct PhysicalConfigDedicated *physicalConfigDedicated; -#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) + struct LTE_PhysicalConfigDedicated *physicalConfigDedicated; +#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) /// pointer to RRC PHY configuration SCEll - struct PhysicalConfigDedicatedSCell_r10 *physicalConfigDedicatedSCell_r10; + struct LTE_PhysicalConfigDedicatedSCell_r10 *physicalConfigDedicatedSCell_r10; /// Preconfiguration for Sidelink - struct SL_Preconfiguration_r12 *SL_Preconfiguration; + struct LTE_SL_Preconfiguration_r12 *SL_Preconfiguration; /// RX Pool for Sidelink from SIB18 - SL_CommRxPoolList_r12_t commRxPool_r12; + LTE_SL_CommRxPoolList_r12_t commRxPool_r12; /// TX Pool Normal for Sidelink from SIB18 - struct SL_CommTxPoolList_r12 *commTxPoolNormalCommon_r12; + struct LTE_SL_CommTxPoolList_r12 *commTxPoolNormalCommon_r12; /// TX Pool Exceptional for Sidelink from SIB18 - struct SL_CommTxPoolList_r12 *commTxPoolExceptional_r12; + struct LTE_SL_CommTxPoolList_r12 *commTxPoolExceptional_r12; /// Common Sync Config for Sidelink from SIB18 - struct SL_SyncConfigList_r12 *commSyncConfig_r12; + struct LTE_SL_SyncConfigList_r12 *commSyncConfig_r12; /// Dedicated Sync TX control for Sidelink - struct SL_SyncTxControl_r12 *sl_SyncTxControl_r12; + struct LTE_SL_SyncTxControl_r12 *sl_SyncTxControl_r12; /// Dedicated Discovery TX control for Sidelink - struct SL_DiscConfig_r12 *sl_DiscConfig_r12; + struct LTE_SL_DiscConfig_r12 *sl_DiscConfig_r12; /// Dedicated TX config for Sidelink - struct SL_CommConfig_r12 *sl_CommConfig_r12; + struct LTE_SL_CommConfig_r12 *sl_CommConfig_r12; //SL sourceL2ID uint32_t sourceL2Id; //SL groupL2Id @@ -1535,17 +1535,17 @@ typedef struct { #endif /// pointer to TDD Configuration (NULL for FDD) - TDD_Config_t *tdd_Config; + LTE_TDD_Config_t *tdd_Config; /// Number of adjacent cells to measure uint8_t n_adj_cells; /// Array of adjacent physical cell ids uint32_t adj_cell_id[6]; /// Pointer to RRC MAC configuration - MAC_MainConfig_t *macConfig; + LTE_MAC_MainConfig_t *macConfig; /// Pointer to RRC Measurement gap configuration - MeasGapConfig_t *measGapConfig; + LTE_MeasGapConfig_t *measGapConfig; /// Pointers to LogicalChannelConfig indexed by LogicalChannelIdentity. Note NULL means LCHAN is inactive. - LogicalChannelConfig_t *logicalChannelConfig[MAX_NUM_LCID]; + LTE_LogicalChannelConfig_t *logicalChannelConfig[MAX_NUM_LCID]; /// Scheduling Information UE_SCHEDULING_INFO scheduling_info; /// Outgoing CCCH pdu for PHY @@ -1554,7 +1554,7 @@ typedef struct { RAR_PDU RAR_pdu; /// Incoming DLSCH pdu for PHY DLSCH_PDU DLSCH_pdu[MAX_MOBILES_PER_ENB][2]; -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) int sltx_active; SLSCH_t slsch; SLDCH_t sldch; @@ -1610,16 +1610,16 @@ typedef struct { uint8_t periodBSRTimer_expires_flag; /// MBSFN_Subframe Configuration - struct MBSFN_SubframeConfig *mbsfn_SubframeConfig[8]; // FIXME replace 8 by MAX_MBSFN_AREA? + struct LTE_MBSFN_SubframeConfig *mbsfn_SubframeConfig[8]; // FIXME replace 8 by MAX_MBSFN_AREA? /// number of subframe allocation pattern available for MBSFN sync area uint8_t num_sf_allocation_pattern; -#if (RRC_VERSION >= MAKE_VERSION(9, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) /// number of active MBSFN area uint8_t num_active_mbsfn_area; /// MBSFN Area Info - struct MBSFN_AreaInfo_r9 *mbsfn_AreaInfo[MAX_MBSFN_AREA]; + struct LTE_MBSFN_AreaInfo_r9 *mbsfn_AreaInfo[MAX_MBSFN_AREA]; /// PMCH Config - struct PMCH_Config_r9 *pmch_Config[MAX_PMCH_perMBSFN]; + struct LTE_PMCH_Config_r9 *pmch_Config[MAX_PMCH_perMBSFN]; /// MCCH status uint8_t mcch_status; /// MSI status @@ -1627,7 +1627,7 @@ typedef struct { uint8_t msi_current_alloc; uint8_t msi_pmch; - struct MBSFN_SubframeConfig *commonSF_Alloc_r9_mbsfn_SubframeConfig[8]; // FIXME replace 8 by MAX_MBSFN_AREA? + struct LTE_MBSFN_SubframeConfig *commonSF_Alloc_r9_mbsfn_SubframeConfig[8]; // FIXME replace 8 by MAX_MBSFN_AREA? uint8_t commonSF_AllocPeriod_r9; int common_num_sf_alloc; diff --git a/openair2/LAYER2/MAC/mac_proto.h b/openair2/LAYER2/MAC/mac_proto.h index e0fdade419..b953c1d431 100644 --- a/openair2/LAYER2/MAC/mac_proto.h +++ b/openair2/LAYER2/MAC/mac_proto.h @@ -290,7 +290,7 @@ void eNB_dlsch_ulsch_scheduler(module_id_t module_idP, frame_t frameP, sub_frame void initiate_ra_proc(module_id_t module_idP, int CC_id, frame_t frameP, sub_frame_t subframeP, uint16_t preamble_index, int16_t timing_offset, uint16_t rnti -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) , uint8_t rach_resource_type #endif ); @@ -309,7 +309,7 @@ unsigned short fill_rar(const module_id_t module_idP, const uint16_t N_RB_UL, const uint8_t input_buffer_length); -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) unsigned short fill_rar_br(eNB_MAC_INST * eNB, int CC_id, RA_t * ra, @@ -465,7 +465,7 @@ void set_ue_dai(sub_frame_t subframeP, int UE_id, uint8_t CC_id, uint8_t tdd_config, UE_list_t * UE_list); -uint8_t frame_subframe2_dl_harq_pid(TDD_Config_t *tdd_Config, int abs_frameP, sub_frame_t subframeP); +uint8_t frame_subframe2_dl_harq_pid(LTE_TDD_Config_t *tdd_Config, int abs_frameP, sub_frame_t subframeP); /** \brief First stage of PCH Scheduling. Gets a PCH SDU from RRC if available and computes the MCS required to transport it as a function of the SDU length. It assumes a length less than or equal to 64 bytes (MCS 6, 3 PRBs). @param Mod_id Instance ID of eNB @param frame Frame index @@ -549,7 +549,7 @@ void ue_send_sl_sdu(module_id_t module_idP, sl_discovery_flag_t sl_discovery_flag ); -#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) /* \brief Called by PHY to transfer MCH transport block to ue MAC. @param Mod_id Index of module instance @param frame Frame index @@ -694,7 +694,7 @@ int to_prb(int); int to_rbg(int); int mac_init(void); int add_new_ue(module_id_t Mod_id, int CC_id, rnti_t rnti, int harq_pid -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) , uint8_t rach_resource_type #endif ); @@ -956,46 +956,46 @@ int rrc_mac_config_req_eNB(module_id_t module_idP, int p_eNB, int Ncp, int eutra_band, uint32_t dl_CarrierFreq, -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) int pbch_repetition, #endif rnti_t rntiP, - BCCH_BCH_Message_t * mib, - RadioResourceConfigCommonSIB_t * + LTE_BCCH_BCH_Message_t * mib, + LTE_RadioResourceConfigCommonSIB_t * radioResourceConfigCommon, -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - RadioResourceConfigCommonSIB_t * - radioResourceConfigCommon_BR, +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + LTE_RadioResourceConfigCommonSIB_t * + LTE_radioResourceConfigCommon_BR, #endif - struct PhysicalConfigDedicated + struct LTE_PhysicalConfigDedicated *physicalConfigDedicated, -#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) - SCellToAddMod_r10_t * sCellToAddMod_r10, +#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) + LTE_SCellToAddMod_r10_t * sCellToAddMod_r10, //struct PhysicalConfigDedicatedSCell_r10 *physicalConfigDedicatedSCell_r10, #endif - MeasObjectToAddMod_t ** measObj, - MAC_MainConfig_t * mac_MainConfig, + LTE_MeasObjectToAddMod_t ** measObj, + LTE_MAC_MainConfig_t * mac_MainConfig, long logicalChannelIdentity, - LogicalChannelConfig_t * logicalChannelConfig, - MeasGapConfig_t * measGapConfig, - TDD_Config_t * tdd_Config, - MobilityControlInfo_t * mobilityControlInfo, - SchedulingInfoList_t * schedulingInfoList, + LTE_LogicalChannelConfig_t * logicalChannelConfig, + LTE_MeasGapConfig_t * measGapConfig, + LTE_TDD_Config_t * tdd_Config, + LTE_MobilityControlInfo_t * mobilityControlInfo, + LTE_SchedulingInfoList_t * schedulingInfoList, uint32_t ul_CarrierFreq, long *ul_Bandwidth, - AdditionalSpectrumEmission_t * + LTE_AdditionalSpectrumEmission_t * additionalSpectrumEmission, - struct MBSFN_SubframeConfigList + struct LTE_MBSFN_SubframeConfigList *mbsfn_SubframeConfigList -#if (RRC_VERSION >= MAKE_VERSION(9, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) , uint8_t MBMS_Flag, - MBSFN_AreaInfoList_r9_t * mbsfn_AreaInfoList, - PMCH_InfoList_r9_t * pmch_InfoList + LTE_MBSFN_AreaInfoList_r9_t * mbsfn_AreaInfoList, + LTE_PMCH_InfoList_r9_t * pmch_InfoList #endif -#if (RRC_VERSION >= MAKE_VERSION(13, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(13, 0, 0)) , - SystemInformationBlockType1_v1310_IEs_t * + LTE_SystemInformationBlockType1_v1310_IEs_t * sib1_ext_r13 #endif ); @@ -1023,40 +1023,40 @@ int rrc_mac_config_req_eNB(module_id_t module_idP, int rrc_mac_config_req_ue(module_id_t module_idP, int CC_id, uint8_t eNB_index, - RadioResourceConfigCommonSIB_t * + LTE_RadioResourceConfigCommonSIB_t * radioResourceConfigCommon, - struct PhysicalConfigDedicated + struct LTE_PhysicalConfigDedicated *physicalConfigDedicated, -#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) - SCellToAddMod_r10_t * sCellToAddMod_r10, +#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) + LTE_SCellToAddMod_r10_t * sCellToAddMod_r10, //struct PhysicalConfigDedicatedSCell_r10 *physicalConfigDedicatedSCell_r10, #endif - MeasObjectToAddMod_t ** measObj, - MAC_MainConfig_t * mac_MainConfig, + LTE_MeasObjectToAddMod_t ** measObj, + LTE_MAC_MainConfig_t * mac_MainConfig, long logicalChannelIdentity, - LogicalChannelConfig_t * logicalChannelConfig, - MeasGapConfig_t * measGapConfig, - TDD_Config_t * tdd_Config, - MobilityControlInfo_t * mobilityControlInfo, + LTE_LogicalChannelConfig_t * logicalChannelConfig, + LTE_MeasGapConfig_t * measGapConfig, + LTE_TDD_Config_t * tdd_Config, + LTE_MobilityControlInfo_t * mobilityControlInfo, uint8_t * SIwindowsize, uint16_t * SIperiod, - ARFCN_ValueEUTRA_t * ul_CarrierFreq, + LTE_ARFCN_ValueEUTRA_t * ul_CarrierFreq, long *ul_Bandwidth, - AdditionalSpectrumEmission_t * + LTE_AdditionalSpectrumEmission_t * additionalSpectrumEmission, - struct MBSFN_SubframeConfigList + struct LTE_MBSFN_SubframeConfigList *mbsfn_SubframeConfigList -#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) , uint8_t MBMS_Flag, - MBSFN_AreaInfoList_r9_t * mbsfn_AreaInfoList, - PMCH_InfoList_r9_t * pmch_InfoList + LTE_MBSFN_AreaInfoList_r9_t * mbsfn_AreaInfoList, + LTE_PMCH_InfoList_r9_t * pmch_InfoList #endif #ifdef CBA , uint8_t num_active_cba_groups, uint16_t cba_rnti #endif -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) ,config_action_t config_action ,const uint32_t * const sourceL2Id ,const uint32_t * const destinationL2Id @@ -1084,11 +1084,11 @@ uint16_t mac_computeRIV(uint16_t N_RB_DL, uint16_t RBstart, int get_phich_resource_times6(COMMON_channels_t * cc); -uint8_t frame_subframe2_dl_harq_pid(TDD_Config_t *tdd_Config, int abs_frameP, sub_frame_t subframeP); +uint8_t frame_subframe2_dl_harq_pid(LTE_TDD_Config_t *tdd_Config, int abs_frameP, sub_frame_t subframeP); uint8_t ul_subframe2_k_phich(COMMON_channels_t * cc, sub_frame_t ul_subframe); -unsigned char ul_ACK_subframe2M(TDD_Config_t *tdd_Config,unsigned char subframe); +unsigned char ul_ACK_subframe2M(LTE_TDD_Config_t *tdd_Config,unsigned char subframe); int to_rbg(int dl_Bandwidth); @@ -1113,17 +1113,17 @@ void get_srs_pos(COMMON_channels_t * cc, uint16_t isrs, uint16_t * psrsPeriodicity, uint16_t * psrsOffset); void get_csi_params(COMMON_channels_t * cc, - struct CQI_ReportPeriodic *cqi_PMI_ConfigIndex, + struct LTE_CQI_ReportPeriodic *cqi_PMI_ConfigIndex, uint16_t * Npd, uint16_t * N_OFFSET_CQI, int *H); uint8_t get_rel8_dl_cqi_pmi_size(UE_sched_ctrl * sched_ctl, int CC_idP, COMMON_channels_t * cc, uint8_t tmode, - struct CQI_ReportPeriodic + struct LTE_CQI_ReportPeriodic *cqi_ReportPeriodic); uint8_t get_dl_cqi_pmi_size_pusch(COMMON_channels_t * cc, uint8_t tmode, uint8_t ri, - CQI_ReportModeAperiodic_t * + LTE_CQI_ReportModeAperiodic_t * cqi_ReportModeAperiodic); void extract_pucch_csi(module_id_t mod_idP, int CC_idP, int UE_id, frame_t frameP, sub_frame_t subframeP, @@ -1140,7 +1140,7 @@ uint16_t fill_nfapi_tx_req(nfapi_tx_request_body_t * tx_req_body, void fill_nfapi_ulsch_config_request_rel8(nfapi_ul_config_request_pdu_t * ul_config_pdu, uint8_t cqi_req, COMMON_channels_t * cc, - struct PhysicalConfigDedicated + struct LTE_PhysicalConfigDedicated *physicalConfigDedicated, uint8_t tmode, uint32_t handle, uint16_t rnti, @@ -1159,7 +1159,7 @@ void fill_nfapi_ulsch_config_request_rel8(nfapi_ul_config_request_pdu_t * uint8_t current_tx_nb, uint8_t n_srs, uint16_t size); -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) void fill_nfapi_ulsch_config_request_emtc(nfapi_ul_config_request_pdu_t * ul_config_pdu, uint8_t ue_type, uint16_t @@ -1236,7 +1236,7 @@ uint8_t get_tmode(module_id_t module_idP, int CC_idP, int UE_idP); uint8_t get_ul_req_index(module_id_t module_idP, int CC_idP, sub_frame_t subframeP); -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) int get_numnarrowbandbits(long dl_Bandwidth); int mpdcch_sf_condition(eNB_MAC_INST * eNB, int CC_id, frame_t frameP, diff --git a/openair2/LAYER2/MAC/mac_vars.h b/openair2/LAYER2/MAC/mac_vars.h index 76842afd38..4090d954bc 100644 --- a/openair2/LAYER2/MAC/mac_vars.h +++ b/openair2/LAYER2/MAC/mac_vars.h @@ -124,7 +124,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; -#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) DCI1C_5MHz_t MCCH_alloc_pdu; #endif diff --git a/openair2/LAYER2/MAC/pre_processor.c b/openair2/LAYER2/MAC/pre_processor.c index 5846720c7f..341579a084 100644 --- a/openair2/LAYER2/MAC/pre_processor.c +++ b/openair2/LAYER2/MAC/pre_processor.c @@ -124,7 +124,7 @@ store_dlsch_buffer(module_id_t Mod_id, rlc_status = mac_rlc_status_ind(Mod_id, rnti, Mod_id, frameP, subframeP, ENB_FLAG_YES, MBMS_FLAG_NO, lcid, 0 -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) ,0, 0 #endif ); diff --git a/openair2/LAYER2/MAC/ra_procedures.c b/openair2/LAYER2/MAC/ra_procedures.c index aeabbd092a..d139c8bd47 100644 --- a/openair2/LAYER2/MAC/ra_procedures.c +++ b/openair2/LAYER2/MAC/ra_procedures.c @@ -57,12 +57,12 @@ get_prach_resources(module_id_t module_idP, uint8_t eNB_index, uint8_t t_id, uint8_t first_Msg3, - RACH_ConfigDedicated_t * rach_ConfigDedicated) + LTE_RACH_ConfigDedicated_t * rach_ConfigDedicated) { uint8_t Msg3_size = UE_mac_inst[module_idP].RA_Msg3_size; PRACH_RESOURCES_t *prach_resources = &UE_mac_inst[module_idP].RA_prach_resources; - RACH_ConfigCommon_t *rach_ConfigCommon = NULL; + LTE_RACH_ConfigCommon_t *rach_ConfigCommon = NULL; uint8_t noGroupB = 0; uint8_t f_id = 0, num_prach = 0; int numberOfRA_Preambles; @@ -311,8 +311,8 @@ PRACH_RESOURCES_t *ue_get_rach(module_id_t module_idP, int CC_id, uint8_t lcid = CCCH; uint16_t Size16; - struct RACH_ConfigCommon *rach_ConfigCommon = - (struct RACH_ConfigCommon *) NULL; + struct LTE_RACH_ConfigCommon *rach_ConfigCommon = + (struct LTE_RACH_ConfigCommon *) NULL; int32_t frame_diff = 0; uint8_t dcch_header_len = 0; uint16_t sdu_lengths; @@ -408,7 +408,7 @@ PRACH_RESOURCES_t *ue_get_rach(module_id_t module_idP, int CC_id, UE_mac_inst[module_idP].crnti, eNB_indexP, frameP, subframeP, ENB_FLAG_NO, MBMS_FLAG_NO, DCCH, 6 -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) ,0, 0 #endif ); @@ -428,7 +428,7 @@ PRACH_RESOURCES_t *ue_get_rach(module_id_t module_idP, int CC_id, sdu_lengths = mac_rlc_data_req(module_idP, UE_mac_inst[module_idP].crnti, eNB_indexP, frameP, ENB_FLAG_NO, MBMS_FLAG_NO, DCCH, 6, //not used (char *) &ulsch_buff[0] -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) ,0, 0 #endif @@ -553,37 +553,37 @@ PRACH_RESOURCES_t *ue_get_rach(module_id_t module_idP, int CC_id, int preambleTransMax = -1; switch (rach_ConfigCommon->ra_SupervisionInfo. preambleTransMax) { - case PreambleTransMax_n3: + case LTE_PreambleTransMax_n3: preambleTransMax = 3; break; - case PreambleTransMax_n4: + case LTE_PreambleTransMax_n4: preambleTransMax = 4; break; - case PreambleTransMax_n5: + case LTE_PreambleTransMax_n5: preambleTransMax = 5; break; - case PreambleTransMax_n6: + case LTE_PreambleTransMax_n6: preambleTransMax = 6; break; - case PreambleTransMax_n7: + case LTE_PreambleTransMax_n7: preambleTransMax = 7; break; - case PreambleTransMax_n8: + case LTE_PreambleTransMax_n8: preambleTransMax = 8; break; - case PreambleTransMax_n10: + case LTE_PreambleTransMax_n10: preambleTransMax = 10; break; - case PreambleTransMax_n20: + case LTE_PreambleTransMax_n20: preambleTransMax = 20; break; - case PreambleTransMax_n50: + case LTE_PreambleTransMax_n50: preambleTransMax = 50; break; - case PreambleTransMax_n100: + case LTE_PreambleTransMax_n100: preambleTransMax = 100; break; - case PreambleTransMax_n200: + case LTE_PreambleTransMax_n200: preambleTransMax = 200; break; } diff --git a/openair2/LAYER2/MAC/rar_tools.c b/openair2/LAYER2/MAC/rar_tools.c index 2e6b47ff60..3414d7632f 100644 --- a/openair2/LAYER2/MAC/rar_tools.c +++ b/openair2/LAYER2/MAC/rar_tools.c @@ -108,7 +108,7 @@ fill_rar(const module_id_t module_idP, return (ra->rnti); } -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) //------------------------------------------------------------------------------ unsigned short fill_rar_br(eNB_MAC_INST * eNB, diff --git a/openair2/LAYER2/MAC/ue_procedures.c b/openair2/LAYER2/MAC/ue_procedures.c index 2c99b79ce8..3d86187e88 100644 --- a/openair2/LAYER2/MAC/ue_procedures.c +++ b/openair2/LAYER2/MAC/ue_procedures.c @@ -96,22 +96,22 @@ void ue_init_mac(module_id_t module_idP) LOG_I(MAC, "[UE%d] Applying default macMainConfig\n", module_idP); //UE_mac_inst[module_idP].scheduling_info.macConfig=NULL; UE_mac_inst[module_idP].scheduling_info.retxBSR_Timer = - RetxBSR_Timer_r12_sf10240; + LTE_RetxBSR_Timer_r12_sf10240; UE_mac_inst[module_idP].scheduling_info.periodicBSR_Timer = - PeriodicBSR_Timer_r12_infinity; + LTE_PeriodicBSR_Timer_r12_infinity; UE_mac_inst[module_idP].scheduling_info.periodicPHR_Timer = - MAC_MainConfig__phr_Config__setup__periodicPHR_Timer_sf20; + LTE_MAC_MainConfig__phr_Config__setup__periodicPHR_Timer_sf20; UE_mac_inst[module_idP].scheduling_info.prohibitPHR_Timer = - MAC_MainConfig__phr_Config__setup__prohibitPHR_Timer_sf20; + LTE_MAC_MainConfig__phr_Config__setup__prohibitPHR_Timer_sf20; UE_mac_inst[module_idP].scheduling_info.PathlossChange_db = - MAC_MainConfig__phr_Config__setup__dl_PathlossChange_dB1; + LTE_MAC_MainConfig__phr_Config__setup__dl_PathlossChange_dB1; UE_mac_inst[module_idP].PHR_state = - MAC_MainConfig__phr_Config_PR_setup; + LTE_MAC_MainConfig__phr_Config_PR_setup; UE_mac_inst[module_idP].scheduling_info.SR_COUNTER = 0; UE_mac_inst[module_idP].scheduling_info.sr_ProhibitTimer = 0; UE_mac_inst[module_idP].scheduling_info.sr_ProhibitTimer_Running = 0; UE_mac_inst[module_idP].scheduling_info.maxHARQ_Tx = - MAC_MainConfig__ul_SCH_Config__maxHARQ_Tx_n5; + LTE_MAC_MainConfig__ul_SCH_Config__maxHARQ_Tx_n5; UE_mac_inst[module_idP].scheduling_info.ttiBundling = 0; UE_mac_inst[module_idP].scheduling_info.extendedBSR_Sizes_r10 = 0; UE_mac_inst[module_idP].scheduling_info.extendedPHR_r10 = 0; @@ -304,14 +304,14 @@ ue_get_SR(module_id_t module_idP, int CC_id, frame_t frameP, // determin the measurement gap if (UE_mac_inst[module_idP].measGapConfig != NULL) { if (UE_mac_inst[module_idP].measGapConfig->choice.setup. - gapOffset.present == MeasGapConfig__setup__gapOffset_PR_gp0) { + gapOffset.present == LTE_MeasGapConfig__setup__gapOffset_PR_gp0) { MGRP = 40; gapOffset = UE_mac_inst[module_idP].measGapConfig->choice. setup.gapOffset.choice.gp0; } else if (UE_mac_inst[module_idP].measGapConfig->choice. setup.gapOffset.present == - MeasGapConfig__setup__gapOffset_PR_gp1) { + LTE_MeasGapConfig__setup__gapOffset_PR_gp1) { MGRP = 80; gapOffset = UE_mac_inst[module_idP].measGapConfig->choice. @@ -689,7 +689,7 @@ ue_decode_p(module_id_t module_idP, int CC_id, frame_t frameP, } } -#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) unsigned char *parse_mch_header(unsigned char *mac_header, unsigned char *num_sdu, unsigned char *rx_lcids, @@ -1017,7 +1017,7 @@ int ue_query_p_mch(module_id_t module_idP, uint32_t frameP, uint32_t subframe, i if (UE_mac_inst[module_idP].commonSF_Alloc_r9_mbsfn_SubframeConfig[i] == NULL) continue; - if (UE_mac_inst[module_idP].commonSF_Alloc_r9_mbsfn_SubframeConfig[i]->subframeAllocation.present == MBSFN_SubframeConfig__subframeAllocation_PR_oneFrame) // one-frameP format + if (UE_mac_inst[module_idP].commonSF_Alloc_r9_mbsfn_SubframeConfig[i]->subframeAllocation.present == LTE_MBSFN_SubframeConfig__subframeAllocation_PR_oneFrame) // one-frameP format continue; // four-frameP format @@ -1032,7 +1032,7 @@ int ue_query_p_mch(module_id_t module_idP, uint32_t frameP, uint32_t subframe, i if (UE_mac_inst[module_idP].commonSF_Alloc_r9_mbsfn_SubframeConfig[i] == NULL) continue; - if (UE_mac_inst[module_idP].commonSF_Alloc_r9_mbsfn_SubframeConfig[i]->subframeAllocation.present == MBSFN_SubframeConfig__subframeAllocation_PR_oneFrame) // one-frameP format + if (UE_mac_inst[module_idP].commonSF_Alloc_r9_mbsfn_SubframeConfig[i]->subframeAllocation.present == LTE_MBSFN_SubframeConfig__subframeAllocation_PR_oneFrame) // one-frameP format continue; // four-frameP format @@ -1167,7 +1167,7 @@ int ue_query_mch(module_id_t module_idP, uint8_t CC_id, uint32_t frameP, uint32_ break; } - if (UE_mac_inst[module_idP].mbsfn_SubframeConfig[j]->subframeAllocation.present == MBSFN_SubframeConfig__subframeAllocation_PR_oneFrame) { // one-frameP format + if (UE_mac_inst[module_idP].mbsfn_SubframeConfig[j]->subframeAllocation.present == LTE_MBSFN_SubframeConfig__subframeAllocation_PR_oneFrame) { // one-frameP format if (frameP % mbsfn_period == mbsfn_alloc_offset) { // MBSFN frameP if (UE_mac_inst[module_idP].pmch_Config[0]) { @@ -1372,7 +1372,7 @@ int ue_query_mch(module_id_t module_idP, uint8_t CC_id, uint32_t frameP, uint32_ if (UE_mac_inst[module_idP].commonSF_Alloc_r9_mbsfn_SubframeConfig[i] == NULL) continue; - if (UE_mac_inst[module_idP].commonSF_Alloc_r9_mbsfn_SubframeConfig[i]->subframeAllocation.present != MBSFN_SubframeConfig__subframeAllocation_PR_oneFrame) + if (UE_mac_inst[module_idP].commonSF_Alloc_r9_mbsfn_SubframeConfig[i]->subframeAllocation.present != LTE_MBSFN_SubframeConfig__subframeAllocation_PR_oneFrame) continue; uint32_t common_mbsfn_SubframeConfig = UE_mac_inst[module_idP].commonSF_Alloc_r9_mbsfn_SubframeConfig[i]->subframeAllocation.choice.oneFrame.buf[0]; @@ -1919,7 +1919,7 @@ ue_get_sdu(module_id_t module_idP, int CC_id, frame_t frameP, } // periodicBSR-Timer expires, trigger BSR if ((UE_mac_inst[module_idP].scheduling_info.periodicBSR_Timer != - PeriodicBSR_Timer_r12_infinity) + LTE_PeriodicBSR_Timer_r12_infinity) && (UE_mac_inst[module_idP].scheduling_info.periodicBSR_SF == 0)) { // Trigger BSR Periodic UE_mac_inst[module_idP].BSR_reporting_active |= @@ -2055,7 +2055,7 @@ ue_get_sdu(module_id_t module_idP, int CC_id, frame_t frameP, lcid, buflen_remain, (char *)&ulsch_buff[sdu_length_total] -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) ,0, 0 #endif @@ -2447,7 +2447,7 @@ ue_get_sdu(module_id_t module_idP, int CC_id, frame_t frameP, // Reset Periodic Timer except when BSR is truncated if ((bsr_t == NULL) && (UE_mac_inst[module_idP].scheduling_info. - periodicBSR_Timer != PeriodicBSR_Timer_r12_infinity)) { + periodicBSR_Timer != LTE_PeriodicBSR_Timer_r12_infinity)) { UE_mac_inst[module_idP].scheduling_info.periodicBSR_SF = get_sf_periodicBSRTimer(UE_mac_inst [module_idP].scheduling_info. @@ -2506,8 +2506,8 @@ ue_scheduler(const module_id_t module_idP, int bucketsizeduration_max = -1; // mac_rlc_status_resp_t rlc_status[MAX_NUM_LCGID]; // 4 // int8_t lcg_id; - struct RACH_ConfigCommon *rach_ConfigCommon = - (struct RACH_ConfigCommon *) NULL; + struct LTE_RACH_ConfigCommon *rach_ConfigCommon = + (struct LTE_RACH_ConfigCommon *) NULL; protocol_ctxt_t ctxt; #if defined(ENABLE_ITTI) @@ -2600,7 +2600,7 @@ ue_scheduler(const module_id_t module_idP, eNB_indexP); //Invalid...need to add another MAC UE state for re-connection procedure phy_config_afterHO_ue(module_idP, 0, eNB_indexP, - (MobilityControlInfo_t *) NULL, 1); + (LTE_MobilityControlInfo_t *) NULL, 1); //return(3); break; @@ -2765,7 +2765,7 @@ ue_scheduler(const module_id_t module_idP, physicalConfigDedicated->schedulingRequestConfig == NULL) || (UE_mac_inst[module_idP]. physicalConfigDedicated->schedulingRequestConfig->present == - SchedulingRequestConfig_PR_release)) { + LTE_SchedulingRequestConfig_PR_release)) { // initiate RA with CRNTI included in msg3 (no contention) as descibed in 36.321 sec 5.1.5 @@ -2776,7 +2776,7 @@ ue_scheduler(const module_id_t module_idP, } // Put this in a function // Call PHR procedure as described in Section 5.4.6 in 36.321 - if (UE_mac_inst[module_idP].PHR_state == MAC_MainConfig__phr_Config_PR_setup) { // normal operation + if (UE_mac_inst[module_idP].PHR_state == LTE_MAC_MainConfig__phr_Config_PR_setup) { // normal operation if (UE_mac_inst[module_idP].PHR_reconfigured == 1) { // upon (re)configuration of the power headroom reporting functionality by upper layers UE_mac_inst[module_idP].PHR_reporting_active = 1; @@ -3037,7 +3037,7 @@ update_bsr(module_id_t module_idP, frame_t frameP, rlc_status = mac_rlc_status_ind(module_idP, UE_mac_inst[module_idP].crnti,eNB_index,frameP,subframeP,ENB_FLAG_NO,MBMS_FLAG_NO, lcid, 0xFFFF //TBS is not used in RLC at this step, set a special value for debug -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) ,0, 0 #endif ); @@ -3182,63 +3182,63 @@ int get_sf_periodicBSRTimer(uint8_t sf_offset) { switch (sf_offset) { - case PeriodicBSR_Timer_r12_sf5: + case LTE_PeriodicBSR_Timer_r12_sf5: return 5; break; - case PeriodicBSR_Timer_r12_sf10: + case LTE_PeriodicBSR_Timer_r12_sf10: return 10; break; - case PeriodicBSR_Timer_r12_sf16: + case LTE_PeriodicBSR_Timer_r12_sf16: return 16; break; - case PeriodicBSR_Timer_r12_sf20: + case LTE_PeriodicBSR_Timer_r12_sf20: return 20; break; - case PeriodicBSR_Timer_r12_sf32: + case LTE_PeriodicBSR_Timer_r12_sf32: return 32; break; - case PeriodicBSR_Timer_r12_sf40: + case LTE_PeriodicBSR_Timer_r12_sf40: return 40; break; - case PeriodicBSR_Timer_r12_sf64: + case LTE_PeriodicBSR_Timer_r12_sf64: return 64; break; - case PeriodicBSR_Timer_r12_sf80: + case LTE_PeriodicBSR_Timer_r12_sf80: return 80; break; - case PeriodicBSR_Timer_r12_sf128: + case LTE_PeriodicBSR_Timer_r12_sf128: return 128; break; - case PeriodicBSR_Timer_r12_sf160: + case LTE_PeriodicBSR_Timer_r12_sf160: return 160; break; - case PeriodicBSR_Timer_r12_sf320: + case LTE_PeriodicBSR_Timer_r12_sf320: return 320; break; - case PeriodicBSR_Timer_r12_sf640: + case LTE_PeriodicBSR_Timer_r12_sf640: return 640; break; - case PeriodicBSR_Timer_r12_sf1280: + case LTE_PeriodicBSR_Timer_r12_sf1280: return 1280; break; - case PeriodicBSR_Timer_r12_sf2560: + case LTE_PeriodicBSR_Timer_r12_sf2560: return 2560; break; - case PeriodicBSR_Timer_r12_infinity: + case LTE_PeriodicBSR_Timer_r12_infinity: default: return 0xFFFF; break; @@ -3249,27 +3249,27 @@ int get_sf_retxBSRTimer(uint8_t sf_offset) { switch (sf_offset) { - case RetxBSR_Timer_r12_sf320: + case LTE_RetxBSR_Timer_r12_sf320: return 320; break; - case RetxBSR_Timer_r12_sf640: + case LTE_RetxBSR_Timer_r12_sf640: return 640; break; - case RetxBSR_Timer_r12_sf1280: + case LTE_RetxBSR_Timer_r12_sf1280: return 1280; break; - case RetxBSR_Timer_r12_sf2560: + case LTE_RetxBSR_Timer_r12_sf2560: return 2560; break; - case RetxBSR_Timer_r12_sf5120: + case LTE_RetxBSR_Timer_r12_sf5120: return 5120; break; - case RetxBSR_Timer_r12_sf10240: + case LTE_RetxBSR_Timer_r12_sf10240: return 10240; break; @@ -3283,32 +3283,32 @@ int get_ms_bucketsizeduration(uint8_t bucketsizeduration) { switch (bucketsizeduration) { - case LogicalChannelConfig__ul_SpecificParameters__bucketSizeDuration_ms50: + case LTE_LogicalChannelConfig__ul_SpecificParameters__bucketSizeDuration_ms50: return 50; break; - case LogicalChannelConfig__ul_SpecificParameters__bucketSizeDuration_ms100: + case LTE_LogicalChannelConfig__ul_SpecificParameters__bucketSizeDuration_ms100: return 100; break; - case LogicalChannelConfig__ul_SpecificParameters__bucketSizeDuration_ms150: + case LTE_LogicalChannelConfig__ul_SpecificParameters__bucketSizeDuration_ms150: return 150; break; - case LogicalChannelConfig__ul_SpecificParameters__bucketSizeDuration_ms300: + case LTE_LogicalChannelConfig__ul_SpecificParameters__bucketSizeDuration_ms300: return 300; break; - case LogicalChannelConfig__ul_SpecificParameters__bucketSizeDuration_ms500: + case LTE_LogicalChannelConfig__ul_SpecificParameters__bucketSizeDuration_ms500: return 500; break; - case LogicalChannelConfig__ul_SpecificParameters__bucketSizeDuration_ms1000: + case LTE_LogicalChannelConfig__ul_SpecificParameters__bucketSizeDuration_ms1000: return 1000; break; @@ -3369,19 +3369,19 @@ int get_sf_prohibitPHR_Timer(uint8_t prohibitPHR_Timer) int get_db_dl_PathlossChange(uint8_t dl_PathlossChange) { switch (dl_PathlossChange) { - case MAC_MainConfig__phr_Config__setup__dl_PathlossChange_dB1: + case LTE_MAC_MainConfig__phr_Config__setup__dl_PathlossChange_dB1: return 1; break; - case MAC_MainConfig__phr_Config__setup__dl_PathlossChange_dB3: + case LTE_MAC_MainConfig__phr_Config__setup__dl_PathlossChange_dB3: return 3; break; - case MAC_MainConfig__phr_Config__setup__dl_PathlossChange_dB6: + case LTE_MAC_MainConfig__phr_Config__setup__dl_PathlossChange_dB6: return 6; break; - case MAC_MainConfig__phr_Config__setup__dl_PathlossChange_infinity: + case LTE_MAC_MainConfig__phr_Config__setup__dl_PathlossChange_infinity: default: return -1; break; @@ -3478,7 +3478,7 @@ SLSCH_t *ue_get_slsch(module_id_t module_idP,int CC_id,frame_t frameP,sub_frame_ ue->slsch_lcid, req, (char*)(ue->slsch_pdu.payload + sizeof(SLSCH_SUBHEADER_24_Bit_DST_LONG)) -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) ,ue->sourceL2Id, ue->destinationL2Id #endif diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp.c b/openair2/LAYER2/PDCP_v10.1.0/pdcp.c index 05ddb4151f..6167e1e6ca 100644 --- a/openair2/LAYER2/PDCP_v10.1.0/pdcp.c +++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp.c @@ -96,7 +96,7 @@ boolean_t pdcp_data_req( const sdu_size_t sdu_buffer_sizeP, unsigned char *const sdu_buffer_pP, const pdcp_transmission_mode_t modeP -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) ,const uint32_t * const sourceL2Id ,const uint32_t * const destinationL2Id #endif @@ -143,7 +143,7 @@ boolean_t pdcp_data_req( if (srb_flagP) { AssertError (rb_idP < 3, return FALSE, "RB id is too high (%u/%d) %u %u!\n", rb_idP, 3, ctxt_pP->module_id, ctxt_pP->rnti); } else { - AssertError (rb_idP < maxDRB, return FALSE, "RB id is too high (%u/%d) %u %u!\n", rb_idP, maxDRB, ctxt_pP->module_id, ctxt_pP->rnti); + AssertError (rb_idP < LTE_maxDRB, return FALSE, "RB id is too high (%u/%d) %u %u!\n", rb_idP, LTE_maxDRB, ctxt_pP->module_id, ctxt_pP->rnti); } } @@ -183,7 +183,7 @@ boolean_t pdcp_data_req( sdu_buffer_sizeP); #endif rlc_status = rlc_data_req(ctxt_pP, srb_flagP, MBMS_FLAG_YES, rb_idP, muiP, confirmP, sdu_buffer_sizeP, pdcp_pdu_p -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) ,NULL, NULL #endif ); @@ -317,7 +317,7 @@ boolean_t pdcp_data_req( pdcp_apply_security(ctxt_pP, pdcp_p, srb_flagP, - rb_idP % maxDRB, + rb_idP % LTE_maxDRB, pdcp_header_len, current_sn, pdcp_pdu_p->data, @@ -367,7 +367,7 @@ boolean_t pdcp_data_req( "[MSG] PDCP DL %s PDU on rb_id %d\n",(srb_flagP)? "CONTROL" : "DATA", rb_idP); rlc_status = rlc_data_req(ctxt_pP, srb_flagP, MBMS_FLAG_NO, rb_idP, muiP, confirmP, pdcp_pdu_size, pdcp_pdu_p -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) ,sourceL2Id ,destinationL2Id #endif @@ -504,15 +504,15 @@ pdcp_data_ind( } } else { - rb_id = rb_idP % maxDRB; - AssertError (rb_id < maxDRB, return FALSE, "RB id is too high (%u/%d) %u UE %x!\n", + rb_id = rb_idP % LTE_maxDRB; + AssertError (rb_id < LTE_maxDRB, return FALSE, "RB id is too high (%u/%d) %u UE %x!\n", rb_id, - maxDRB, + LTE_maxDRB, ctxt_pP->module_id, ctxt_pP->rnti); AssertError (rb_id > 0, return FALSE, "RB id is too low (%u/%d) %u UE %x!\n", rb_id, - maxDRB, + LTE_maxDRB, ctxt_pP->module_id, ctxt_pP->rnti); key = PDCP_COLL_KEY_VALUE(ctxt_pP->module_id, ctxt_pP->rnti, ctxt_pP->enb_flag, rb_id, srb_flagP); @@ -798,7 +798,7 @@ pdcp_data_ind( ((pdcp_data_ind_header_t*) new_sdu_p->data)->inst = 1; #endif } else { - ((pdcp_data_ind_header_t*) new_sdu_p->data)->rb_id = rb_id + (ctxt_pP->module_id * maxDRB); + ((pdcp_data_ind_header_t*) new_sdu_p->data)->rb_id = rb_id + (ctxt_pP->module_id * LTE_maxDRB); } ((pdcp_data_ind_header_t*) new_sdu_p->data)->inst = ctxt_pP->module_id; @@ -980,7 +980,7 @@ pdcp_run ( RRC_DCCH_DATA_REQ (msg_p).sdu_size, RRC_DCCH_DATA_REQ (msg_p).sdu_p, RRC_DCCH_DATA_REQ (msg_p).mode -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) , NULL, NULL #endif ); @@ -1083,8 +1083,8 @@ pdcp_remove_UE( ) //----------------------------------------------------------------------------- { - DRB_Identity_t srb_id = 0; - DRB_Identity_t drb_id = 0; + LTE_DRB_Identity_t srb_id = 0; + LTE_DRB_Identity_t drb_id = 0; hash_key_t key = HASHTABLE_NOT_A_KEY_VALUE; hashtable_rc_t h_rc; int i; @@ -1102,7 +1102,7 @@ pdcp_remove_UE( h_rc = hashtable_remove(pdcp_coll_p, key); } - for (drb_id=0; drb_idmodule_id, ctxt_pP->rnti, ctxt_pP->enb_flag, drb_id, SRB_FLAG_NO); h_rc = hashtable_remove(pdcp_coll_p, key); @@ -1131,44 +1131,44 @@ pdcp_remove_UE( boolean_t rrc_pdcp_config_asn1_req ( const protocol_ctxt_t* const ctxt_pP, - SRB_ToAddModList_t *const srb2add_list_pP, - DRB_ToAddModList_t *const drb2add_list_pP, - DRB_ToReleaseList_t *const drb2release_list_pP, + LTE_SRB_ToAddModList_t *const srb2add_list_pP, + LTE_DRB_ToAddModList_t *const drb2add_list_pP, + LTE_DRB_ToReleaseList_t *const drb2release_list_pP, const uint8_t security_modeP, uint8_t *const kRRCenc_pP, uint8_t *const kRRCint_pP, uint8_t *const kUPenc_pP -#if (RRC_VERSION >= MAKE_VERSION(9, 0, 0)) - ,PMCH_InfoList_r9_t* const pmch_InfoList_r9_pP +#if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) + ,LTE_PMCH_InfoList_r9_t* const pmch_InfoList_r9_pP #endif ,rb_id_t *const defaultDRB ) //----------------------------------------------------------------------------- { long int lc_id = 0; - DRB_Identity_t srb_id = 0; + LTE_DRB_Identity_t srb_id = 0; long int mch_id = 0; rlc_mode_t rlc_type = RLC_MODE_NONE; - DRB_Identity_t drb_id = 0; - DRB_Identity_t *pdrb_id_p = NULL; + LTE_DRB_Identity_t drb_id = 0; + LTE_DRB_Identity_t *pdrb_id_p = NULL; uint8_t drb_sn = 12; uint8_t srb_sn = 5; // fixed sn for SRBs uint8_t drb_report = 0; long int cnt = 0; uint16_t header_compression_profile = 0; config_action_t action = CONFIG_ACTION_ADD; - SRB_ToAddMod_t *srb_toaddmod_p = NULL; - DRB_ToAddMod_t *drb_toaddmod_p = NULL; + LTE_SRB_ToAddMod_t *srb_toaddmod_p = NULL; + LTE_DRB_ToAddMod_t *drb_toaddmod_p = NULL; pdcp_t *pdcp_p = NULL; hash_key_t key = HASHTABLE_NOT_A_KEY_VALUE; hashtable_rc_t h_rc; hash_key_t key_defaultDRB = HASHTABLE_NOT_A_KEY_VALUE; hashtable_rc_t h_defaultDRB_rc; -#if (RRC_VERSION >= MAKE_VERSION(9, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) int i,j; - MBMS_SessionInfoList_r9_t *mbms_SessionInfoList_r9_p = NULL; - MBMS_SessionInfo_r9_t *MBMS_SessionInfo_p = NULL; + LTE_MBMS_SessionInfoList_r9_t *mbms_SessionInfoList_r9_p = NULL; + LTE_MBMS_SessionInfo_r9_t *MBMS_SessionInfo_p = NULL; #endif LOG_T(PDCP, PROTOCOL_CTXT_FMT" %s() SRB2ADD %p DRB2ADD %p DRB2RELEASE %p\n", @@ -1215,12 +1215,12 @@ rrc_pdcp_config_asn1_req ( if (srb_toaddmod_p->rlc_Config) { switch (srb_toaddmod_p->rlc_Config->present) { - case SRB_ToAddMod__rlc_Config_PR_NOTHING: + case LTE_SRB_ToAddMod__rlc_Config_PR_NOTHING: break; - case SRB_ToAddMod__rlc_Config_PR_explicitValue: + case LTE_SRB_ToAddMod__rlc_Config_PR_explicitValue: switch (srb_toaddmod_p->rlc_Config->choice.explicitValue.present) { - case RLC_Config_PR_NOTHING: + case LTE_RLC_Config_PR_NOTHING: break; default: @@ -1245,7 +1245,7 @@ rrc_pdcp_config_asn1_req ( break; - case SRB_ToAddMod__rlc_Config_PR_defaultValue: + case LTE_SRB_ToAddMod__rlc_Config_PR_defaultValue: pdcp_config_req_asn1 ( ctxt_pP, pdcp_p, @@ -1294,7 +1294,7 @@ rrc_pdcp_config_asn1_req ( continue; } - DevCheck4(drb_id < maxDRB, drb_id, maxDRB, ctxt_pP->module_id, ctxt_pP->rnti); + DevCheck4(drb_id < LTE_maxDRB, drb_id, LTE_maxDRB, ctxt_pP->module_id, ctxt_pP->rnti); key = PDCP_COLL_KEY_VALUE(ctxt_pP->module_id, ctxt_pP->rnti, ctxt_pP->enb_flag, drb_id, SRB_FLAG_NO); h_rc = hashtable_get(pdcp_coll_p, key, (void**)&pdcp_p); @@ -1343,7 +1343,7 @@ rrc_pdcp_config_asn1_req ( if (drb_toaddmod_p->pdcp_Config->rlc_AM) { drb_report = drb_toaddmod_p->pdcp_Config->rlc_AM->statusReportRequired; - drb_sn = PDCP_Config__rlc_UM__pdcp_SN_Size_len12bits; // default SN size + drb_sn = LTE_PDCP_Config__rlc_UM__pdcp_SN_Size_len12bits; // default SN size rlc_type = RLC_MODE_AM; } @@ -1353,12 +1353,12 @@ rrc_pdcp_config_asn1_req ( } switch (drb_toaddmod_p->pdcp_Config->headerCompression.present) { - case PDCP_Config__headerCompression_PR_NOTHING: - case PDCP_Config__headerCompression_PR_notUsed: + case LTE_PDCP_Config__headerCompression_PR_NOTHING: + case LTE_PDCP_Config__headerCompression_PR_notUsed: header_compression_profile=0x0; break; - case PDCP_Config__headerCompression_PR_rohc: + case LTE_PDCP_Config__headerCompression_PR_rohc: // parse the struc and get the rohc profile if(drb_toaddmod_p->pdcp_Config->headerCompression.choice.rohc.profiles.profile0x0001) { @@ -1463,7 +1463,7 @@ rrc_pdcp_config_asn1_req ( } } -#if (RRC_VERSION >= MAKE_VERSION(9, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) if (pmch_InfoList_r9_pP != NULL) { for (i=0; ilist.count; i++) { @@ -1480,7 +1480,7 @@ rrc_pdcp_config_asn1_req ( // can set the mch_id = i if (ctxt_pP->enb_flag) { - drb_id = (mch_id * maxSessionPerPMCH ) + lc_id ;//+ (maxDRB + 3)*MAX_MOBILES_PER_ENB; // 1 + drb_id = (mch_id * LTE_maxSessionPerPMCH ) + lc_id ;//+ (LTE_maxDRB + 3)*MAX_MOBILES_PER_ENB; // 1 if (pdcp_mbms_array_eNB[ctxt_pP->module_id][mch_id][lc_id].instanciated_instance == TRUE) { action = CONFIG_ACTION_MBMS_MODIFY; @@ -1488,7 +1488,7 @@ rrc_pdcp_config_asn1_req ( action = CONFIG_ACTION_MBMS_ADD; } } else { - drb_id = (mch_id * maxSessionPerPMCH ) + lc_id; // + (maxDRB + 3); // 15 + drb_id = (mch_id * LTE_maxSessionPerPMCH ) + lc_id; // + (LTE_maxDRB + 3); // 15 if (pdcp_mbms_array_ue[ctxt_pP->module_id][mch_id][lc_id].instanciated_instance == TRUE) { action = CONFIG_ACTION_MBMS_MODIFY; @@ -1580,9 +1580,9 @@ pdcp_config_req_asn1 ( pdcp_pP->header_compression_profile = header_compression_profileP; pdcp_pP->status_report = rb_reportP; - if (rb_snP == PDCP_Config__rlc_UM__pdcp_SN_Size_len12bits) { + if (rb_snP == LTE_PDCP_Config__rlc_UM__pdcp_SN_Size_len12bits) { pdcp_pP->seq_num_size = PDCP_SN_12BIT; - } else if (rb_snP == PDCP_Config__rlc_UM__pdcp_SN_Size_len7bits) { + } else if (rb_snP == LTE_PDCP_Config__rlc_UM__pdcp_SN_Size_len7bits) { pdcp_pP->seq_num_size = PDCP_SN_7BIT; } else { pdcp_pP->seq_num_size = PDCP_SN_5BIT; @@ -1640,9 +1640,9 @@ pdcp_config_req_asn1 ( kUPenc_pP); } - if (rb_snP == PDCP_Config__rlc_UM__pdcp_SN_Size_len7bits) { + if (rb_snP == LTE_PDCP_Config__rlc_UM__pdcp_SN_Size_len7bits) { pdcp_pP->seq_num_size = 7; - } else if (rb_snP == PDCP_Config__rlc_UM__pdcp_SN_Size_len12bits) { + } else if (rb_snP == LTE_PDCP_Config__rlc_UM__pdcp_SN_Size_len12bits) { pdcp_pP->seq_num_size = 12; } else { pdcp_pP->seq_num_size=5; @@ -1685,7 +1685,7 @@ pdcp_config_req_asn1 ( memset(pdcp_pP, 0, sizeof(pdcp_t)); break; -#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) case CONFIG_ACTION_MBMS_ADD: case CONFIG_ACTION_MBMS_MODIFY: @@ -2006,7 +2006,7 @@ void pdcp_layer_init(void) module_id_t instance; int i,j; -#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) mbms_session_id_t session_id; mbms_service_id_t service_id; #endif @@ -2014,14 +2014,14 @@ void pdcp_layer_init(void) * Initialize SDU list */ list_init(&pdcp_sdu_list, NULL); - pdcp_coll_p = hashtable_create ((maxDRB + 2) * 16, NULL, pdcp_free); + pdcp_coll_p = hashtable_create ((LTE_maxDRB + 2) * 16, NULL, pdcp_free); AssertFatal(pdcp_coll_p != NULL, "UNRECOVERABLE error, PDCP hashtable_create failed"); for (instance = 0; instance < MAX_MOBILES_PER_ENB; instance++) { -#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) - for (service_id = 0; service_id < maxServiceCount; service_id++) { - for (session_id = 0; session_id < maxSessionPerPMCH; session_id++) { + for (service_id = 0; service_id < LTE_maxServiceCount; service_id++) { + for (session_id = 0; session_id < LTE_maxSessionPerPMCH; session_id++) { memset(&pdcp_mbms_array_ue[instance][service_id][session_id], 0, sizeof(pdcp_mbms_t)); } } @@ -2032,10 +2032,10 @@ void pdcp_layer_init(void) for (instance = 0; instance < NUMBER_OF_eNB_MAX; instance++) { -#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) - for (service_id = 0; service_id < maxServiceCount; service_id++) { - for (session_id = 0; session_id < maxSessionPerPMCH; session_id++) { + for (service_id = 0; service_id < LTE_maxServiceCount; service_id++) { + for (session_id = 0; session_id < LTE_maxSessionPerPMCH; session_id++) { memset(&pdcp_mbms_array_eNB[instance][service_id][session_id], 0, sizeof(pdcp_mbms_t)); } } diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp.h b/openair2/LAYER2/PDCP_v10.1.0/pdcp.h index 054bb5fac4..bc3bdac828 100644 --- a/openair2/LAYER2/PDCP_v10.1.0/pdcp.h +++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp.h @@ -42,13 +42,13 @@ #include "RRC/LTE/rrc_defs.h" #include "COMMON/platform_constants.h" #include "COMMON/platform_types.h" -#include "DRB-ToAddMod.h" -#include "DRB-ToAddModList.h" -#include "SRB-ToAddMod.h" -#include "SRB-ToAddModList.h" -#if (RRC_VERSION >= MAKE_VERSION(9, 0, 0)) -#include "MBMS-SessionInfoList-r9.h" -#include "PMCH-InfoList-r9.h" +#include "LTE_DRB-ToAddMod.h" +#include "LTE_DRB-ToAddModList.h" +#include "LTE_SRB-ToAddMod.h" +#include "LTE_SRB-ToAddModList.h" +#if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) +#include "LTE_MBMS-SessionInfoList-r9.h" +#include "LTE_PMCH-InfoList-r9.h" #endif @@ -195,7 +195,7 @@ typedef struct pdcp_s { } pdcp_t; -#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) typedef struct pdcp_mbms_s { boolean_t instanciated_instance; rb_id_t rb_id; @@ -232,7 +232,7 @@ boolean_t pdcp_data_req( const sdu_size_t sdu_buffer_size, unsigned char* const sdu_buffer, const pdcp_transmission_mode_t mode -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) ,const uint32_t * const sourceL2Id ,const uint32_t * const destinationL2Id #endif @@ -292,15 +292,15 @@ void rrc_pdcp_config_req ( */ boolean_t rrc_pdcp_config_asn1_req ( const protocol_ctxt_t* const ctxt_pP, - SRB_ToAddModList_t *const srb2add_list, - DRB_ToAddModList_t *const drb2add_list, - DRB_ToReleaseList_t *const drb2release_list, + LTE_SRB_ToAddModList_t *const srb2add_list, + LTE_DRB_ToAddModList_t *const drb2add_list, + LTE_DRB_ToReleaseList_t *const drb2release_list, const uint8_t security_modeP, uint8_t *const kRRCenc, uint8_t *const kRRCint, uint8_t *const kUPenc -#if (RRC_VERSION >= MAKE_VERSION(9, 0, 0)) - ,PMCH_InfoList_r9_t *pmch_InfoList_r9 +#if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) + ,LTE_PMCH_InfoList_r9_t *pmch_InfoList_r9 #endif ,rb_id_t *const defaultDRB ); @@ -404,7 +404,7 @@ typedef struct pdcp_data_req_header_s { sdu_size_t data_size; signed int inst; ip_traffic_type_t traffic_type; -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) uint32_t sourceL2Id; uint32_t destinationL2Id; #endif @@ -415,7 +415,7 @@ typedef struct pdcp_data_ind_header_s { sdu_size_t data_size; signed int inst; ip_traffic_type_t dummy_traffic_type; -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) uint32_t sourceL2Id; uint32_t destinationL2Id; #endif @@ -429,7 +429,7 @@ struct pdcp_netlink_element_s { }; //TTN for D2D (PC5S) -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) #define PDCP_SOCKET_PORT_NO 9999 //temporary value #define PC5_SIGNALLING_PAYLOAD_SIZE 100 //should be updated with a correct value int pdcp_pc5_sockfd; @@ -499,9 +499,9 @@ pdcp_stats_t eNB_pdcp_stats[NUMBER_OF_eNB_MAX]; rnti_t pdcp_UE_UE_module_id_to_rnti[MAX_MOBILES_PER_ENB]; rnti_t pdcp_eNB_UE_instance_to_rnti[MAX_MOBILES_PER_ENB]; // for noS1 mode unsigned int pdcp_eNB_UE_instance_to_rnti_index; -#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) -pdcp_mbms_t pdcp_mbms_array_ue[MAX_MOBILES_PER_ENB][maxServiceCount][maxSessionPerPMCH]; // some constants from openair2/RRC/LTE/MESSAGES/asn1_constants.h -pdcp_mbms_t pdcp_mbms_array_eNB[NUMBER_OF_eNB_MAX][maxServiceCount][maxSessionPerPMCH]; // some constants from openair2/RRC/LTE/MESSAGES/asn1_constants.h +#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) +pdcp_mbms_t pdcp_mbms_array_ue[MAX_MOBILES_PER_ENB][LTE_maxServiceCount][LTE_maxSessionPerPMCH]; // some constants from openair2/RRC/LTE/MESSAGES/asn1_constants.h +pdcp_mbms_t pdcp_mbms_array_eNB[NUMBER_OF_eNB_MAX][LTE_maxServiceCount][LTE_maxSessionPerPMCH]; // some constants from openair2/RRC/LTE/MESSAGES/asn1_constants.h #endif sdu_size_t pdcp_output_sdu_bytes_to_write; sdu_size_t pdcp_output_header_bytes_to_write; diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c b/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c index 92409d96dc..7cab8cb40e 100644 --- a/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c +++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c @@ -178,7 +178,7 @@ int pdcp_fifo_flush_sdus(const protocol_ctxt_t* const ctxt_pP) LOG_D(PDCP,"Sending to GTPV1U %d bytes\n", ((pdcp_data_ind_header_t *)(sdu_p->data))->data_size); gtpv1u_new_data_req( ctxt_pP->module_id, //gtpv1u_data_t *gtpv1u_data_p, - ctxt_pP->rnti,//rb_id/maxDRB, TO DO UE ID + ctxt_pP->rnti,//rb_id/LTE_maxDRB, TO DO UE ID ((pdcp_data_ind_header_t *)(sdu_p->data))->rb_id + 4, &(((uint8_t *) sdu_p->data)[sizeof (pdcp_data_ind_header_t)]), ((pdcp_data_ind_header_t *)(sdu_p->data))->data_size, @@ -202,7 +202,7 @@ int pdcp_fifo_flush_sdus(const protocol_ctxt_t* const ctxt_pP) cont = 0; //TTN - for D2D (PC5S) -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) sidelink_pc5s_element *sl_pc5s_msg_recv = NULL; char send_buf[BUFSIZE]; int rb_id = ((pdcp_data_ind_header_t *)(sdu_p->data))->rb_id; @@ -452,7 +452,7 @@ int pdcp_fifo_read_input_sdus (const protocol_ctxt_t* const ctxt_pP) pdcp_data_req(&ctxt, SRB_FLAG_NO, rab_id, RLC_MUI_UNDEFINED, RLC_SDU_CONFIRM_NO, len, (unsigned char *)nl_rx_buf, PDCP_TRANSMISSION_MODE_DATA -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) , NULL, NULL #endif ); @@ -488,7 +488,7 @@ int pdcp_fifo_read_input_sdus (const protocol_ctxt_t* const ctxt_pP) pdcp_t* pdcp_p = NULL; //TTN for D2D (PC5S) -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) int prose_addr_len; char send_buf[BUFSIZE], receive_buf[BUFSIZE]; //int optval; @@ -509,7 +509,7 @@ int pdcp_fifo_read_input_sdus (const protocol_ctxt_t* const ctxt_pP) while (pdcp_netlink_dequeue_element(ctxt_pP, &data_p) != 0) { DevAssert(data_p != NULL); - rab_id = data_p->pdcp_read_header.rb_id % maxDRB; + rab_id = data_p->pdcp_read_header.rb_id % LTE_maxDRB; // ctxt_pP->rnti is NOT_A_RNTI ctxt_cpy.rnti = pdcp_module_id_to_rnti[ctxt_cpy.module_id][data_p->pdcp_read_header.inst]; key = PDCP_COLL_KEY_VALUE(ctxt_pP->module_id, ctxt_cpy.rnti, ctxt_pP->enb_flag, rab_id, SRB_FLAG_NO); @@ -526,7 +526,7 @@ int pdcp_fifo_read_input_sdus (const protocol_ctxt_t* const ctxt_pP) CHECK_CTXT_ARGS(&ctxt_cpy); - AssertFatal (rab_id < maxDRB, "RB id is too high (%u/%d)!\n", rab_id, maxDRB); + AssertFatal (rab_id < LTE_maxDRB, "RB id is too high (%u/%d)!\n", rab_id, LTE_maxDRB); if (rab_id != 0) { LOG_D(PDCP, "[FRAME %05d][%s][IP][INSTANCE %u][RB %u][--- PDCP_DATA_REQ " @@ -543,7 +543,7 @@ int pdcp_fifo_read_input_sdus (const protocol_ctxt_t* const ctxt_pP) if ((data_p->pdcp_read_header.traffic_type == TRAFFIC_IPV6_TYPE_MULTICAST) /*TRAFFIC_IPV6_TYPE_MULTICAST */ || (data_p->pdcp_read_header.traffic_type == TRAFFIC_IPV4_TYPE_MULTICAST) /*TRAFFIC_IPV4_TYPE_MULTICAST */ || (data_p->pdcp_read_header.traffic_type == TRAFFIC_IPV4_TYPE_BROADCAST) /*TRAFFIC_IPV4_TYPE_BROADCAST */ ) { -#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) PDCP_TRANSMISSION_MODE_TRANSPARENT; #else pdcp_mode= PDCP_TRANSMISSION_MODE_DATA; @@ -561,13 +561,13 @@ int pdcp_fifo_read_input_sdus (const protocol_ctxt_t* const ctxt_pP) #endif pdcp_data_req(&ctxt_cpy, SRB_FLAG_NO, - rab_id % maxDRB, + rab_id % LTE_maxDRB, RLC_MUI_UNDEFINED, RLC_SDU_CONFIRM_NO, data_p->pdcp_read_header.data_size, data_p->data, pdcp_mode -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) ,NULL, NULL #endif ); @@ -595,7 +595,7 @@ int pdcp_fifo_read_input_sdus (const protocol_ctxt_t* const ctxt_pP) data_p->pdcp_read_header.data_size, data_p->data, PDCP_TRANSMISSION_MODE_DATA -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) ,NULL, NULL #endif ); @@ -612,7 +612,7 @@ int pdcp_fifo_read_input_sdus (const protocol_ctxt_t* const ctxt_pP) data_p->pdcp_read_header.data_size, data_p->data, PDCP_TRANSMISSION_MODE_DATA -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) ,NULL, NULL #endif ); @@ -632,7 +632,7 @@ int pdcp_fifo_read_input_sdus (const protocol_ctxt_t* const ctxt_pP) //TTN for D2D (PC5S) -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) prose_addr_len = sizeof(prose_pdcp_addr); // receive a message from ProSe App memset(receive_buf, 0, BUFSIZE); @@ -680,18 +680,18 @@ int pdcp_fifo_read_input_sdus (const protocol_ctxt_t* const ctxt_pP) ctxt.frame = ctxt_cpy.frame; ctxt.enb_flag = ENB_FLAG_YES; ctxt.module_id = pc5s_header.inst + oai_emulation.info.first_enb_local; - ctxt.rnti = oai_emulation.info.eNB_ue_module_id_to_rnti[ctxt.module_id ][pc5s_header->rb_id / maxDRB + oai_emulation.info.first_ue_local]; - rab_id = pc5s_header->rb_id % maxDRB; + ctxt.rnti = oai_emulation.info.eNB_ue_module_id_to_rnti[ctxt.module_id ][pc5s_header->rb_id / LTE_maxDRB + oai_emulation.info.first_ue_local]; + rab_id = pc5s_header->rb_id % LTE_maxDRB; } else { ctxt.frame = ctxt_cpy.frame; ctxt.enb_flag = ENB_FLAG_NO; ctxt.module_id = pc5s_header->inst - oai_emulation.info.nb_enb_local + oai_emulation.info.first_ue_local; ctxt.rnti = pdcp_UE_UE_module_id_to_rnti[ctxt.module_id]; - rab_id = pc5s_header->rb_id % maxDRB; + rab_id = pc5s_header->rb_id % LTE_maxDRB; } CHECK_CTXT_ARGS(&ctxt); - AssertFatal (rab_id < maxDRB, "RB id is too high (%u/%d)!\n", rab_id, maxDRB); + AssertFatal (rab_id < LTE_maxDRB, "RB id is too high (%u/%d)!\n", rab_id, LTE_maxDRB); /*LGpdcp_read_header.inst = (pc5s_header.inst >= oai_emulation.info.nb_enb_local) ? \ pc5s_header.inst - oai_emulation.info.nb_enb_local+ NB_eNB_INST + oai_emulation.info.first_ue_local : pc5s_header.inst + oai_emulation.info.first_enb_local;*/ @@ -706,11 +706,11 @@ int pdcp_fifo_read_input_sdus (const protocol_ctxt_t* const ctxt_pP) if (ctxt_cpy.enb_flag) { ctxt.module_id = 0; - rab_id = pc5s_header->rb_id % maxDRB; + rab_id = pc5s_header->rb_id % LTE_maxDRB; ctxt.rnti = pdcp_eNB_UE_instance_to_rnti[pdcp_eNB_UE_instance_to_rnti_index]; } else { ctxt.module_id = 0; - rab_id = pc5s_header->rb_id % maxDRB; + rab_id = pc5s_header->rb_id % LTE_maxDRB; ctxt.rnti = pdcp_UE_UE_module_id_to_rnti[ctxt.module_id]; } #endif @@ -726,7 +726,7 @@ int pdcp_fifo_read_input_sdus (const protocol_ctxt_t* const ctxt_pP) LOG_I(PDCP,"request key %x : (%d,%x,%d,%d)\n", (uint8_t)key,ctxt.module_id, ctxt.rnti, ctxt.enb_flag, rab_id); } else { - rab_id = rab_id % maxDRB; + rab_id = rab_id % LTE_maxDRB; LOG_I(PDCP, "PDCP_COLL_KEY_VALUE(module_id=%d, rnti=%x, enb_flag=%d, rab_id=%d, SRB_FLAG=%d)\n", ctxt.module_id, ctxt.rnti, ctxt.enb_flag, rab_id, SRB_FLAG_NO); key = PDCP_COLL_KEY_VALUE(ctxt.module_id, ctxt.rnti, ctxt.enb_flag, rab_id, SRB_FLAG_NO); @@ -774,7 +774,7 @@ int pdcp_fifo_read_input_sdus (const protocol_ctxt_t* const ctxt_pP) pc5s_header->data_size, (unsigned char *)receive_buf, PDCP_TRANSMISSION_MODE_DATA -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) ,&pc5s_header->sourceL2Id ,&pc5s_header->destinationL2Id #endif @@ -832,7 +832,7 @@ int pdcp_fifo_read_input_sdus (const protocol_ctxt_t* const ctxt_pP) pc5s_header->data_size, (unsigned char *)receive_buf, PDCP_TRANSMISSION_MODE_DATA -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) ,&pc5s_header->sourceL2Id ,&pc5s_header->destinationL2Id #endif @@ -897,18 +897,18 @@ int pdcp_fifo_read_input_sdus (const protocol_ctxt_t* const ctxt_pP) ctxt.frame = ctxt_cpy.frame; ctxt.enb_flag = ENB_FLAG_YES; ctxt.module_id = pdcp_read_header_g.inst + oai_emulation.info.first_enb_local; - ctxt.rnti = oai_emulation.info.eNB_ue_module_id_to_rnti[ctxt.module_id ][pdcp_read_header_g.rb_id / maxDRB + oai_emulation.info.first_ue_local]; - rab_id = pdcp_read_header_g.rb_id % maxDRB; + ctxt.rnti = oai_emulation.info.eNB_ue_module_id_to_rnti[ctxt.module_id ][pdcp_read_header_g.rb_id / LTE_maxDRB + oai_emulation.info.first_ue_local]; + rab_id = pdcp_read_header_g.rb_id % LTE_maxDRB; } else { ctxt.frame = ctxt_cpy.frame; ctxt.enb_flag = ENB_FLAG_NO; ctxt.module_id = pdcp_read_header_g.inst - oai_emulation.info.nb_enb_local + oai_emulation.info.first_ue_local; ctxt.rnti = pdcp_UE_UE_module_id_to_rnti[ctxt.module_id]; - rab_id = pdcp_read_header_g.rb_id % maxDRB; + rab_id = pdcp_read_header_g.rb_id % LTE_maxDRB; } CHECK_CTXT_ARGS(&ctxt); - AssertFatal (rab_id < maxDRB, "RB id is too high (%u/%d)!\n", rab_id, maxDRB); + AssertFatal (rab_id < LTE_maxDRB, "RB id is too high (%u/%d)!\n", rab_id, LTE_maxDRB); /*LGpdcp_read_header.inst = (pdcp_read_header_g.inst >= oai_emulation.info.nb_enb_local) ? \ pdcp_read_header_g.inst - oai_emulation.info.nb_enb_local+ NB_eNB_INST + oai_emulation.info.first_ue_local : pdcp_read_header_g.inst + oai_emulation.info.first_enb_local;*/ @@ -924,11 +924,11 @@ int pdcp_fifo_read_input_sdus (const protocol_ctxt_t* const ctxt_pP) #endif if (ctxt_cpy.enb_flag) { ctxt.module_id = 0; - rab_id = pdcp_read_header_g.rb_id % maxDRB; - ctxt.rnti = pdcp_eNB_UE_instance_to_rnti[pdcp_read_header_g.rb_id / maxDRB]; + rab_id = pdcp_read_header_g.rb_id % LTE_maxDRB; + ctxt.rnti = pdcp_eNB_UE_instance_to_rnti[pdcp_read_header_g.rb_id / LTE_maxDRB]; } else { ctxt.module_id = 0; - rab_id = pdcp_read_header_g.rb_id % maxDRB; + rab_id = pdcp_read_header_g.rb_id % LTE_maxDRB; ctxt.rnti = pdcp_UE_UE_module_id_to_rnti[ctxt.module_id]; } @@ -936,7 +936,7 @@ int pdcp_fifo_read_input_sdus (const protocol_ctxt_t* const ctxt_pP) if (ctxt.enb_flag) { if (rab_id != 0) { - rab_id = rab_id % maxDRB; + rab_id = rab_id % LTE_maxDRB; key = PDCP_COLL_KEY_VALUE(ctxt.module_id, ctxt.rnti, ctxt.enb_flag, rab_id, SRB_FLAG_NO); h_rc = hashtable_get(pdcp_coll_p, key, (void**)&pdcp_p); @@ -979,7 +979,7 @@ int pdcp_fifo_read_input_sdus (const protocol_ctxt_t* const ctxt_pP) pdcp_read_header_g.data_size, (unsigned char *)NLMSG_DATA(nas_nlh_rx), PDCP_TRANSMISSION_MODE_DATA -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) ,NULL, NULL #endif ); @@ -1016,7 +1016,7 @@ int pdcp_fifo_read_input_sdus (const protocol_ctxt_t* const ctxt_pP) pdcp_read_header_g.data_size, (unsigned char *)NLMSG_DATA(nas_nlh_rx), PDCP_TRANSMISSION_MODE_DATA -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) ,NULL, NULL #endif ); @@ -1033,7 +1033,7 @@ int pdcp_fifo_read_input_sdus (const protocol_ctxt_t* const ctxt_pP) LOG_D(PDCP,"request key %x : (%d,%x,%d,%d)\n", (uint8_t)key,ctxt.module_id, ctxt.rnti, ctxt.enb_flag, rab_id); } else { - rab_id = rab_id % maxDRB; + rab_id = rab_id % LTE_maxDRB; LOG_D(PDCP, "PDCP_COLL_KEY_VALUE(module_id=%d, rnti=%x, enb_flag=%d, rab_id=%d, SRB_FLAG=%d)\n", ctxt.module_id, ctxt.rnti, ctxt.enb_flag, rab_id, SRB_FLAG_NO); key = PDCP_COLL_KEY_VALUE(ctxt.module_id, ctxt.rnti, ctxt.enb_flag, rab_id, SRB_FLAG_NO); @@ -1082,7 +1082,7 @@ int pdcp_fifo_read_input_sdus (const protocol_ctxt_t* const ctxt_pP) pdcp_read_header_g.data_size, (unsigned char *)NLMSG_DATA(nas_nlh_rx), PDCP_TRANSMISSION_MODE_DATA -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) ,&pdcp_read_header_g.sourceL2Id ,&pdcp_read_header_g.destinationL2Id #endif @@ -1140,7 +1140,7 @@ int pdcp_fifo_read_input_sdus (const protocol_ctxt_t* const ctxt_pP) pdcp_read_header_g.data_size, (unsigned char *)NLMSG_DATA(nas_nlh_rx), PDCP_TRANSMISSION_MODE_DATA -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) ,&pdcp_read_header_g.sourceL2Id ,&pdcp_read_header_g.destinationL2Id #endif @@ -1188,7 +1188,7 @@ void pdcp_fifo_read_input_sdus_from_otg (const protocol_ctxt_t* const ctxt_pP) } //TTN for D2D (PC5S) -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) void pdcp_pc5_socket_init() { diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp_proto_extern.h b/openair2/LAYER2/PDCP_v10.1.0/pdcp_proto_extern.h index 291ec5e2a7..676ece7b3a 100644 --- a/openair2/LAYER2/PDCP_v10.1.0/pdcp_proto_extern.h +++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp_proto_extern.h @@ -53,7 +53,7 @@ extern int reception_from_rohc_bs(void); extern BOOL pdcp_data_ind (module_id_t module_idP, rb_id_t rab_idP, sdu_size_t data_sizeP, mem_block_t * sduP, uint8_t is_data_plane); extern BOOL pdcp_data_req (module_id_t module_id, uint32_t frame, uint8_t eNB_flag, rb_id_t rab_id, uint32_t muiP, uint32_t confirmP, sdu_size_t sdu_buffer_size, unsigned char* sdu_buffer, uint8_t is_data_pdu -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) ,const uint32_t * const sourceL2Id ,const uint32_t * const destinationL2Id #endif diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp_security.c b/openair2/LAYER2/PDCP_v10.1.0/pdcp_security.c index 95a6c28ae6..83293a709d 100644 --- a/openair2/LAYER2/PDCP_v10.1.0/pdcp_security.c +++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp_security.c @@ -62,7 +62,7 @@ uint32_t pdcp_get_next_count_tx( /* 5 bits length SN */ count = ((pdcp_pP->tx_hfn << 5) | (pdcp_sn & 0x001F)); } else { - if (pdcp_pP->seq_num_size == PDCP_Config__rlc_UM__pdcp_SN_Size_len7bits) { + if (pdcp_pP->seq_num_size == LTE_PDCP_Config__rlc_UM__pdcp_SN_Size_len7bits) { count = ((pdcp_pP->tx_hfn << 7) | (pdcp_sn & 0x07F)); } else { /*Default is the 12 bits length SN */ count = ((pdcp_pP->tx_hfn << 12) | (pdcp_sn & 0x0FFF)); @@ -88,7 +88,7 @@ uint32_t pdcp_get_next_count_rx( /* 5 bits length SN */ count = (((pdcp_pP->rx_hfn + pdcp_pP->rx_hfn_offset) << 5) | (pdcp_sn & 0x001F)); } else { - if (pdcp_pP->seq_num_size == PDCP_Config__rlc_UM__pdcp_SN_Size_len7bits) { + if (pdcp_pP->seq_num_size == LTE_PDCP_Config__rlc_UM__pdcp_SN_Size_len7bits) { /* 7 bits length SN */ count = (((pdcp_pP->rx_hfn + pdcp_pP->rx_hfn_offset) << 7) | (pdcp_sn & 0x007F)); } else { // default diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am.c b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am.c index d4e43fda47..e2911efcaf 100644 --- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am.c +++ b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am.c @@ -39,8 +39,8 @@ #include "list.h" #include "LAYER2/MAC/mac_extern.h" #include "common/utils/LOG/log.h" -#include "UL-AM-RLC.h" -#include "DL-AM-RLC.h" +#include "LTE_UL-AM-RLC.h" +#include "LTE_DL-AM-RLC.h" //----------------------------------------------------------------------------- @@ -237,24 +237,24 @@ config_req_rlc_am ( PROTOCOL_RLC_AM_CTXT_ARGS(ctxt_pP,l_rlc_p)); } } -uint16_t pollPDU_tab[PollPDU_pInfinity+1]= {4,8,16,32,64,128,256,RLC_AM_POLL_PDU_INFINITE}; //PollPDU_pInfinity is chosen to 0xFFFF for now -uint32_t maxRetxThreshold_tab[UL_AM_RLC__maxRetxThreshold_t32+1]= {1,2,3,4,6,8,16,32}; -uint32_t pollByte_tab[PollByte_spare1]= {25000,50000,75000,100000,125000,250000,375000,500000,750000,1000000,1250000,1500000,2000000,3000000,RLC_AM_POLL_BYTE_INFINITE}; // PollByte_kBinfinity is chosen to 0xFFFFFFFF for now -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) -uint32_t PollRetransmit_tab[T_PollRetransmit_spare5]= {5,10,15,20,25,30,35,40,45,50,55,60,65,70,75,80,85,90,95,100,105,110,115,120,125,130,135,140,145,150,155,160,165,170,175,180,185,190,195,200,205,210,215,220,225,230,235,240,245,250,300,350,400,450,500,800,1000,2000,4000}; +uint16_t pollPDU_tab[LTE_PollPDU_pInfinity+1]= {4,8,16,32,64,128,256,RLC_AM_POLL_PDU_INFINITE}; //PollPDU_pInfinity is chosen to 0xFFFF for now +uint32_t maxRetxThreshold_tab[LTE_UL_AM_RLC__maxRetxThreshold_t32+1]= {1,2,3,4,6,8,16,32}; +uint32_t pollByte_tab[LTE_PollByte_spare1]= {25000,50000,75000,100000,125000,250000,375000,500000,750000,1000000,1250000,1500000,2000000,3000000,RLC_AM_POLL_BYTE_INFINITE}; // PollByte_kBinfinity is chosen to 0xFFFFFFFF for now +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +uint32_t PollRetransmit_tab[LTE_T_PollRetransmit_spare5]= {5,10,15,20,25,30,35,40,45,50,55,60,65,70,75,80,85,90,95,100,105,110,115,120,125,130,135,140,145,150,155,160,165,170,175,180,185,190,195,200,205,210,215,220,225,230,235,240,245,250,300,350,400,450,500,800,1000,2000,4000}; uint32_t am_t_Reordering_tab[32]= {0,5,10,15,20,25,30,35,40,45,50,55,60,65,70,75,80,85,90,95,100,110,120,130,140,150,160,170,180,190,200,1600}; -uint32_t t_StatusProhibit_tab[T_StatusProhibit_spare2]= {0,5,10,15,20,25,30,35,40,45,50,55,60,65,70,75,80,85,90,95,100,105,110,115,120,125,130,135,140,145,150,155,160,165,170,175,180,185,190,195,200,205,210,215,220,225,230,235,240,245,250,300,350,400,450,500,800,1000,1200,1600,2000,2400}; +uint32_t t_StatusProhibit_tab[LTE_T_StatusProhibit_spare2]= {0,5,10,15,20,25,30,35,40,45,50,55,60,65,70,75,80,85,90,95,100,105,110,115,120,125,130,135,140,145,150,155,160,165,170,175,180,185,190,195,200,205,210,215,220,225,230,235,240,245,250,300,350,400,450,500,800,1000,1200,1600,2000,2400}; #else -uint32_t PollRetransmit_tab[T_PollRetransmit_spare9]= {5,10,15,20,25,30,35,40,45,50,55,60,65,70,75,80,85,90,95,100,105,110,115,120,125,130,135,140,145,150,155,160,165,170,175,180,185,190,195,200,205,210,215,220,225,230,235,240,245,250,300,350,400,450,500}; -uint32_t am_t_Reordering_tab[T_Reordering_spare1]= {0,5,10,15,20,25,30,35,40,45,50,55,60,65,70,75,80,85,90,95,100,110,120,130,140,150,160,170,180,190,200}; -uint32_t t_StatusProhibit_tab[T_StatusProhibit_spare8]= {0,5,10,15,20,25,30,35,40,45,50,55,60,65,70,75,80,85,90,95,100,105,110,115,120,125,130,135,140,145,150,155,160,165,170,175,180,185,190,195,200,205,210,215,220,225,230,235,240,245,250,300,350,400,450,500}; +uint32_t PollRetransmit_tab[LTE_T_PollRetransmit_spare9]= {5,10,15,20,25,30,35,40,45,50,55,60,65,70,75,80,85,90,95,100,105,110,115,120,125,130,135,140,145,150,155,160,165,170,175,180,185,190,195,200,205,210,215,220,225,230,235,240,245,250,300,350,400,450,500}; +uint32_t am_t_Reordering_tab[LTE_T_Reordering_spare1]= {0,5,10,15,20,25,30,35,40,45,50,55,60,65,70,75,80,85,90,95,100,110,120,130,140,150,160,170,180,190,200}; +uint32_t t_StatusProhibit_tab[LTE_T_StatusProhibit_spare8]= {0,5,10,15,20,25,30,35,40,45,50,55,60,65,70,75,80,85,90,95,100,105,110,115,120,125,130,135,140,145,150,155,160,165,170,175,180,185,190,195,200,205,210,215,220,225,230,235,240,245,250,300,350,400,450,500}; #endif //----------------------------------------------------------------------------- void config_req_rlc_am_asn1 ( const protocol_ctxt_t* const ctxt_pP, const srb_flag_t srb_flagP, - const struct RLC_Config__am * const config_am_pP, + const struct LTE_RLC_Config__am * const config_am_pP, const rb_id_t rb_idP, const logical_chan_id_t chan_idP) { @@ -268,17 +268,17 @@ void config_req_rlc_am_asn1 ( if (h_rc == HASH_TABLE_OK) { l_rlc_p = &rlc_union_p->rlc.am; - if ((config_am_pP->ul_AM_RLC.maxRetxThreshold <= UL_AM_RLC__maxRetxThreshold_t32) && - (config_am_pP->ul_AM_RLC.pollPDU<=PollPDU_pInfinity) && - (config_am_pP->ul_AM_RLC.pollByte= MAKE_VERSION(14, 0, 0)) - (config_am_pP->ul_AM_RLC.t_PollRetransmitul_AM_RLC.maxRetxThreshold <= LTE_UL_AM_RLC__maxRetxThreshold_t32) && + (config_am_pP->ul_AM_RLC.pollPDU<=LTE_PollPDU_pInfinity) && + (config_am_pP->ul_AM_RLC.pollByte= MAKE_VERSION(14, 0, 0)) + (config_am_pP->ul_AM_RLC.t_PollRetransmitdl_AM_RLC.t_Reordering<32) && - (config_am_pP->dl_AM_RLC.t_StatusProhibitdl_AM_RLC.t_StatusProhibitul_AM_RLC.t_PollRetransmitdl_AM_RLC.t_Reorderingdl_AM_RLC.t_StatusProhibitul_AM_RLC.t_PollRetransmitLTE_T_PollRetransmit_spare9) && + (config_am_pP->dl_AM_RLC.t_Reorderingdl_AM_RLC.t_StatusProhibit= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) const uint32_t t_Reordering_tab[32] = {0,5,10,15,20,25,30,35,40,45,50,55,60,65,70,75,80,85,90,95,100,110,120,130,140,150,160,170,180,190,200,1600}; #else -const uint32_t t_Reordering_tab[T_Reordering_spare1] = {0,5,10,15,20,25,30,35,40,45,50,55,60,65,70,75,80,85,90,95,100,110,120,130,140,150,160,170,180,190,200}; +const uint32_t t_Reordering_tab[LTE_T_Reordering_spare1] = {0,5,10,15,20,25,30,35,40,45,50,55,60,65,70,75,80,85,90,95,100,110,120,130,140,150,160,170,180,190,200}; #endif void config_req_rlc_um_asn1 ( @@ -90,11 +90,11 @@ void config_req_rlc_um_asn1 ( const MBMS_flag_t mbms_flagP, const mbms_session_id_t mbms_session_idP, const mbms_service_id_t mbms_service_idP, - const UL_UM_RLC_t * const ul_rlc_pP, - const DL_UM_RLC_t * const dl_rlc_pP, + const LTE_UL_UM_RLC_t * const ul_rlc_pP, + const LTE_DL_UM_RLC_t * const dl_rlc_pP, const rb_id_t rb_idP, const logical_chan_id_t chan_idP -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) ,const uint32_t sourceL2Id ,const uint32_t destinationL2Id #endif @@ -108,7 +108,7 @@ void config_req_rlc_um_asn1 ( hash_key_t key = RLC_COLL_KEY_VALUE(ctxt_pP->module_id, ctxt_pP->rnti, ctxt_pP->enb_flag, rb_idP, srb_flagP); hashtable_rc_t h_rc; -#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) if (mbms_flagP) { //AssertFatal(dl_rlc_pP, "No RLC UM DL config"); @@ -173,11 +173,11 @@ void config_req_rlc_um_asn1 ( if (ul_rlc_pP != NULL) { switch (ul_rlc_pP->sn_FieldLength) { - case SN_FieldLength_size5: + case LTE_SN_FieldLength_size5: ul_sn_FieldLength = 5; break; - case SN_FieldLength_size10: + case LTE_SN_FieldLength_size10: ul_sn_FieldLength = 10; break; @@ -201,11 +201,11 @@ void config_req_rlc_um_asn1 ( if (dl_rlc_pP != NULL) { switch (dl_rlc_pP->sn_FieldLength) { - case SN_FieldLength_size5: + case LTE_SN_FieldLength_size5: dl_sn_FieldLength = 5; break; - case SN_FieldLength_size10: + case LTE_SN_FieldLength_size10: dl_sn_FieldLength = 10; break; @@ -226,7 +226,7 @@ void config_req_rlc_um_asn1 ( return; } -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) if (dl_rlc_pP->t_Reordering<32) { #else if (dl_rlc_pP->t_Reordering= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) ,const uint32_t sourceL2Id ,const uint32_t destinationL2Id #endif diff --git a/openair2/LAYER2/RLC/rlc.c b/openair2/LAYER2/RLC/rlc.c index 846d406319..e56877d601 100644 --- a/openair2/LAYER2/RLC/rlc.c +++ b/openair2/LAYER2/RLC/rlc.c @@ -320,7 +320,7 @@ rlc_op_status_t rlc_data_req (const protocol_ctxt_t* const ctxt_pP, confirm_t confirmP, sdu_size_t sdu_sizeP, mem_block_t *sdu_pP -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) ,const uint32_t * const sourceL2Id ,const uint32_t * const destinationL2Id #endif @@ -333,7 +333,7 @@ rlc_op_status_t rlc_data_req (const protocol_ctxt_t* const ctxt_pP, hash_key_t key = HASHTABLE_NOT_A_KEY_VALUE; hashtable_rc_t h_rc; -#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) rlc_mbms_id_t *mbms_id_p = NULL; logical_chan_id_t log_ch_id = 0; #endif @@ -347,7 +347,7 @@ rlc_op_status_t rlc_data_req (const protocol_ctxt_t* const ctxt_pP, sdu_sizeP, sdu_pP); #endif -#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) #else AssertFatal(MBMS_flagP == 0, "MBMS_flagP %u", MBMS_flagP); #endif @@ -383,13 +383,13 @@ rlc_op_status_t rlc_data_req (const protocol_ctxt_t* const ctxt_pP, return RLC_OP_STATUS_BAD_PARAMETER; } -#if (RRC_VERSION < MAKE_VERSION(10, 0, 0)) +#if (LTE_RRC_VERSION < MAKE_VERSION(10, 0, 0)) DevCheck(MBMS_flagP == 0, MBMS_flagP, 0, 0); #endif VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RLC_DATA_REQ,VCD_FUNCTION_IN); -#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) if (MBMS_flagP == TRUE) { if (ctxt_pP->enb_flag) { @@ -534,7 +534,7 @@ rlc_op_status_t rlc_data_req (const protocol_ctxt_t* const ctxt_pP, } -#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) } else { /* MBMS_flag != 0 */ // LOG_I(RLC,"DUY rlc_data_req: mbms_rb_id in RLC instant is: %d\n", mbms_rb_id); if (sdu_pP != NULL) { @@ -649,7 +649,7 @@ rlc_module_init (void) rlc_rrc_data_ind = NULL; rlc_rrc_data_conf = NULL; - rlc_coll_p = hashtable_create ((maxDRB + 2) * 16, NULL, rb_free_rlc_union); + rlc_coll_p = hashtable_create ((LTE_maxDRB + 2) * 16, NULL, rb_free_rlc_union); //AssertFatal(rlc_coll_p != NULL, "UNRECOVERABLE error, RLC hashtable_create failed"); if(rlc_coll_p == NULL) { LOG_E(RLC, "UNRECOVERABLE error, RLC hashtable_create failed\n"); @@ -657,7 +657,7 @@ rlc_module_init (void) } for (module_id1=0; module_id1 < MAX_MOBILES_PER_ENB; module_id1++) { -#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) for (k=0; k < RLC_MAX_MBMS_LC; k++) { rlc_mbms_lcid2service_session_id_ue[module_id1][k].service_id = 0; @@ -672,7 +672,7 @@ rlc_module_init (void) } for (module_id1=0; module_id1 < NUMBER_OF_eNB_MAX; module_id1++) { -#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) for (k=0; k < RLC_MAX_MBMS_LC; k++) { rlc_mbms_lcid2service_session_id_eNB[module_id1][k].service_id = 0; diff --git a/openair2/LAYER2/RLC/rlc.h b/openair2/LAYER2/RLC/rlc.h index 8c557188a2..fbb13373a3 100644 --- a/openair2/LAYER2/RLC/rlc.h +++ b/openair2/LAYER2/RLC/rlc.h @@ -44,19 +44,19 @@ # include "rlc_am_structs.h" # include "rlc_tm_structs.h" # include "rlc_um_structs.h" -# include "asn_constant.h" +# include "LTE_asn_constant.h" # include "common/utils/LOG/log.h" # include "mem_block.h" //# include "PHY/defs.h" -# include "RLC-Config.h" -# include "DRB-ToAddMod.h" -# include "DRB-ToAddModList.h" -# include "SRB-ToAddMod.h" -# include "SRB-ToAddModList.h" -# include "DRB-ToReleaseList.h" +# include "LTE_RLC-Config.h" +# include "LTE_DRB-ToAddMod.h" +# include "LTE_DRB-ToAddModList.h" +# include "LTE_SRB-ToAddMod.h" +# include "LTE_SRB-ToAddModList.h" +# include "LTE_DRB-ToReleaseList.h" -#if (RRC_VERSION >= MAKE_VERSION(9, 0, 0)) -#include "PMCH-InfoList-r9.h" +#if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) +#include "LTE_PMCH-InfoList-r9.h" #endif typedef uint64_t hash_key_t; @@ -132,8 +132,8 @@ typedef struct { // PRIVATE INTERNALS OF RLC //----------------------------------------------------------------------------- -#define RLC_MAX_MBMS_LC (maxSessionPerPMCH * maxServiceCount) -#define RLC_MAX_LC ((max_val_DRB_Identity+1)* MAX_MOBILES_PER_ENB) +#define RLC_MAX_MBMS_LC (LTE_maxSessionPerPMCH * LTE_maxServiceCount) +#define RLC_MAX_LC ((max_val_LTE_DRB_Identity+1)* MAX_MOBILES_PER_ENB) void (*rlc_rrc_data_ind)( const protocol_ctxt_t* const ctxtP, @@ -183,7 +183,7 @@ typedef struct rlc_mbms_id_s { mbms_session_id_t session_id; } rlc_mbms_id_t; -#if (RRC_VERSION < MAKE_VERSION(10, 0, 0)) +#if (LTE_RRC_VERSION < MAKE_VERSION(10, 0, 0)) # if !defined(maxServiceCount) //unused arrays rlc_mbms_array_ue rlc_mbms_array_eNB # define maxServiceCount 1 @@ -285,7 +285,7 @@ struct mac_data_ind mac_rlc_deserialize_tb (char*, tb_size_t, num_tb_t, crc_t //----------------------------------------------------------------------------- // PUBLIC INTERFACE WITH RRC //----------------------------------------------------------------------------- -#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) /*! \fn rlc_op_status_t rrc_rlc_config_asn1_req (const protocol_ctxt_t* const ctxtP, const srb_flag_t srb_flagP, const SRB_ToAddMod_t* const srb2addmod, const DRB_ToAddModList_t* const drb2add_listP, const DRB_ToReleaseList_t* const drb2release_listP, const PMCH_InfoList_r9_t * const pmch_info_listP) * \brief Function for RRC to configure a Radio Bearer. * \param[in] ctxtP Running context. @@ -297,10 +297,10 @@ struct mac_data_ind mac_rlc_deserialize_tb (char*, tb_size_t, num_tb_t, crc_t */ rlc_op_status_t rrc_rlc_config_asn1_req ( const protocol_ctxt_t* const, - const SRB_ToAddModList_t* const , - const DRB_ToAddModList_t* const , - const DRB_ToReleaseList_t* const , - const PMCH_InfoList_r9_t * const pmch_info_listP , + const LTE_SRB_ToAddModList_t* const , + const LTE_DRB_ToAddModList_t* const , + const LTE_DRB_ToReleaseList_t* const , + const LTE_PMCH_InfoList_r9_t * const pmch_info_listP , const uint32_t , const uint32_t ); #else @@ -314,9 +314,9 @@ rlc_op_status_t rrc_rlc_config_asn1_req ( */ rlc_op_status_t rrc_rlc_config_asn1_req ( const protocol_ctxt_t* const, - const SRB_ToAddModList_t* const , - const DRB_ToAddModList_t* const , - const DRB_ToReleaseList_t* const ); + const LTE_SRB_ToAddModList_t* const , + const LTE_DRB_ToAddModList_t* const , + const LTE_DRB_ToReleaseList_t* const ); #endif @@ -358,7 +358,7 @@ rlc_op_status_t rrc_rlc_remove_rlc (const protocol_ctxt_t* const, const srb_fl * \return A status about the processing, OK or error code. */ rlc_union_t* rrc_rlc_add_rlc (const protocol_ctxt_t* const, const srb_flag_t, const MBMS_flag_t MBMS_flagP, const rb_id_t, logical_chan_id_t, rlc_mode_t -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) ,const uint32_t sourceL2Id, const uint32_t destinationL2Id #endif @@ -424,7 +424,7 @@ void rrc_rlc_register_rrc (rrc_data_ind_cb_t rrc_data_indP, rrc_data_conf_cb_t r * \return A status about the processing, OK or error code. */ tbs_size_t mac_rlc_data_req (const module_id_t, const rnti_t, const eNB_index_t, const frame_t, const eNB_flag_t, const MBMS_flag_t, logical_chan_id_t, const tb_size_t,char* -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) ,const uint32_t sourceL2Id ,const uint32_t destinationL2Id #endif @@ -459,7 +459,7 @@ void mac_rlc_data_ind (const module_id_t, const rnti_t, con * \return The maximum number of bytes that the RLC instance can send in the next transmission sequence. */ mac_rlc_status_resp_t mac_rlc_status_ind (const module_id_t, const rnti_t, const eNB_index_t, const frame_t, const sub_frame_t, const eNB_flag_t, const MBMS_flag_t, logical_chan_id_t, tb_size_t -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) ,const uint32_t sourceL2Id ,const uint32_t destinationL2Id #endif @@ -514,7 +514,7 @@ rlc_op_status_t rlc_data_req ( const confirm_t , const sdu_size_t , mem_block_t * const -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) ,const uint32_t * const ,const uint32_t * const #endif diff --git a/openair2/LAYER2/RLC/rlc_mac.c b/openair2/LAYER2/RLC/rlc_mac.c index dbc2d1d342..da90a58a59 100644 --- a/openair2/LAYER2/RLC/rlc_mac.c +++ b/openair2/LAYER2/RLC/rlc_mac.c @@ -128,7 +128,7 @@ tbs_size_t mac_rlc_data_req( const logical_chan_id_t channel_idP, const tb_size_t tb_sizeP, char *buffer_pP -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) ,const uint32_t sourceL2Id ,const uint32_t destinationL2Id #endif @@ -180,7 +180,7 @@ tbs_size_t mac_rlc_data_req( } } else { key = RLC_COLL_KEY_LCID_VALUE(module_idP, rntiP, enb_flagP, channel_idP, srb_flag); -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) if ((sourceL2Id > 0) && (destinationL2Id > 0)) key = RLC_COLL_KEY_LCID_SOURCE_DEST_VALUE(module_idP, rntiP, enb_flagP, channel_idP, sourceL2Id, destinationL2Id, srb_flag); #endif @@ -330,7 +330,7 @@ mac_rlc_status_resp_t mac_rlc_status_ind( const MBMS_flag_t MBMS_flagP, const logical_chan_id_t channel_idP, const tb_size_t tb_sizeP -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) ,const uint32_t sourceL2Id ,const uint32_t destinationL2Id #endif @@ -363,7 +363,7 @@ mac_rlc_status_resp_t mac_rlc_status_ind( key = RLC_COLL_KEY_MBMS_VALUE(module_idP, rntiP, enb_flagP, mbms_id_p->service_id, mbms_id_p->session_id); } else { -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) if ((sourceL2Id > 0) && (destinationL2Id > 0)) { key = RLC_COLL_KEY_SOURCE_DEST_VALUE(module_idP, rntiP, enb_flagP, channel_idP, sourceL2Id, destinationL2Id, srb_flag); } else diff --git a/openair2/LAYER2/RLC/rlc_mpls.c b/openair2/LAYER2/RLC/rlc_mpls.c index 8c6cea379b..d6f7afa12d 100644 --- a/openair2/LAYER2/RLC/rlc_mpls.c +++ b/openair2/LAYER2/RLC/rlc_mpls.c @@ -41,7 +41,7 @@ rlc_op_status_t mpls_rlc_data_req ( //----------------------------------------------------------------------------- // third arg should be set to 1 or 0 return rlc_data_req(ctxtP, SRB_FLAG_NO, MBMS_FLAG_NO, rb_idP, RLC_MUI_UNDEFINED, RLC_SDU_CONFIRM_NO, sdu_sizeP, sduP -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) ,NULL, NULL #endif ); diff --git a/openair2/LAYER2/RLC/rlc_rrc.c b/openair2/LAYER2/RLC/rlc_rrc.c index 8977e422b6..63c24d6e3c 100644 --- a/openair2/LAYER2/RLC/rlc_rrc.c +++ b/openair2/LAYER2/RLC/rlc_rrc.c @@ -33,25 +33,25 @@ #include "rlc_um.h" #include "rlc_tm.h" #include "common/utils/LOG/log.h" -#include "RLC-Config.h" -#include "DRB-ToAddMod.h" -#include "DRB-ToAddModList.h" -#include "SRB-ToAddMod.h" -#include "SRB-ToAddModList.h" -#include "DL-UM-RLC.h" -#if (RRC_VERSION >= MAKE_VERSION(9, 0, 0)) -#include "PMCH-InfoList-r9.h" +#include "LTE_RLC-Config.h" +#include "LTE_DRB-ToAddMod.h" +#include "LTE_DRB-ToAddModList.h" +#include "LTE_SRB-ToAddMod.h" +#include "LTE_SRB-ToAddModList.h" +#include "LTE_DL-UM-RLC.h" +#if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) +#include "LTE_PMCH-InfoList-r9.h" #endif #include "LAYER2/MAC/mac_extern.h" #include "assertions.h" //----------------------------------------------------------------------------- rlc_op_status_t rrc_rlc_config_asn1_req (const protocol_ctxt_t * const ctxt_pP, - const SRB_ToAddModList_t * const srb2add_listP, - const DRB_ToAddModList_t * const drb2add_listP, - const DRB_ToReleaseList_t * const drb2release_listP -#if (RRC_VERSION >= MAKE_VERSION(9, 0, 0)) - ,const PMCH_InfoList_r9_t * const pmch_InfoList_r9_pP + const LTE_SRB_ToAddModList_t * const srb2add_listP, + const LTE_DRB_ToAddModList_t * const drb2add_listP, + const LTE_DRB_ToReleaseList_t * const drb2release_listP +#if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) + ,const LTE_PMCH_InfoList_r9_t * const pmch_InfoList_r9_pP ,const uint32_t sourceL2Id ,const uint32_t destinationL2Id #endif @@ -60,21 +60,21 @@ rlc_op_status_t rrc_rlc_config_asn1_req (const protocol_ctxt_t * const ctxt_pP //----------------------------------------------------------------------------- rb_id_t rb_id = 0; logical_chan_id_t lc_id = 0; - DRB_Identity_t drb_id = 0; - DRB_Identity_t* pdrb_id = NULL; + LTE_DRB_Identity_t drb_id = 0; + LTE_DRB_Identity_t* pdrb_id = NULL; long int cnt = 0; - const SRB_ToAddMod_t *srb_toaddmod_p = NULL; - const DRB_ToAddMod_t *drb_toaddmod_p = NULL; + const LTE_SRB_ToAddMod_t *srb_toaddmod_p = NULL; + const LTE_DRB_ToAddMod_t *drb_toaddmod_p = NULL; rlc_union_t *rlc_union_p = NULL; hash_key_t key = HASHTABLE_NOT_A_KEY_VALUE; hashtable_rc_t h_rc; -#if (RRC_VERSION >= MAKE_VERSION(9, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) int i, j; - MBMS_SessionInfoList_r9_t *mbms_SessionInfoList_r9_p = NULL; - MBMS_SessionInfo_r9_t *MBMS_SessionInfo_p = NULL; + LTE_MBMS_SessionInfoList_r9_t *mbms_SessionInfoList_r9_p = NULL; + LTE_MBMS_SessionInfo_r9_t *MBMS_SessionInfo_p = NULL; mbms_session_id_t mbms_session_id; mbms_service_id_t mbms_service_id; - DL_UM_RLC_t dl_um_rlc; + LTE_DL_UM_RLC_t dl_um_rlc; #endif @@ -97,17 +97,17 @@ rlc_op_status_t rrc_rlc_config_asn1_req (const protocol_ctxt_t * const ctxt_pP if (srb_toaddmod_p->rlc_Config) { switch (srb_toaddmod_p->rlc_Config->present) { - case SRB_ToAddMod__rlc_Config_PR_NOTHING: + case LTE_SRB_ToAddMod__rlc_Config_PR_NOTHING: break; - case SRB_ToAddMod__rlc_Config_PR_explicitValue: + case LTE_SRB_ToAddMod__rlc_Config_PR_explicitValue: switch (srb_toaddmod_p->rlc_Config->choice.explicitValue.present) { - case RLC_Config_PR_NOTHING: + case LTE_RLC_Config_PR_NOTHING: break; - case RLC_Config_PR_am: + case LTE_RLC_Config_PR_am: if (rrc_rlc_add_rlc (ctxt_pP, SRB_FLAG_YES, MBMS_FLAG_NO, rb_id, lc_id, RLC_MODE_AM -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) ,0, 0 #endif @@ -125,9 +125,9 @@ rlc_op_status_t rrc_rlc_config_asn1_req (const protocol_ctxt_t * const ctxt_pP break; - case RLC_Config_PR_um_Bi_Directional: + case LTE_RLC_Config_PR_um_Bi_Directional: if (rrc_rlc_add_rlc (ctxt_pP, SRB_FLAG_YES, MBMS_FLAG_NO, rb_id, lc_id, RLC_MODE_UM -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) ,0, 0 #endif @@ -141,7 +141,7 @@ rlc_op_status_t rrc_rlc_config_asn1_req (const protocol_ctxt_t * const ctxt_pP &srb_toaddmod_p->rlc_Config->choice.explicitValue.choice.um_Bi_Directional.ul_UM_RLC, &srb_toaddmod_p->rlc_Config->choice.explicitValue.choice.um_Bi_Directional.dl_UM_RLC, rb_id, lc_id -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) ,0, 0 #endif ); @@ -153,9 +153,9 @@ rlc_op_status_t rrc_rlc_config_asn1_req (const protocol_ctxt_t * const ctxt_pP break; - case RLC_Config_PR_um_Uni_Directional_UL: + case LTE_RLC_Config_PR_um_Uni_Directional_UL: if (rrc_rlc_add_rlc (ctxt_pP, SRB_FLAG_YES, MBMS_FLAG_NO, rb_id, lc_id, RLC_MODE_UM -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) ,0, 0 #endif @@ -169,7 +169,7 @@ rlc_op_status_t rrc_rlc_config_asn1_req (const protocol_ctxt_t * const ctxt_pP &srb_toaddmod_p->rlc_Config->choice.explicitValue.choice.um_Uni_Directional_UL.ul_UM_RLC, NULL, rb_id, lc_id -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) ,0, 0 #endif ); @@ -181,9 +181,9 @@ rlc_op_status_t rrc_rlc_config_asn1_req (const protocol_ctxt_t * const ctxt_pP break; - case RLC_Config_PR_um_Uni_Directional_DL: + case LTE_RLC_Config_PR_um_Uni_Directional_DL: if (rrc_rlc_add_rlc (ctxt_pP, SRB_FLAG_YES, MBMS_FLAG_NO, rb_id, lc_id, RLC_MODE_UM -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) ,0, 0 #endif @@ -197,7 +197,7 @@ rlc_op_status_t rrc_rlc_config_asn1_req (const protocol_ctxt_t * const ctxt_pP NULL, &srb_toaddmod_p->rlc_Config->choice.explicitValue.choice.um_Uni_Directional_DL.dl_UM_RLC, rb_id, lc_id -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) ,0, 0 #endif ); @@ -218,19 +218,19 @@ rlc_op_status_t rrc_rlc_config_asn1_req (const protocol_ctxt_t * const ctxt_pP break; - case SRB_ToAddMod__rlc_Config_PR_defaultValue: + case LTE_SRB_ToAddMod__rlc_Config_PR_defaultValue: //#warning TO DO SRB_ToAddMod__rlc_Config_PR_defaultValue LOG_I(RRC, "RLC SRB1 is default value !!\n"); - struct RLC_Config__am * config_am_pP = &srb_toaddmod_p->rlc_Config->choice.explicitValue.choice.am; - config_am_pP->dl_AM_RLC.t_Reordering = T_Reordering_ms35; - config_am_pP->dl_AM_RLC.t_StatusProhibit = T_StatusProhibit_ms0; - config_am_pP->ul_AM_RLC.t_PollRetransmit = T_PollRetransmit_ms45; - config_am_pP->ul_AM_RLC.pollPDU = PollPDU_pInfinity; - config_am_pP->ul_AM_RLC.pollByte = PollByte_kBinfinity; - config_am_pP->ul_AM_RLC.maxRetxThreshold = UL_AM_RLC__maxRetxThreshold_t4; + struct LTE_RLC_Config__am * config_am_pP = &srb_toaddmod_p->rlc_Config->choice.explicitValue.choice.am; + config_am_pP->dl_AM_RLC.t_Reordering = LTE_T_Reordering_ms35; + config_am_pP->dl_AM_RLC.t_StatusProhibit = LTE_T_StatusProhibit_ms0; + config_am_pP->ul_AM_RLC.t_PollRetransmit = LTE_T_PollRetransmit_ms45; + config_am_pP->ul_AM_RLC.pollPDU = LTE_PollPDU_pInfinity; + config_am_pP->ul_AM_RLC.pollByte = LTE_PollByte_kBinfinity; + config_am_pP->ul_AM_RLC.maxRetxThreshold = LTE_UL_AM_RLC__maxRetxThreshold_t4; if (rrc_rlc_add_rlc (ctxt_pP, SRB_FLAG_YES, MBMS_FLAG_NO, rb_id, lc_id, RLC_MODE_AM -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) ,0, 0 #endif @@ -294,12 +294,12 @@ rlc_op_status_t rrc_rlc_config_asn1_req (const protocol_ctxt_t * const ctxt_pP if (drb_toaddmod_p->rlc_Config) { switch (drb_toaddmod_p->rlc_Config->present) { - case RLC_Config_PR_NOTHING: + case LTE_RLC_Config_PR_NOTHING: break; - case RLC_Config_PR_am: + case LTE_RLC_Config_PR_am: if (rrc_rlc_add_rlc (ctxt_pP, SRB_FLAG_NO, MBMS_FLAG_NO, drb_id, lc_id, RLC_MODE_AM -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) ,0, 0 #endif @@ -313,9 +313,9 @@ rlc_op_status_t rrc_rlc_config_asn1_req (const protocol_ctxt_t * const ctxt_pP break; - case RLC_Config_PR_um_Bi_Directional: + case LTE_RLC_Config_PR_um_Bi_Directional: if (rrc_rlc_add_rlc (ctxt_pP, SRB_FLAG_NO, MBMS_FLAG_NO, drb_id, lc_id, RLC_MODE_UM -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) ,sourceL2Id, destinationL2Id #endif @@ -329,7 +329,7 @@ rlc_op_status_t rrc_rlc_config_asn1_req (const protocol_ctxt_t * const ctxt_pP &drb_toaddmod_p->rlc_Config->choice.um_Bi_Directional.ul_UM_RLC, &drb_toaddmod_p->rlc_Config->choice.um_Bi_Directional.dl_UM_RLC, drb_id, lc_id -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) ,sourceL2Id, destinationL2Id #endif @@ -338,9 +338,9 @@ rlc_op_status_t rrc_rlc_config_asn1_req (const protocol_ctxt_t * const ctxt_pP break; - case RLC_Config_PR_um_Uni_Directional_UL: + case LTE_RLC_Config_PR_um_Uni_Directional_UL: if (rrc_rlc_add_rlc (ctxt_pP, SRB_FLAG_NO, MBMS_FLAG_NO, drb_id, lc_id, RLC_MODE_UM -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) ,0, 0 #endif @@ -354,7 +354,7 @@ rlc_op_status_t rrc_rlc_config_asn1_req (const protocol_ctxt_t * const ctxt_pP &drb_toaddmod_p->rlc_Config->choice.um_Uni_Directional_UL.ul_UM_RLC, NULL, drb_id, lc_id -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) ,0, 0 #endif ); @@ -362,9 +362,9 @@ rlc_op_status_t rrc_rlc_config_asn1_req (const protocol_ctxt_t * const ctxt_pP break; - case RLC_Config_PR_um_Uni_Directional_DL: + case LTE_RLC_Config_PR_um_Uni_Directional_DL: if (rrc_rlc_add_rlc (ctxt_pP, SRB_FLAG_NO, MBMS_FLAG_NO, drb_id, lc_id, RLC_MODE_UM -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) ,0, 0 #endif @@ -378,7 +378,7 @@ rlc_op_status_t rrc_rlc_config_asn1_req (const protocol_ctxt_t * const ctxt_pP NULL, &drb_toaddmod_p->rlc_Config->choice.um_Uni_Directional_DL.dl_UM_RLC, drb_id, lc_id -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) ,0, 0 #endif ); @@ -406,7 +406,7 @@ rlc_op_status_t rrc_rlc_config_asn1_req (const protocol_ctxt_t * const ctxt_pP } } -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) if (pmch_InfoList_r9_pP != NULL) { for (i=0; ilist.count; i++) { @@ -424,13 +424,13 @@ rlc_op_status_t rrc_rlc_config_asn1_req (const protocol_ctxt_t * const ctxt_pP // can set the mch_id = i if (ctxt_pP->enb_flag) { - rb_id = (mbms_service_id * maxSessionPerPMCH ) + mbms_session_id;//+ (maxDRB + 3) * MAX_MOBILES_PER_ENB; // 1 + rb_id = (mbms_service_id * LTE_maxSessionPerPMCH ) + mbms_session_id;//+ (LTE_maxDRB + 3) * MAX_MOBILES_PER_ENB; // 1 rlc_mbms_lcid2service_session_id_eNB[ctxt_pP->module_id][lc_id].service_id = mbms_service_id; rlc_mbms_lcid2service_session_id_eNB[ctxt_pP->module_id][lc_id].session_id = mbms_session_id; rlc_mbms_enb_set_lcid_by_rb_id(ctxt_pP->module_id,rb_id,lc_id); } else { - rb_id = (mbms_service_id * maxSessionPerPMCH ) + mbms_session_id; // + (maxDRB + 3); // 15 + rb_id = (mbms_service_id * LTE_maxSessionPerPMCH ) + mbms_session_id; // + (LTE_maxDRB + 3); // 15 rlc_mbms_lcid2service_session_id_ue[ctxt_pP->module_id][lc_id].service_id = mbms_service_id; rlc_mbms_lcid2service_session_id_ue[ctxt_pP->module_id][lc_id].session_id = mbms_session_id; rlc_mbms_ue_set_lcid_by_rb_id(ctxt_pP->module_id,rb_id,lc_id); @@ -461,8 +461,8 @@ rlc_op_status_t rrc_rlc_config_asn1_req (const protocol_ctxt_t * const ctxt_pP mbms_session_id, mbms_service_id ); - dl_um_rlc.sn_FieldLength = SN_FieldLength_size5; - dl_um_rlc.t_Reordering = T_Reordering_ms0; + dl_um_rlc.sn_FieldLength = LTE_SN_FieldLength_size5; + dl_um_rlc.t_Reordering = LTE_T_Reordering_ms0; config_req_rlc_um_asn1 ( ctxt_pP, @@ -473,7 +473,7 @@ rlc_op_status_t rrc_rlc_config_asn1_req (const protocol_ctxt_t * const ctxt_pP NULL, &dl_um_rlc, rb_id, lc_id -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) ,0, 0 #endif ); @@ -536,7 +536,7 @@ rlc_op_status_t rrc_rlc_remove_ue ( rb_id); } - for (rb_id = 1; rb_id <= maxDRB; rb_id++) { + for (rb_id = 1; rb_id <= LTE_maxDRB; rb_id++) { rrc_rlc_remove_rlc(ctxt_pP, SRB_FLAG_NO, MBMS_FLAG_NO, @@ -560,14 +560,14 @@ rlc_op_status_t rrc_rlc_remove_rlc ( hash_key_t key_lcid = HASHTABLE_NOT_A_KEY_VALUE; hashtable_rc_t h_lcid_rc; rlc_union_t *rlc_union_p = NULL; -#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) rlc_mbms_id_t *mbms_id_p = NULL; #endif /* for no gcc warnings */ (void)lcid; -#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) if (MBMS_flagP == TRUE) { if (ctxt_pP->enb_flag) { @@ -658,7 +658,7 @@ rlc_union_t* rrc_rlc_add_rlc ( const rb_id_t rb_idP, const logical_chan_id_t chan_idP, const rlc_mode_t rlc_modeP -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) ,const uint32_t sourceL2Id, const uint32_t destinationL2Id #endif @@ -671,7 +671,7 @@ rlc_union_t* rrc_rlc_add_rlc ( hash_key_t key_lcid = HASHTABLE_NOT_A_KEY_VALUE; hashtable_rc_t h_lcid_rc; rlc_union_t *rlc_union_p = NULL; -#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) rlc_mbms_id_t *mbms_id_p = NULL; logical_chan_id_t lcid = 0; #endif @@ -691,7 +691,7 @@ rlc_union_t* rrc_rlc_add_rlc ( } -#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) if (MBMS_flagP == TRUE) { if (ctxt_pP->enb_flag) { @@ -741,7 +741,7 @@ rlc_union_t* rrc_rlc_add_rlc ( h_lcid_rc = hashtable_insert(rlc_coll_p, key_lcid, rlc_union_p); if ((h_rc == HASH_TABLE_OK) && (h_lcid_rc == HASH_TABLE_OK)) { -#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) if (MBMS_flagP == TRUE) { LOG_I(RLC, PROTOCOL_CTXT_FMT" RLC service id %u session id %u rrc_rlc_add_rlc\n", @@ -806,7 +806,7 @@ rlc_op_status_t rrc_rlc_config_req ( case CONFIG_ACTION_ADD: if (rrc_rlc_add_rlc(ctxt_pP, srb_flagP, MBMS_FLAG_NO, rb_idP, rb_idP, rlc_infoP.rlc_mode -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) ,0, 0 #endif @@ -885,7 +885,7 @@ rlc_op_status_t rrc_rlc_data_req ( if (sdu != NULL) { memcpy (sdu->data, sduP, sdu_sizeP); return rlc_data_req(ctxt_pP, SRB_FLAG_YES, MBMS_flagP, rb_idP, muiP, confirmP, sdu_sizeP, sdu -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) ,NULL, NULL #endif ); diff --git a/openair2/NETWORK_DRIVER/UE_IP/common.c b/openair2/NETWORK_DRIVER/UE_IP/common.c index b21ca5f2dc..87d8ca01ed 100644 --- a/openair2/NETWORK_DRIVER/UE_IP/common.c +++ b/openair2/NETWORK_DRIVER/UE_IP/common.c @@ -248,7 +248,7 @@ ue_ip_common_ip2wireless( //--------------------------------------------------------------------------- struct pdcp_data_req_header_s pdcph; ue_ip_priv_t *priv_p=netdev_priv(ue_ip_dev[instP]); -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) ipversion_t *ipv_p = NULL; unsigned int hard_header_len = 0; unsigned char *src_addr = 0; diff --git a/openair2/NETWORK_DRIVER/UE_IP/local.h b/openair2/NETWORK_DRIVER/UE_IP/local.h index e590109b13..4a918a5c94 100644 --- a/openair2/NETWORK_DRIVER/UE_IP/local.h +++ b/openair2/NETWORK_DRIVER/UE_IP/local.h @@ -90,7 +90,7 @@ typedef struct pdcp_data_req_header_s { sdu_size_t data_size; signed int inst; ip_traffic_type_t traffic_type; -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) uint32_t sourceL2Id; uint32_t destinationL2Id; #endif @@ -101,7 +101,7 @@ typedef struct pdcp_data_ind_header_s { sdu_size_t data_size; signed int inst; ip_traffic_type_t dummy_traffic_type; -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) uint32_t sourceL2Id; uint32_t destinationL2Id; #endif diff --git a/openair2/PHY_INTERFACE/IF_Module.c b/openair2/PHY_INTERFACE/IF_Module.c index bd9f4bb8b2..9ebee10f9b 100644 --- a/openair2/PHY_INTERFACE/IF_Module.c +++ b/openair2/PHY_INTERFACE/IF_Module.c @@ -33,13 +33,13 @@ void handle_rach(UL_IND_t *UL_info) { UL_info->rach_ind.rach_indication_body.preamble_list[0].preamble_rel8.preamble, UL_info->rach_ind.rach_indication_body.preamble_list[0].preamble_rel8.timing_advance, UL_info->rach_ind.rach_indication_body.preamble_list[0].preamble_rel8.rnti -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) ,0 #endif ); } -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) if (UL_info->rach_ind_br.rach_indication_body.number_of_preambles>0) { AssertFatal(UL_info->rach_ind_br.rach_indication_body.number_of_preambles<5,"More than 4 preambles not supported\n"); diff --git a/openair2/PHY_INTERFACE/IF_Module.h b/openair2/PHY_INTERFACE/IF_Module.h index 0390a90551..26c9a60476 100644 --- a/openair2/PHY_INTERFACE/IF_Module.h +++ b/openair2/PHY_INTERFACE/IF_Module.h @@ -76,7 +76,7 @@ typedef struct{ /// RACH indication list nfapi_rach_indication_t rach_ind; -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) /// RACH indication list for BR UEs nfapi_rach_indication_t rach_ind_br; #endif diff --git a/openair2/PHY_INTERFACE/IF_Module_NB_IoT.h b/openair2/PHY_INTERFACE/IF_Module_NB_IoT.h index 479bd47d94..954eaaa281 100644 --- a/openair2/PHY_INTERFACE/IF_Module_NB_IoT.h +++ b/openair2/PHY_INTERFACE/IF_Module_NB_IoT.h @@ -10,7 +10,7 @@ #include "nfapi_interface.h" //#include "openair1/PHY/LTE_TRANSPORT/defs_NB_IoT.h" -#include "PhysicalConfigDedicated-NB-r13.h" +#include "LTE_PhysicalConfigDedicated-NB-r13.h" //#include "openair2/PHY_INTERFACE/IF_Module_NB_IoT.h" #include "openair2/COMMON/platform_types.h" //#include "openair1/SCHED/IF_Module_L1_primitives_NB_IoT.h" @@ -54,7 +54,7 @@ typedef struct{ uint16_t npdcch_Offset_USS; //Alfa_offset (see TS 36.213 ch 16.6) - ACK_NACK_NumRepetitions_NB_r13_t *ack_nack_numRepetitions_MSG4; //pointer to the first cell of a list of ack_nack_num_repetitions + LTE_ACK_NACK_NumRepetitions_NB_r13_t *ack_nack_numRepetitions_MSG4; //pointer to the first cell of a list of ack_nack_num_repetitions //ulPowerControlCommon (UE side) uint16_t p0_nominal_npusch; diff --git a/openair2/RRC/LTE/L2_interface.c b/openair2/RRC/LTE/L2_interface.c index d201732177..126d7c3aac 100644 --- a/openair2/RRC/LTE/L2_interface.c +++ b/openair2/RRC/LTE/L2_interface.c @@ -71,7 +71,7 @@ mac_rrc_data_req( eNB_RRC_INST *rrc; rrc_eNB_carrier_data_t *carrier; - BCCH_BCH_Message_t *mib; + LTE_BCCH_BCH_Message_t *mib; rrc = RC.rrc[Mod_idP]; @@ -126,7 +126,7 @@ mac_rrc_data_req( if( (Srb_id & RAB_OFFSET ) == MIBCH) { mib->message.systemFrameNumber.buf = &sfn; - enc_rval = uper_encode_to_buffer(&asn_DEF_BCCH_BCH_Message, + enc_rval = uper_encode_to_buffer(&asn_DEF_LTE_BCCH_BCH_Message, NULL, (void*)mib, carrier->MIB, @@ -178,7 +178,7 @@ mac_rrc_data_req( return (Sdu_size); } -#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) if((Srb_id & RAB_OFFSET) == MCCH) { if(RC.rrc[Mod_idP]->carrier[CC_id].MCCH_MESS[mbsfn_sync_area].Active==0) { @@ -202,9 +202,9 @@ mac_rrc_data_req( return (RC.rrc[Mod_idP]->carrier[CC_id].sizeof_MCCH_MESSAGE[mbsfn_sync_area]); } -#endif // #if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) +#endif // #if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) -#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) if ((Srb_id & RAB_OFFSET) == BCCH_SIB1_BR){ memcpy(&buffer_pP[0], RC.rrc[Mod_idP]->carrier[CC_id].SIB1_BR, diff --git a/openair2/RRC/LTE/L2_interface_ue.c b/openair2/RRC/LTE/L2_interface_ue.c index 3b7219af42..9dfbeed61e 100644 --- a/openair2/RRC/LTE/L2_interface_ue.c +++ b/openair2/RRC/LTE/L2_interface_ue.c @@ -63,7 +63,7 @@ mac_rrc_data_req_ue( LOG_D(RRC,"[eNB %d] mac_rrc_data_req to SRB ID=%d\n",Mod_idP,Srb_id); -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) LOG_D(RRC,"[UE %d] Frame %d Filling SL DISCOVERY SRB_ID %d\n",Mod_idP,frameP,Srb_id); LOG_D(RRC,"[UE %d] Frame %d buffer_pP status %d,\n",Mod_idP,frameP, UE_rrc_inst[Mod_idP].SL_Discovery[eNB_index].Tx_buffer.payload_size); @@ -217,7 +217,7 @@ mac_rrc_data_ind_ue( } } -#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) if ((srb_idP & RAB_OFFSET) == MCCH) { LOG_T(RRC,"[UE %d] Frame %d: Received SDU on MBSFN sync area %d for MCCH on SRB %d from eNB %d\n", @@ -253,7 +253,7 @@ mac_rrc_data_ind_ue( decode_SL_Discovery_Message(&ctxt, eNB_indexP, sduP, sdu_lenP); } -#endif // #if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) +#endif // #if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) return(0); @@ -327,7 +327,7 @@ rrc_data_req_ue( sdu_sizeP, buffer_pP, modeP -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) ,NULL, NULL #endif ); diff --git a/openair2/RRC/LTE/MESSAGES/asn1_msg.c b/openair2/RRC/LTE/MESSAGES/asn1_msg.c index f75d73224e..8d0992f17a 100644 --- a/openair2/RRC/LTE/MESSAGES/asn1_msg.c +++ b/openair2/RRC/LTE/MESSAGES/asn1_msg.c @@ -41,43 +41,43 @@ #include #include "assertions.h" -#include "RRCConnectionRequest.h" -#include "UL-CCCH-Message.h" -#include "UL-DCCH-Message.h" -#include "DL-CCCH-Message.h" -#include "DL-DCCH-Message.h" -#include "PCCH-Message.h" +#include "LTE_RRCConnectionRequest.h" +#include "LTE_UL-CCCH-Message.h" +#include "LTE_UL-DCCH-Message.h" +#include "LTE_DL-CCCH-Message.h" +#include "LTE_DL-DCCH-Message.h" +#include "LTE_PCCH-Message.h" #include "openair3/UTILS/conversions.h" -#include "EstablishmentCause.h" -#include "RRCConnectionSetup.h" -#include "SRB-ToAddModList.h" -#include "DRB-ToAddModList.h" -#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) -#include "MCCH-Message.h" +#include "LTE_EstablishmentCause.h" +#include "LTE_RRCConnectionSetup.h" +#include "LTE_SRB-ToAddModList.h" +#include "LTE_DRB-ToAddModList.h" +#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) +#include "LTE_MCCH-Message.h" //#define MRB1 1 #endif #include "RRC/LTE/rrc_defs.h" #include "RRC/LTE/rrc_extern.h" -#include "RRCConnectionSetupComplete.h" -#include "RRCConnectionReconfigurationComplete.h" -#include "RRCConnectionReconfiguration.h" -#include "MasterInformationBlock.h" -#include "SystemInformation.h" +#include "LTE_RRCConnectionSetupComplete.h" +#include "LTE_RRCConnectionReconfigurationComplete.h" +#include "LTE_RRCConnectionReconfiguration.h" +#include "LTE_MasterInformationBlock.h" +#include "LTE_SystemInformation.h" -#include "SystemInformationBlockType1.h" +#include "LTE_SystemInformationBlockType1.h" -#include "SIB-Type.h" +#include "LTE_SIB-Type.h" -#include "BCCH-DL-SCH-Message.h" -#include "SBCCH-SL-BCH-MessageType.h" -#include "SBCCH-SL-BCH-Message.h" +#include "LTE_BCCH-DL-SCH-Message.h" +#include "LTE_SBCCH-SL-BCH-MessageType.h" +#include "LTE_SBCCH-SL-BCH-Message.h" //#include "PHY/defs.h" -#include "MeasObjectToAddModList.h" -#include "ReportConfigToAddModList.h" -#include "MeasIdToAddModList.h" +#include "LTE_MeasObjectToAddModList.h" +#include "LTE_ReportConfigToAddModList.h" +#include "LTE_MeasIdToAddModList.h" #include "enb_config.h" #if defined(ENABLE_ITTI) @@ -182,7 +182,7 @@ uint8_t do_MIB(rrc_eNB_carrier_data_t *carrier, uint32_t N_RB_DL, uint32_t phich { asn_enc_rval_t enc_rval; - BCCH_BCH_Message_t *mib=&carrier->mib ; + LTE_BCCH_BCH_Message_t *mib=&carrier->mib ; uint8_t sfn = (uint8_t)((frame>>2)&0xff); uint16_t *spare= calloc(1, sizeof(uint16_t)); if (spare == NULL) abort(); @@ -190,35 +190,35 @@ uint8_t do_MIB(rrc_eNB_carrier_data_t *carrier, uint32_t N_RB_DL, uint32_t phich switch (N_RB_DL) { case 6: - mib->message.dl_Bandwidth = MasterInformationBlock__dl_Bandwidth_n6; + mib->message.dl_Bandwidth = LTE_MasterInformationBlock__dl_Bandwidth_n6; break; case 15: - mib->message.dl_Bandwidth = MasterInformationBlock__dl_Bandwidth_n15; + mib->message.dl_Bandwidth = LTE_MasterInformationBlock__dl_Bandwidth_n15; break; case 25: - mib->message.dl_Bandwidth = MasterInformationBlock__dl_Bandwidth_n25; + mib->message.dl_Bandwidth = LTE_MasterInformationBlock__dl_Bandwidth_n25; break; case 50: - mib->message.dl_Bandwidth = MasterInformationBlock__dl_Bandwidth_n50; + mib->message.dl_Bandwidth = LTE_MasterInformationBlock__dl_Bandwidth_n50; break; case 75: - mib->message.dl_Bandwidth = MasterInformationBlock__dl_Bandwidth_n75; + mib->message.dl_Bandwidth = LTE_MasterInformationBlock__dl_Bandwidth_n75; break; case 100: - mib->message.dl_Bandwidth = MasterInformationBlock__dl_Bandwidth_n100; + mib->message.dl_Bandwidth = LTE_MasterInformationBlock__dl_Bandwidth_n100; break; default: AssertFatal(1==0,"Unknown dl_Bandwidth %d\n",N_RB_DL); } - AssertFatal(phich_Resource <= PHICH_Config__phich_Resource_two,"Illegal phich_Resource\n"); + AssertFatal(phich_Resource <= LTE_PHICH_Config__phich_Resource_two,"Illegal phich_Resource\n"); mib->message.phich_Config.phich_Resource = phich_Resource; - AssertFatal(phich_duration <= PHICH_Config__phich_Duration_extended,"Illegal phich_Duration\n"); + AssertFatal(phich_duration <= LTE_PHICH_Config__phich_Duration_extended,"Illegal phich_Duration\n"); mib->message.phich_Config.phich_Duration = phich_duration; LOG_I(RRC,"[MIB] systemBandwidth %x, phich_duration %x, phich_resource %x,sfn %x\n", (uint32_t)mib->message.dl_Bandwidth, @@ -230,7 +230,7 @@ uint8_t do_MIB(rrc_eNB_carrier_data_t *carrier, uint32_t N_RB_DL, uint32_t phich mib->message.systemFrameNumber.size = 1; mib->message.systemFrameNumber.bits_unused=0; mib->message.spare.buf = (uint8_t *)spare; -#if (RRC_VERSION < MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION < MAKE_VERSION(14, 0, 0)) mib->message.spare.size = 2; mib->message.spare.bits_unused = 6; // This makes a spare of 10 bits #else @@ -239,7 +239,7 @@ uint8_t do_MIB(rrc_eNB_carrier_data_t *carrier, uint32_t N_RB_DL, uint32_t phich mib->message.schedulingInfoSIB1_BR_r13 = 0; // turn off eMTC #endif - enc_rval = uper_encode_to_buffer(&asn_DEF_BCCH_BCH_Message, + enc_rval = uper_encode_to_buffer(&asn_DEF_LTE_BCCH_BCH_Message, NULL, (void*)mib, carrier->MIB, @@ -280,7 +280,7 @@ uint8_t do_MIB_SL(const protocol_ctxt_t* const ctxt_pP, const uint8_t eNB_index, { asn_enc_rval_t enc_rval; - SBCCH_SL_BCH_MessageType_t *mib_sl = &UE_rrc_inst[ctxt_pP->module_id].mib_sl[eNB_index]; + LTE_SBCCH_SL_BCH_MessageType_t *mib_sl = &UE_rrc_inst[ctxt_pP->module_id].mib_sl[eNB_index]; uint8_t sfn = (uint8_t)((frame>>2)&0xff); UE_rrc_inst[ctxt_pP->module_id].MIB = (uint8_t*) malloc16(4); @@ -291,7 +291,7 @@ uint8_t do_MIB_SL(const protocol_ctxt_t* const ctxt_pP, const uint8_t eNB_index, if (UE_rrc_inst[ctxt_pP->module_id].sib1[eNB_index]->tdd_Config) { mib_sl->tdd_ConfigSL_r12.subframeAssignmentSL_r12 = UE_rrc_inst[ctxt_pP->module_id].sib1[eNB_index]->tdd_Config->subframeAssignment; } else { - mib_sl->tdd_ConfigSL_r12.subframeAssignmentSL_r12 = TDD_ConfigSL_r12__subframeAssignmentSL_r12_none; + mib_sl->tdd_ConfigSL_r12.subframeAssignmentSL_r12 = LTE_TDD_ConfigSL_r12__subframeAssignmentSL_r12_none; } //if triggered by sl communication if (UE_rrc_inst[ctxt_pP->module_id].sib18[eNB_index]->commConfig_r12->commSyncConfig_r12->list.array[0]->txParameters_r12->syncInfoReserved_r12){ @@ -319,7 +319,7 @@ uint8_t do_MIB_SL(const protocol_ctxt_t* const ctxt_pP, const uint8_t eNB_index, LOG_I(RRC,"[MIB-SL] sfn %x, subframe %x\n", (uint32_t)sfn, (uint8_t)subframe); - enc_rval = uper_encode_to_buffer(&asn_DEF_SBCCH_SL_BCH_Message, + enc_rval = uper_encode_to_buffer(&asn_DEF_LTE_SBCCH_SL_BCH_Message, NULL, (void*)mib_sl, UE_rrc_inst[ctxt_pP->module_id].MIB, @@ -350,28 +350,28 @@ uint8_t do_SIB1(rrc_eNB_carrier_data_t *carrier, #else int num_plmn = 1; #endif - PLMN_IdentityInfo_t PLMN_identity_info[num_plmn]; - MCC_MNC_Digit_t dummy_mcc[num_plmn][3], dummy_mnc[num_plmn][3]; + LTE_PLMN_IdentityInfo_t PLMN_identity_info[num_plmn]; + LTE_MCC_MNC_Digit_t dummy_mcc[num_plmn][3], dummy_mnc[num_plmn][3]; asn_enc_rval_t enc_rval; - SchedulingInfo_t schedulingInfo; - SIB_Type_t sib_type; + LTE_SchedulingInfo_t schedulingInfo; + LTE_SIB_Type_t sib_type; uint8_t *buffer = carrier->SIB1; - BCCH_DL_SCH_Message_t *bcch_message = &carrier->siblock1; - SystemInformationBlockType1_t **sib1 = &carrier->sib1; + LTE_BCCH_DL_SCH_Message_t *bcch_message = &carrier->siblock1; + LTE_SystemInformationBlockType1_t **sib1 = &carrier->sib1; int i; - memset(bcch_message,0,sizeof(BCCH_DL_SCH_Message_t)); - bcch_message->message.present = BCCH_DL_SCH_MessageType_PR_c1; - bcch_message->message.choice.c1.present = BCCH_DL_SCH_MessageType__c1_PR_systemInformationBlockType1; + memset(bcch_message,0,sizeof(LTE_BCCH_DL_SCH_Message_t)); + bcch_message->message.present = LTE_BCCH_DL_SCH_MessageType_PR_c1; + bcch_message->message.choice.c1.present = LTE_BCCH_DL_SCH_MessageType__c1_PR_systemInformationBlockType1; // memcpy(&bcch_message.message.choice.c1.choice.systemInformationBlockType1,sib1,sizeof(SystemInformationBlockType1_t)); *sib1 = &bcch_message->message.choice.c1.choice.systemInformationBlockType1; - memset(PLMN_identity_info,0,num_plmn * sizeof(PLMN_IdentityInfo_t)); - memset(&schedulingInfo,0,sizeof(SchedulingInfo_t)); - memset(&sib_type,0,sizeof(SIB_Type_t)); + memset(PLMN_identity_info,0,num_plmn * sizeof(LTE_PLMN_IdentityInfo_t)); + memset(&schedulingInfo,0,sizeof(LTE_SchedulingInfo_t)); + memset(&sib_type,0,sizeof(LTE_SIB_Type_t)); /* as per TS 36.311, up to 6 PLMN_identity_info are allowed in list -> add one by one */ for (i = 0; i < configuration->num_plmn; ++i) { @@ -426,7 +426,7 @@ uint8_t do_SIB1(rrc_eNB_carrier_data_t *carrier, } //assign_enum(&PLMN_identity_info.cellReservedForOperatorUse,PLMN_IdentityInfo__cellReservedForOperatorUse_notReserved); - PLMN_identity_info[i].cellReservedForOperatorUse=PLMN_IdentityInfo__cellReservedForOperatorUse_notReserved; + PLMN_identity_info[i].cellReservedForOperatorUse=LTE_PLMN_IdentityInfo__cellReservedForOperatorUse_notReserved; ASN_SEQUENCE_ADD(&(*sib1)->cellAccessRelatedInfo.plmn_IdentityList.list,&PLMN_identity_info[i]); } @@ -461,10 +461,10 @@ uint8_t do_SIB1(rrc_eNB_carrier_data_t *carrier, (*sib1)->cellAccessRelatedInfo.cellIdentity.bits_unused=4; // assign_enum(&(*sib1)->cellAccessRelatedInfo.cellBarred,SystemInformationBlockType1__cellAccessRelatedInfo__cellBarred_notBarred); - (*sib1)->cellAccessRelatedInfo.cellBarred=SystemInformationBlockType1__cellAccessRelatedInfo__cellBarred_notBarred; + (*sib1)->cellAccessRelatedInfo.cellBarred=LTE_SystemInformationBlockType1__cellAccessRelatedInfo__cellBarred_notBarred; // assign_enum(&(*sib1)->cellAccessRelatedInfo.intraFreqReselection,SystemInformationBlockType1__cellAccessRelatedInfo__intraFreqReselection_allowed); - (*sib1)->cellAccessRelatedInfo.intraFreqReselection=SystemInformationBlockType1__cellAccessRelatedInfo__intraFreqReselection_notAllowed; + (*sib1)->cellAccessRelatedInfo.intraFreqReselection=LTE_SystemInformationBlockType1__cellAccessRelatedInfo__intraFreqReselection_notAllowed; (*sib1)->cellAccessRelatedInfo.csg_Indication=0; (*sib1)->cellSelectionInfo.q_RxLevMin=-65; @@ -478,10 +478,10 @@ uint8_t do_SIB1(rrc_eNB_carrier_data_t *carrier, 7; #endif - schedulingInfo.si_Periodicity=SchedulingInfo__si_Periodicity_rf8; + schedulingInfo.si_Periodicity=LTE_SchedulingInfo__si_Periodicity_rf8; // This is for SIB2/3 - sib_type=SIB_Type_sibType3; + sib_type=LTE_SIB_Type_sibType3; ASN_SEQUENCE_ADD(&schedulingInfo.sib_MappingInfo.list,&sib_type); ASN_SEQUENCE_ADD(&(*sib1)->schedulingInfoList.list,&schedulingInfo); @@ -492,7 +492,7 @@ uint8_t do_SIB1(rrc_eNB_carrier_data_t *carrier, if (configuration->frame_type[CC_id] == TDD) #endif { - (*sib1)->tdd_Config = CALLOC(1,sizeof(struct TDD_Config)); + (*sib1)->tdd_Config = CALLOC(1,sizeof(struct LTE_TDD_Config)); (*sib1)->tdd_Config->subframeAssignment = #if defined(ENABLE_ITTI) @@ -509,14 +509,14 @@ uint8_t do_SIB1(rrc_eNB_carrier_data_t *carrier, #endif } - (*sib1)->si_WindowLength=SystemInformationBlockType1__si_WindowLength_ms20; + (*sib1)->si_WindowLength=LTE_SystemInformationBlockType1__si_WindowLength_ms20; (*sib1)->systemInfoValueTag=0; // (*sib1).nonCriticalExtension = calloc(1,sizeof(*(*sib1).nonCriticalExtension)); #ifdef XER_PRINT xer_fprint(stdout, &asn_DEF_BCCH_DL_SCH_Message, (void*)bcch_message); #endif - enc_rval = uper_encode_to_buffer(&asn_DEF_BCCH_DL_SCH_Message, + enc_rval = uper_encode_to_buffer(&asn_DEF_LTE_BCCH_DL_SCH_Message, NULL, (void*)bcch_message, buffer, @@ -530,7 +530,7 @@ uint8_t do_SIB1(rrc_eNB_carrier_data_t *carrier, char message_string[10000]; size_t message_string_size; - if ((message_string_size = xer_sprint(message_string, sizeof(message_string), &asn_DEF_BCCH_DL_SCH_Message, (void *)bcch_message)) > 0) { + if ((message_string_size = xer_sprint(message_string, sizeof(message_string), &asn_DEF_LTE_BCCH_DL_SCH_Message, (void *)bcch_message)) > 0) { MessageDef *msg_p; msg_p = itti_alloc_new_message_sized (TASK_RRC_ENB, RRC_DL_BCCH, message_string_size + sizeof (IttiMsgText)); @@ -560,46 +560,46 @@ uint8_t do_SIB23(uint8_t Mod_id, ) { - struct SystemInformation_r8_IEs__sib_TypeAndInfo__Member *sib2_part,*sib3_part; + struct LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member *sib2_part,*sib3_part; -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) //TTN - for D2D - struct SystemInformation_r8_IEs__sib_TypeAndInfo__Member *sib18_part, *sib19_part, *sib21_part; - SL_CommRxPoolList_r12_t *SL_CommRxPoolList; //for SIB18 - struct SL_CommResourcePool_r12 *SL_CommResourcePool; //for SIB18 - SL_DiscRxPoolList_r12_t *SL_DiscRxPoolList; //for SIB19 (discRxPool) - struct SL_DiscResourcePool_r12 *SL_DiscResourcePool; //for SIB19 (discRxPool) + struct LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member *sib18_part, *sib19_part, *sib21_part; + LTE_SL_CommRxPoolList_r12_t *SL_CommRxPoolList; //for SIB18 + struct LTE_SL_CommResourcePool_r12 *SL_CommResourcePool; //for SIB18 + LTE_SL_DiscRxPoolList_r12_t *SL_DiscRxPoolList; //for SIB19 (discRxPool) + struct LTE_SL_DiscResourcePool_r12 *SL_DiscResourcePool; //for SIB19 (discRxPool) //SL_DiscRxPoolList_r12_t *SL_DiscRxPoolPSList; //for SIB19 (discRxPoolPS) //struct SL_DiscResourcePool_r12 *SL_DiscResourcePoolPS; //for SIB19 (discRxPoolPS) //struct SL_V2X_ConfigCommon_r14 *SL_V2X_ConfigCommon; #endif -#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) - struct SystemInformation_r8_IEs__sib_TypeAndInfo__Member *sib13_part; - MBSFN_SubframeConfigList_t *MBSFNSubframeConfigList; - MBSFN_AreaInfoList_r9_t *MBSFNArea_list; - struct MBSFN_AreaInfo_r9 *MBSFN_Area1, *MBSFN_Area2; +#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) + struct LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member *sib13_part; + LTE_MBSFN_SubframeConfigList_t *MBSFNSubframeConfigList; + LTE_MBSFN_AreaInfoList_r9_t *MBSFNArea_list; + struct LTE_MBSFN_AreaInfo_r9 *MBSFN_Area1, *MBSFN_Area2; #endif asn_enc_rval_t enc_rval; uint8_t *buffer = RC.rrc[Mod_id]->carrier[CC_id].SIB23; - BCCH_DL_SCH_Message_t *bcch_message = &RC.rrc[Mod_id]->carrier[CC_id].systemInformation; - SystemInformationBlockType2_t **sib2 = &RC.rrc[Mod_id]->carrier[CC_id].sib2; - SystemInformationBlockType3_t **sib3 = &RC.rrc[Mod_id]->carrier[CC_id].sib3; -#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) - SystemInformationBlockType13_r9_t **sib13 = &RC.rrc[Mod_id]->carrier[CC_id].sib13; + LTE_BCCH_DL_SCH_Message_t *bcch_message = &RC.rrc[Mod_id]->carrier[CC_id].systemInformation; + LTE_SystemInformationBlockType2_t **sib2 = &RC.rrc[Mod_id]->carrier[CC_id].sib2; + LTE_SystemInformationBlockType3_t **sib3 = &RC.rrc[Mod_id]->carrier[CC_id].sib3; +#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) + LTE_SystemInformationBlockType13_r9_t **sib13 = &RC.rrc[Mod_id]->carrier[CC_id].sib13; uint8_t MBMS_flag = RC.rrc[Mod_id]->carrier[CC_id].MBMS_flag; #endif -#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) //TTN - for D2D - SystemInformationBlockType18_r12_t **sib18 = &RC.rrc[Mod_id]->carrier[CC_id].sib18; - SystemInformationBlockType19_r12_t **sib19 = &RC.rrc[Mod_id]->carrier[CC_id].sib19; - SystemInformationBlockType21_r14_t **sib21 = &RC.rrc[Mod_id]->carrier[CC_id].sib21; + LTE_SystemInformationBlockType18_r12_t **sib18 = &RC.rrc[Mod_id]->carrier[CC_id].sib18; + LTE_SystemInformationBlockType19_r12_t **sib19 = &RC.rrc[Mod_id]->carrier[CC_id].sib19; + LTE_SystemInformationBlockType21_r14_t **sib21 = &RC.rrc[Mod_id]->carrier[CC_id].sib21; #endif if (bcch_message) { - memset(bcch_message,0,sizeof(BCCH_DL_SCH_Message_t)); + memset(bcch_message,0,sizeof(LTE_BCCH_DL_SCH_Message_t)); } else { LOG_E(RRC,"[eNB %d] BCCH_MESSAGE is null, exiting\n", Mod_id); exit(-1); @@ -615,45 +615,45 @@ uint8_t do_SIB23(uint8_t Mod_id, exit(-1); } -#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) LOG_I(RRC,"[eNB %d] Configuration SIB2/3, MBMS = %d\n", Mod_id, MBMS_flag); #else LOG_I(RRC,"[eNB %d] Configuration SIB2/3\n", Mod_id); #endif - sib2_part = CALLOC(1,sizeof(struct SystemInformation_r8_IEs__sib_TypeAndInfo__Member)); - sib3_part = CALLOC(1,sizeof(struct SystemInformation_r8_IEs__sib_TypeAndInfo__Member)); - memset(sib2_part,0,sizeof(struct SystemInformation_r8_IEs__sib_TypeAndInfo__Member)); - memset(sib3_part,0,sizeof(struct SystemInformation_r8_IEs__sib_TypeAndInfo__Member)); + sib2_part = CALLOC(1,sizeof(struct LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member)); + sib3_part = CALLOC(1,sizeof(struct LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member)); + memset(sib2_part,0,sizeof(struct LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member)); + memset(sib3_part,0,sizeof(struct LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member)); - sib2_part->present = SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib2; - sib3_part->present = SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib3; + sib2_part->present = LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib2; + sib3_part->present = LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib3; *sib2 = &sib2_part->choice.sib2; *sib3 = &sib3_part->choice.sib3; -#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) if (MBMS_flag > 0) { - sib13_part = CALLOC(1,sizeof(struct SystemInformation_r8_IEs__sib_TypeAndInfo__Member)); - memset(sib13_part,0,sizeof(struct SystemInformation_r8_IEs__sib_TypeAndInfo__Member)); - sib13_part->present = SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib13_v920; + sib13_part = CALLOC(1,sizeof(struct LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member)); + memset(sib13_part,0,sizeof(struct LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member)); + sib13_part->present = LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib13_v920; *sib13 = &sib13_part->choice.sib13_v920; } #endif -#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) //TTN - for D2D - sib18_part = CALLOC(1,sizeof(struct SystemInformation_r8_IEs__sib_TypeAndInfo__Member)); - sib19_part = CALLOC(1,sizeof(struct SystemInformation_r8_IEs__sib_TypeAndInfo__Member)); - sib21_part = CALLOC(1,sizeof(struct SystemInformation_r8_IEs__sib_TypeAndInfo__Member)); - memset(sib18_part,0,sizeof(struct SystemInformation_r8_IEs__sib_TypeAndInfo__Member)); - memset(sib19_part,0,sizeof(struct SystemInformation_r8_IEs__sib_TypeAndInfo__Member)); - memset(sib21_part,0,sizeof(struct SystemInformation_r8_IEs__sib_TypeAndInfo__Member)); + sib18_part = CALLOC(1,sizeof(struct LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member)); + sib19_part = CALLOC(1,sizeof(struct LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member)); + sib21_part = CALLOC(1,sizeof(struct LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member)); + memset(sib18_part,0,sizeof(struct LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member)); + memset(sib19_part,0,sizeof(struct LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member)); + memset(sib21_part,0,sizeof(struct LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member)); - sib18_part->present = SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib18_v1250; - sib19_part->present = SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib19_v1250; - sib21_part->present = SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib21_v1430; + sib18_part->present = LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib18_v1250; + sib19_part->present = LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib19_v1250; + sib21_part->present = LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib21_v1430; *sib18 = &sib18_part->choice.sib18_v1250; *sib19 = &sib19_part->choice.sib19_v1250; @@ -665,7 +665,7 @@ uint8_t do_SIB23(uint8_t Mod_id, // sib2 (*sib2)->ac_BarringInfo = NULL; -#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) (*sib2)->ext1 = NULL; (*sib2)->ext2 = NULL; #endif @@ -677,7 +677,7 @@ uint8_t do_SIB23(uint8_t Mod_id, if (configuration->rach_preamblesGroupAConfig[CC_id]) { (*sib2)->radioResourceConfigCommon.rach_ConfigCommon.preambleInfo.preamblesGroupAConfig - = CALLOC(1,sizeof(struct RACH_ConfigCommon__preambleInfo__preamblesGroupAConfig)); + = CALLOC(1,sizeof(struct LTE_RACH_ConfigCommon__preambleInfo__preamblesGroupAConfig)); (*sib2)->radioResourceConfigCommon.rach_ConfigCommon.preambleInfo.preamblesGroupAConfig->sizeOfRA_PreamblesGroupA = configuration->rach_sizeOfRA_PreamblesGroupA[CC_id]; (*sib2)->radioResourceConfigCommon.rach_ConfigCommon.preambleInfo.preamblesGroupAConfig->messageSizeGroupA @@ -749,7 +749,7 @@ uint8_t do_SIB23(uint8_t Mod_id, = configuration->pucch_nRB_CQI[CC_id]; (*sib2)->radioResourceConfigCommon.pucch_ConfigCommon.nCS_AN = configuration->pucch_nCS_AN[CC_id]; -//#if (RRC_VERSION < MAKE_VERSION(10, 0, 0)) +//#if (LTE_RRC_VERSION < MAKE_VERSION(10, 0, 0)) (*sib2)->radioResourceConfigCommon.pucch_ConfigCommon.n1PUCCH_AN = configuration->pucch_n1_AN[CC_id]; //#endif @@ -757,7 +757,7 @@ uint8_t do_SIB23(uint8_t Mod_id, // SRS Config if (configuration->srs_enable[CC_id]==1) { (*sib2)->radioResourceConfigCommon.soundingRS_UL_ConfigCommon.present - = SoundingRS_UL_ConfigCommon_PR_setup; + = LTE_SoundingRS_UL_ConfigCommon_PR_setup; (*sib2)->radioResourceConfigCommon.soundingRS_UL_ConfigCommon.choice.setup.srs_BandwidthConfig = configuration->srs_BandwidthConfig[CC_id]; (*sib2)->radioResourceConfigCommon.soundingRS_UL_ConfigCommon.choice.setup.srs_SubframeConfig @@ -775,7 +775,7 @@ uint8_t do_SIB23(uint8_t Mod_id, RC.rrc[Mod_id]->srs_enable[CC_id] = 1; } else { RC.rrc[Mod_id]->srs_enable[CC_id] = 0; - (*sib2)->radioResourceConfigCommon.soundingRS_UL_ConfigCommon.present=SoundingRS_UL_ConfigCommon_PR_release; + (*sib2)->radioResourceConfigCommon.soundingRS_UL_ConfigCommon.present=LTE_SoundingRS_UL_ConfigCommon_PR_release; (*sib2)->radioResourceConfigCommon.soundingRS_UL_ConfigCommon.choice.release=0; } @@ -818,23 +818,23 @@ uint8_t do_SIB23(uint8_t Mod_id, = configuration->ue_TimersAndConstants_n311[CC_id]; #else - (*sib2)->radioResourceConfigCommon.rach_ConfigCommon.preambleInfo.numberOfRA_Preambles=RACH_ConfigCommon__preambleInfo__numberOfRA_Preambles_n64; + (*sib2)->radioResourceConfigCommon.rach_ConfigCommon.preambleInfo.numberOfRA_Preambles=LTE_RACH_ConfigCommon__preambleInfo__numberOfRA_Preambles_n64; (*sib2)->radioResourceConfigCommon.rach_ConfigCommon.preambleInfo.preamblesGroupAConfig = NULL; - (*sib2)->radioResourceConfigCommon.rach_ConfigCommon.powerRampingParameters.powerRampingStep=RACH_ConfigCommon__powerRampingParameters__powerRampingStep_dB2; + (*sib2)->radioResourceConfigCommon.rach_ConfigCommon.powerRampingParameters.powerRampingStep=LTE_RACH_ConfigCommon__powerRampingParameters__powerRampingStep_dB2; (*sib2)->radioResourceConfigCommon.rach_ConfigCommon.powerRampingParameters.preambleInitialReceivedTargetPower= RACH_ConfigCommon__powerRampingParameters__preambleInitialReceivedTargetPower_dBm_100; - (*sib2)->radioResourceConfigCommon.rach_ConfigCommon.ra_SupervisionInfo.preambleTransMax=RACH_ConfigCommon__ra_SupervisionInfo__preambleTransMax_n10; - (*sib2)->radioResourceConfigCommon.rach_ConfigCommon.ra_SupervisionInfo.ra_ResponseWindowSize=RACH_ConfigCommon__ra_SupervisionInfo__ra_ResponseWindowSize_sf10; + (*sib2)->radioResourceConfigCommon.rach_ConfigCommon.ra_SupervisionInfo.preambleTransMax=LTE_RACH_ConfigCommon__ra_SupervisionInfo__preambleTransMax_n10; + (*sib2)->radioResourceConfigCommon.rach_ConfigCommon.ra_SupervisionInfo.ra_ResponseWindowSize=LTE_RACH_ConfigCommon__ra_SupervisionInfo__ra_ResponseWindowSize_sf10; (*sib2)->radioResourceConfigCommon.rach_ConfigCommon.ra_SupervisionInfo.mac_ContentionResolutionTimer= - RACH_ConfigCommon__ra_SupervisionInfo__mac_ContentionResolutionTimer_sf48; + LTE_RACH_ConfigCommon__ra_SupervisionInfo__mac_ContentionResolutionTimer_sf48; (*sib2)->radioResourceConfigCommon.rach_ConfigCommon.maxHARQ_Msg3Tx = 4; // BCCH-Config (*sib2)->radioResourceConfigCommon.bcch_Config.modificationPeriodCoeff=BCCH_Config__modificationPeriodCoeff_n2; // PCCH-Config - (*sib2)->radioResourceConfigCommon.pcch_Config.defaultPagingCycle = PCCH_Config__defaultPagingCycle_rf128; - (*sib2)->radioResourceConfigCommon.pcch_Config.nB=PCCH_Config__nB_oneT; + (*sib2)->radioResourceConfigCommon.pcch_Config.defaultPagingCycle = LTE_PCCH_Config__defaultPagingCycle_rf128; + (*sib2)->radioResourceConfigCommon.pcch_Config.nB=LTE_PCCH_Config__nB_oneT; // PRACH-Config (*sib2)->radioResourceConfigCommon.prach_Config.rootSequenceIndex=Mod_id;//0;//384; @@ -851,7 +851,7 @@ uint8_t do_SIB23(uint8_t Mod_id, // PUSCH-Config (*sib2)->radioResourceConfigCommon.pusch_ConfigCommon.pusch_ConfigBasic.n_SB=1; - (*sib2)->radioResourceConfigCommon.pusch_ConfigCommon.pusch_ConfigBasic.hoppingMode=PUSCH_ConfigCommon__pusch_ConfigBasic__hoppingMode_interSubFrame; + (*sib2)->radioResourceConfigCommon.pusch_ConfigCommon.pusch_ConfigBasic.hoppingMode=LTE_PUSCH_ConfigCommon__pusch_ConfigBasic__hoppingMode_interSubFrame; (*sib2)->radioResourceConfigCommon.pusch_ConfigCommon.pusch_ConfigBasic.pusch_HoppingOffset=0; (*sib2)->radioResourceConfigCommon.pusch_ConfigCommon.pusch_ConfigBasic.enable64QAM=0; (*sib2)->radioResourceConfigCommon.pusch_ConfigCommon.ul_ReferenceSignalsPUSCH.groupHoppingEnabled=1; @@ -861,28 +861,28 @@ uint8_t do_SIB23(uint8_t Mod_id, // PUCCH-Config - (*sib2)->radioResourceConfigCommon.pucch_ConfigCommon.deltaPUCCH_Shift=PUCCH_ConfigCommon__deltaPUCCH_Shift_ds1; + (*sib2)->radioResourceConfigCommon.pucch_ConfigCommon.deltaPUCCH_Shift=LTE_PUCCH_ConfigCommon__deltaPUCCH_Shift_ds1; (*sib2)->radioResourceConfigCommon.pucch_ConfigCommon.nRB_CQI = 1; (*sib2)->radioResourceConfigCommon.pucch_ConfigCommon.nCS_AN = 0; (*sib2)->radioResourceConfigCommon.pucch_ConfigCommon.n1PUCCH_AN = 32; - (*sib2)->radioResourceConfigCommon.soundingRS_UL_ConfigCommon.present=SoundingRS_UL_ConfigCommon_PR_release; + (*sib2)->radioResourceConfigCommon.soundingRS_UL_ConfigCommon.present=LTE_SoundingRS_UL_ConfigCommon_PR_release; (*sib2)->radioResourceConfigCommon.soundingRS_UL_ConfigCommon.choice.release=0; // uplinkPowerControlCommon (*sib2)->radioResourceConfigCommon.uplinkPowerControlCommon.p0_NominalPUSCH = -108; (*sib2)->radioResourceConfigCommon.uplinkPowerControlCommon.p0_NominalPUCCH = -108; - (*sib2)->radioResourceConfigCommon.uplinkPowerControlCommon.alpha=UplinkPowerControlCommon__alpha_al1; - (*sib2)->radioResourceConfigCommon.uplinkPowerControlCommon.deltaFList_PUCCH.deltaF_PUCCH_Format1=DeltaFList_PUCCH__deltaF_PUCCH_Format1_deltaF2; - (*sib2)->radioResourceConfigCommon.uplinkPowerControlCommon.deltaFList_PUCCH.deltaF_PUCCH_Format1b=DeltaFList_PUCCH__deltaF_PUCCH_Format1b_deltaF3; + (*sib2)->radioResourceConfigCommon.uplinkPowerControlCommon.alpha=LTE_UplinkPowerControlCommon__alpha_al1; + (*sib2)->radioResourceConfigCommon.uplinkPowerControlCommon.deltaFList_PUCCH.deltaF_PUCCH_Format1=LTE_DeltaFList_PUCCH__deltaF_PUCCH_Format1_deltaF2; + (*sib2)->radioResourceConfigCommon.uplinkPowerControlCommon.deltaFList_PUCCH.deltaF_PUCCH_Format1b=LTE_DeltaFList_PUCCH__deltaF_PUCCH_Format1b_deltaF3; - (*sib2)->radioResourceConfigCommon.uplinkPowerControlCommon.deltaFList_PUCCH.deltaF_PUCCH_Format2=DeltaFList_PUCCH__deltaF_PUCCH_Format2_deltaF0; + (*sib2)->radioResourceConfigCommon.uplinkPowerControlCommon.deltaFList_PUCCH.deltaF_PUCCH_Format2=LTE_DeltaFList_PUCCH__deltaF_PUCCH_Format2_deltaF0; - (*sib2)->radioResourceConfigCommon.uplinkPowerControlCommon.deltaFList_PUCCH.deltaF_PUCCH_Format2a=DeltaFList_PUCCH__deltaF_PUCCH_Format2a_deltaF0; + (*sib2)->radioResourceConfigCommon.uplinkPowerControlCommon.deltaFList_PUCCH.deltaF_PUCCH_Format2a=LTE_DeltaFList_PUCCH__deltaF_PUCCH_Format2a_deltaF0; - (*sib2)->radioResourceConfigCommon.uplinkPowerControlCommon.deltaFList_PUCCH.deltaF_PUCCH_Format2b=DeltaFList_PUCCH__deltaF_PUCCH_Format2b_deltaF0; + (*sib2)->radioResourceConfigCommon.uplinkPowerControlCommon.deltaFList_PUCCH.deltaF_PUCCH_Format2b=LTE_DeltaFList_PUCCH__deltaF_PUCCH_Format2b_deltaF0; (*sib2)->radioResourceConfigCommon.uplinkPowerControlCommon.deltaPreambleMsg3 = 6; @@ -907,20 +907,20 @@ uint8_t do_SIB23(uint8_t Mod_id, (*sib2)->freqInfo.ul_Bandwidth = NULL; // (*sib2)->mbsfn_SubframeConfigList = NULL; -#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) if (MBMS_flag > 0) { LOG_I(RRC,"Adding MBSFN subframe Configuration 1 to SIB2\n"); - MBSFN_SubframeConfig_t *sib2_mbsfn_SubframeConfig1; - (*sib2)->mbsfn_SubframeConfigList = CALLOC(1,sizeof(struct MBSFN_SubframeConfigList)); + LTE_MBSFN_SubframeConfig_t *sib2_mbsfn_SubframeConfig1; + (*sib2)->mbsfn_SubframeConfigList = CALLOC(1,sizeof(struct LTE_MBSFN_SubframeConfigList)); MBSFNSubframeConfigList = (*sib2)->mbsfn_SubframeConfigList; sib2_mbsfn_SubframeConfig1= CALLOC(1,sizeof(*sib2_mbsfn_SubframeConfig1)); memset((void*)sib2_mbsfn_SubframeConfig1,0,sizeof(*sib2_mbsfn_SubframeConfig1)); - sib2_mbsfn_SubframeConfig1->radioframeAllocationPeriod= MBSFN_SubframeConfig__radioframeAllocationPeriod_n4; + sib2_mbsfn_SubframeConfig1->radioframeAllocationPeriod= LTE_MBSFN_SubframeConfig__radioframeAllocationPeriod_n4; sib2_mbsfn_SubframeConfig1->radioframeAllocationOffset= 1; - sib2_mbsfn_SubframeConfig1->subframeAllocation.present= MBSFN_SubframeConfig__subframeAllocation_PR_oneFrame; + sib2_mbsfn_SubframeConfig1->subframeAllocation.present= LTE_MBSFN_SubframeConfig__subframeAllocation_PR_oneFrame; sib2_mbsfn_SubframeConfig1->subframeAllocation.choice.oneFrame.buf= MALLOC(1); sib2_mbsfn_SubframeConfig1->subframeAllocation.choice.oneFrame.size= 1; sib2_mbsfn_SubframeConfig1->subframeAllocation.choice.oneFrame.bits_unused= 2; @@ -931,13 +931,13 @@ uint8_t do_SIB23(uint8_t Mod_id, if (MBMS_flag == 4 ) { LOG_I(RRC,"Adding MBSFN subframe Configuration 2 to SIB2\n"); - MBSFN_SubframeConfig_t *sib2_mbsfn_SubframeConfig2; + LTE_MBSFN_SubframeConfig_t *sib2_mbsfn_SubframeConfig2; sib2_mbsfn_SubframeConfig2= CALLOC(1,sizeof(*sib2_mbsfn_SubframeConfig2)); memset((void*)sib2_mbsfn_SubframeConfig2,0,sizeof(*sib2_mbsfn_SubframeConfig2)); - sib2_mbsfn_SubframeConfig2->radioframeAllocationPeriod= MBSFN_SubframeConfig__radioframeAllocationPeriod_n4; + sib2_mbsfn_SubframeConfig2->radioframeAllocationPeriod= LTE_MBSFN_SubframeConfig__radioframeAllocationPeriod_n4; sib2_mbsfn_SubframeConfig2->radioframeAllocationOffset= 1; - sib2_mbsfn_SubframeConfig2->subframeAllocation.present= MBSFN_SubframeConfig__subframeAllocation_PR_oneFrame; + sib2_mbsfn_SubframeConfig2->subframeAllocation.present= LTE_MBSFN_SubframeConfig__subframeAllocation_PR_oneFrame; sib2_mbsfn_SubframeConfig2->subframeAllocation.choice.oneFrame.buf= MALLOC(1); sib2_mbsfn_SubframeConfig2->subframeAllocation.choice.oneFrame.size= 1; sib2_mbsfn_SubframeConfig2->subframeAllocation.choice.oneFrame.bits_unused= 2; @@ -953,13 +953,13 @@ uint8_t do_SIB23(uint8_t Mod_id, (*sib2)->mbsfn_SubframeConfigList = NULL; #endif - (*sib2)->timeAlignmentTimerCommon=TimeAlignmentTimer_infinity;//TimeAlignmentTimer_sf5120; + (*sib2)->timeAlignmentTimerCommon=LTE_TimeAlignmentTimer_infinity;//TimeAlignmentTimer_sf5120; /// (*SIB3) -#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) (*sib3)->ext1 = NULL; #endif - (*sib3)->cellReselectionInfoCommon.q_Hyst=SystemInformationBlockType3__cellReselectionInfoCommon__q_Hyst_dB4; + (*sib3)->cellReselectionInfoCommon.q_Hyst=LTE_SystemInformationBlockType3__cellReselectionInfoCommon__q_Hyst_dB4; (*sib3)->cellReselectionInfoCommon.speedStateReselectionPars=NULL; @@ -973,7 +973,7 @@ uint8_t do_SIB23(uint8_t Mod_id, *(*sib3)->intraFreqCellReselectionInfo.s_IntraSearch = 31; (*sib3)->intraFreqCellReselectionInfo.allowedMeasBandwidth=CALLOC(1,sizeof(*(*sib3)->intraFreqCellReselectionInfo.allowedMeasBandwidth)); - *(*sib3)->intraFreqCellReselectionInfo.allowedMeasBandwidth = AllowedMeasBandwidth_mbw6; + *(*sib3)->intraFreqCellReselectionInfo.allowedMeasBandwidth = LTE_AllowedMeasBandwidth_mbw6; (*sib3)->intraFreqCellReselectionInfo.presenceAntennaPort1 = 0; (*sib3)->intraFreqCellReselectionInfo.neighCellConfig.buf = CALLOC(8,1); @@ -981,15 +981,15 @@ uint8_t do_SIB23(uint8_t Mod_id, (*sib3)->intraFreqCellReselectionInfo.neighCellConfig.buf[0] = 1 << 6; (*sib3)->intraFreqCellReselectionInfo.neighCellConfig.bits_unused = 6; (*sib3)->intraFreqCellReselectionInfo.t_ReselectionEUTRA = 1; - (*sib3)->intraFreqCellReselectionInfo.t_ReselectionEUTRA_SF = (struct SpeedStateScaleFactors *)NULL; + (*sib3)->intraFreqCellReselectionInfo.t_ReselectionEUTRA_SF = (struct LTE_SpeedStateScaleFactors *)NULL; // SIB13 // fill in all elements of SIB13 if present -#if (RRC_VERSION >= MAKE_VERSION(9, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) if (MBMS_flag > 0 ) { // Notification for mcch change - (*sib13)->notificationConfig_r9.notificationRepetitionCoeff_r9= MBMS_NotificationConfig_r9__notificationRepetitionCoeff_r9_n2; + (*sib13)->notificationConfig_r9.notificationRepetitionCoeff_r9= LTE_MBMS_NotificationConfig_r9__notificationRepetitionCoeff_r9_n2; (*sib13)->notificationConfig_r9.notificationOffset_r9= 0; (*sib13)->notificationConfig_r9.notificationSF_Index_r9= 1; @@ -999,11 +999,11 @@ uint8_t do_SIB23(uint8_t Mod_id, // MBSFN Area 1 MBSFN_Area1= CALLOC(1, sizeof(*MBSFN_Area1)); MBSFN_Area1->mbsfn_AreaId_r9= 1; - MBSFN_Area1->non_MBSFNregionLength= MBSFN_AreaInfo_r9__non_MBSFNregionLength_s2; + MBSFN_Area1->non_MBSFNregionLength= LTE_MBSFN_AreaInfo_r9__non_MBSFNregionLength_s2; MBSFN_Area1->notificationIndicator_r9= 0; - MBSFN_Area1->mcch_Config_r9.mcch_RepetitionPeriod_r9= MBSFN_AreaInfo_r9__mcch_Config_r9__mcch_RepetitionPeriod_r9_rf32; + MBSFN_Area1->mcch_Config_r9.mcch_RepetitionPeriod_r9= LTE_MBSFN_AreaInfo_r9__mcch_Config_r9__mcch_RepetitionPeriod_r9_rf32; MBSFN_Area1->mcch_Config_r9.mcch_Offset_r9= 1; // in accordance with mbsfn subframe configuration in sib2 - MBSFN_Area1->mcch_Config_r9.mcch_ModificationPeriod_r9= MBSFN_AreaInfo_r9__mcch_Config_r9__mcch_ModificationPeriod_r9_rf512; + MBSFN_Area1->mcch_Config_r9.mcch_ModificationPeriod_r9= LTE_MBSFN_AreaInfo_r9__mcch_Config_r9__mcch_ModificationPeriod_r9_rf512; // Subframe Allocation Info MBSFN_Area1->mcch_Config_r9.sf_AllocInfo_r9.buf= MALLOC(1); MBSFN_Area1->mcch_Config_r9.sf_AllocInfo_r9.size= 1; @@ -1013,7 +1013,7 @@ uint8_t do_SIB23(uint8_t Mod_id, MBSFN_Area1->mcch_Config_r9.sf_AllocInfo_r9.bits_unused= 2; - MBSFN_Area1->mcch_Config_r9.signallingMCS_r9= MBSFN_AreaInfo_r9__mcch_Config_r9__signallingMCS_r9_n7; + MBSFN_Area1->mcch_Config_r9.signallingMCS_r9= LTE_MBSFN_AreaInfo_r9__mcch_Config_r9__signallingMCS_r9_n7; ASN_SEQUENCE_ADD(&MBSFNArea_list->list,MBSFN_Area1); @@ -1021,11 +1021,11 @@ uint8_t do_SIB23(uint8_t Mod_id, if (MBMS_flag == 4 ) { MBSFN_Area2= CALLOC(1, sizeof(*MBSFN_Area2)); MBSFN_Area2->mbsfn_AreaId_r9= 2; - MBSFN_Area2->non_MBSFNregionLength= MBSFN_AreaInfo_r9__non_MBSFNregionLength_s2; + MBSFN_Area2->non_MBSFNregionLength= LTE_MBSFN_AreaInfo_r9__non_MBSFNregionLength_s2; MBSFN_Area2->notificationIndicator_r9= 1; - MBSFN_Area2->mcch_Config_r9.mcch_RepetitionPeriod_r9= MBSFN_AreaInfo_r9__mcch_Config_r9__mcch_RepetitionPeriod_r9_rf32; + MBSFN_Area2->mcch_Config_r9.mcch_RepetitionPeriod_r9= LTE_MBSFN_AreaInfo_r9__mcch_Config_r9__mcch_RepetitionPeriod_r9_rf32; MBSFN_Area2->mcch_Config_r9.mcch_Offset_r9= 1; - MBSFN_Area2->mcch_Config_r9.mcch_ModificationPeriod_r9= MBSFN_AreaInfo_r9__mcch_Config_r9__mcch_ModificationPeriod_r9_rf512; + MBSFN_Area2->mcch_Config_r9.mcch_ModificationPeriod_r9= LTE_MBSFN_AreaInfo_r9__mcch_Config_r9__mcch_ModificationPeriod_r9_rf512; // Subframe Allocation Info MBSFN_Area2->mcch_Config_r9.sf_AllocInfo_r9.buf= MALLOC(1); MBSFN_Area2->mcch_Config_r9.sf_AllocInfo_r9.size= 1; @@ -1034,7 +1034,7 @@ uint8_t do_SIB23(uint8_t Mod_id, MBSFN_Area2->mcch_Config_r9.sf_AllocInfo_r9.buf[0]=0x04<<2; // FDD: SF6 - MBSFN_Area2->mcch_Config_r9.signallingMCS_r9= MBSFN_AreaInfo_r9__mcch_Config_r9__signallingMCS_r9_n7; + MBSFN_Area2->mcch_Config_r9.signallingMCS_r9= LTE_MBSFN_AreaInfo_r9__mcch_Config_r9__signallingMCS_r9_n7; ASN_SEQUENCE_ADD(&MBSFNArea_list->list,MBSFN_Area2); } @@ -1045,7 +1045,7 @@ uint8_t do_SIB23(uint8_t Mod_id, #endif -#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) //TTN - for D2D // SIB18 //commRxPool_r12 @@ -1065,44 +1065,44 @@ uint8_t do_SIB23(uint8_t Mod_id, SL_CommResourcePool->sc_TF_ResourceConfig_r12.prb_End_r12 = configuration->rxPool_ResourceConfig_prb_End[CC_id]; SL_CommResourcePool->sc_TF_ResourceConfig_r12.offsetIndicator_r12.present = configuration->rxPool_ResourceConfig_offsetIndicator_present[CC_id]; - if (SL_CommResourcePool->sc_TF_ResourceConfig_r12.offsetIndicator_r12.present == SL_OffsetIndicator_r12_PR_small_r12 ) { + if (SL_CommResourcePool->sc_TF_ResourceConfig_r12.offsetIndicator_r12.present == LTE_SL_OffsetIndicator_r12_PR_small_r12 ) { SL_CommResourcePool->sc_TF_ResourceConfig_r12.offsetIndicator_r12.choice.small_r12 = configuration->rxPool_ResourceConfig_offsetIndicator_choice[CC_id] ; - } else if (SL_CommResourcePool->sc_TF_ResourceConfig_r12.offsetIndicator_r12.present == SL_OffsetIndicator_r12_PR_large_r12 ){ + } else if (SL_CommResourcePool->sc_TF_ResourceConfig_r12.offsetIndicator_r12.present == LTE_SL_OffsetIndicator_r12_PR_large_r12 ){ SL_CommResourcePool->sc_TF_ResourceConfig_r12.offsetIndicator_r12.choice.large_r12 = configuration->rxPool_ResourceConfig_offsetIndicator_choice[CC_id] ; } SL_CommResourcePool->sc_TF_ResourceConfig_r12.subframeBitmap_r12.present = configuration->rxPool_ResourceConfig_subframeBitmap_present[CC_id]; - if (SL_CommResourcePool->sc_TF_ResourceConfig_r12.subframeBitmap_r12.present == SubframeBitmapSL_r12_PR_bs4_r12){ + if (SL_CommResourcePool->sc_TF_ResourceConfig_r12.subframeBitmap_r12.present == LTE_SubframeBitmapSL_r12_PR_bs4_r12){ //for BS4 SL_CommResourcePool->sc_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs4_r12.size = configuration->rxPool_ResourceConfig_subframeBitmap_choice_bs_size[CC_id]; SL_CommResourcePool->sc_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs4_r12.buf = (uint8_t *)configuration->rxPool_ResourceConfig_subframeBitmap_choice_bs_buf[CC_id];; SL_CommResourcePool->sc_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs4_r12.bits_unused = configuration->rxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused[CC_id]; - } else if (SL_CommResourcePool->sc_TF_ResourceConfig_r12.subframeBitmap_r12.present == SubframeBitmapSL_r12_PR_bs8_r12){ + } else if (SL_CommResourcePool->sc_TF_ResourceConfig_r12.subframeBitmap_r12.present == LTE_SubframeBitmapSL_r12_PR_bs8_r12){ //for BS8 SL_CommResourcePool->sc_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs8_r12.size = configuration->rxPool_ResourceConfig_subframeBitmap_choice_bs_size[CC_id]; SL_CommResourcePool->sc_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs8_r12.buf = (uint8_t *)configuration->rxPool_ResourceConfig_subframeBitmap_choice_bs_buf[CC_id];; SL_CommResourcePool->sc_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs8_r12.bits_unused = configuration->rxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused[CC_id]; - } else if (SL_CommResourcePool->sc_TF_ResourceConfig_r12.subframeBitmap_r12.present == SubframeBitmapSL_r12_PR_bs12_r12){ + } else if (SL_CommResourcePool->sc_TF_ResourceConfig_r12.subframeBitmap_r12.present == LTE_SubframeBitmapSL_r12_PR_bs12_r12){ //for BS12 SL_CommResourcePool->sc_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs12_r12.size = configuration->rxPool_ResourceConfig_subframeBitmap_choice_bs_size[CC_id]; SL_CommResourcePool->sc_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs12_r12.buf = (uint8_t *)configuration->rxPool_ResourceConfig_subframeBitmap_choice_bs_buf[CC_id];; SL_CommResourcePool->sc_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs12_r12.bits_unused = configuration->rxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused[CC_id]; - }else if (SL_CommResourcePool->sc_TF_ResourceConfig_r12.subframeBitmap_r12.present == SubframeBitmapSL_r12_PR_bs16_r12){ + }else if (SL_CommResourcePool->sc_TF_ResourceConfig_r12.subframeBitmap_r12.present == LTE_SubframeBitmapSL_r12_PR_bs16_r12){ //for BS16 SL_CommResourcePool->sc_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs16_r12.size = configuration->rxPool_ResourceConfig_subframeBitmap_choice_bs_size[CC_id]; SL_CommResourcePool->sc_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs16_r12.buf = (uint8_t *)configuration->rxPool_ResourceConfig_subframeBitmap_choice_bs_buf[CC_id];; SL_CommResourcePool->sc_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs16_r12.bits_unused = configuration->rxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused[CC_id]; - }else if (SL_CommResourcePool->sc_TF_ResourceConfig_r12.subframeBitmap_r12.present == SubframeBitmapSL_r12_PR_bs30_r12){ + }else if (SL_CommResourcePool->sc_TF_ResourceConfig_r12.subframeBitmap_r12.present == LTE_SubframeBitmapSL_r12_PR_bs30_r12){ //for BS30 SL_CommResourcePool->sc_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs30_r12.size = configuration->rxPool_ResourceConfig_subframeBitmap_choice_bs_size[CC_id]; SL_CommResourcePool->sc_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs30_r12.buf = (uint8_t *)configuration->rxPool_ResourceConfig_subframeBitmap_choice_bs_buf[CC_id];; SL_CommResourcePool->sc_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs30_r12.bits_unused = configuration->rxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused[CC_id]; - }else if (SL_CommResourcePool->sc_TF_ResourceConfig_r12.subframeBitmap_r12.present == SubframeBitmapSL_r12_PR_bs40_r12){ + }else if (SL_CommResourcePool->sc_TF_ResourceConfig_r12.subframeBitmap_r12.present == LTE_SubframeBitmapSL_r12_PR_bs40_r12){ //for BS40 SL_CommResourcePool->sc_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs40_r12.size = configuration->rxPool_ResourceConfig_subframeBitmap_choice_bs_size[CC_id]; SL_CommResourcePool->sc_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs40_r12.buf = (uint8_t *)configuration->rxPool_ResourceConfig_subframeBitmap_choice_bs_buf[CC_id];; SL_CommResourcePool->sc_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs40_r12.bits_unused = configuration->rxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused[CC_id]; - }else if (SL_CommResourcePool->sc_TF_ResourceConfig_r12.subframeBitmap_r12.present == SubframeBitmapSL_r12_PR_bs42_r12){ + }else if (SL_CommResourcePool->sc_TF_ResourceConfig_r12.subframeBitmap_r12.present == LTE_SubframeBitmapSL_r12_PR_bs42_r12){ //for BS42 SL_CommResourcePool->sc_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs42_r12.size = configuration->rxPool_ResourceConfig_subframeBitmap_choice_bs_size[CC_id]; SL_CommResourcePool->sc_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs42_r12.buf = (uint8_t *)configuration->rxPool_ResourceConfig_subframeBitmap_choice_bs_buf[CC_id];; @@ -1111,7 +1111,7 @@ uint8_t do_SIB23(uint8_t Mod_id, //dataHoppingConfig_r12 SL_CommResourcePool->dataHoppingConfig_r12.hoppingParameter_r12 = 0; - SL_CommResourcePool->dataHoppingConfig_r12.numSubbands_r12 = SL_HoppingConfigComm_r12__numSubbands_r12_ns1; + SL_CommResourcePool->dataHoppingConfig_r12.numSubbands_r12 = LTE_SL_HoppingConfigComm_r12__numSubbands_r12_ns1; SL_CommResourcePool->dataHoppingConfig_r12.rb_Offset_r12 = 0; //ue_SelectedResourceConfig_r12 @@ -1119,9 +1119,9 @@ uint8_t do_SIB23(uint8_t Mod_id, SL_CommResourcePool->ue_SelectedResourceConfig_r12->data_TF_ResourceConfig_r12.prb_Num_r12 = 20; SL_CommResourcePool->ue_SelectedResourceConfig_r12->data_TF_ResourceConfig_r12.prb_Start_r12 = 5; SL_CommResourcePool->ue_SelectedResourceConfig_r12->data_TF_ResourceConfig_r12.prb_End_r12 = 44; - SL_CommResourcePool->ue_SelectedResourceConfig_r12->data_TF_ResourceConfig_r12.offsetIndicator_r12.present = SL_OffsetIndicator_r12_PR_small_r12; + SL_CommResourcePool->ue_SelectedResourceConfig_r12->data_TF_ResourceConfig_r12.offsetIndicator_r12.present = LTE_SL_OffsetIndicator_r12_PR_small_r12; SL_CommResourcePool->ue_SelectedResourceConfig_r12->data_TF_ResourceConfig_r12.offsetIndicator_r12.choice.small_r12 = 0 ; - SL_CommResourcePool->ue_SelectedResourceConfig_r12->data_TF_ResourceConfig_r12.subframeBitmap_r12.present = SubframeBitmapSL_r12_PR_bs40_r12; + SL_CommResourcePool->ue_SelectedResourceConfig_r12->data_TF_ResourceConfig_r12.subframeBitmap_r12.present = LTE_SubframeBitmapSL_r12_PR_bs40_r12; SL_CommResourcePool->ue_SelectedResourceConfig_r12->data_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs4_r12.size = 5; SL_CommResourcePool->ue_SelectedResourceConfig_r12->data_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs4_r12.buf = CALLOC(1,5); SL_CommResourcePool->ue_SelectedResourceConfig_r12->data_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs4_r12.bits_unused = 0; @@ -1139,7 +1139,7 @@ uint8_t do_SIB23(uint8_t Mod_id, SL_CommResourcePool->rxParametersNCell_r12->syncConfigIndex_r12 = 0; //txParameters_r12 SL_CommResourcePool->txParameters_r12 = CALLOC (1, sizeof (*SL_CommResourcePool->txParameters_r12)); - SL_CommResourcePool->txParameters_r12->sc_TxParameters_r12.alpha_r12 = Alpha_r12_al0; + SL_CommResourcePool->txParameters_r12->sc_TxParameters_r12.alpha_r12 = LTE_Alpha_r12_al0; SL_CommResourcePool->txParameters_r12->sc_TxParameters_r12.p0_r12 = 0; SL_CommResourcePool->ext1 = NULL ; @@ -1175,43 +1175,43 @@ uint8_t do_SIB23(uint8_t Mod_id, SL_DiscResourcePool->tf_ResourceConfig_r12.prb_Start_r12 = configuration->discRxPool_ResourceConfig_prb_Start[CC_id]; SL_DiscResourcePool->tf_ResourceConfig_r12.prb_End_r12 = configuration->discRxPool_ResourceConfig_prb_End[CC_id]; SL_DiscResourcePool->tf_ResourceConfig_r12.offsetIndicator_r12.present = configuration->discRxPool_ResourceConfig_offsetIndicator_present[CC_id]; - if (SL_DiscResourcePool->tf_ResourceConfig_r12.offsetIndicator_r12.present == SL_OffsetIndicator_r12_PR_small_r12 ) { + if (SL_DiscResourcePool->tf_ResourceConfig_r12.offsetIndicator_r12.present == LTE_SL_OffsetIndicator_r12_PR_small_r12 ) { SL_DiscResourcePool->tf_ResourceConfig_r12.offsetIndicator_r12.choice.small_r12 = configuration->discRxPool_ResourceConfig_offsetIndicator_choice[CC_id] ; - } else if (SL_DiscResourcePool->tf_ResourceConfig_r12.offsetIndicator_r12.present == SL_OffsetIndicator_r12_PR_large_r12 ){ + } else if (SL_DiscResourcePool->tf_ResourceConfig_r12.offsetIndicator_r12.present == LTE_SL_OffsetIndicator_r12_PR_large_r12 ){ SL_DiscResourcePool->tf_ResourceConfig_r12.offsetIndicator_r12.choice.large_r12 = configuration->discRxPool_ResourceConfig_offsetIndicator_choice[CC_id] ; } SL_DiscResourcePool->tf_ResourceConfig_r12.subframeBitmap_r12.present = configuration->discRxPool_ResourceConfig_subframeBitmap_present[CC_id]; - if (SL_DiscResourcePool->tf_ResourceConfig_r12.subframeBitmap_r12.present == SubframeBitmapSL_r12_PR_bs4_r12){ + if (SL_DiscResourcePool->tf_ResourceConfig_r12.subframeBitmap_r12.present == LTE_SubframeBitmapSL_r12_PR_bs4_r12){ //for BS4 SL_DiscResourcePool->tf_ResourceConfig_r12.subframeBitmap_r12.choice.bs4_r12.size = configuration->discRxPool_ResourceConfig_subframeBitmap_choice_bs_size[CC_id]; SL_DiscResourcePool->tf_ResourceConfig_r12.subframeBitmap_r12.choice.bs4_r12.buf = (uint8_t *)configuration->discRxPool_ResourceConfig_subframeBitmap_choice_bs_buf[CC_id];; SL_DiscResourcePool->tf_ResourceConfig_r12.subframeBitmap_r12.choice.bs4_r12.bits_unused = configuration->discRxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused[CC_id]; - } else if (SL_DiscResourcePool->tf_ResourceConfig_r12.subframeBitmap_r12.present == SubframeBitmapSL_r12_PR_bs8_r12){ + } else if (SL_DiscResourcePool->tf_ResourceConfig_r12.subframeBitmap_r12.present == LTE_SubframeBitmapSL_r12_PR_bs8_r12){ //for BS8 SL_DiscResourcePool->tf_ResourceConfig_r12.subframeBitmap_r12.choice.bs8_r12.size = configuration->discRxPool_ResourceConfig_subframeBitmap_choice_bs_size[CC_id]; SL_DiscResourcePool->tf_ResourceConfig_r12.subframeBitmap_r12.choice.bs8_r12.buf = (uint8_t *)configuration->discRxPool_ResourceConfig_subframeBitmap_choice_bs_buf[CC_id];; SL_DiscResourcePool->tf_ResourceConfig_r12.subframeBitmap_r12.choice.bs8_r12.bits_unused = configuration->discRxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused[CC_id]; - } else if (SL_DiscResourcePool->tf_ResourceConfig_r12.subframeBitmap_r12.present == SubframeBitmapSL_r12_PR_bs12_r12){ + } else if (SL_DiscResourcePool->tf_ResourceConfig_r12.subframeBitmap_r12.present == LTE_SubframeBitmapSL_r12_PR_bs12_r12){ //for BS12 SL_DiscResourcePool->tf_ResourceConfig_r12.subframeBitmap_r12.choice.bs12_r12.size = configuration->discRxPool_ResourceConfig_subframeBitmap_choice_bs_size[CC_id]; SL_DiscResourcePool->tf_ResourceConfig_r12.subframeBitmap_r12.choice.bs12_r12.buf = (uint8_t *)configuration->discRxPool_ResourceConfig_subframeBitmap_choice_bs_buf[CC_id];; SL_DiscResourcePool->tf_ResourceConfig_r12.subframeBitmap_r12.choice.bs12_r12.bits_unused = configuration->discRxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused[CC_id]; - }else if (SL_DiscResourcePool->tf_ResourceConfig_r12.subframeBitmap_r12.present == SubframeBitmapSL_r12_PR_bs16_r12){ + }else if (SL_DiscResourcePool->tf_ResourceConfig_r12.subframeBitmap_r12.present == LTE_SubframeBitmapSL_r12_PR_bs16_r12){ //for BS16 SL_DiscResourcePool->tf_ResourceConfig_r12.subframeBitmap_r12.choice.bs16_r12.size = configuration->discRxPool_ResourceConfig_subframeBitmap_choice_bs_size[CC_id]; SL_DiscResourcePool->tf_ResourceConfig_r12.subframeBitmap_r12.choice.bs16_r12.buf = (uint8_t *)configuration->discRxPool_ResourceConfig_subframeBitmap_choice_bs_buf[CC_id];; SL_DiscResourcePool->tf_ResourceConfig_r12.subframeBitmap_r12.choice.bs16_r12.bits_unused = configuration->discRxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused[CC_id]; - }else if (SL_DiscResourcePool->tf_ResourceConfig_r12.subframeBitmap_r12.present == SubframeBitmapSL_r12_PR_bs30_r12){ + }else if (SL_DiscResourcePool->tf_ResourceConfig_r12.subframeBitmap_r12.present == LTE_SubframeBitmapSL_r12_PR_bs30_r12){ //for BS30 SL_DiscResourcePool->tf_ResourceConfig_r12.subframeBitmap_r12.choice.bs30_r12.size = configuration->discRxPool_ResourceConfig_subframeBitmap_choice_bs_size[CC_id]; SL_DiscResourcePool->tf_ResourceConfig_r12.subframeBitmap_r12.choice.bs30_r12.buf = (uint8_t *)configuration->discRxPool_ResourceConfig_subframeBitmap_choice_bs_buf[CC_id];; SL_DiscResourcePool->tf_ResourceConfig_r12.subframeBitmap_r12.choice.bs30_r12.bits_unused = configuration->discRxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused[CC_id]; - }else if (SL_DiscResourcePool->tf_ResourceConfig_r12.subframeBitmap_r12.present == SubframeBitmapSL_r12_PR_bs40_r12){ + }else if (SL_DiscResourcePool->tf_ResourceConfig_r12.subframeBitmap_r12.present == LTE_SubframeBitmapSL_r12_PR_bs40_r12){ //for BS40 SL_DiscResourcePool->tf_ResourceConfig_r12.subframeBitmap_r12.choice.bs40_r12.size = configuration->discRxPool_ResourceConfig_subframeBitmap_choice_bs_size[CC_id]; SL_DiscResourcePool->tf_ResourceConfig_r12.subframeBitmap_r12.choice.bs40_r12.buf = (uint8_t *)configuration->discRxPool_ResourceConfig_subframeBitmap_choice_bs_buf[CC_id];; SL_DiscResourcePool->tf_ResourceConfig_r12.subframeBitmap_r12.choice.bs40_r12.bits_unused = configuration->discRxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused[CC_id]; - }else if (SL_DiscResourcePool->tf_ResourceConfig_r12.subframeBitmap_r12.present == SubframeBitmapSL_r12_PR_bs42_r12){ + }else if (SL_DiscResourcePool->tf_ResourceConfig_r12.subframeBitmap_r12.present == LTE_SubframeBitmapSL_r12_PR_bs42_r12){ //for BS42 SL_DiscResourcePool->tf_ResourceConfig_r12.subframeBitmap_r12.choice.bs42_r12.size = configuration->discRxPool_ResourceConfig_subframeBitmap_choice_bs_size[CC_id]; SL_DiscResourcePool->tf_ResourceConfig_r12.subframeBitmap_r12.choice.bs42_r12.buf = (uint8_t *)configuration->discRxPool_ResourceConfig_subframeBitmap_choice_bs_buf[CC_id];; @@ -1298,8 +1298,8 @@ uint8_t do_SIB23(uint8_t Mod_id, //SL_V2X_ConfigCommon= (*sib21)->sl_V2X_ConfigCommon_r14; memset((*sib21)->sl_V2X_ConfigCommon_r14,0,sizeof(*(*sib21)->sl_V2X_ConfigCommon_r14)); - struct SL_CommRxPoolListV2X_r14 *SL_CommRxPoolListV2X; - struct SL_CommResourcePoolV2X_r14 *SL_CommResourcePoolV2X; + struct LTE_SL_CommRxPoolListV2X_r14 *SL_CommRxPoolListV2X; + struct LTE_SL_CommResourcePoolV2X_r14 *SL_CommResourcePoolV2X; (*sib21)->sl_V2X_ConfigCommon_r14->v2x_CommRxPool_r14 = CALLOC(1, sizeof(*(*sib21)->sl_V2X_ConfigCommon_r14->v2x_CommRxPool_r14)); SL_CommRxPoolListV2X = (*sib21)->sl_V2X_ConfigCommon_r14->v2x_CommRxPool_r14; @@ -1307,9 +1307,9 @@ uint8_t do_SIB23(uint8_t Mod_id, memset(SL_CommResourcePoolV2X,0,sizeof(*SL_CommResourcePoolV2X)); SL_CommResourcePoolV2X->sl_OffsetIndicator_r14 = CALLOC(1, sizeof(*SL_CommResourcePoolV2X->sl_OffsetIndicator_r14)); - SL_CommResourcePoolV2X->sl_OffsetIndicator_r14->present = SL_OffsetIndicator_r12_PR_small_r12; + SL_CommResourcePoolV2X->sl_OffsetIndicator_r14->present = LTE_SL_OffsetIndicator_r12_PR_small_r12; SL_CommResourcePoolV2X->sl_OffsetIndicator_r14->choice.small_r12 = 0; - SL_CommResourcePoolV2X->sl_Subframe_r14.present = SubframeBitmapSL_r14_PR_bs40_r14; + SL_CommResourcePoolV2X->sl_Subframe_r14.present = LTE_SubframeBitmapSL_r14_PR_bs40_r14; SL_CommResourcePoolV2X->sl_Subframe_r14.choice.bs40_r14.size = 5; SL_CommResourcePoolV2X->sl_Subframe_r14.choice.bs40_r14.buf = CALLOC(1,5); SL_CommResourcePoolV2X->sl_Subframe_r14.choice.bs40_r14.bits_unused = 0; @@ -1336,14 +1336,14 @@ uint8_t do_SIB23(uint8_t Mod_id, #endif - bcch_message->message.present = BCCH_DL_SCH_MessageType_PR_c1; - bcch_message->message.choice.c1.present = BCCH_DL_SCH_MessageType__c1_PR_systemInformation; + bcch_message->message.present = LTE_BCCH_DL_SCH_MessageType_PR_c1; + bcch_message->message.choice.c1.present = LTE_BCCH_DL_SCH_MessageType__c1_PR_systemInformation; /* memcpy((void*)&bcch_message.message.choice.c1.choice.systemInformation, (void*)systemInformation, sizeof(SystemInformation_t));*/ - bcch_message->message.choice.c1.choice.systemInformation.criticalExtensions.present = SystemInformation__criticalExtensions_PR_systemInformation_r8; + bcch_message->message.choice.c1.choice.systemInformation.criticalExtensions.present = LTE_SystemInformation__criticalExtensions_PR_systemInformation_r8; bcch_message->message.choice.c1.choice.systemInformation.criticalExtensions.choice.systemInformation_r8.sib_TypeAndInfo.list.count=0; // asn_set_empty(&systemInformation->criticalExtensions.choice.systemInformation_r8.sib_TypeAndInfo.list);//.size=0; @@ -1352,7 +1352,7 @@ uint8_t do_SIB23(uint8_t Mod_id, sib2_part); ASN_SEQUENCE_ADD(&bcch_message->message.choice.c1.choice.systemInformation.criticalExtensions.choice.systemInformation_r8.sib_TypeAndInfo.list, sib3_part); -#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) if (MBMS_flag > 0) { ASN_SEQUENCE_ADD(&bcch_message->message.choice.c1.choice.systemInformation.criticalExtensions.choice.systemInformation_r8.sib_TypeAndInfo.list,sib13_part); @@ -1360,9 +1360,9 @@ uint8_t do_SIB23(uint8_t Mod_id, #endif if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) { - xer_fprint(stdout, &asn_DEF_BCCH_DL_SCH_Message, (void*)bcch_message); + xer_fprint(stdout, &asn_DEF_LTE_BCCH_DL_SCH_Message, (void*)bcch_message); } - enc_rval = uper_encode_to_buffer(&asn_DEF_BCCH_DL_SCH_Message, + enc_rval = uper_encode_to_buffer(&asn_DEF_LTE_BCCH_DL_SCH_Message, NULL, (void*)bcch_message, buffer, @@ -1377,7 +1377,7 @@ uint8_t do_SIB23(uint8_t Mod_id, char message_string[15000]; size_t message_string_size; - if ((message_string_size = xer_sprint(message_string, sizeof(message_string), &asn_DEF_BCCH_DL_SCH_Message, (void *)bcch_message)) > 0) { + if ((message_string_size = xer_sprint(message_string, sizeof(message_string), &asn_DEF_LTE_BCCH_DL_SCH_Message, (void *)bcch_message)) > 0) { MessageDef *msg_p; msg_p = itti_alloc_new_message_sized (TASK_RRC_ENB, RRC_DL_BCCH, message_string_size + sizeof (IttiMsgText)); @@ -1406,20 +1406,20 @@ uint8_t do_RRCConnectionRequest(uint8_t Mod_id, uint8_t *buffer,uint8_t *rv) asn_enc_rval_t enc_rval; uint8_t buf[5],buf2=0; - UL_CCCH_Message_t ul_ccch_msg; + LTE_UL_CCCH_Message_t ul_ccch_msg; - RRCConnectionRequest_t *rrcConnectionRequest; + LTE_RRCConnectionRequest_t *rrcConnectionRequest; - memset((void *)&ul_ccch_msg,0,sizeof(UL_CCCH_Message_t)); + memset((void *)&ul_ccch_msg,0,sizeof(LTE_UL_CCCH_Message_t)); - ul_ccch_msg.message.present = UL_CCCH_MessageType_PR_c1; - ul_ccch_msg.message.choice.c1.present = UL_CCCH_MessageType__c1_PR_rrcConnectionRequest; + ul_ccch_msg.message.present = LTE_UL_CCCH_MessageType_PR_c1; + ul_ccch_msg.message.choice.c1.present = LTE_UL_CCCH_MessageType__c1_PR_rrcConnectionRequest; rrcConnectionRequest = &ul_ccch_msg.message.choice.c1.choice.rrcConnectionRequest; - rrcConnectionRequest->criticalExtensions.present = RRCConnectionRequest__criticalExtensions_PR_rrcConnectionRequest_r8; + rrcConnectionRequest->criticalExtensions.present = LTE_RRCConnectionRequest__criticalExtensions_PR_rrcConnectionRequest_r8; if (1) { - rrcConnectionRequest->criticalExtensions.choice.rrcConnectionRequest_r8.ue_Identity.present = InitialUE_Identity_PR_randomValue; + rrcConnectionRequest->criticalExtensions.choice.rrcConnectionRequest_r8.ue_Identity.present = LTE_InitialUE_Identity_PR_randomValue; rrcConnectionRequest->criticalExtensions.choice.rrcConnectionRequest_r8.ue_Identity.choice.randomValue.size = 5; rrcConnectionRequest->criticalExtensions.choice.rrcConnectionRequest_r8.ue_Identity.choice.randomValue.bits_unused = 0; rrcConnectionRequest->criticalExtensions.choice.rrcConnectionRequest_r8.ue_Identity.choice.randomValue.buf = buf; @@ -1429,7 +1429,7 @@ uint8_t do_RRCConnectionRequest(uint8_t Mod_id, uint8_t *buffer,uint8_t *rv) rrcConnectionRequest->criticalExtensions.choice.rrcConnectionRequest_r8.ue_Identity.choice.randomValue.buf[3] = rv[3]; rrcConnectionRequest->criticalExtensions.choice.rrcConnectionRequest_r8.ue_Identity.choice.randomValue.buf[4] = rv[4]; } else { - rrcConnectionRequest->criticalExtensions.choice.rrcConnectionRequest_r8.ue_Identity.present = InitialUE_Identity_PR_s_TMSI; + rrcConnectionRequest->criticalExtensions.choice.rrcConnectionRequest_r8.ue_Identity.present = LTE_InitialUE_Identity_PR_s_TMSI; rrcConnectionRequest->criticalExtensions.choice.rrcConnectionRequest_r8.ue_Identity.choice.s_TMSI.mmec.size = 1; rrcConnectionRequest->criticalExtensions.choice.rrcConnectionRequest_r8.ue_Identity.choice.s_TMSI.mmec.bits_unused = 0; rrcConnectionRequest->criticalExtensions.choice.rrcConnectionRequest_r8.ue_Identity.choice.s_TMSI.mmec.buf = buf; @@ -1443,14 +1443,14 @@ uint8_t do_RRCConnectionRequest(uint8_t Mod_id, uint8_t *buffer,uint8_t *rv) rrcConnectionRequest->criticalExtensions.choice.rrcConnectionRequest_r8.ue_Identity.choice.s_TMSI.m_TMSI.buf[3] = 0x9a; } - rrcConnectionRequest->criticalExtensions.choice.rrcConnectionRequest_r8.establishmentCause = EstablishmentCause_mo_Signalling; //EstablishmentCause_mo_Data; + rrcConnectionRequest->criticalExtensions.choice.rrcConnectionRequest_r8.establishmentCause = LTE_EstablishmentCause_mo_Signalling; //EstablishmentCause_mo_Data; rrcConnectionRequest->criticalExtensions.choice.rrcConnectionRequest_r8.spare.buf = &buf2; rrcConnectionRequest->criticalExtensions.choice.rrcConnectionRequest_r8.spare.size=1; rrcConnectionRequest->criticalExtensions.choice.rrcConnectionRequest_r8.spare.bits_unused = 7; - enc_rval = uper_encode_to_buffer(&asn_DEF_UL_CCCH_Message, + enc_rval = uper_encode_to_buffer(&asn_DEF_LTE_UL_CCCH_Message, NULL, (void*)&ul_ccch_msg, buffer, @@ -1464,7 +1464,7 @@ uint8_t do_RRCConnectionRequest(uint8_t Mod_id, uint8_t *buffer,uint8_t *rv) char message_string[20000]; size_t message_string_size; - if ((message_string_size = xer_sprint(message_string, sizeof(message_string), &asn_DEF_UL_CCCH_Message, (void *) &ul_ccch_msg)) > 0) { + if ((message_string_size = xer_sprint(message_string, sizeof(message_string), &asn_DEF_LTE_UL_CCCH_Message, (void *) &ul_ccch_msg)) > 0) { MessageDef *msg_p; msg_p = itti_alloc_new_message_sized (TASK_RRC_UE, RRC_UL_CCCH, message_string_size + sizeof (IttiMsgText)); @@ -1485,30 +1485,30 @@ uint8_t do_RRCConnectionRequest(uint8_t Mod_id, uint8_t *buffer,uint8_t *rv) //TTN for D2D - 3GPP TS 36.331 (Section 5.10.2.3) -uint8_t do_SidelinkUEInformation(uint8_t Mod_id, uint8_t *buffer, SL_DestinationInfoList_r12_t *destinationInfoList, long *discTxResourceReq, SL_TRIGGER_t mode) +uint8_t do_SidelinkUEInformation(uint8_t Mod_id, uint8_t *buffer, LTE_SL_DestinationInfoList_r12_t *destinationInfoList, long *discTxResourceReq, SL_TRIGGER_t mode) { asn_enc_rval_t enc_rval; - UL_DCCH_Message_t ul_dcch_msg; - SidelinkUEInformation_r12_t *sidelinkUEInformation; - ARFCN_ValueEUTRA_r9_t carrierFreq = 25655;//sidelink communication frequency (hardcoded - should come from SIB2) + LTE_UL_DCCH_Message_t ul_dcch_msg; + LTE_SidelinkUEInformation_r12_t *sidelinkUEInformation; + LTE_ARFCN_ValueEUTRA_r9_t carrierFreq = 25655;//sidelink communication frequency (hardcoded - should come from SIB2) - memset((void *)&ul_dcch_msg,0,sizeof(UL_DCCH_Message_t)); - ul_dcch_msg.message.present = UL_DCCH_MessageType_PR_messageClassExtension; - ul_dcch_msg.message.choice.messageClassExtension.present = UL_DCCH_MessageType__messageClassExtension_PR_c2; - ul_dcch_msg.message.choice.messageClassExtension.choice.c2.present = UL_DCCH_MessageType__messageClassExtension__c2_PR_sidelinkUEInformation_r12; + memset((void *)&ul_dcch_msg,0,sizeof(LTE_UL_DCCH_Message_t)); + ul_dcch_msg.message.present = LTE_UL_DCCH_MessageType_PR_messageClassExtension; + ul_dcch_msg.message.choice.messageClassExtension.present = LTE_UL_DCCH_MessageType__messageClassExtension_PR_c2; + ul_dcch_msg.message.choice.messageClassExtension.choice.c2.present = LTE_UL_DCCH_MessageType__messageClassExtension__c2_PR_sidelinkUEInformation_r12; sidelinkUEInformation = &ul_dcch_msg.message.choice.messageClassExtension.choice.c2.choice.sidelinkUEInformation_r12; //3GPP TS 36.331 (Section 5.10.2.3) - sidelinkUEInformation->criticalExtensions.present = SidelinkUEInformation_r12__criticalExtensions_PR_c1; - sidelinkUEInformation->criticalExtensions.choice.c1.present = SidelinkUEInformation_r12__criticalExtensions__c1_PR_sidelinkUEInformation_r12; + sidelinkUEInformation->criticalExtensions.present = LTE_SidelinkUEInformation_r12__criticalExtensions_PR_c1; + sidelinkUEInformation->criticalExtensions.choice.c1.present = LTE_SidelinkUEInformation_r12__criticalExtensions__c1_PR_sidelinkUEInformation_r12; switch(mode) { //if SIB18 is available case SL_RECEIVE_COMMUNICATION: // to receive sidelink communication sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.commRxInterestedFreq_r12 = CALLOC(1, sizeof(*sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.commRxInterestedFreq_r12)); memcpy((void*)sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.commRxInterestedFreq_r12, (void*)&carrierFreq, - sizeof(ARFCN_ValueEUTRA_r9_t)); + sizeof(LTE_ARFCN_ValueEUTRA_r9_t)); break; case SL_TRANSMIT_NON_RELAY_ONE_TO_MANY: //to transmit non-relay related one-to-many sidelink communication @@ -1518,10 +1518,10 @@ uint8_t do_SidelinkUEInformation(uint8_t Mod_id, uint8_t *buffer, SL_Destinatio sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.commTxResourceReq_r12->carrierFreq_r12 = CALLOC(1, sizeof(*sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.commTxResourceReq_r12->carrierFreq_r12)); memcpy((void*)sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.commTxResourceReq_r12->carrierFreq_r12, (void*)&carrierFreq, - sizeof(ARFCN_ValueEUTRA_r9_t)); + sizeof(LTE_ARFCN_ValueEUTRA_r9_t)); memcpy(&sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.commTxResourceReq_r12->destinationInfoList_r12, destinationInfoList, - sizeof(SL_DestinationInfoList_r12_t)); + sizeof(LTE_SL_DestinationInfoList_r12_t)); break; case SL_TRANSMIT_NON_RELAY_ONE_TO_ONE://transmit non-relay related one-to-one sidelink communication @@ -1534,10 +1534,10 @@ uint8_t do_SidelinkUEInformation(uint8_t Mod_id, uint8_t *buffer, SL_Destinatio sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.nonCriticalExtension->commTxResourceReqUC_r13->carrierFreq_r12 = CALLOC(1, sizeof(*sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.nonCriticalExtension->commTxResourceReqUC_r13->carrierFreq_r12)); memcpy((void*)sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.nonCriticalExtension->commTxResourceReqUC_r13->carrierFreq_r12, (void*)&carrierFreq, - sizeof (ARFCN_ValueEUTRA_r9_t)); + sizeof (LTE_ARFCN_ValueEUTRA_r9_t)); memcpy(&sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.nonCriticalExtension->commTxResourceReqUC_r13->destinationInfoList_r12, destinationInfoList, - sizeof(SL_DestinationInfoList_r12_t)); + sizeof(LTE_SL_DestinationInfoList_r12_t)); break; case SL_TRANSMIT_RELAY_ONE_TO_ONE: //transmit relay related one-to-one sidelink communication @@ -1552,7 +1552,7 @@ uint8_t do_SidelinkUEInformation(uint8_t Mod_id, uint8_t *buffer, SL_Destinatio destinationInfoList, sizeof(*destinationInfoList)); //set ue-type to relayUE or remoteUE - sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.nonCriticalExtension->commTxResourceInfoReqRelay_r13->ue_Type_r13 =SidelinkUEInformation_v1310_IEs__commTxResourceInfoReqRelay_r13__ue_Type_r13_relayUE; + sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.nonCriticalExtension->commTxResourceInfoReqRelay_r13->ue_Type_r13 =LTE_SidelinkUEInformation_v1310_IEs__commTxResourceInfoReqRelay_r13__ue_Type_r13_relayUE; //sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12->nonCriticalExtension->commTxResourceInfoReqRelay_r13->ue_Type_r13 =SidelinkUEInformation_v1310_IEs__commTxResourceInfoReqRelay_r13__ue_Type_r13_remoteUE; break; @@ -1565,7 +1565,7 @@ uint8_t do_SidelinkUEInformation(uint8_t Mod_id, uint8_t *buffer, SL_Destinatio sizeof(*sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.nonCriticalExtension->commTxResourceInfoReqRelay_r13)); sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.nonCriticalExtension->commTxResourceInfoReqRelay_r13->commTxResourceReqRelay_r13 = CALLOC(1, sizeof(*sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.nonCriticalExtension->commTxResourceInfoReqRelay_r13->commTxResourceReqRelay_r13)); - sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.nonCriticalExtension->commTxResourceInfoReqRelay_r13->ue_Type_r13 =SidelinkUEInformation_v1310_IEs__commTxResourceInfoReqRelay_r13__ue_Type_r13_relayUE; + sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.nonCriticalExtension->commTxResourceInfoReqRelay_r13->ue_Type_r13 = LTE_SidelinkUEInformation_v1310_IEs__commTxResourceInfoReqRelay_r13__ue_Type_r13_relayUE; memcpy(&sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.nonCriticalExtension->commTxResourceInfoReqRelay_r13->commTxResourceReqRelay_r13->destinationInfoList_r12, destinationInfoList, sizeof(*destinationInfoList)); @@ -1577,7 +1577,7 @@ uint8_t do_SidelinkUEInformation(uint8_t Mod_id, uint8_t *buffer, SL_Destinatio sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.discRxInterest_r12 = CALLOC(1, sizeof(*sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.discRxInterest_r12)); - *sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.discRxInterest_r12 = SidelinkUEInformation_r12_IEs__discRxInterest_r12_true; + *sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.discRxInterest_r12 = LTE_SidelinkUEInformation_r12_IEs__discRxInterest_r12_true; break; case SL_TRANSMIT_NON_PS_DISCOVERY://to transmit non-PS related sidelink discovery announcements //for the first frequency @@ -1614,11 +1614,11 @@ uint8_t do_SidelinkUEInformation(uint8_t Mod_id, uint8_t *buffer, SL_Destinatio } if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) { - xer_fprint(stdout, &asn_DEF_UL_DCCH_Message, (void*)&ul_dcch_msg); + xer_fprint(stdout, &asn_DEF_LTE_UL_DCCH_Message, (void*)&ul_dcch_msg); } - enc_rval = uper_encode_to_buffer(&asn_DEF_UL_DCCH_Message, + enc_rval = uper_encode_to_buffer(&asn_DEF_LTE_UL_DCCH_Message, NULL, (void*)&ul_dcch_msg, buffer, @@ -1632,7 +1632,7 @@ uint8_t do_SidelinkUEInformation(uint8_t Mod_id, uint8_t *buffer, SL_Destinatio char message_string[20000]; size_t message_string_size; - if ((message_string_size = xer_sprint(message_string, sizeof(message_string), &asn_DEF_UL_DCCH_Message, (void *) &ul_dcch_msg)) > 0) { + if ((message_string_size = xer_sprint(message_string, sizeof(message_string), &asn_DEF_LTE_UL_DCCH_Message, (void *) &ul_dcch_msg)) > 0) { MessageDef *msg_p; msg_p = itti_alloc_new_message_sized (TASK_RRC_UE, RRC_UL_DCCH, message_string_size + sizeof (IttiMsgText)); @@ -1660,19 +1660,19 @@ uint8_t do_RRCConnectionSetupComplete(uint8_t Mod_id, uint8_t *buffer, const uin asn_enc_rval_t enc_rval; - UL_DCCH_Message_t ul_dcch_msg; + LTE_UL_DCCH_Message_t ul_dcch_msg; - RRCConnectionSetupComplete_t *rrcConnectionSetupComplete; + LTE_RRCConnectionSetupComplete_t *rrcConnectionSetupComplete; - memset((void *)&ul_dcch_msg,0,sizeof(UL_DCCH_Message_t)); + memset((void *)&ul_dcch_msg,0,sizeof(LTE_UL_DCCH_Message_t)); - ul_dcch_msg.message.present = UL_DCCH_MessageType_PR_c1; - ul_dcch_msg.message.choice.c1.present = UL_DCCH_MessageType__c1_PR_rrcConnectionSetupComplete; + ul_dcch_msg.message.present = LTE_UL_DCCH_MessageType_PR_c1; + ul_dcch_msg.message.choice.c1.present = LTE_UL_DCCH_MessageType__c1_PR_rrcConnectionSetupComplete; rrcConnectionSetupComplete = &ul_dcch_msg.message.choice.c1.choice.rrcConnectionSetupComplete; rrcConnectionSetupComplete->rrc_TransactionIdentifier = Transaction_id; - rrcConnectionSetupComplete->criticalExtensions.present = RRCConnectionSetupComplete__criticalExtensions_PR_c1; - rrcConnectionSetupComplete->criticalExtensions.choice.c1.present = RRCConnectionSetupComplete__criticalExtensions__c1_PR_rrcConnectionSetupComplete_r8; + rrcConnectionSetupComplete->criticalExtensions.present = LTE_RRCConnectionSetupComplete__criticalExtensions_PR_c1; + rrcConnectionSetupComplete->criticalExtensions.choice.c1.present = LTE_RRCConnectionSetupComplete__criticalExtensions__c1_PR_rrcConnectionSetupComplete_r8; rrcConnectionSetupComplete->criticalExtensions.choice.c1.choice.rrcConnectionSetupComplete_r8.nonCriticalExtension=CALLOC(1, sizeof(*rrcConnectionSetupComplete->criticalExtensions.choice.c1.choice.rrcConnectionSetupComplete_r8.nonCriticalExtension)); @@ -1700,7 +1700,7 @@ uint8_t do_RRCConnectionSetupComplete(uint8_t Mod_id, uint8_t *buffer, const uin rrcConnectionSetupComplete->criticalExtensions.choice.c1.choice.rrcConnectionSetupComplete_r8.registeredMME->mmec.bits_unused=0; */ - enc_rval = uper_encode_to_buffer(&asn_DEF_UL_DCCH_Message, + enc_rval = uper_encode_to_buffer(&asn_DEF_LTE_UL_DCCH_Message, NULL, (void*)&ul_dcch_msg, buffer, @@ -1714,7 +1714,7 @@ uint8_t do_RRCConnectionSetupComplete(uint8_t Mod_id, uint8_t *buffer, const uin char message_string[20000]; size_t message_string_size; - if ((message_string_size = xer_sprint(message_string, sizeof(message_string), &asn_DEF_UL_DCCH_Message, (void *) &ul_dcch_msg)) > 0) { + if ((message_string_size = xer_sprint(message_string, sizeof(message_string), &asn_DEF_LTE_UL_DCCH_Message, (void *) &ul_dcch_msg)) > 0) { MessageDef *msg_p; msg_p = itti_alloc_new_message_sized (TASK_RRC_UE, RRC_UL_DCCH, message_string_size + sizeof (IttiMsgText)); @@ -1746,22 +1746,22 @@ do_RRCConnectionReconfigurationComplete( asn_enc_rval_t enc_rval; - UL_DCCH_Message_t ul_dcch_msg; + LTE_UL_DCCH_Message_t ul_dcch_msg; - RRCConnectionReconfigurationComplete_t *rrcConnectionReconfigurationComplete; + LTE_RRCConnectionReconfigurationComplete_t *rrcConnectionReconfigurationComplete; - memset((void *)&ul_dcch_msg,0,sizeof(UL_DCCH_Message_t)); + memset((void *)&ul_dcch_msg,0,sizeof(LTE_UL_DCCH_Message_t)); - ul_dcch_msg.message.present = UL_DCCH_MessageType_PR_c1; - ul_dcch_msg.message.choice.c1.present = UL_DCCH_MessageType__c1_PR_rrcConnectionReconfigurationComplete; + ul_dcch_msg.message.present = LTE_UL_DCCH_MessageType_PR_c1; + ul_dcch_msg.message.choice.c1.present = LTE_UL_DCCH_MessageType__c1_PR_rrcConnectionReconfigurationComplete; rrcConnectionReconfigurationComplete = &ul_dcch_msg.message.choice.c1.choice.rrcConnectionReconfigurationComplete; rrcConnectionReconfigurationComplete->rrc_TransactionIdentifier = Transaction_id; rrcConnectionReconfigurationComplete->criticalExtensions.present = - RRCConnectionReconfigurationComplete__criticalExtensions_PR_rrcConnectionReconfigurationComplete_r8; + LTE_RRCConnectionReconfigurationComplete__criticalExtensions_PR_rrcConnectionReconfigurationComplete_r8; rrcConnectionReconfigurationComplete->criticalExtensions.choice.rrcConnectionReconfigurationComplete_r8.nonCriticalExtension=NULL; - enc_rval = uper_encode_to_buffer(&asn_DEF_UL_DCCH_Message, + enc_rval = uper_encode_to_buffer(&asn_DEF_LTE_UL_DCCH_Message, NULL, (void*)&ul_dcch_msg, buffer, @@ -1775,7 +1775,7 @@ do_RRCConnectionReconfigurationComplete( char message_string[20000]; size_t message_string_size; - if ((message_string_size = xer_sprint(message_string, sizeof(message_string), &asn_DEF_UL_DCCH_Message, (void *) &ul_dcch_msg)) > 0) { + if ((message_string_size = xer_sprint(message_string, sizeof(message_string), &asn_DEF_LTE_UL_DCCH_Message, (void *) &ul_dcch_msg)) > 0) { MessageDef *msg_p; msg_p = itti_alloc_new_message_sized (TASK_RRC_UE, RRC_UL_DCCH, message_string_size + sizeof (IttiMsgText)); @@ -1803,8 +1803,8 @@ do_RRCConnectionSetup( uint8_t* const buffer, const uint8_t transmission_mode, const uint8_t Transaction_id, - SRB_ToAddModList_t **SRB_configList, - struct PhysicalConfigDedicated **physicalConfigDedicated) + LTE_SRB_ToAddModList_t **SRB_configList, + struct LTE_PhysicalConfigDedicated **physicalConfigDedicated) { asn_enc_rval_t enc_rval; @@ -1812,27 +1812,27 @@ do_RRCConnectionSetup( rrc_eNB_carrier_data_t *carrier = &rrc->carrier[CC_id]; long* logicalchannelgroup = NULL; - struct SRB_ToAddMod* SRB1_config = NULL; - struct SRB_ToAddMod__rlc_Config* SRB1_rlc_config = NULL; - struct SRB_ToAddMod__logicalChannelConfig* SRB1_lchan_config = NULL; - struct LogicalChannelConfig__ul_SpecificParameters* SRB1_ul_SpecificParameters = NULL; + struct LTE_SRB_ToAddMod* SRB1_config = NULL; + struct LTE_SRB_ToAddMod__rlc_Config* SRB1_rlc_config = NULL; + struct LTE_SRB_ToAddMod__logicalChannelConfig* SRB1_lchan_config = NULL; + struct LTE_LogicalChannelConfig__ul_SpecificParameters* SRB1_ul_SpecificParameters = NULL; #ifdef CBA - struct PUSCH_CBAConfigDedicated_vlola* pusch_CBAConfigDedicated_vlola = NULL; + struct LTE_PUSCH_CBAConfigDedicated_vlola* pusch_CBAConfigDedicated_vlola = NULL; long* betaOffset_CBA_Index = NULL; long* cShift_CBA = NULL; #endif - PhysicalConfigDedicated_t* physicalConfigDedicated2 = NULL; + LTE_PhysicalConfigDedicated_t* physicalConfigDedicated2 = NULL; - DL_CCCH_Message_t dl_ccch_msg; + LTE_DL_CCCH_Message_t dl_ccch_msg; - RRCConnectionSetup_t* rrcConnectionSetup = NULL; + LTE_RRCConnectionSetup_t* rrcConnectionSetup = NULL; LTE_DL_FRAME_PARMS *frame_parms = &RC.eNB[ctxt_pP->module_id][CC_id]->frame_parms; - memset((void *)&dl_ccch_msg,0,sizeof(DL_CCCH_Message_t)); - dl_ccch_msg.message.present = DL_CCCH_MessageType_PR_c1; - dl_ccch_msg.message.choice.c1.present = DL_CCCH_MessageType__c1_PR_rrcConnectionSetup; + memset((void *)&dl_ccch_msg,0,sizeof(LTE_DL_CCCH_Message_t)); + dl_ccch_msg.message.present = LTE_DL_CCCH_MessageType_PR_c1; + dl_ccch_msg.message.choice.c1.present = LTE_DL_CCCH_MessageType__c1_PR_rrcConnectionSetup; rrcConnectionSetup = &dl_ccch_msg.message.choice.c1.choice.rrcConnectionSetup; // RRCConnectionSetup @@ -1843,7 +1843,7 @@ do_RRCConnectionSetup( free(*SRB_configList); } - *SRB_configList = CALLOC(1,sizeof(SRB_ToAddModList_t)); + *SRB_configList = CALLOC(1,sizeof(LTE_SRB_ToAddModList_t)); /// SRB1 SRB1_config = CALLOC(1,sizeof(*SRB1_config)); @@ -1852,8 +1852,8 @@ do_RRCConnectionSetup( 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->present = LTE_SRB_ToAddMod__rlc_Config_PR_explicitValue; + SRB1_rlc_config->choice.explicitValue.present=LTE_RLC_Config_PR_am; #if defined(ENABLE_ITTI) SRB1_rlc_config->choice.explicitValue.choice.am.ul_AM_RLC.t_PollRetransmit = rrc->srb1_timer_poll_retransmit; SRB1_rlc_config->choice.explicitValue.choice.am.ul_AM_RLC.pollPDU = rrc->srb1_poll_pdu; @@ -1862,18 +1862,18 @@ do_RRCConnectionSetup( SRB1_rlc_config->choice.explicitValue.choice.am.dl_AM_RLC.t_Reordering = rrc->srb1_timer_reordering; SRB1_rlc_config->choice.explicitValue.choice.am.dl_AM_RLC.t_StatusProhibit = rrc->srb1_timer_status_prohibit; #else - SRB1_rlc_config->choice.explicitValue.choice.am.ul_AM_RLC.t_PollRetransmit = T_PollRetransmit_ms20;; - SRB1_rlc_config->choice.explicitValue.choice.am.ul_AM_RLC.pollPDU = PollPDU_p4;; - SRB1_rlc_config->choice.explicitValue.choice.am.ul_AM_RLC.pollByte = PollByte_kBinfinity; - SRB1_rlc_config->choice.explicitValue.choice.am.ul_AM_RLC.maxRetxThreshold = UL_AM_RLC__maxRetxThreshold_t8; - SRB1_rlc_config->choice.explicitValue.choice.am.dl_AM_RLC.t_Reordering = T_Reordering_ms35; - SRB1_rlc_config->choice.explicitValue.choice.am.dl_AM_RLC.t_StatusProhibit = T_StatusProhibit_ms0; + SRB1_rlc_config->choice.explicitValue.choice.am.ul_AM_RLC.t_PollRetransmit = LTE_T_PollRetransmit_ms20;; + SRB1_rlc_config->choice.explicitValue.choice.am.ul_AM_RLC.pollPDU = LTE_PollPDU_p4;; + SRB1_rlc_config->choice.explicitValue.choice.am.ul_AM_RLC.pollByte = LTE_PollByte_kBinfinity; + SRB1_rlc_config->choice.explicitValue.choice.am.ul_AM_RLC.maxRetxThreshold = LTE_UL_AM_RLC__maxRetxThreshold_t8; + SRB1_rlc_config->choice.explicitValue.choice.am.dl_AM_RLC.t_Reordering = LTE_T_Reordering_ms35; + SRB1_rlc_config->choice.explicitValue.choice.am.dl_AM_RLC.t_StatusProhibit = LTE_T_StatusProhibit_ms0; #endif 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_lchan_config->present = LTE_SRB_ToAddMod__logicalChannelConfig_PR_explicitValue; SRB1_ul_SpecificParameters = CALLOC(1,sizeof(*SRB1_ul_SpecificParameters)); SRB1_lchan_config->choice.explicitValue.ul_SpecificParameters = SRB1_ul_SpecificParameters; @@ -1882,10 +1882,10 @@ do_RRCConnectionSetup( 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; + SRB1_ul_SpecificParameters->prioritisedBitRate=LTE_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; + SRB1_ul_SpecificParameters->bucketSizeDuration=LTE_LogicalChannelConfig__ul_SpecificParameters__bucketSizeDuration_ms50; logicalchannelgroup = CALLOC(1,sizeof(long)); *logicalchannelgroup=0; @@ -1917,12 +1917,12 @@ do_RRCConnectionSetup( //assign_enum(&physicalConfigDedicated2->pdsch_ConfigDedicated->p_a, // PDSCH_ConfigDedicated__p_a_dB0); if (carrier->p_eNB==2) - physicalConfigDedicated2->pdsch_ConfigDedicated->p_a= PDSCH_ConfigDedicated__p_a_dB_3; + physicalConfigDedicated2->pdsch_ConfigDedicated->p_a= LTE_PDSCH_ConfigDedicated__p_a_dB_3; else - physicalConfigDedicated2->pdsch_ConfigDedicated->p_a= PDSCH_ConfigDedicated__p_a_dB0; + physicalConfigDedicated2->pdsch_ConfigDedicated->p_a= LTE_PDSCH_ConfigDedicated__p_a_dB0; // PUCCH - physicalConfigDedicated2->pucch_ConfigDedicated->ackNackRepetition.present=PUCCH_ConfigDedicated__ackNackRepetition_PR_release; + physicalConfigDedicated2->pucch_ConfigDedicated->ackNackRepetition.present=LTE_PUCCH_ConfigDedicated__ackNackRepetition_PR_release; physicalConfigDedicated2->pucch_ConfigDedicated->ackNackRepetition.choice.release=0; if (carrier->sib1->tdd_Config == NULL) { @@ -1930,7 +1930,7 @@ do_RRCConnectionSetup( } else { //TDD physicalConfigDedicated2->pucch_ConfigDedicated->tdd_AckNackFeedbackMode= CALLOC(1,sizeof(long)); *(physicalConfigDedicated2->pucch_ConfigDedicated->tdd_AckNackFeedbackMode) = - PUCCH_ConfigDedicated__tdd_AckNackFeedbackMode_bundling;//PUCCH_ConfigDedicated__tdd_AckNackFeedbackMode_multiplexing; + LTE_PUCCH_ConfigDedicated__tdd_AckNackFeedbackMode_bundling;//PUCCH_ConfigDedicated__tdd_AckNackFeedbackMode_multiplexing; } // Pusch_config_dedicated @@ -1942,19 +1942,19 @@ do_RRCConnectionSetup( 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->deltaMCS_Enabled= LTE_UplinkPowerControlDedicated__deltaMCS_Enabled_en1; physicalConfigDedicated2->uplinkPowerControlDedicated->accumulationEnabled = 1; // TRUE 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 + *physicalConfigDedicated2->uplinkPowerControlDedicated->filterCoefficient=LTE_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->present=LTE_TPC_PDCCH_Config_PR_setup; + physicalConfigDedicated2->tpc_PDCCH_ConfigPUCCH->choice.setup.tpc_Index.present = LTE_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; @@ -1962,8 +1962,8 @@ do_RRCConnectionSetup( physicalConfigDedicated2->tpc_PDCCH_ConfigPUCCH->choice.setup.tpc_RNTI.buf[1]=0x34+ue_context_pP->local_uid; 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->present=LTE_TPC_PDCCH_Config_PR_setup; + physicalConfigDedicated2->tpc_PDCCH_ConfigPUSCH->choice.setup.tpc_Index.present = LTE_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; @@ -1974,16 +1974,16 @@ do_RRCConnectionSetup( // CQI ReportConfig physicalConfigDedicated2->cqi_ReportConfig->cqi_ReportModeAperiodic=CALLOC(1,sizeof(*physicalConfigDedicated2->cqi_ReportConfig->cqi_ReportModeAperiodic)); -#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) - *physicalConfigDedicated2->cqi_ReportConfig->cqi_ReportModeAperiodic= CQI_ReportModeAperiodic_rm30; +#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) + *physicalConfigDedicated2->cqi_ReportConfig->cqi_ReportModeAperiodic= LTE_CQI_ReportModeAperiodic_rm30; #else - *physicalConfigDedicated2->cqi_ReportConfig->cqi_ReportModeAperiodic=CQI_ReportConfig__cqi_ReportModeAperiodic_rm30; // HLC CQI, no PMI + *physicalConfigDedicated2->cqi_ReportConfig->cqi_ReportModeAperiodic=LTE_CQI_ReportConfig__cqi_ReportModeAperiodic_rm30; // HLC CQI, no PMI #endif physicalConfigDedicated2->cqi_ReportConfig->nomPDSCH_RS_EPRE_Offset = 0; // 0 dB //physicalConfigDedicated2->cqi_ReportConfig->cqi_ReportPeriodic=NULL; physicalConfigDedicated2->cqi_ReportConfig->cqi_ReportPeriodic=CALLOC(1,sizeof(*physicalConfigDedicated2->cqi_ReportConfig->cqi_ReportPeriodic)); - physicalConfigDedicated2->cqi_ReportConfig->cqi_ReportPeriodic->present = CQI_ReportPeriodic_PR_release; + physicalConfigDedicated2->cqi_ReportConfig->cqi_ReportPeriodic->present = LTE_CQI_ReportPeriodic_PR_release; /* physicalConfigDedicated2->cqi_ReportConfig->cqi_ReportPeriodic->present = CQI_ReportPeriodic_PR_setup; physicalConfigDedicated2->cqi_ReportConfig->cqi_ReportPeriodic->choice.setup.cqi_PUCCH_ResourceIndex = 0; // n2_pucch @@ -1997,16 +1997,16 @@ do_RRCConnectionSetup( //soundingRS-UL-ConfigDedicated if (rrc->srs_enable[CC_id]==1) { - physicalConfigDedicated2->soundingRS_UL_ConfigDedicated->present = SoundingRS_UL_ConfigDedicated_PR_setup; + physicalConfigDedicated2->soundingRS_UL_ConfigDedicated->present = LTE_SoundingRS_UL_ConfigDedicated_PR_setup; physicalConfigDedicated2->soundingRS_UL_ConfigDedicated->choice.setup.srs_Bandwidth = - SoundingRS_UL_ConfigDedicated__setup__srs_Bandwidth_bw0; + LTE_SoundingRS_UL_ConfigDedicated__setup__srs_Bandwidth_bw0; physicalConfigDedicated2->soundingRS_UL_ConfigDedicated->choice.setup.srs_HoppingBandwidth = - SoundingRS_UL_ConfigDedicated__setup__srs_HoppingBandwidth_hbw0; + LTE_SoundingRS_UL_ConfigDedicated__setup__srs_HoppingBandwidth_hbw0; physicalConfigDedicated2->soundingRS_UL_ConfigDedicated->choice.setup.freqDomainPosition=0; physicalConfigDedicated2->soundingRS_UL_ConfigDedicated->choice.setup.duration=1; if (carrier->sib1->tdd_Config==NULL) { // FDD if (carrier->sib2->radioResourceConfigCommon.soundingRS_UL_ConfigCommon.present - == SoundingRS_UL_ConfigCommon_PR_setup) + == LTE_SoundingRS_UL_ConfigCommon_PR_setup) if (carrier->sib2->radioResourceConfigCommon.soundingRS_UL_ConfigCommon.choice.setup.srs_SubframeConfig!=0) LOG_W(RRC,"This code has been optimized for SRS Subframe Config 0, but current config is %zd. Expect undefined behaviour!\n", carrier->sib2->radioResourceConfigCommon.soundingRS_UL_ConfigCommon.choice.setup.srs_SubframeConfig); @@ -2019,7 +2019,7 @@ do_RRCConnectionSetup( } else { if (carrier->sib2->radioResourceConfigCommon.soundingRS_UL_ConfigCommon.present - == SoundingRS_UL_ConfigCommon_PR_setup) + == LTE_SoundingRS_UL_ConfigCommon_PR_setup) if (carrier->sib2->radioResourceConfigCommon.soundingRS_UL_ConfigCommon.choice.setup.srs_SubframeConfig!=7) { LOG_W(RRC,"This code has been optimized for SRS Subframe Config 7 and TDD config 3, but current configs are %zd and %zd. Expect undefined behaviour!\n", carrier->sib2->radioResourceConfigCommon.soundingRS_UL_ConfigCommon.choice.setup.srs_SubframeConfig, @@ -2036,13 +2036,13 @@ do_RRCConnectionSetup( physicalConfigDedicated2->soundingRS_UL_ConfigDedicated->choice.setup.transmissionComb); physicalConfigDedicated2->soundingRS_UL_ConfigDedicated->choice.setup.cyclicShift= - SoundingRS_UL_ConfigDedicated__setup__cyclicShift_cs0; + LTE_SoundingRS_UL_ConfigDedicated__setup__cyclicShift_cs0; } //AntennaInfoDedicated physicalConfigDedicated2->antennaInfo = CALLOC(1,sizeof(*physicalConfigDedicated2->antennaInfo)); - physicalConfigDedicated2->antennaInfo->present = PhysicalConfigDedicated__antennaInfo_PR_explicitValue; + physicalConfigDedicated2->antennaInfo->present = LTE_PhysicalConfigDedicated__antennaInfo_PR_explicitValue; //assign_enum(&physicalConfigDedicated2->antennaInfo->choice.explicitValue.transmissionMode, // AntennaInfoDedicated__transmissionMode_tm2); @@ -2050,11 +2050,11 @@ do_RRCConnectionSetup( default: LOG_W(RRC,"At RRCConnectionSetup Transmission mode can only take values 1 or 2! Defaulting to 1!\n"); case 1: - physicalConfigDedicated2->antennaInfo->choice.explicitValue.transmissionMode= AntennaInfoDedicated__transmissionMode_tm1; + physicalConfigDedicated2->antennaInfo->choice.explicitValue.transmissionMode= LTE_AntennaInfoDedicated__transmissionMode_tm1; break; case 2: - physicalConfigDedicated2->antennaInfo->choice.explicitValue.transmissionMode= AntennaInfoDedicated__transmissionMode_tm2; + physicalConfigDedicated2->antennaInfo->choice.explicitValue.transmissionMode= LTE_AntennaInfoDedicated__transmissionMode_tm2; break; /* case 3: @@ -2089,12 +2089,12 @@ do_RRCConnectionSetup( } - physicalConfigDedicated2->antennaInfo->choice.explicitValue.ue_TransmitAntennaSelection.present = AntennaInfoDedicated__ue_TransmitAntennaSelection_PR_release; + physicalConfigDedicated2->antennaInfo->choice.explicitValue.ue_TransmitAntennaSelection.present = LTE_AntennaInfoDedicated__ue_TransmitAntennaSelection_PR_release; physicalConfigDedicated2->antennaInfo->choice.explicitValue.ue_TransmitAntennaSelection.choice.release = 0; // SchedulingRequestConfig - physicalConfigDedicated2->schedulingRequestConfig->present = SchedulingRequestConfig_PR_setup; + physicalConfigDedicated2->schedulingRequestConfig->present = LTE_SchedulingRequestConfig_PR_setup; if (carrier->sib1->tdd_Config == NULL) { physicalConfigDedicated2->schedulingRequestConfig->choice.setup.sr_PUCCH_ResourceIndex = 71 - ue_context_pP->local_uid/10;//ue_context_pP->local_uid; } else { @@ -2146,11 +2146,11 @@ do_RRCConnectionSetup( // 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; + physicalConfigDedicated2->schedulingRequestConfig->choice.setup.dsr_TransMax = LTE_SchedulingRequestConfig__setup__dsr_TransMax_n4; rrcConnectionSetup->rrc_TransactionIdentifier = Transaction_id; - rrcConnectionSetup->criticalExtensions.present = RRCConnectionSetup__criticalExtensions_PR_c1; - rrcConnectionSetup->criticalExtensions.choice.c1.present =RRCConnectionSetup__criticalExtensions__c1_PR_rrcConnectionSetup_r8 ; + rrcConnectionSetup->criticalExtensions.present = LTE_RRCConnectionSetup__criticalExtensions_PR_c1; + rrcConnectionSetup->criticalExtensions.choice.c1.present = LTE_RRCConnectionSetup__criticalExtensions__c1_PR_rrcConnectionSetup_r8 ; rrcConnectionSetup->criticalExtensions.choice.c1.choice.rrcConnectionSetup_r8.radioResourceConfigDedicated.srb_ToAddModList = *SRB_configList; rrcConnectionSetup->criticalExtensions.choice.c1.choice.rrcConnectionSetup_r8.radioResourceConfigDedicated.drb_ToAddModList = NULL; rrcConnectionSetup->criticalExtensions.choice.c1.choice.rrcConnectionSetup_r8.radioResourceConfigDedicated.drb_ToReleaseList = NULL; @@ -2169,9 +2169,9 @@ do_RRCConnectionSetup( if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) { - xer_fprint(stdout, &asn_DEF_DL_CCCH_Message, (void*)&dl_ccch_msg); + xer_fprint(stdout, &asn_DEF_LTE_DL_CCCH_Message, (void*)&dl_ccch_msg); } - enc_rval = uper_encode_to_buffer(&asn_DEF_DL_CCCH_Message, + enc_rval = uper_encode_to_buffer(&asn_DEF_LTE_DL_CCCH_Message, NULL, (void*)&dl_ccch_msg, buffer, @@ -2188,7 +2188,7 @@ do_RRCConnectionSetup( char message_string[20000]; size_t message_string_size; - if ((message_string_size = xer_sprint(message_string, sizeof(message_string), &asn_DEF_DL_CCCH_Message, (void *) &dl_ccch_msg)) > 0) { + if ((message_string_size = xer_sprint(message_string, sizeof(message_string), &asn_DEF_LTE_DL_CCCH_Message, (void *) &dl_ccch_msg)) > 0) { MessageDef *msg_p; msg_p = itti_alloc_new_message_sized (TASK_RRC_ENB, RRC_DL_CCCH, message_string_size + sizeof (IttiMsgText)); @@ -2224,29 +2224,29 @@ do_SecurityModeCommand( ) //------------------------------------------------------------------------------ { - DL_DCCH_Message_t dl_dcch_msg; + LTE_DL_DCCH_Message_t dl_dcch_msg; asn_enc_rval_t enc_rval; - memset(&dl_dcch_msg,0,sizeof(DL_DCCH_Message_t)); + memset(&dl_dcch_msg,0,sizeof(LTE_DL_DCCH_Message_t)); - dl_dcch_msg.message.present = DL_DCCH_MessageType_PR_c1; - dl_dcch_msg.message.choice.c1.present = DL_DCCH_MessageType__c1_PR_securityModeCommand; + dl_dcch_msg.message.present = LTE_DL_DCCH_MessageType_PR_c1; + dl_dcch_msg.message.choice.c1.present = LTE_DL_DCCH_MessageType__c1_PR_securityModeCommand; dl_dcch_msg.message.choice.c1.choice.securityModeCommand.rrc_TransactionIdentifier = Transaction_id; - dl_dcch_msg.message.choice.c1.choice.securityModeCommand.criticalExtensions.present = SecurityModeCommand__criticalExtensions_PR_c1; + dl_dcch_msg.message.choice.c1.choice.securityModeCommand.criticalExtensions.present = LTE_SecurityModeCommand__criticalExtensions_PR_c1; dl_dcch_msg.message.choice.c1.choice.securityModeCommand.criticalExtensions.choice.c1.present = - SecurityModeCommand__criticalExtensions__c1_PR_securityModeCommand_r8; + LTE_SecurityModeCommand__criticalExtensions__c1_PR_securityModeCommand_r8; // the two following information could be based on the mod_id dl_dcch_msg.message.choice.c1.choice.securityModeCommand.criticalExtensions.choice.c1.choice.securityModeCommand_r8.securityConfigSMC.securityAlgorithmConfig.cipheringAlgorithm - = (CipheringAlgorithm_r12_t)cipheringAlgorithm; + = (LTE_CipheringAlgorithm_r12_t)cipheringAlgorithm; dl_dcch_msg.message.choice.c1.choice.securityModeCommand.criticalExtensions.choice.c1.choice.securityModeCommand_r8.securityConfigSMC.securityAlgorithmConfig.integrityProtAlgorithm - = (e_SecurityAlgorithmConfig__integrityProtAlgorithm)integrityProtAlgorithm; + = (e_LTE_SecurityAlgorithmConfig__integrityProtAlgorithm)integrityProtAlgorithm; if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) { - xer_fprint(stdout, &asn_DEF_DL_DCCH_Message, (void*)&dl_dcch_msg); + xer_fprint(stdout, &asn_DEF_LTE_DL_DCCH_Message, (void*)&dl_dcch_msg); } - enc_rval = uper_encode_to_buffer(&asn_DEF_DL_DCCH_Message, + enc_rval = uper_encode_to_buffer(&asn_DEF_LTE_DL_DCCH_Message, NULL, (void*)&dl_dcch_msg, buffer, @@ -2263,7 +2263,7 @@ do_SecurityModeCommand( char message_string[20000]; size_t message_string_size; - if ((message_string_size = xer_sprint(message_string, sizeof(message_string), &asn_DEF_DL_DCCH_Message, (void *) &dl_dcch_msg)) > 0) { + if ((message_string_size = xer_sprint(message_string, sizeof(message_string), &asn_DEF_LTE_DL_DCCH_Message, (void *) &dl_dcch_msg)) > 0) { MessageDef *msg_p; msg_p = itti_alloc_new_message_sized (TASK_RRC_ENB, RRC_DL_DCCH, message_string_size + sizeof (IttiMsgText)); @@ -2304,29 +2304,29 @@ do_UECapabilityEnquiry( //------------------------------------------------------------------------------ { - DL_DCCH_Message_t dl_dcch_msg; + LTE_DL_DCCH_Message_t dl_dcch_msg; - RAT_Type_t rat=RAT_Type_eutra; + LTE_RAT_Type_t rat=LTE_RAT_Type_eutra; asn_enc_rval_t enc_rval; - memset(&dl_dcch_msg,0,sizeof(DL_DCCH_Message_t)); + memset(&dl_dcch_msg,0,sizeof(LTE_DL_DCCH_Message_t)); - dl_dcch_msg.message.present = DL_DCCH_MessageType_PR_c1; - dl_dcch_msg.message.choice.c1.present = DL_DCCH_MessageType__c1_PR_ueCapabilityEnquiry; + dl_dcch_msg.message.present = LTE_DL_DCCH_MessageType_PR_c1; + dl_dcch_msg.message.choice.c1.present = LTE_DL_DCCH_MessageType__c1_PR_ueCapabilityEnquiry; dl_dcch_msg.message.choice.c1.choice.ueCapabilityEnquiry.rrc_TransactionIdentifier = Transaction_id; - dl_dcch_msg.message.choice.c1.choice.ueCapabilityEnquiry.criticalExtensions.present = UECapabilityEnquiry__criticalExtensions_PR_c1; + dl_dcch_msg.message.choice.c1.choice.ueCapabilityEnquiry.criticalExtensions.present = LTE_UECapabilityEnquiry__criticalExtensions_PR_c1; dl_dcch_msg.message.choice.c1.choice.ueCapabilityEnquiry.criticalExtensions.choice.c1.present = - UECapabilityEnquiry__criticalExtensions__c1_PR_ueCapabilityEnquiry_r8; + LTE_UECapabilityEnquiry__criticalExtensions__c1_PR_ueCapabilityEnquiry_r8; dl_dcch_msg.message.choice.c1.choice.ueCapabilityEnquiry.criticalExtensions.choice.c1.choice.ueCapabilityEnquiry_r8.ue_CapabilityRequest.list.count=0; ASN_SEQUENCE_ADD(&dl_dcch_msg.message.choice.c1.choice.ueCapabilityEnquiry.criticalExtensions.choice.c1.choice.ueCapabilityEnquiry_r8.ue_CapabilityRequest.list, &rat); if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) { - xer_fprint(stdout, &asn_DEF_DL_DCCH_Message, (void*)&dl_dcch_msg); + xer_fprint(stdout, &asn_DEF_LTE_DL_DCCH_Message, (void*)&dl_dcch_msg); } - enc_rval = uper_encode_to_buffer(&asn_DEF_DL_DCCH_Message, + enc_rval = uper_encode_to_buffer(&asn_DEF_LTE_DL_DCCH_Message, NULL, (void*)&dl_dcch_msg, buffer, @@ -2343,7 +2343,7 @@ do_UECapabilityEnquiry( char message_string[20000]; size_t message_string_size; - if ((message_string_size = xer_sprint(message_string, sizeof(message_string), &asn_DEF_DL_DCCH_Message, (void *) &dl_dcch_msg)) > 0) { + if ((message_string_size = xer_sprint(message_string, sizeof(message_string), &asn_DEF_LTE_DL_DCCH_Message, (void *) &dl_dcch_msg)) > 0) { MessageDef *msg_p; msg_p = itti_alloc_new_message_sized (TASK_RRC_ENB, RRC_DL_CCCH, message_string_size + sizeof (IttiMsgText)); @@ -2378,27 +2378,27 @@ do_RRCConnectionReconfiguration( const protocol_ctxt_t* const ctxt_pP, uint8_t *buffer, uint8_t Transaction_id, - SRB_ToAddModList_t *SRB_list, - DRB_ToAddModList_t *DRB_list, - DRB_ToReleaseList_t *DRB_list2, - struct SPS_Config *sps_Config, - struct PhysicalConfigDedicated *physicalConfigDedicated, - MeasObjectToAddModList_t *MeasObj_list, - ReportConfigToAddModList_t *ReportConfig_list, - 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, - struct RRCConnectionReconfiguration_r8_IEs__dedicatedInfoNASList + LTE_SRB_ToAddModList_t *SRB_list, + LTE_DRB_ToAddModList_t *DRB_list, + LTE_DRB_ToReleaseList_t *DRB_list2, + struct LTE_SPS_Config *sps_Config, + struct LTE_PhysicalConfigDedicated *physicalConfigDedicated, + LTE_MeasObjectToAddModList_t *MeasObj_list, + LTE_ReportConfigToAddModList_t *ReportConfig_list, + LTE_QuantityConfig_t *quantityConfig, + LTE_MeasIdToAddModList_t *MeasId_list, + LTE_MAC_MainConfig_t *mac_MainConfig, + LTE_MeasGapConfig_t *measGapConfig, + LTE_MobilityControlInfo_t *mobilityInfo, + struct LTE_MeasConfig__speedStatePars *speedStatePars, + LTE_RSRP_Range_t *rsrp, + LTE_C_RNTI_t *cba_rnti, + struct LTE_RRCConnectionReconfiguration_r8_IEs__dedicatedInfoNASList *dedicatedInfoNASList, - SL_CommConfig_r12_t *sl_CommConfig, - SL_DiscConfig_r12_t *sl_DiscConfig -#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) - , SCellToAddMod_r10_t *SCell_config + LTE_SL_CommConfig_r12_t *sl_CommConfig, + LTE_SL_DiscConfig_r12_t *sl_DiscConfig +#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) + , LTE_SCellToAddMod_r10_t *SCell_config #endif ) @@ -2407,20 +2407,20 @@ do_RRCConnectionReconfiguration( asn_enc_rval_t enc_rval; - DL_DCCH_Message_t dl_dcch_msg; - RRCConnectionReconfiguration_t *rrcConnectionReconfiguration; + LTE_DL_DCCH_Message_t dl_dcch_msg; + LTE_RRCConnectionReconfiguration_t *rrcConnectionReconfiguration; - memset(&dl_dcch_msg,0,sizeof(DL_DCCH_Message_t)); + memset(&dl_dcch_msg,0,sizeof(LTE_DL_DCCH_Message_t)); - dl_dcch_msg.message.present = DL_DCCH_MessageType_PR_c1; - dl_dcch_msg.message.choice.c1.present = DL_DCCH_MessageType__c1_PR_rrcConnectionReconfiguration; + dl_dcch_msg.message.present = LTE_DL_DCCH_MessageType_PR_c1; + dl_dcch_msg.message.choice.c1.present = LTE_DL_DCCH_MessageType__c1_PR_rrcConnectionReconfiguration; rrcConnectionReconfiguration = &dl_dcch_msg.message.choice.c1.choice.rrcConnectionReconfiguration; // RRCConnectionReconfiguration rrcConnectionReconfiguration->rrc_TransactionIdentifier = Transaction_id; - rrcConnectionReconfiguration->criticalExtensions.present = RRCConnectionReconfiguration__criticalExtensions_PR_c1; - rrcConnectionReconfiguration->criticalExtensions.choice.c1.present =RRCConnectionReconfiguration__criticalExtensions__c1_PR_rrcConnectionReconfiguration_r8 ; + rrcConnectionReconfiguration->criticalExtensions.present = LTE_RRCConnectionReconfiguration__criticalExtensions_PR_c1; + rrcConnectionReconfiguration->criticalExtensions.choice.c1.present = LTE_RRCConnectionReconfiguration__criticalExtensions__c1_PR_rrcConnectionReconfiguration_r8 ; rrcConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.radioResourceConfigDedicated = CALLOC(1, sizeof(*rrcConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.radioResourceConfigDedicated)); @@ -2437,7 +2437,7 @@ do_RRCConnectionReconfiguration( 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; + =LTE_RadioResourceConfigDedicated__mac_MainConfig_PR_explicitValue; memcpy(&rrcConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.radioResourceConfigDedicated->mac_MainConfig->choice.explicitValue, mac_MainConfig, sizeof(*mac_MainConfig)); @@ -2483,7 +2483,7 @@ do_RRCConnectionReconfiguration( 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)); + sizeof(LTE_MobilityControlInfo_t)); } else { rrcConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.mobilityControlInfo = NULL; @@ -2509,7 +2509,7 @@ do_RRCConnectionReconfiguration( rrcConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->sl_CommConfig_r12 = CALLOC(1, sizeof(*rrcConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->sl_CommConfig_r12)); memcpy((void*)rrcConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->sl_CommConfig_r12, (void*)sl_CommConfig, - sizeof(SL_CommConfig_r12_t)); + sizeof(LTE_SL_CommConfig_r12_t)); } //allocate dedicated resource pools for SL discovery (sl_DiscConfig) @@ -2528,10 +2528,10 @@ do_RRCConnectionReconfiguration( rrcConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->sl_DiscConfig_r12 = CALLOC(1, sizeof(*rrcConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->sl_DiscConfig_r12)); memcpy((void*)rrcConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->sl_DiscConfig_r12, (void*)sl_DiscConfig, - sizeof(SL_DiscConfig_r12_t)); + sizeof(LTE_SL_DiscConfig_r12_t)); } - enc_rval = uper_encode_to_buffer(&asn_DEF_DL_DCCH_Message, + enc_rval = uper_encode_to_buffer(&asn_DEF_LTE_DL_DCCH_Message, NULL, (void*)&dl_dcch_msg, buffer, @@ -2543,7 +2543,7 @@ do_RRCConnectionReconfiguration( return -1; } if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) { - xer_fprint(stdout,&asn_DEF_DL_DCCH_Message,(void*)&dl_dcch_msg); + xer_fprint(stdout,&asn_DEF_LTE_DL_DCCH_Message,(void*)&dl_dcch_msg); } #if defined(ENABLE_ITTI) @@ -2552,7 +2552,7 @@ do_RRCConnectionReconfiguration( char message_string[30000]; size_t message_string_size; - if ((message_string_size = xer_sprint(message_string, sizeof(message_string), &asn_DEF_DL_DCCH_Message, (void *) &dl_dcch_msg)) > 0) { + if ((message_string_size = xer_sprint(message_string, sizeof(message_string), &asn_DEF_LTE_DL_DCCH_Message, (void *) &dl_dcch_msg)) > 0) { MessageDef *msg_p; msg_p = itti_alloc_new_message_sized (TASK_RRC_ENB, RRC_DL_DCCH, message_string_size + sizeof (IttiMsgText)); @@ -2583,41 +2583,41 @@ do_RRCConnectionReestablishment( uint8_t* const buffer, const uint8_t transmission_mode, const uint8_t Transaction_id, - SRB_ToAddModList_t **SRB_configList, - struct PhysicalConfigDedicated **physicalConfigDedicated) + LTE_SRB_ToAddModList_t **SRB_configList, + struct LTE_PhysicalConfigDedicated **physicalConfigDedicated) { asn_enc_rval_t enc_rval; long* logicalchannelgroup = NULL; - struct SRB_ToAddMod* SRB1_config = NULL; - struct SRB_ToAddMod* SRB2_config = NULL; - struct SRB_ToAddMod__rlc_Config* SRB1_rlc_config = NULL; - struct SRB_ToAddMod__logicalChannelConfig* SRB1_lchan_config = NULL; - struct LogicalChannelConfig__ul_SpecificParameters* SRB1_ul_SpecificParameters = NULL; + struct LTE_SRB_ToAddMod* SRB1_config = NULL; + struct LTE_SRB_ToAddMod* SRB2_config = NULL; + struct LTE_SRB_ToAddMod__rlc_Config* SRB1_rlc_config = NULL; + struct LTE_SRB_ToAddMod__logicalChannelConfig* SRB1_lchan_config = NULL; + struct LTE_LogicalChannelConfig__ul_SpecificParameters* SRB1_ul_SpecificParameters = NULL; eNB_RRC_INST *rrc = RC.rrc[ctxt_pP->module_id]; #ifdef CBA - struct PUSCH_CBAConfigDedicated_vlola* pusch_CBAConfigDedicated_vlola = NULL; + struct LTE_PUSCH_CBAConfigDedicated_vlola* pusch_CBAConfigDedicated_vlola = NULL; long* betaOffset_CBA_Index = NULL; long* cShift_CBA = NULL; #endif - PhysicalConfigDedicated_t* physicalConfigDedicated2 = NULL; + LTE_PhysicalConfigDedicated_t* physicalConfigDedicated2 = NULL; - DL_CCCH_Message_t dl_ccch_msg; + LTE_DL_CCCH_Message_t dl_ccch_msg; - RRCConnectionReestablishment_t* rrcConnectionReestablishment = NULL; + LTE_RRCConnectionReestablishment_t* rrcConnectionReestablishment = NULL; int i = 0; - SRB_ToAddModList_t **SRB_configList2 = NULL; + LTE_SRB_ToAddModList_t **SRB_configList2 = NULL; SRB_configList2 = &ue_context_pP->ue_context.SRB_configList2[Transaction_id]; if (*SRB_configList2) { free(*SRB_configList2); } - *SRB_configList2 = CALLOC(1, sizeof(SRB_ToAddModList_t)); + *SRB_configList2 = CALLOC(1, sizeof(LTE_SRB_ToAddModList_t)); - memset((void *)&dl_ccch_msg, 0, sizeof(DL_CCCH_Message_t)); - dl_ccch_msg.message.present = DL_CCCH_MessageType_PR_c1; - dl_ccch_msg.message.choice.c1.present = DL_CCCH_MessageType__c1_PR_rrcConnectionReestablishment; + memset((void *)&dl_ccch_msg, 0, sizeof(LTE_DL_CCCH_Message_t)); + dl_ccch_msg.message.present = LTE_DL_CCCH_MessageType_PR_c1; + dl_ccch_msg.message.choice.c1.present = LTE_DL_CCCH_MessageType__c1_PR_rrcConnectionReestablishment; rrcConnectionReestablishment = &dl_ccch_msg.message.choice.c1.choice.rrcConnectionReestablishment; // RRCConnectionReestablishment @@ -2647,8 +2647,8 @@ do_RRCConnectionReestablishment( 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->present = LTE_SRB_ToAddMod__rlc_Config_PR_explicitValue; + SRB1_rlc_config->choice.explicitValue.present=LTE_RLC_Config_PR_am; #if defined(ENABLE_ITTI) SRB1_rlc_config->choice.explicitValue.choice.am.ul_AM_RLC.t_PollRetransmit = rrc->srb1_timer_poll_retransmit; SRB1_rlc_config->choice.explicitValue.choice.am.ul_AM_RLC.pollPDU = rrc->srb1_poll_pdu; @@ -2657,28 +2657,28 @@ do_RRCConnectionReestablishment( SRB1_rlc_config->choice.explicitValue.choice.am.dl_AM_RLC.t_Reordering = rrc->srb1_timer_reordering; SRB1_rlc_config->choice.explicitValue.choice.am.dl_AM_RLC.t_StatusProhibit = rrc->srb1_timer_status_prohibit; #else - SRB1_rlc_config->choice.explicitValue.choice.am.ul_AM_RLC.t_PollRetransmit = T_PollRetransmit_ms20;; - SRB1_rlc_config->choice.explicitValue.choice.am.ul_AM_RLC.pollPDU = PollPDU_p4;; - SRB1_rlc_config->choice.explicitValue.choice.am.ul_AM_RLC.pollByte = PollByte_kBinfinity; - SRB1_rlc_config->choice.explicitValue.choice.am.ul_AM_RLC.maxRetxThreshold = UL_AM_RLC__maxRetxThreshold_t8; - SRB1_rlc_config->choice.explicitValue.choice.am.dl_AM_RLC.t_Reordering = T_Reordering_ms35; - SRB1_rlc_config->choice.explicitValue.choice.am.dl_AM_RLC.t_StatusProhibit = T_StatusProhibit_ms0; + SRB1_rlc_config->choice.explicitValue.choice.am.ul_AM_RLC.t_PollRetransmit = LTE_T_PollRetransmit_ms20;; + SRB1_rlc_config->choice.explicitValue.choice.am.ul_AM_RLC.pollPDU = LTE_PollPDU_p4;; + SRB1_rlc_config->choice.explicitValue.choice.am.ul_AM_RLC.pollByte = LTE_PollByte_kBinfinity; + SRB1_rlc_config->choice.explicitValue.choice.am.ul_AM_RLC.maxRetxThreshold = LTE_UL_AM_RLC__maxRetxThreshold_t8; + SRB1_rlc_config->choice.explicitValue.choice.am.dl_AM_RLC.t_Reordering = LTE_T_Reordering_ms35; + SRB1_rlc_config->choice.explicitValue.choice.am.dl_AM_RLC.t_StatusProhibit = LTE_T_StatusProhibit_ms0; #endif 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_lchan_config->present = LTE_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; + SRB1_ul_SpecificParameters->prioritisedBitRate=LTE_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; + SRB1_ul_SpecificParameters->bucketSizeDuration=LTE_LogicalChannelConfig__ul_SpecificParameters__bucketSizeDuration_ms50; logicalchannelgroup = CALLOC(1, sizeof(long)); *logicalchannelgroup = 0; @@ -2695,15 +2695,15 @@ do_RRCConnectionReestablishment( free(*SRB_configList); } - *SRB_configList = CALLOC(1, sizeof(SRB_ToAddModList_t)); + *SRB_configList = CALLOC(1, sizeof(LTE_SRB_ToAddModList_t)); ASN_SEQUENCE_ADD(&(*SRB_configList)->list,SRB1_config); physicalConfigDedicated2 = *physicalConfigDedicated; rrcConnectionReestablishment->rrc_TransactionIdentifier = Transaction_id; - rrcConnectionReestablishment->criticalExtensions.present = RRCConnectionReestablishment__criticalExtensions_PR_c1; - rrcConnectionReestablishment->criticalExtensions.choice.c1.present = RRCConnectionReestablishment__criticalExtensions__c1_PR_rrcConnectionReestablishment_r8; + rrcConnectionReestablishment->criticalExtensions.present = LTE_RRCConnectionReestablishment__criticalExtensions_PR_c1; + rrcConnectionReestablishment->criticalExtensions.choice.c1.present = LTE_RRCConnectionReestablishment__criticalExtensions__c1_PR_rrcConnectionReestablishment_r8; rrcConnectionReestablishment->criticalExtensions.choice.c1.choice.rrcConnectionReestablishment_r8.radioResourceConfigDedicated.srb_ToAddModList = *SRB_configList; rrcConnectionReestablishment->criticalExtensions.choice.c1.choice.rrcConnectionReestablishment_r8.radioResourceConfigDedicated.drb_ToAddModList = NULL; rrcConnectionReestablishment->criticalExtensions.choice.c1.choice.rrcConnectionReestablishment_r8.radioResourceConfigDedicated.drb_ToReleaseList = NULL; @@ -2746,9 +2746,9 @@ do_RRCConnectionReestablishment( rrcConnectionReestablishment->criticalExtensions.choice.c1.choice.rrcConnectionReestablishment_r8.nonCriticalExtension = NULL; if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) { - xer_fprint(stdout, &asn_DEF_DL_CCCH_Message, (void*)&dl_ccch_msg); + xer_fprint(stdout, &asn_DEF_LTE_DL_CCCH_Message, (void*)&dl_ccch_msg); } - enc_rval = uper_encode_to_buffer(&asn_DEF_DL_CCCH_Message, + enc_rval = uper_encode_to_buffer(&asn_DEF_LTE_DL_CCCH_Message, NULL, (void*)&dl_ccch_msg, buffer, @@ -2765,7 +2765,7 @@ do_RRCConnectionReestablishment( char message_string[20000]; size_t message_string_size; - if ((message_string_size = xer_sprint(message_string, sizeof(message_string), &asn_DEF_DL_CCCH_Message, (void *) &dl_ccch_msg)) > 0) { + if ((message_string_size = xer_sprint(message_string, sizeof(message_string), &asn_DEF_LTE_DL_CCCH_Message, (void *) &dl_ccch_msg)) > 0) { MessageDef *msg_p; msg_p = itti_alloc_new_message_sized (TASK_RRC_ENB, RRC_DL_CCCH, message_string_size + sizeof (IttiMsgText)); @@ -2796,21 +2796,21 @@ do_RRCConnectionReestablishmentReject( asn_enc_rval_t enc_rval; - DL_CCCH_Message_t dl_ccch_msg; - RRCConnectionReestablishmentReject_t *rrcConnectionReestablishmentReject; + LTE_DL_CCCH_Message_t dl_ccch_msg; + LTE_RRCConnectionReestablishmentReject_t *rrcConnectionReestablishmentReject; - memset((void *)&dl_ccch_msg,0,sizeof(DL_CCCH_Message_t)); - dl_ccch_msg.message.present = DL_CCCH_MessageType_PR_c1; - dl_ccch_msg.message.choice.c1.present = DL_CCCH_MessageType__c1_PR_rrcConnectionReestablishmentReject; + memset((void *)&dl_ccch_msg,0,sizeof(LTE_DL_CCCH_Message_t)); + dl_ccch_msg.message.present = LTE_DL_CCCH_MessageType_PR_c1; + dl_ccch_msg.message.choice.c1.present = LTE_DL_CCCH_MessageType__c1_PR_rrcConnectionReestablishmentReject; rrcConnectionReestablishmentReject = &dl_ccch_msg.message.choice.c1.choice.rrcConnectionReestablishmentReject; // RRCConnectionReestablishmentReject - rrcConnectionReestablishmentReject->criticalExtensions.present = RRCConnectionReestablishmentReject__criticalExtensions_PR_rrcConnectionReestablishmentReject_r8; + rrcConnectionReestablishmentReject->criticalExtensions.present = LTE_RRCConnectionReestablishmentReject__criticalExtensions_PR_rrcConnectionReestablishmentReject_r8; if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) { - xer_fprint(stdout, &asn_DEF_DL_CCCH_Message, (void*)&dl_ccch_msg); + xer_fprint(stdout, &asn_DEF_LTE_DL_CCCH_Message, (void*)&dl_ccch_msg); } - enc_rval = uper_encode_to_buffer(&asn_DEF_DL_CCCH_Message, + enc_rval = uper_encode_to_buffer(&asn_DEF_LTE_DL_CCCH_Message, NULL, (void*)&dl_ccch_msg, buffer, @@ -2827,7 +2827,7 @@ do_RRCConnectionReestablishmentReject( char message_string[20000]; size_t message_string_size; - if ((message_string_size = xer_sprint(message_string, sizeof(message_string), &asn_DEF_DL_CCCH_Message, (void *) &dl_ccch_msg)) > 0) { + if ((message_string_size = xer_sprint(message_string, sizeof(message_string), &asn_DEF_LTE_DL_CCCH_Message, (void *) &dl_ccch_msg)) > 0) { MessageDef *msg_p; msg_p = itti_alloc_new_message_sized (TASK_RRC_ENB, RRC_DL_CCCH, message_string_size + sizeof (IttiMsgText)); @@ -2856,24 +2856,24 @@ do_RRCConnectionReject( asn_enc_rval_t enc_rval; - DL_CCCH_Message_t dl_ccch_msg; - RRCConnectionReject_t *rrcConnectionReject; + LTE_DL_CCCH_Message_t dl_ccch_msg; + LTE_RRCConnectionReject_t *rrcConnectionReject; - memset((void *)&dl_ccch_msg,0,sizeof(DL_CCCH_Message_t)); - dl_ccch_msg.message.present = DL_CCCH_MessageType_PR_c1; - dl_ccch_msg.message.choice.c1.present = DL_CCCH_MessageType__c1_PR_rrcConnectionReject; + memset((void *)&dl_ccch_msg,0,sizeof(LTE_DL_CCCH_Message_t)); + dl_ccch_msg.message.present = LTE_DL_CCCH_MessageType_PR_c1; + dl_ccch_msg.message.choice.c1.present = LTE_DL_CCCH_MessageType__c1_PR_rrcConnectionReject; rrcConnectionReject = &dl_ccch_msg.message.choice.c1.choice.rrcConnectionReject; // RRCConnectionReject - rrcConnectionReject->criticalExtensions.present = RRCConnectionReject__criticalExtensions_PR_c1; - rrcConnectionReject->criticalExtensions.choice.c1.present = RRCConnectionReject__criticalExtensions__c1_PR_rrcConnectionReject_r8; + rrcConnectionReject->criticalExtensions.present = LTE_RRCConnectionReject__criticalExtensions_PR_c1; + rrcConnectionReject->criticalExtensions.choice.c1.present = LTE_RRCConnectionReject__criticalExtensions__c1_PR_rrcConnectionReject_r8; /* let's put a wait time of 1s for the moment */ rrcConnectionReject->criticalExtensions.choice.c1.choice.rrcConnectionReject_r8.waitTime = 1; if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) { - xer_fprint(stdout, &asn_DEF_DL_CCCH_Message, (void*)&dl_ccch_msg); + xer_fprint(stdout, &asn_DEF_LTE_DL_CCCH_Message, (void*)&dl_ccch_msg); } - enc_rval = uper_encode_to_buffer(&asn_DEF_DL_CCCH_Message, + enc_rval = uper_encode_to_buffer(&asn_DEF_LTE_DL_CCCH_Message, NULL, (void*)&dl_ccch_msg, buffer, @@ -2890,7 +2890,7 @@ do_RRCConnectionReject( char message_string[20000]; size_t message_string_size; - if ((message_string_size = xer_sprint(message_string, sizeof(message_string), &asn_DEF_DL_CCCH_Message, (void *) &dl_ccch_msg)) > 0) { + if ((message_string_size = xer_sprint(message_string, sizeof(message_string), &asn_DEF_LTE_DL_CCCH_Message, (void *) &dl_ccch_msg)) > 0) { MessageDef *msg_p; msg_p = itti_alloc_new_message_sized (TASK_RRC_ENB, RRC_DL_CCCH, message_string_size + sizeof (IttiMsgText)); @@ -2917,29 +2917,29 @@ uint8_t do_RRCConnectionRelease( asn_enc_rval_t enc_rval; - DL_DCCH_Message_t dl_dcch_msg; - RRCConnectionRelease_t *rrcConnectionRelease; + LTE_DL_DCCH_Message_t dl_dcch_msg; + LTE_RRCConnectionRelease_t *rrcConnectionRelease; - memset(&dl_dcch_msg,0,sizeof(DL_DCCH_Message_t)); + memset(&dl_dcch_msg,0,sizeof(LTE_DL_DCCH_Message_t)); - dl_dcch_msg.message.present = DL_DCCH_MessageType_PR_c1; - dl_dcch_msg.message.choice.c1.present = DL_DCCH_MessageType__c1_PR_rrcConnectionRelease; + dl_dcch_msg.message.present = LTE_DL_DCCH_MessageType_PR_c1; + dl_dcch_msg.message.choice.c1.present = LTE_DL_DCCH_MessageType__c1_PR_rrcConnectionRelease; rrcConnectionRelease = &dl_dcch_msg.message.choice.c1.choice.rrcConnectionRelease; // RRCConnectionRelease rrcConnectionRelease->rrc_TransactionIdentifier = Transaction_id; - rrcConnectionRelease->criticalExtensions.present = RRCConnectionRelease__criticalExtensions_PR_c1; - rrcConnectionRelease->criticalExtensions.choice.c1.present =RRCConnectionRelease__criticalExtensions__c1_PR_rrcConnectionRelease_r8 ; + rrcConnectionRelease->criticalExtensions.present = LTE_RRCConnectionRelease__criticalExtensions_PR_c1; + rrcConnectionRelease->criticalExtensions.choice.c1.present =LTE_RRCConnectionRelease__criticalExtensions__c1_PR_rrcConnectionRelease_r8 ; - rrcConnectionRelease->criticalExtensions.choice.c1.choice.rrcConnectionRelease_r8.releaseCause = ReleaseCause_other; + rrcConnectionRelease->criticalExtensions.choice.c1.choice.rrcConnectionRelease_r8.releaseCause = LTE_ReleaseCause_other; rrcConnectionRelease->criticalExtensions.choice.c1.choice.rrcConnectionRelease_r8.redirectedCarrierInfo = NULL; rrcConnectionRelease->criticalExtensions.choice.c1.choice.rrcConnectionRelease_r8.idleModeMobilityControlInfo = NULL; rrcConnectionRelease->criticalExtensions.choice.c1.choice.rrcConnectionRelease_r8.nonCriticalExtension=CALLOC(1, sizeof(*rrcConnectionRelease->criticalExtensions.choice.c1.choice.rrcConnectionRelease_r8.nonCriticalExtension)); - enc_rval = uper_encode_to_buffer(&asn_DEF_DL_DCCH_Message, + enc_rval = uper_encode_to_buffer(&asn_DEF_LTE_DL_DCCH_Message, NULL, (void*)&dl_dcch_msg, buffer, @@ -2951,26 +2951,26 @@ uint8_t do_RRCConnectionRelease( uint8_t TMGI[5] = {4,3,2,1,0};//TMGI is a string of octet, ref. TS 24.008 fig. 10.5.4a -#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) uint8_t do_MBSFNAreaConfig(uint8_t Mod_id, uint8_t sync_area, uint8_t *buffer, - MCCH_Message_t *mcch_message, - MBSFNAreaConfiguration_r9_t **mbsfnAreaConfiguration) + LTE_MCCH_Message_t *mcch_message, + LTE_MBSFNAreaConfiguration_r9_t **mbsfnAreaConfiguration) { asn_enc_rval_t enc_rval; - MBSFN_SubframeConfig_t *mbsfn_SubframeConfig1; - PMCH_Info_r9_t *pmch_Info_1; - MBMS_SessionInfo_r9_t *mbms_Session_1; + LTE_MBSFN_SubframeConfig_t *mbsfn_SubframeConfig1; + LTE_PMCH_Info_r9_t *pmch_Info_1; + LTE_MBMS_SessionInfo_r9_t *mbms_Session_1; // MBMS_SessionInfo_r9_t *mbms_Session_2; eNB_RRC_INST *rrc = RC.rrc[Mod_id]; rrc_eNB_carrier_data_t *carrier = &rrc->carrier[0]; - memset(mcch_message,0,sizeof(MCCH_Message_t)); - mcch_message->message.present = MCCH_MessageType_PR_c1; - mcch_message->message.choice.c1.present = MCCH_MessageType__c1_PR_mbsfnAreaConfiguration_r9; + memset(mcch_message,0,sizeof(LTE_MCCH_Message_t)); + mcch_message->message.present = LTE_MCCH_MessageType_PR_c1; + mcch_message->message.choice.c1.present = LTE_MCCH_MessageType__c1_PR_mbsfnAreaConfiguration_r9; *mbsfnAreaConfiguration = &mcch_message->message.choice.c1.choice.mbsfnAreaConfiguration_r9; // Common Subframe Allocation (CommonSF-Alloc-r9) @@ -2978,9 +2978,9 @@ uint8_t do_MBSFNAreaConfig(uint8_t Mod_id, mbsfn_SubframeConfig1= CALLOC(1,sizeof(*mbsfn_SubframeConfig1)); memset((void*)mbsfn_SubframeConfig1,0,sizeof(*mbsfn_SubframeConfig1)); // - mbsfn_SubframeConfig1->radioframeAllocationPeriod= MBSFN_SubframeConfig__radioframeAllocationPeriod_n4; + mbsfn_SubframeConfig1->radioframeAllocationPeriod= LTE_MBSFN_SubframeConfig__radioframeAllocationPeriod_n4; mbsfn_SubframeConfig1->radioframeAllocationOffset= 1; - mbsfn_SubframeConfig1->subframeAllocation.present= MBSFN_SubframeConfig__subframeAllocation_PR_oneFrame; + mbsfn_SubframeConfig1->subframeAllocation.present= LTE_MBSFN_SubframeConfig__subframeAllocation_PR_oneFrame; mbsfn_SubframeConfig1->subframeAllocation.choice.oneFrame.buf= MALLOC(1); mbsfn_SubframeConfig1->subframeAllocation.choice.oneFrame.size= 1; mbsfn_SubframeConfig1->subframeAllocation.choice.oneFrame.bits_unused= 2; @@ -3010,12 +3010,12 @@ uint8_t do_MBSFNAreaConfig(uint8_t Mod_id, ASN_SEQUENCE_ADD(&(*mbsfnAreaConfiguration)->commonSF_Alloc_r9.list,mbsfn_SubframeConfig1); // commonSF-AllocPeriod-r9 - (*mbsfnAreaConfiguration)->commonSF_AllocPeriod_r9= MBSFNAreaConfiguration_r9__commonSF_AllocPeriod_r9_rf16; + (*mbsfnAreaConfiguration)->commonSF_AllocPeriod_r9= LTE_MBSFNAreaConfiguration_r9__commonSF_AllocPeriod_r9_rf16; // PMCHs Information List (PMCH-InfoList-r9) // PMCH_1 Config - pmch_Info_1 = CALLOC(1,sizeof(PMCH_Info_r9_t)); - memset((void*)pmch_Info_1,0,sizeof(PMCH_Info_r9_t)); + pmch_Info_1 = CALLOC(1,sizeof(LTE_PMCH_Info_r9_t)); + memset((void*)pmch_Info_1,0,sizeof(LTE_PMCH_Info_r9_t)); /* * take the value of last mbsfn subframe in this CSA period because there is only one PMCH in this mbsfn area @@ -3023,15 +3023,15 @@ uint8_t do_MBSFNAreaConfig(uint8_t Mod_id, */ pmch_Info_1->pmch_Config_r9.sf_AllocEnd_r9= 3; pmch_Info_1->pmch_Config_r9.dataMCS_r9= 7; - pmch_Info_1->pmch_Config_r9.mch_SchedulingPeriod_r9= PMCH_Config_r9__mch_SchedulingPeriod_r9_rf16; + pmch_Info_1->pmch_Config_r9.mch_SchedulingPeriod_r9= LTE_PMCH_Config_r9__mch_SchedulingPeriod_r9_rf16; // MBMSs-SessionInfoList-r9 // pmch_Info_1->mbms_SessionInfoList_r9 = CALLOC(1,sizeof(struct MBMS_SessionInfoList_r9)); // Session 1 - mbms_Session_1 = CALLOC(1,sizeof(MBMS_SessionInfo_r9_t)); - memset(mbms_Session_1,0,sizeof(MBMS_SessionInfo_r9_t)); + mbms_Session_1 = CALLOC(1,sizeof(LTE_MBMS_SessionInfo_r9_t)); + memset(mbms_Session_1,0,sizeof(LTE_MBMS_SessionInfo_r9_t)); // TMGI value - mbms_Session_1->tmgi_r9.plmn_Id_r9.present= TMGI_r9__plmn_Id_r9_PR_plmn_Index_r9; + mbms_Session_1->tmgi_r9.plmn_Id_r9.present= LTE_TMGI_r9__plmn_Id_r9_PR_plmn_Index_r9; mbms_Session_1->tmgi_r9.plmn_Id_r9.choice.plmn_Index_r9= 1; // Service ID memset(&mbms_Session_1->tmgi_r9.serviceId_r9,0,sizeof(OCTET_STRING_t));// need to check @@ -3065,9 +3065,9 @@ uint8_t do_MBSFNAreaConfig(uint8_t Mod_id, ASN_SEQUENCE_ADD(&(*mbsfnAreaConfiguration)->pmch_InfoList_r9.list,pmch_Info_1); if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) { - xer_fprint(stdout,&asn_DEF_MCCH_Message,(void*)mcch_message); + xer_fprint(stdout,&asn_DEF_LTE_MCCH_Message,(void*)mcch_message); } - enc_rval = uper_encode_to_buffer(&asn_DEF_MCCH_Message, + enc_rval = uper_encode_to_buffer(&asn_DEF_LTE_MCCH_Message, NULL, (void*)mcch_message, buffer, @@ -3084,7 +3084,7 @@ uint8_t do_MBSFNAreaConfig(uint8_t Mod_id, char message_string[20000]; size_t message_string_size; - if ((message_string_size = xer_sprint(message_string, sizeof(message_string), &asn_DEF_MCCH_Message, (void *) &mcch_message)) > 0) { + if ((message_string_size = xer_sprint(message_string, sizeof(message_string), &asn_DEF_LTE_MCCH_Message, (void *) &mcch_message)) > 0) { MessageDef *msg_p; msg_p = itti_alloc_new_message_sized (TASK_RRC_ENB, RRC_DL_MCCH, message_string_size); @@ -3113,21 +3113,21 @@ uint8_t do_MeasurementReport(uint8_t Mod_id, uint8_t *buffer,int measid,int phy_ asn_enc_rval_t enc_rval; - UL_DCCH_Message_t ul_dcch_msg; + LTE_UL_DCCH_Message_t ul_dcch_msg; - MeasurementReport_t *measurementReport; + LTE_MeasurementReport_t *measurementReport; - ul_dcch_msg.message.present = UL_DCCH_MessageType_PR_c1; - ul_dcch_msg.message.choice.c1.present = UL_DCCH_MessageType__c1_PR_measurementReport; + ul_dcch_msg.message.present = LTE_UL_DCCH_MessageType_PR_c1; + ul_dcch_msg.message.choice.c1.present = LTE_UL_DCCH_MessageType__c1_PR_measurementReport; measurementReport = &ul_dcch_msg.message.choice.c1.choice.measurementReport; - measurementReport->criticalExtensions.present=MeasurementReport__criticalExtensions_PR_c1; - measurementReport->criticalExtensions.choice.c1.present=MeasurementReport__criticalExtensions__c1_PR_measurementReport_r8; + measurementReport->criticalExtensions.present=LTE_MeasurementReport__criticalExtensions_PR_c1; + measurementReport->criticalExtensions.choice.c1.present=LTE_MeasurementReport__criticalExtensions__c1_PR_measurementReport_r8; measurementReport->criticalExtensions.choice.c1.choice.measurementReport_r8.nonCriticalExtension=CALLOC(1, sizeof(*measurementReport->criticalExtensions.choice.c1.choice.measurementReport_r8.nonCriticalExtension)); measurementReport->criticalExtensions.choice.c1.choice.measurementReport_r8.measResults.measId=measid; -#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) measurementReport->criticalExtensions.choice.c1.choice.measurementReport_r8.measResults.measResultPCell.rsrpResult=rsrp_s; measurementReport->criticalExtensions.choice.c1.choice.measurementReport_r8.measResults.measResultPCell.rsrqResult=rsrq_s; #else @@ -3136,16 +3136,16 @@ uint8_t do_MeasurementReport(uint8_t Mod_id, uint8_t *buffer,int measid,int phy_ #endif measurementReport->criticalExtensions.choice.c1.choice.measurementReport_r8.measResults.measResultNeighCells=CALLOC(1, sizeof(*measurementReport->criticalExtensions.choice.c1.choice.measurementReport_r8.measResults.measResultNeighCells)); - measurementReport->criticalExtensions.choice.c1.choice.measurementReport_r8.measResults.measResultNeighCells->present=MeasResults__measResultNeighCells_PR_measResultListEUTRA; + measurementReport->criticalExtensions.choice.c1.choice.measurementReport_r8.measResults.measResultNeighCells->present=LTE_MeasResults__measResultNeighCells_PR_measResultListEUTRA; - MeasResultListEUTRA_t *measResultListEUTRA2; + LTE_MeasResultListEUTRA_t *measResultListEUTRA2; measResultListEUTRA2 = CALLOC(1,sizeof(*measResultListEUTRA2)); - struct MeasResultEUTRA *measresulteutra2; + struct LTE_MeasResultEUTRA *measresulteutra2; measresulteutra2 = CALLOC(1,sizeof(*measresulteutra2)); measresulteutra2->physCellId=phy_id;//1; - struct MeasResultEUTRA__cgi_Info *measresult_cgi2; + struct LTE_MeasResultEUTRA__cgi_Info *measresult_cgi2; measresult_cgi2 = CALLOC(1,sizeof(*measresult_cgi2)); memset(&measresult_cgi2->cellGlobalId.plmn_Identity,0,sizeof(measresult_cgi2->cellGlobalId.plmn_Identity)); @@ -3155,7 +3155,7 @@ uint8_t do_MeasurementReport(uint8_t Mod_id, uint8_t *buffer,int measid,int phy_ asn_set_empty(&measresult_cgi2->cellGlobalId.plmn_Identity.mcc->list);//.size=0; - MCC_MNC_Digit_t dummy; + LTE_MCC_MNC_Digit_t dummy; dummy=2; ASN_SEQUENCE_ADD(&measresult_cgi2->cellGlobalId.plmn_Identity.mcc->list,&dummy); dummy=6; @@ -3187,7 +3187,7 @@ uint8_t do_MeasurementReport(uint8_t Mod_id, uint8_t *buffer,int measid,int phy_ measresulteutra2->cgi_Info=measresult_cgi2; - struct MeasResultEUTRA__measResult meas2; + struct LTE_MeasResultEUTRA__measResult meas2; // int rsrp_va=10; meas2.rsrpResult=&(rsrp_t); @@ -3200,7 +3200,7 @@ uint8_t do_MeasurementReport(uint8_t Mod_id, uint8_t *buffer,int measid,int phy_ measurementReport->criticalExtensions.choice.c1.choice.measurementReport_r8.measResults.measResultNeighCells->choice.measResultListEUTRA=*(measResultListEUTRA2); - enc_rval = uper_encode_to_buffer(&asn_DEF_UL_DCCH_Message, + enc_rval = uper_encode_to_buffer(&asn_DEF_LTE_UL_DCCH_Message, NULL, (void*)&ul_dcch_msg, buffer, @@ -3217,7 +3217,7 @@ uint8_t do_MeasurementReport(uint8_t Mod_id, uint8_t *buffer,int measid,int phy_ char message_string[20000]; size_t message_string_size; - if ((message_string_size = xer_sprint(message_string, sizeof(message_string), &asn_DEF_UL_DCCH_Message, (void *) &ul_dcch_msg)) > 0) { + if ((message_string_size = xer_sprint(message_string, sizeof(message_string), &asn_DEF_LTE_UL_DCCH_Message, (void *) &ul_dcch_msg)) > 0) { MessageDef *msg_p; msg_p = itti_alloc_new_message_sized (TASK_RRC_UE, RRC_DL_DCCH, message_string_size + sizeof (IttiMsgText)); @@ -3239,21 +3239,21 @@ uint8_t do_DLInformationTransfer(uint8_t Mod_id, uint8_t **buffer, uint8_t trans { ssize_t encoded; - DL_DCCH_Message_t dl_dcch_msg; + LTE_DL_DCCH_Message_t dl_dcch_msg; - memset(&dl_dcch_msg, 0, sizeof(DL_DCCH_Message_t)); + memset(&dl_dcch_msg, 0, sizeof(LTE_DL_DCCH_Message_t)); - dl_dcch_msg.message.present = DL_DCCH_MessageType_PR_c1; - dl_dcch_msg.message.choice.c1.present = DL_DCCH_MessageType__c1_PR_dlInformationTransfer; + dl_dcch_msg.message.present = LTE_DL_DCCH_MessageType_PR_c1; + dl_dcch_msg.message.choice.c1.present = LTE_DL_DCCH_MessageType__c1_PR_dlInformationTransfer; dl_dcch_msg.message.choice.c1.choice.dlInformationTransfer.rrc_TransactionIdentifier = transaction_id; - dl_dcch_msg.message.choice.c1.choice.dlInformationTransfer.criticalExtensions.present = DLInformationTransfer__criticalExtensions_PR_c1; - dl_dcch_msg.message.choice.c1.choice.dlInformationTransfer.criticalExtensions.choice.c1.present = DLInformationTransfer__criticalExtensions__c1_PR_dlInformationTransfer_r8; + dl_dcch_msg.message.choice.c1.choice.dlInformationTransfer.criticalExtensions.present = LTE_DLInformationTransfer__criticalExtensions_PR_c1; + dl_dcch_msg.message.choice.c1.choice.dlInformationTransfer.criticalExtensions.choice.c1.present = LTE_DLInformationTransfer__criticalExtensions__c1_PR_dlInformationTransfer_r8; dl_dcch_msg.message.choice.c1.choice.dlInformationTransfer.criticalExtensions.choice.c1.choice.dlInformationTransfer_r8.dedicatedInfoType.present = - DLInformationTransfer_r8_IEs__dedicatedInfoType_PR_dedicatedInfoNAS; + LTE_DLInformationTransfer_r8_IEs__dedicatedInfoType_PR_dedicatedInfoNAS; dl_dcch_msg.message.choice.c1.choice.dlInformationTransfer.criticalExtensions.choice.c1.choice.dlInformationTransfer_r8.dedicatedInfoType.choice.dedicatedInfoNAS.size = pdu_length; dl_dcch_msg.message.choice.c1.choice.dlInformationTransfer.criticalExtensions.choice.c1.choice.dlInformationTransfer_r8.dedicatedInfoType.choice.dedicatedInfoNAS.buf = pdu_buffer; - encoded = uper_encode_to_new_buffer (&asn_DEF_DL_DCCH_Message, NULL, (void*) &dl_dcch_msg, (void **) buffer); + encoded = uper_encode_to_new_buffer (&asn_DEF_LTE_DL_DCCH_Message, NULL, (void*) &dl_dcch_msg, (void **) buffer); /* #if defined(ENABLE_ITTI) @@ -3284,12 +3284,12 @@ uint8_t do_Paging(uint8_t Mod_id, uint8_t *buffer, ue_paging_identity_t ue_pagin LOG_D(RRC, "[eNB %d] do_Paging start\n", Mod_id); asn_enc_rval_t enc_rval; - PCCH_Message_t pcch_msg; - PagingRecord_t *paging_record_p; + LTE_PCCH_Message_t pcch_msg; + LTE_PagingRecord_t *paging_record_p; int j; - pcch_msg.message.present = PCCH_MessageType_PR_c1; - pcch_msg.message.choice.c1.present = PCCH_MessageType__c1_PR_paging; + pcch_msg.message.present = LTE_PCCH_MessageType_PR_c1; + pcch_msg.message.choice.c1.present = LTE_PCCH_MessageType__c1_PR_paging; pcch_msg.message.choice.c1.choice.paging.pagingRecordList = CALLOC(1,sizeof(*pcch_msg.message.choice.c1.choice.paging.pagingRecordList)); @@ -3300,16 +3300,16 @@ uint8_t do_Paging(uint8_t Mod_id, uint8_t *buffer, ue_paging_identity_t ue_pagin asn_set_empty(&pcch_msg.message.choice.c1.choice.paging.pagingRecordList->list); pcch_msg.message.choice.c1.choice.paging.pagingRecordList->list.count = 0; - if ((paging_record_p = calloc(1, sizeof(PagingRecord_t))) == NULL) { + if ((paging_record_p = calloc(1, sizeof(LTE_PagingRecord_t))) == NULL) { /* Possible error on calloc */ return (-1); } - memset(paging_record_p, 0, sizeof(PagingRecord_t)); + memset(paging_record_p, 0, sizeof(LTE_PagingRecord_t)); /* convert ue_paging_identity_t to PagingUE_Identity_t */ if (ue_paging_identity.presenceMask == UE_PAGING_IDENTITY_s_tmsi) { - paging_record_p->ue_Identity.present = PagingUE_Identity_PR_s_TMSI; + paging_record_p->ue_Identity.present = LTE_PagingUE_Identity_PR_s_TMSI; MME_CODE_TO_OCTET_STRING(ue_paging_identity.choice.s_tmsi.mme_code, &paging_record_p->ue_Identity.choice.s_TMSI.mmec); paging_record_p->ue_Identity.choice.s_TMSI.mmec.bits_unused = 0; @@ -3317,26 +3317,26 @@ uint8_t do_Paging(uint8_t Mod_id, uint8_t *buffer, ue_paging_identity_t ue_pagin &paging_record_p->ue_Identity.choice.s_TMSI.m_TMSI); paging_record_p->ue_Identity.choice.s_TMSI.m_TMSI.bits_unused = 0; } else if (ue_paging_identity.presenceMask == UE_PAGING_IDENTITY_imsi) { - paging_record_p->ue_Identity.present = PagingUE_Identity_PR_imsi; - IMSI_Digit_t imsi_digit[21]; + paging_record_p->ue_Identity.present = LTE_PagingUE_Identity_PR_imsi; + LTE_IMSI_Digit_t imsi_digit[21]; for (j = 0; j< ue_paging_identity.choice.imsi.length; j++) { /* IMSI size */ - imsi_digit[j] = (IMSI_Digit_t)ue_paging_identity.choice.imsi.buffer[j]; + imsi_digit[j] = (LTE_IMSI_Digit_t)ue_paging_identity.choice.imsi.buffer[j]; ASN_SEQUENCE_ADD(&paging_record_p->ue_Identity.choice.imsi.list, &imsi_digit[j]); } } /* set cn_domain */ if (cn_domain == CN_DOMAIN_PS) { - paging_record_p->cn_Domain = PagingRecord__cn_Domain_ps; + paging_record_p->cn_Domain = LTE_PagingRecord__cn_Domain_ps; } else { - paging_record_p->cn_Domain = PagingRecord__cn_Domain_cs; + paging_record_p->cn_Domain = LTE_PagingRecord__cn_Domain_cs; } /* add to list */ ASN_SEQUENCE_ADD(&pcch_msg.message.choice.c1.choice.paging.pagingRecordList->list, paging_record_p); LOG_D(RRC, "[eNB %d] do_Paging paging_record: cn_Domain %ld, ue_paging_identity.presenceMask %d, PagingRecordList.count %d\n", Mod_id, paging_record_p->cn_Domain, ue_paging_identity.presenceMask, pcch_msg.message.choice.c1.choice.paging.pagingRecordList->list.count); - enc_rval = uper_encode_to_buffer(&asn_DEF_PCCH_Message, NULL, (void*)&pcch_msg, buffer, RRC_BUF_SIZE); + enc_rval = uper_encode_to_buffer(&asn_DEF_LTE_PCCH_Message, NULL, (void*)&pcch_msg, buffer, RRC_BUF_SIZE); if(enc_rval.encoded == -1) { LOG_I(RRC, "[eNB AssertFatal]ASN1 message encoding failed (%s, %lu)!\n", @@ -3344,7 +3344,7 @@ uint8_t do_Paging(uint8_t Mod_id, uint8_t *buffer, ue_paging_identity_t ue_pagin return -1; } if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) { - xer_fprint(stdout, &asn_DEF_PCCH_Message, (void*)&pcch_msg); + xer_fprint(stdout, &asn_DEF_LTE_PCCH_Message, (void*)&pcch_msg); } return((enc_rval.encoded+7)/8); @@ -3354,20 +3354,20 @@ uint8_t do_ULInformationTransfer(uint8_t **buffer, uint32_t pdu_length, uint8_t { ssize_t encoded; - UL_DCCH_Message_t ul_dcch_msg; + LTE_UL_DCCH_Message_t ul_dcch_msg; - memset(&ul_dcch_msg, 0, sizeof(UL_DCCH_Message_t)); + memset(&ul_dcch_msg, 0, sizeof(LTE_UL_DCCH_Message_t)); - ul_dcch_msg.message.present = UL_DCCH_MessageType_PR_c1; - ul_dcch_msg.message.choice.c1.present = UL_DCCH_MessageType__c1_PR_ulInformationTransfer; - ul_dcch_msg.message.choice.c1.choice.ulInformationTransfer.criticalExtensions.present = ULInformationTransfer__criticalExtensions_PR_c1; - ul_dcch_msg.message.choice.c1.choice.ulInformationTransfer.criticalExtensions.choice.c1.present = DLInformationTransfer__criticalExtensions__c1_PR_dlInformationTransfer_r8; + ul_dcch_msg.message.present = LTE_UL_DCCH_MessageType_PR_c1; + ul_dcch_msg.message.choice.c1.present = LTE_UL_DCCH_MessageType__c1_PR_ulInformationTransfer; + ul_dcch_msg.message.choice.c1.choice.ulInformationTransfer.criticalExtensions.present = LTE_ULInformationTransfer__criticalExtensions_PR_c1; + ul_dcch_msg.message.choice.c1.choice.ulInformationTransfer.criticalExtensions.choice.c1.present = LTE_DLInformationTransfer__criticalExtensions__c1_PR_dlInformationTransfer_r8; ul_dcch_msg.message.choice.c1.choice.ulInformationTransfer.criticalExtensions.choice.c1.choice.ulInformationTransfer_r8.dedicatedInfoType.present = - ULInformationTransfer_r8_IEs__dedicatedInfoType_PR_dedicatedInfoNAS; + LTE_ULInformationTransfer_r8_IEs__dedicatedInfoType_PR_dedicatedInfoNAS; ul_dcch_msg.message.choice.c1.choice.ulInformationTransfer.criticalExtensions.choice.c1.choice.ulInformationTransfer_r8.dedicatedInfoType.choice.dedicatedInfoNAS.size = pdu_length; ul_dcch_msg.message.choice.c1.choice.ulInformationTransfer.criticalExtensions.choice.c1.choice.ulInformationTransfer_r8.dedicatedInfoType.choice.dedicatedInfoNAS.buf = pdu_buffer; - encoded = uper_encode_to_new_buffer (&asn_DEF_UL_DCCH_Message, NULL, (void*) &ul_dcch_msg, (void **) buffer); + encoded = uper_encode_to_new_buffer (&asn_DEF_LTE_UL_DCCH_Message, NULL, (void*) &ul_dcch_msg, (void **) buffer); return encoded; } @@ -3375,17 +3375,17 @@ uint8_t do_ULInformationTransfer(uint8_t **buffer, uint32_t pdu_length, uint8_t OAI_UECapability_t *fill_ue_capability(char *UE_EUTRA_Capability_xer_fname) { static OAI_UECapability_t UECapability; /* TODO declared static to allow returning this has an address should be allocated in a cleaner way. */ - static SupportedBandEUTRA_t Bandlist[4]; // the macro ASN_SEQUENCE_ADD() does not copy the source, but only stores a reference to it - static InterFreqBandInfo_t InterFreqBandInfo[4][4]; // the macro ASN_SEQUENCE_ADD() does not copy the source, but only stores a reference to it - static BandInfoEUTRA_t BandInfoEUTRA[4]; // the macro ASN_SEQUENCE_ADD() does not copy the source, but only stores a reference to it + static LTE_SupportedBandEUTRA_t Bandlist[4]; // the macro ASN_SEQUENCE_ADD() does not copy the source, but only stores a reference to it + static LTE_InterFreqBandInfo_t InterFreqBandInfo[4][4]; // the macro ASN_SEQUENCE_ADD() does not copy the source, but only stores a reference to it + static LTE_BandInfoEUTRA_t BandInfoEUTRA[4]; // the macro ASN_SEQUENCE_ADD() does not copy the source, but only stores a reference to it asn_enc_rval_t enc_rval; asn_dec_rval_t dec_rval; - long maxNumberROHC_ContextSessions = PDCP_Parameters__maxNumberROHC_ContextSessions_cs16; + long maxNumberROHC_ContextSessions = LTE_PDCP_Parameters__maxNumberROHC_ContextSessions_cs16; int i; - UE_EUTRA_Capability_t *UE_EUTRA_Capability; + LTE_UE_EUTRA_Capability_t *UE_EUTRA_Capability; char UE_EUTRA_Capability_xer[8192]; size_t size; @@ -3503,15 +3503,15 @@ OAI_UECapability_t *fill_ue_capability(char *UE_EUTRA_Capability_xer_fname) return(NULL); } - dec_rval = xer_decode(0, &asn_DEF_UE_EUTRA_Capability, (void*)UE_EUTRA_Capability, UE_EUTRA_Capability_xer, size); + dec_rval = xer_decode(0, &asn_DEF_LTE_UE_EUTRA_Capability, (void*)UE_EUTRA_Capability, UE_EUTRA_Capability_xer, size); assert(dec_rval.code == RC_OK); } UECapability.UE_EUTRA_Capability = UE_EUTRA_Capability; if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) { - xer_fprint(stdout,&asn_DEF_UE_EUTRA_Capability,(void *)UE_EUTRA_Capability); + xer_fprint(stdout,&asn_DEF_LTE_UE_EUTRA_Capability,(void *)UE_EUTRA_Capability); } - enc_rval = uper_encode_to_buffer(&asn_DEF_UE_EUTRA_Capability, + enc_rval = uper_encode_to_buffer(&asn_DEF_LTE_UE_EUTRA_Capability, NULL, (void*)UE_EUTRA_Capability, &UECapability.sdu[0], @@ -3534,7 +3534,7 @@ OAI_UECapability_t *fill_ue_capability(char *UE_EUTRA_Capability_xer_fname) char message_string[10000]; size_t message_string_size; - if ((message_string_size = xer_sprint(message_string, sizeof(message_string), &asn_DEF_UE_EUTRA_Capability, (void *)UE_EUTRA_Capability)) > 0) { + if ((message_string_size = xer_sprint(message_string, sizeof(message_string), &asn_DEF_LTE_UE_EUTRA_Capability, (void *)UE_EUTRA_Capability)) > 0) { MessageDef *msg_p; msg_p = itti_alloc_new_message_sized (TASK_RRC_UE, RRC_UE_EUTRA_CAPABILITY, message_string_size + sizeof (IttiMsgText)); diff --git a/openair2/RRC/LTE/MESSAGES/asn1_msg.h b/openair2/RRC/LTE/MESSAGES/asn1_msg.h index a4da38c019..690b3e8525 100644 --- a/openair2/RRC/LTE/MESSAGES/asn1_msg.h +++ b/openair2/RRC/LTE/MESSAGES/asn1_msg.h @@ -40,7 +40,7 @@ #include /* for _ASN_DEFAULT_STACK_MAX */ #include "RRC/LTE/rrc_defs.h" -#include "SL-DestinationInfoList-r12.h" +#include "LTE_SL-DestinationInfoList-r12.h" /* * The variant of the above function which dumps the BASIC-XER (XER_F_BASIC) @@ -110,7 +110,7 @@ uint8_t do_RRCConnectionRequest(uint8_t Mod_id, uint8_t *buffer,uint8_t *rv); @param discTxResourceReq Pointer to number of discovery messages for discovery announcements for which UE requests E-UTRAN to assign dedicated resources @param mode Indicates different requests from upper layers @returns Size of encoded bit stream in bytes*/ -uint8_t do_SidelinkUEInformation(uint8_t Mod_id, uint8_t *buffer, SL_DestinationInfoList_r12_t *destinationInfoList, long *discTxResourceReq, SL_TRIGGER_t mode); +uint8_t do_SidelinkUEInformation(uint8_t Mod_id, uint8_t *buffer, LTE_SL_DestinationInfoList_r12_t *destinationInfoList, long *discTxResourceReq, SL_TRIGGER_t mode); /** \brief Generate an RRCConnectionSetupComplete UL-DCCH-Message (UE) @param buffer Pointer to PER-encoded ASN.1 description of UL-DCCH-Message PDU @@ -149,8 +149,8 @@ do_RRCConnectionSetup( uint8_t* const buffer, const uint8_t transmission_mode, const uint8_t Transaction_id, - SRB_ToAddModList_t** SRB_configList, - struct PhysicalConfigDedicated** physicalConfigDedicated + LTE_SRB_ToAddModList_t** SRB_configList, + struct LTE_PhysicalConfigDedicated** physicalConfigDedicated ); /** @@ -180,26 +180,26 @@ do_RRCConnectionReconfiguration( const protocol_ctxt_t* const ctxt_pP, uint8_t *buffer, uint8_t Transaction_id, - SRB_ToAddModList_t *SRB_list, - DRB_ToAddModList_t *DRB_list, - DRB_ToReleaseList_t *DRB_list2, - struct SPS_Config *sps_Config, - struct PhysicalConfigDedicated *physicalConfigDedicated, - MeasObjectToAddModList_t *MeasObj_list, - ReportConfigToAddModList_t *ReportConfig_list, - 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, - struct RRCConnectionReconfiguration_r8_IEs__dedicatedInfoNASList* dedicatedInfoNASList, - SL_CommConfig_r12_t *sl_CommConfig, - SL_DiscConfig_r12_t *sl_DiscConfig -#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) - , SCellToAddMod_r10_t *SCell_config + LTE_SRB_ToAddModList_t *SRB_list, + LTE_DRB_ToAddModList_t *DRB_list, + LTE_DRB_ToReleaseList_t *DRB_list2, + struct LTE_SPS_Config *sps_Config, + struct LTE_PhysicalConfigDedicated *physicalConfigDedicated, + LTE_MeasObjectToAddModList_t *MeasObj_list, + LTE_ReportConfigToAddModList_t *ReportConfig_list, + LTE_QuantityConfig_t *quantityConfig, + LTE_MeasIdToAddModList_t *MeasId_list, + LTE_MAC_MainConfig_t *mac_MainConfig, + LTE_MeasGapConfig_t *measGapConfig, + LTE_MobilityControlInfo_t *mobilityInfo, + struct LTE_MeasConfig__speedStatePars *speedStatePars, + LTE_RSRP_Range_t *rsrp, + LTE_C_RNTI_t *cba_rnti, + struct LTE_RRCConnectionReconfiguration_r8_IEs__dedicatedInfoNASList* dedicatedInfoNASList, + LTE_SL_CommConfig_r12_t *sl_CommConfig, + LTE_SL_DiscConfig_r12_t *sl_DiscConfig +#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) + , LTE_SCellToAddMod_r10_t *SCell_config #endif ); /** @@ -222,8 +222,8 @@ do_RRCConnectionReestablishment( uint8_t* const buffer, const uint8_t transmission_mode, const uint8_t Transaction_id, - SRB_ToAddModList_t **SRB_configList, - struct PhysicalConfigDedicated **physicalConfigDedicated); + LTE_SRB_ToAddModList_t **SRB_configList, + struct LTE_PhysicalConfigDedicated **physicalConfigDedicated); /** \brief Generate an RRCConnectionReestablishmentReject DL-CCCH-Message (eNB). @@ -261,7 +261,7 @@ uint8_t do_RRCConnectionRelease(uint8_t Mod_id, uint8_t *buffer,int Transaction_ * @returns Size of encoded bit stream in bytes */ uint8_t do_MCCHMessage(uint8_t *buffer); -#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) /*** * \brief Generate an MCCH-Message (eNB). This routine configures MBSFNAreaConfiguration (PMCH-InfoList and Subframe Allocation for MBMS data) * @param buffer Pointer to PER-encoded ASN.1 description of MCCH-Message PDU @@ -270,8 +270,8 @@ uint8_t do_MCCHMessage(uint8_t *buffer); uint8_t do_MBSFNAreaConfig(uint8_t Mod_id, uint8_t sync_area, uint8_t *buffer, - MCCH_Message_t *mcch_message, - MBSFNAreaConfiguration_r9_t **mbsfnAreaConfiguration); + LTE_MCCH_Message_t *mcch_message, + LTE_MBSFNAreaConfiguration_r9_t **mbsfnAreaConfiguration); #endif uint8_t do_MeasurementReport(uint8_t Mod_id, uint8_t *buffer,int measid,int phy_id,long rsrp_s,long rsrq_s,long rsrp_t,long rsrq_t); @@ -282,7 +282,7 @@ uint8_t do_Paging(uint8_t Mod_id, uint8_t *buffer, ue_paging_identity_t ue_pagin uint8_t do_ULInformationTransfer(uint8_t **buffer, uint32_t pdu_length, uint8_t *pdu_buffer); -OAI_UECapability_t *fill_ue_capability(char *UE_EUTRA_Capability_xer); +OAI_UECapability_t *fill_ue_capability(char *LTE_UE_EUTRA_Capability_xer); uint8_t do_UECapabilityEnquiry( diff --git a/openair2/RRC/LTE/MESSAGES/asn1_msg_NB_IoT.c b/openair2/RRC/LTE/MESSAGES/asn1_msg_NB_IoT.c index 20962f3ca1..4c63db1d03 100644 --- a/openair2/RRC/LTE/MESSAGES/asn1_msg_NB_IoT.c +++ b/openair2/RRC/LTE/MESSAGES/asn1_msg_NB_IoT.c @@ -43,26 +43,26 @@ //#include for NB-IoT------------------- -#include "RRCConnectionRequest-NB.h" -#include "BCCH-DL-SCH-Message-NB.h" -#include "UL-CCCH-Message-NB.h" -#include "UL-DCCH-Message-NB.h" -#include "DL-CCCH-Message-NB.h" -#include "DL-DCCH-Message-NB.h" -#include "EstablishmentCause-NB-r13.h" -#include "RRCConnectionSetup-NB.h" -#include "SRB-ToAddModList-NB-r13.h" -#include "DRB-ToAddModList-NB-r13.h" +#include "LTE_RRCConnectionRequest-NB.h" +#include "LTE_BCCH-DL-SCH-Message-NB.h" +#include "LTE_UL-CCCH-Message-NB.h" +#include "LTE_UL-DCCH-Message-NB.h" +#include "LTE_DL-CCCH-Message-NB.h" +#include "LTE_DL-DCCH-Message-NB.h" +#include "LTE_EstablishmentCause-NB-r13.h" +#include "LTE_RRCConnectionSetup-NB.h" +#include "LTE_SRB-ToAddModList-NB-r13.h" +#include "LTE_DRB-ToAddModList-NB-r13.h" #include "RRC/LTE/defs_NB_IoT.h" -#include "RRCConnectionSetupComplete-NB.h" -#include "RRCConnectionReconfigurationComplete-NB.h" -#include "RRCConnectionReconfiguration-NB.h" -#include "MasterInformationBlock-NB.h" -#include "SystemInformation-NB.h" -#include "SystemInformationBlockType1.h" -#include "SIB-Type-NB-r13.h" -#include "RRCConnectionResume-NB.h" -#include "RRCConnectionReestablishment-NB.h" +#include "LTE_RRCConnectionSetupComplete-NB.h" +#include "LTE_RRCConnectionReconfigurationComplete-NB.h" +#include "LTE_RRCConnectionReconfiguration-NB.h" +#include "LTE_MasterInformationBlock-NB.h" +#include "LTE_SystemInformation-NB.h" +#include "LTE_SystemInformationBlockType1.h" +#include "LTE_SIB-Type-NB-r13.h" +#include "LTE_RRCConnectionResume-NB.h" +#include "LTE_RRCConnectionReestablishment-NB.h" #include "../defs_NB_IoT.h" //---------------------------------------- @@ -84,7 +84,7 @@ uint8_t do_MIB_NB_IoT( uint32_t hyper_frame) { asn_enc_rval_t enc_rval; - BCCH_BCH_Message_NB_t *mib_NB_IoT = &(carrier->mib_NB_IoT); + LTE_BCCH_BCH_Message_NB_t *mib_NB_IoT = &(carrier->mib_NB_IoT); /* * systemFrameNumber-MSB: (TS 36.331 pag 576) @@ -123,14 +123,14 @@ uint8_t do_MIB_NB_IoT( mib_NB_IoT->message.ab_Enabled_r13 = 0; //to be decided - mib_NB_IoT->message.operationModeInfo_r13.present = MasterInformationBlock_NB__operationModeInfo_r13_PR_inband_SamePCI_r13; + mib_NB_IoT->message.operationModeInfo_r13.present = LTE_MasterInformationBlock_NB__operationModeInfo_r13_PR_inband_SamePCI_r13; mib_NB_IoT->message.operationModeInfo_r13.choice.inband_SamePCI_r13.eutra_CRS_SequenceInfo_r13 = 0; printf("[MIB] Initialization of frame information,sfn_MSB %x, hsfn_LSB %x\n", (uint32_t)sfn_MSB, (uint32_t)hsfn_LSB); - enc_rval = uper_encode_to_buffer(&asn_DEF_BCCH_BCH_Message_NB, + enc_rval = uper_encode_to_buffer(&asn_DEF_LTE_BCCH_BCH_Message_NB, NULL, (void*)mib_NB_IoT, carrier->MIB_NB_IoT, @@ -155,16 +155,16 @@ uint8_t do_SIB1_NB_IoT(uint8_t Mod_id, int CC_id, uint32_t frame ) { - BCCH_DL_SCH_Message_NB_t *bcch_message= &(carrier->siblock1_NB_IoT); - SystemInformationBlockType1_NB_t **sib1_NB_IoT= &(carrier->sib1_NB_IoT); + LTE_BCCH_DL_SCH_Message_NB_t *bcch_message= &(carrier->siblock1_NB_IoT); + LTE_SystemInformationBlockType1_NB_t **sib1_NB_IoT= &(carrier->sib1_NB_IoT); asn_enc_rval_t enc_rval; - PLMN_IdentityInfo_NB_r13_t PLMN_identity_info_NB_IoT; - MCC_MNC_Digit_t dummy_mcc[3],dummy_mnc[3]; - SchedulingInfo_NB_r13_t *schedulingInfo_NB_IoT; - SIB_Type_NB_r13_t *sib_type_NB_IoT; + LTE_PLMN_IdentityInfo_NB_r13_t PLMN_identity_info_NB_IoT; + LTE_MCC_MNC_Digit_t dummy_mcc[3],dummy_mnc[3]; + LTE_SchedulingInfo_NB_r13_t *schedulingInfo_NB_IoT; + LTE_SIB_Type_NB_r13_t *sib_type_NB_IoT; long* attachWithoutPDN_Connectivity = NULL; @@ -175,9 +175,9 @@ uint8_t do_SIB1_NB_IoT(uint8_t Mod_id, int CC_id, eutraControlRegionSize = CALLOC(1,sizeof(long)); long systemInfoValueTagSI = 0; - memset(bcch_message,0,sizeof(BCCH_DL_SCH_Message_NB_t)); - bcch_message->message.present = BCCH_DL_SCH_MessageType_NB_PR_c1; - bcch_message->message.choice.c1.present = BCCH_DL_SCH_MessageType_NB__c1_PR_systemInformationBlockType1_r13; + memset(bcch_message,0,sizeof(LTE_BCCH_DL_SCH_Message_NB_t)); + bcch_message->message.present = LTE_BCCH_DL_SCH_MessageType_NB_PR_c1; + bcch_message->message.choice.c1.present = LTE_BCCH_DL_SCH_MessageType_NB__c1_PR_systemInformationBlockType1_r13; //allocation *sib1_NB_IoT = &bcch_message->message.choice.c1.choice.systemInformationBlockType1_r13; @@ -195,7 +195,7 @@ uint8_t do_SIB1_NB_IoT(uint8_t Mod_id, int CC_id, (*sib1_NB_IoT)->hyperSFN_MSB_r13.size = 1; (*sib1_NB_IoT)->hyperSFN_MSB_r13.bits_unused = 0; - memset(&PLMN_identity_info_NB_IoT,0,sizeof(PLMN_IdentityInfo_NB_r13_t)); + memset(&PLMN_identity_info_NB_IoT,0,sizeof(LTE_PLMN_IdentityInfo_NB_r13_t)); PLMN_identity_info_NB_IoT.plmn_Identity_r13.mcc = CALLOC(1,sizeof(*PLMN_identity_info_NB_IoT.plmn_Identity_r13.mcc)); memset(PLMN_identity_info_NB_IoT.plmn_Identity_r13.mcc,0,sizeof(*PLMN_identity_info_NB_IoT.plmn_Identity_r13.mcc)); @@ -251,7 +251,7 @@ uint8_t do_SIB1_NB_IoT(uint8_t Mod_id, int CC_id, } //still set to "notReserved" as in the previous case - PLMN_identity_info_NB_IoT.cellReservedForOperatorUse_r13=PLMN_IdentityInfo_NB_r13__cellReservedForOperatorUse_r13_notReserved; + PLMN_identity_info_NB_IoT.cellReservedForOperatorUse_r13=LTE_PLMN_IdentityInfo_NB_r13__cellReservedForOperatorUse_r13_notReserved; *attachWithoutPDN_Connectivity = 0; PLMN_identity_info_NB_IoT.attachWithoutPDN_Connectivity_r13 = attachWithoutPDN_Connectivity; @@ -289,16 +289,16 @@ uint8_t do_SIB1_NB_IoT(uint8_t Mod_id, int CC_id, (*sib1_NB_IoT)->cellAccessRelatedInfo_r13.cellIdentity_r13.bits_unused=4; //Still set to "notBarred" as in the previous case - (*sib1_NB_IoT)->cellAccessRelatedInfo_r13.cellBarred_r13=SystemInformationBlockType1_NB__cellAccessRelatedInfo_r13__cellBarred_r13_notBarred; + (*sib1_NB_IoT)->cellAccessRelatedInfo_r13.cellBarred_r13=LTE_SystemInformationBlockType1_NB__cellAccessRelatedInfo_r13__cellBarred_r13_notBarred; //Still Set to "notAllowed" like in the previous case - (*sib1_NB_IoT)->cellAccessRelatedInfo_r13.intraFreqReselection_r13=SystemInformationBlockType1_NB__cellAccessRelatedInfo_r13__intraFreqReselection_r13_notAllowed; + (*sib1_NB_IoT)->cellAccessRelatedInfo_r13.intraFreqReselection_r13=LTE_SystemInformationBlockType1_NB__cellAccessRelatedInfo_r13__intraFreqReselection_r13_notAllowed; (*sib1_NB_IoT)->cellSelectionInfo_r13.q_RxLevMin_r13=-65; //which value?? TS 36.331 V14.2.1 pag. 589 (*sib1_NB_IoT)->cellSelectionInfo_r13.q_QualMin_r13 = 0; //FIXME new parameter for SIB1-NB, not present in SIB1 (for cell reselection but if not used the UE should apply the default value) - (*sib1_NB_IoT)->p_Max_r13 = CALLOC(1, sizeof(P_Max_t)); + (*sib1_NB_IoT)->p_Max_r13 = CALLOC(1, sizeof(LTE_P_Max_t)); *((*sib1_NB_IoT)->p_Max_r13) = 23; //FIXME @@ -318,8 +318,8 @@ uint8_t do_SIB1_NB_IoT(uint8_t Mod_id, int CC_id, */ - (*sib1_NB_IoT)->downlinkBitmap_r13 = CALLOC(1, sizeof(struct DL_Bitmap_NB_r13)); - ((*sib1_NB_IoT)->downlinkBitmap_r13)->present= DL_Bitmap_NB_r13_PR_NOTHING; + (*sib1_NB_IoT)->downlinkBitmap_r13 = CALLOC(1, sizeof(struct LTE_DL_Bitmap_NB_r13)); + ((*sib1_NB_IoT)->downlinkBitmap_r13)->present= LTE_DL_Bitmap_NB_r13_PR_NOTHING; *eutraControlRegionSize = 1; (*sib1_NB_IoT)->eutraControlRegionSize_r13 = eutraControlRegionSize; @@ -328,22 +328,22 @@ uint8_t do_SIB1_NB_IoT(uint8_t Mod_id, int CC_id, *nrs_CRS_PowerOffset= 0; (*sib1_NB_IoT)->nrs_CRS_PowerOffset_r13 = nrs_CRS_PowerOffset; - schedulingInfo_NB_IoT = (SchedulingInfo_NB_r13_t*) malloc (3*sizeof(SchedulingInfo_NB_r13_t)); - sib_type_NB_IoT = (SIB_Type_NB_r13_t *) malloc (3*sizeof(SIB_Type_NB_r13_t)); + schedulingInfo_NB_IoT = (LTE_SchedulingInfo_NB_r13_t*) malloc (3*sizeof(LTE_SchedulingInfo_NB_r13_t)); + sib_type_NB_IoT = (LTE_SIB_Type_NB_r13_t *) malloc (3*sizeof(LTE_SIB_Type_NB_r13_t)); - memset(&schedulingInfo_NB_IoT[0],0,sizeof(SchedulingInfo_NB_r13_t)); - memset(&schedulingInfo_NB_IoT[1],0,sizeof(SchedulingInfo_NB_r13_t)); - memset(&schedulingInfo_NB_IoT[2],0,sizeof(SchedulingInfo_NB_r13_t)); - memset(&sib_type_NB_IoT[0],0,sizeof(SIB_Type_NB_r13_t)); - memset(&sib_type_NB_IoT[1],0,sizeof(SIB_Type_NB_r13_t)); - memset(&sib_type_NB_IoT[2],0,sizeof(SIB_Type_NB_r13_t)); + memset(&schedulingInfo_NB_IoT[0],0,sizeof(LTE_SchedulingInfo_NB_r13_t)); + memset(&schedulingInfo_NB_IoT[1],0,sizeof(LTE_SchedulingInfo_NB_r13_t)); + memset(&schedulingInfo_NB_IoT[2],0,sizeof(LTE_SchedulingInfo_NB_r13_t)); + memset(&sib_type_NB_IoT[0],0,sizeof(LTE_SIB_Type_NB_r13_t)); + memset(&sib_type_NB_IoT[1],0,sizeof(LTE_SIB_Type_NB_r13_t)); + memset(&sib_type_NB_IoT[2],0,sizeof(LTE_SIB_Type_NB_r13_t)); // Now, follow the scheduler SIB configuration // There is only one sib2+sib3 common setting - schedulingInfo_NB_IoT[0].si_Periodicity_r13=SchedulingInfo_NB_r13__si_Periodicity_r13_rf4096; - schedulingInfo_NB_IoT[0].si_RepetitionPattern_r13=SchedulingInfo_NB_r13__si_RepetitionPattern_r13_every2ndRF; //This Indicates the starting radio frames within the SI window used for SI message transmission. - schedulingInfo_NB_IoT[0].si_TB_r13= SchedulingInfo_NB_r13__si_TB_r13_b680;//208 bits + schedulingInfo_NB_IoT[0].si_Periodicity_r13=LTE_SchedulingInfo_NB_r13__si_Periodicity_r13_rf4096; + schedulingInfo_NB_IoT[0].si_RepetitionPattern_r13=LTE_SchedulingInfo_NB_r13__si_RepetitionPattern_r13_every2ndRF; //This Indicates the starting radio frames within the SI window used for SI message transmission. + schedulingInfo_NB_IoT[0].si_TB_r13= LTE_SchedulingInfo_NB_r13__si_TB_r13_b680;//208 bits // This is for SIB2/3 @@ -351,7 +351,7 @@ uint8_t do_SIB1_NB_IoT(uint8_t Mod_id, int CC_id, * in the first SystemInformation message * listed in the schedulingInfoList list. * */ - sib_type_NB_IoT[0]=SIB_Type_NB_r13_sibType3_NB_r13; + sib_type_NB_IoT[0]=LTE_SIB_Type_NB_r13_sibType3_NB_r13; ASN_SEQUENCE_ADD(&schedulingInfo_NB_IoT[0].sib_MappingInfo_r13.list,&sib_type_NB_IoT[0]); ASN_SEQUENCE_ADD(&(*sib1_NB_IoT)->schedulingInfoList_r13.list,&schedulingInfo_NB_IoT[0]); @@ -369,7 +369,7 @@ uint8_t do_SIB1_NB_IoT(uint8_t Mod_id, int CC_id, } //FIXME which value chose for the following parameter - (*sib1_NB_IoT)->si_WindowLength_r13=SystemInformationBlockType1_NB__si_WindowLength_r13_ms160; + (*sib1_NB_IoT)->si_WindowLength_r13=LTE_SystemInformationBlockType1_NB__si_WindowLength_r13_ms160; (*sib1_NB_IoT)->si_RadioFrameOffset_r13= 0; /*In Nb-IoT change/update of specific SI message can additionally be indicated by a SI message specific value tag @@ -377,17 +377,17 @@ uint8_t do_SIB1_NB_IoT(uint8_t Mod_id, int CC_id, *contained in systemInfoValueTagList_r13 **/ //FIXME correct? - (*sib1_NB_IoT)->systemInfoValueTagList_r13 = CALLOC(1, sizeof(struct SystemInfoValueTagList_NB_r13)); + (*sib1_NB_IoT)->systemInfoValueTagList_r13 = CALLOC(1, sizeof(struct LTE_SystemInfoValueTagList_NB_r13)); asn_set_empty(&(*sib1_NB_IoT)->systemInfoValueTagList_r13->list); ASN_SEQUENCE_ADD(&(*sib1_NB_IoT)->systemInfoValueTagList_r13->list,&systemInfoValueTagSI); if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) { - xer_fprint(stdout, &asn_DEF_BCCH_DL_SCH_Message_NB, (void*)bcch_message); + xer_fprint(stdout, &asn_DEF_LTE_BCCH_DL_SCH_Message_NB, (void*)bcch_message); } - enc_rval = uper_encode_to_buffer(&asn_DEF_BCCH_DL_SCH_Message_NB, + enc_rval = uper_encode_to_buffer(&asn_DEF_LTE_BCCH_DL_SCH_Message_NB, NULL, (void*)bcch_message, carrier->SIB1_NB_IoT, @@ -417,16 +417,16 @@ uint8_t do_SIB23_NB_IoT(uint8_t Mod_id, rrc_eNB_carrier_data_NB_IoT_t *carrier,//MP: this is already a carrier[CC_id] NbIoTRrcConfigurationReq *configuration ) //openair2/COMMON/rrc_messages_types.h { - struct SystemInformation_NB_r13_IEs__sib_TypeAndInfo_r13__Member *sib2_NB_part; - struct SystemInformation_NB_r13_IEs__sib_TypeAndInfo_r13__Member *sib3_NB_part; + struct LTE_SystemInformation_NB_r13_IEs__sib_TypeAndInfo_r13__Member *sib2_NB_part; + struct LTE_SystemInformation_NB_r13_IEs__sib_TypeAndInfo_r13__Member *sib3_NB_part; - BCCH_DL_SCH_Message_NB_t *bcch_message = &(carrier->systemInformation_NB_IoT); //is the systeminformation-->BCCH_DL_SCH_Message_NB - SystemInformationBlockType2_NB_r13_t *sib2_NB_IoT; - SystemInformationBlockType3_NB_r13_t *sib3_NB_IoT; + LTE_BCCH_DL_SCH_Message_NB_t *bcch_message = &(carrier->systemInformation_NB_IoT); //is the systeminformation-->BCCH_DL_SCH_Message_NB + LTE_SystemInformationBlockType2_NB_r13_t *sib2_NB_IoT; + LTE_SystemInformationBlockType3_NB_r13_t *sib3_NB_IoT; asn_enc_rval_t enc_rval; - RACH_Info_NB_r13_t rach_Info_NB_IoT; - NPRACH_Parameters_NB_r13_t *nprach_parameters; + LTE_RACH_Info_NB_r13_t rach_Info_NB_IoT; + LTE_NPRACH_Parameters_NB_r13_t *nprach_parameters; //optional long *connEstFailOffset = NULL; @@ -435,16 +435,16 @@ uint8_t do_SIB23_NB_IoT(uint8_t Mod_id, // RSRP_ThresholdsNPRACH_InfoList_NB_r13_t *rsrp_ThresholdsPrachInfoList; // RSRP_Range_t rsrp_range; - ACK_NACK_NumRepetitions_NB_r13_t ack_nack_repetition; - struct NPUSCH_ConfigCommon_NB_r13__dmrs_Config_r13 *dmrs_config; - struct DL_GapConfig_NB_r13 *dl_Gap; + LTE_ACK_NACK_NumRepetitions_NB_r13_t ack_nack_repetition; + struct LTE_NPUSCH_ConfigCommon_NB_r13__dmrs_Config_r13 *dmrs_config; + struct LTE_DL_GapConfig_NB_r13 *dl_Gap; long *srs_SubframeConfig; srs_SubframeConfig= CALLOC(1, sizeof(long)); if (bcch_message) { - memset(bcch_message,0,sizeof(BCCH_DL_SCH_Message_NB_t)); + memset(bcch_message,0,sizeof(LTE_BCCH_DL_SCH_Message_NB_t)); } else { LOG_E(RRC,"[NB-IoT %d] BCCH_MESSAGE_NB is null, exiting\n", Mod_id); exit(-1); @@ -464,13 +464,13 @@ uint8_t do_SIB23_NB_IoT(uint8_t Mod_id, LOG_I(RRC,"[NB-IoT %d] Configuration SIB2/3\n", Mod_id); - sib2_NB_part = CALLOC(1,sizeof(struct SystemInformation_NB_r13_IEs__sib_TypeAndInfo_r13__Member)); - sib3_NB_part = CALLOC(1,sizeof(struct SystemInformation_NB_r13_IEs__sib_TypeAndInfo_r13__Member)); - memset(sib2_NB_part,0,sizeof(struct SystemInformation_NB_r13_IEs__sib_TypeAndInfo_r13__Member)); - memset(sib3_NB_part,0,sizeof(struct SystemInformation_NB_r13_IEs__sib_TypeAndInfo_r13__Member)); + sib2_NB_part = CALLOC(1,sizeof(struct LTE_SystemInformation_NB_r13_IEs__sib_TypeAndInfo_r13__Member)); + sib3_NB_part = CALLOC(1,sizeof(struct LTE_SystemInformation_NB_r13_IEs__sib_TypeAndInfo_r13__Member)); + memset(sib2_NB_part,0,sizeof(struct LTE_SystemInformation_NB_r13_IEs__sib_TypeAndInfo_r13__Member)); + memset(sib3_NB_part,0,sizeof(struct LTE_SystemInformation_NB_r13_IEs__sib_TypeAndInfo_r13__Member)); - sib2_NB_part->present = SystemInformation_NB_r13_IEs__sib_TypeAndInfo_r13__Member_PR_sib2_r13; - sib3_NB_part->present = SystemInformation_NB_r13_IEs__sib_TypeAndInfo_r13__Member_PR_sib3_r13; + sib2_NB_part->present = LTE_SystemInformation_NB_r13_IEs__sib_TypeAndInfo_r13__Member_PR_sib2_r13; + sib3_NB_part->present = LTE_SystemInformation_NB_r13_IEs__sib_TypeAndInfo_r13__Member_PR_sib3_r13; //may bug if not correct allocation of memory carrier->sib2_NB_IoT = &sib2_NB_part->choice.sib2_r13; @@ -478,11 +478,11 @@ uint8_t do_SIB23_NB_IoT(uint8_t Mod_id, sib2_NB_IoT = carrier->sib2_NB_IoT; sib3_NB_IoT = carrier->sib3_NB_IoT; - nprach_parameters = (NPRACH_Parameters_NB_r13_t *) malloc (3*sizeof(NPRACH_Parameters_NB_r13_t)); + nprach_parameters = (LTE_NPRACH_Parameters_NB_r13_t *) malloc (3*sizeof(LTE_NPRACH_Parameters_NB_r13_t)); - memset(&nprach_parameters[0],0,sizeof(NPRACH_Parameters_NB_r13_t)); - memset(&nprach_parameters[1],0,sizeof(NPRACH_Parameters_NB_r13_t)); - memset(&nprach_parameters[2],0,sizeof(NPRACH_Parameters_NB_r13_t)); + memset(&nprach_parameters[0],0,sizeof(LTE_NPRACH_Parameters_NB_r13_t)); + memset(&nprach_parameters[1],0,sizeof(LTE_NPRACH_Parameters_NB_r13_t)); + memset(&nprach_parameters[2],0,sizeof(LTE_NPRACH_Parameters_NB_r13_t)); /// SIB2-NB----------------------------------------- @@ -582,7 +582,7 @@ uint8_t do_SIB23_NB_IoT(uint8_t Mod_id, /*OPTIONAL*/ - dmrs_config = CALLOC(1,sizeof(struct NPUSCH_ConfigCommon_NB_r13__dmrs_Config_r13)); + dmrs_config = CALLOC(1,sizeof(struct LTE_NPUSCH_ConfigCommon_NB_r13__dmrs_Config_r13)); dmrs_config->threeTone_CyclicShift_r13 = configuration->npusch_threeTone_CyclicShift_r13; dmrs_config->sixTone_CyclicShift_r13 = configuration->npusch_sixTone_CyclicShift_r13; @@ -606,7 +606,7 @@ uint8_t do_SIB23_NB_IoT(uint8_t Mod_id, //dl_GAP---------------------------------------------------------------------------------/*OPTIONAL*/ - dl_Gap = CALLOC(1,sizeof(struct DL_GapConfig_NB_r13)); + dl_Gap = CALLOC(1,sizeof(struct LTE_DL_GapConfig_NB_r13)); dl_Gap->dl_GapDurationCoeff_r13= configuration-> dl_GapDurationCoeff_NB; dl_Gap->dl_GapPeriodicity_r13= configuration->dl_GapPeriodicity_NB; dl_Gap->dl_GapThreshold_r13= configuration->dl_GapThreshold_NB; @@ -631,14 +631,14 @@ uint8_t do_SIB23_NB_IoT(uint8_t Mod_id, sib2_NB_IoT->freqInfo_r13.additionalSpectrumEmission_r13 = 1; sib2_NB_IoT->freqInfo_r13.ul_CarrierFreq_r13 = NULL; /*OPTIONAL*/ - sib2_NB_IoT->timeAlignmentTimerCommon_r13=TimeAlignmentTimer_infinity;//TimeAlignmentTimer_sf5120; + sib2_NB_IoT->timeAlignmentTimerCommon_r13=LTE_TimeAlignmentTimer_infinity;//TimeAlignmentTimer_sf5120; /*OPTIONAL*/ sib2_NB_IoT->multiBandInfoList_r13 = NULL; /// SIB3-NB------------------------------------------------------- - sib3_NB_IoT->cellReselectionInfoCommon_r13.q_Hyst_r13=SystemInformationBlockType3_NB_r13__cellReselectionInfoCommon_r13__q_Hyst_r13_dB4; + sib3_NB_IoT->cellReselectionInfoCommon_r13.q_Hyst_r13=LTE_SystemInformationBlockType3_NB_r13__cellReselectionInfoCommon_r13__q_Hyst_r13_dB4; sib3_NB_IoT->cellReselectionServingFreqInfo_r13.s_NonIntraSearch_r13=0; //or define in configuration? sib3_NB_IoT->intraFreqCellReselectionInfo_r13.q_RxLevMin_r13 = -70; @@ -656,10 +656,10 @@ uint8_t do_SIB23_NB_IoT(uint8_t Mod_id, ///BCCH message (generate the SI message) - bcch_message->message.present = BCCH_DL_SCH_MessageType_NB_PR_c1; - bcch_message->message.choice.c1.present = BCCH_DL_SCH_MessageType_NB__c1_PR_systemInformation_r13; + bcch_message->message.present = LTE_BCCH_DL_SCH_MessageType_NB_PR_c1; + bcch_message->message.choice.c1.present = LTE_BCCH_DL_SCH_MessageType_NB__c1_PR_systemInformation_r13; - bcch_message->message.choice.c1.choice.systemInformation_r13.criticalExtensions.present = SystemInformation_NB__criticalExtensions_PR_systemInformation_r13; + bcch_message->message.choice.c1.choice.systemInformation_r13.criticalExtensions.present = LTE_SystemInformation_NB__criticalExtensions_PR_systemInformation_r13; bcch_message->message.choice.c1.choice.systemInformation_r13.criticalExtensions.choice.systemInformation_r13.sib_TypeAndInfo_r13.list.count=0; ASN_SEQUENCE_ADD(&bcch_message->message.choice.c1.choice.systemInformation_r13.criticalExtensions.choice.systemInformation_r13.sib_TypeAndInfo_r13.list, @@ -668,9 +668,9 @@ uint8_t do_SIB23_NB_IoT(uint8_t Mod_id, sib3_NB_part); if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) { - xer_fprint(stdout, &asn_DEF_BCCH_DL_SCH_Message_NB, (void*)bcch_message); + xer_fprint(stdout, &asn_DEF_LTE_BCCH_DL_SCH_Message_NB, (void*)bcch_message); } - enc_rval = uper_encode_to_buffer(&asn_DEF_BCCH_DL_SCH_Message_NB, + enc_rval = uper_encode_to_buffer(&asn_DEF_LTE_BCCH_DL_SCH_Message_NB, NULL, (void*)bcch_message, carrier->SIB23_NB_IoT, @@ -704,8 +704,8 @@ uint8_t do_RRCConnectionSetup_NB_IoT( uint8_t* const buffer, //Srb0.Tx_buffer.Payload const uint8_t Transaction_id, const NB_IoT_DL_FRAME_PARMS* const frame_parms, // maybe not used - SRB_ToAddModList_NB_r13_t** SRB_configList_NB_IoT, //for both SRB1bis and SRB1 - struct PhysicalConfigDedicated_NB_r13** physicalConfigDedicated_NB_IoT + LTE_SRB_ToAddModList_NB_r13_t** SRB_configList_NB_IoT, //for both SRB1bis and SRB1 + struct LTE_PhysicalConfigDedicated_NB_r13** physicalConfigDedicated_NB_IoT ) { @@ -725,26 +725,26 @@ uint8_t do_RRCConnectionSetup_NB_IoT( // struct SRB_ToAddMod_NB_r13__rlc_Config_r13* SRB1_rlc_config_NB = NULL; // struct SRB_ToAddMod_NB_r13__logicalChannelConfig_r13* SRB1_lchan_config_NB = NULL; - struct SRB_ToAddMod_NB_r13* SRB1bis_config_NB_IoT = NULL; - struct SRB_ToAddMod_NB_r13__rlc_Config_r13* SRB1bis_rlc_config_NB_IoT = NULL; - struct SRB_ToAddMod_NB_r13__logicalChannelConfig_r13* SRB1bis_lchan_config_NB_IoT = NULL; + struct LTE_SRB_ToAddMod_NB_r13* SRB1bis_config_NB_IoT = NULL; + struct LTE_SRB_ToAddMod_NB_r13__rlc_Config_r13* SRB1bis_rlc_config_NB_IoT = NULL; + struct LTE_SRB_ToAddMod_NB_r13__logicalChannelConfig_r13* SRB1bis_lchan_config_NB_IoT = NULL; //No UL_specific parameters for NB-IoT in LogicalChanelConfig-NB - PhysicalConfigDedicated_NB_r13_t* physicalConfigDedicated2_NB_IoT = NULL; - DL_CCCH_Message_NB_t dl_ccch_msg_NB_IoT; - RRCConnectionSetup_NB_t* rrcConnectionSetup_NB_IoT = NULL; + LTE_PhysicalConfigDedicated_NB_r13_t* physicalConfigDedicated2_NB_IoT = NULL; + LTE_DL_CCCH_Message_NB_t dl_ccch_msg_NB_IoT; + LTE_RRCConnectionSetup_NB_t* rrcConnectionSetup_NB_IoT = NULL; - memset((void *)&dl_ccch_msg_NB_IoT,0,sizeof(DL_CCCH_Message_NB_t)); - dl_ccch_msg_NB_IoT.message.present = DL_CCCH_MessageType_NB_PR_c1; - dl_ccch_msg_NB_IoT.message.choice.c1.present = DL_CCCH_MessageType_NB__c1_PR_rrcConnectionSetup_r13; + memset((void *)&dl_ccch_msg_NB_IoT,0,sizeof(LTE_DL_CCCH_Message_NB_t)); + dl_ccch_msg_NB_IoT.message.present = LTE_DL_CCCH_MessageType_NB_PR_c1; + dl_ccch_msg_NB_IoT.message.choice.c1.present = LTE_DL_CCCH_MessageType_NB__c1_PR_rrcConnectionSetup_r13; rrcConnectionSetup_NB_IoT = &dl_ccch_msg_NB_IoT.message.choice.c1.choice.rrcConnectionSetup_r13; if (*SRB_configList_NB_IoT) { free(*SRB_configList_NB_IoT); } - *SRB_configList_NB_IoT = CALLOC(1,sizeof(SRB_ToAddModList_NB_r13_t)); + *SRB_configList_NB_IoT = CALLOC(1,sizeof(LTE_SRB_ToAddModList_NB_r13_t)); /// SRB1-------------------- { @@ -796,18 +796,18 @@ uint8_t do_RRCConnectionSetup_NB_IoT( SRB1bis_rlc_config_NB_IoT = CALLOC(1,sizeof(*SRB1bis_rlc_config_NB_IoT)); SRB1bis_config_NB_IoT->rlc_Config_r13 = SRB1bis_rlc_config_NB_IoT; - SRB1bis_rlc_config_NB_IoT->present = SRB_ToAddMod_NB_r13__rlc_Config_r13_PR_explicitValue; - SRB1bis_rlc_config_NB_IoT->choice.explicitValue.present=RLC_Config_NB_r13_PR_am;//MP: the only possible RLC config in NB_IoT + SRB1bis_rlc_config_NB_IoT->present = LTE_SRB_ToAddMod_NB_r13__rlc_Config_r13_PR_explicitValue; + SRB1bis_rlc_config_NB_IoT->choice.explicitValue.present=LTE_RLC_Config_NB_r13_PR_am;//MP: the only possible RLC config in NB_IoT - SRB1bis_rlc_config_NB_IoT->choice.explicitValue.choice.am.ul_AM_RLC_r13.t_PollRetransmit_r13 = T_PollRetransmit_NB_r13_ms25000; - SRB1bis_rlc_config_NB_IoT->choice.explicitValue.choice.am.ul_AM_RLC_r13.maxRetxThreshold_r13 = UL_AM_RLC_NB_r13__maxRetxThreshold_r13_t8; + SRB1bis_rlc_config_NB_IoT->choice.explicitValue.choice.am.ul_AM_RLC_r13.t_PollRetransmit_r13 = LTE_T_PollRetransmit_NB_r13_ms25000; + SRB1bis_rlc_config_NB_IoT->choice.explicitValue.choice.am.ul_AM_RLC_r13.maxRetxThreshold_r13 = LTE_UL_AM_RLC_NB_r13__maxRetxThreshold_r13_t8; //(musT be disabled--> SRB1 config pag 640 specs ) SRB1bis_rlc_config_NB_IoT->choice.explicitValue.choice.am.dl_AM_RLC_r13.enableStatusReportSN_Gap_r13 =NULL; SRB1bis_lchan_config_NB_IoT = CALLOC(1,sizeof(*SRB1bis_lchan_config_NB_IoT)); SRB1bis_config_NB_IoT->logicalChannelConfig_r13 = SRB1bis_lchan_config_NB_IoT; - SRB1bis_lchan_config_NB_IoT->present = SRB_ToAddMod_NB_r13__logicalChannelConfig_r13_PR_explicitValue; + SRB1bis_lchan_config_NB_IoT->present = LTE_SRB_ToAddMod_NB_r13__logicalChannelConfig_r13_PR_explicitValue; prioritySRB1bis = CALLOC(1, sizeof(long)); *prioritySRB1bis = 1; //same as SRB1? @@ -846,13 +846,13 @@ uint8_t do_RRCConnectionSetup_NB_IoT( //DL physicalConfigDedicated2_NB_IoT->carrierConfigDedicated_r13->dl_CarrierConfig_r13.dl_CarrierFreq_r13.carrierFreq_r13=0;//random value set - physicalConfigDedicated2_NB_IoT->carrierConfigDedicated_r13->dl_CarrierConfig_r13.downlinkBitmapNonAnchor_r13= CALLOC(1,sizeof(struct DL_CarrierConfigDedicated_NB_r13__downlinkBitmapNonAnchor_r13)); + physicalConfigDedicated2_NB_IoT->carrierConfigDedicated_r13->dl_CarrierConfig_r13.downlinkBitmapNonAnchor_r13= CALLOC(1,sizeof(struct LTE_DL_CarrierConfigDedicated_NB_r13__downlinkBitmapNonAnchor_r13)); physicalConfigDedicated2_NB_IoT->carrierConfigDedicated_r13->dl_CarrierConfig_r13.downlinkBitmapNonAnchor_r13->present= - DL_CarrierConfigDedicated_NB_r13__downlinkBitmapNonAnchor_r13_PR_useNoBitmap_r13; + LTE_DL_CarrierConfigDedicated_NB_r13__downlinkBitmapNonAnchor_r13_PR_useNoBitmap_r13; - physicalConfigDedicated2_NB_IoT->carrierConfigDedicated_r13->dl_CarrierConfig_r13.dl_GapNonAnchor_r13 = CALLOC(1,sizeof(struct DL_CarrierConfigDedicated_NB_r13__dl_GapNonAnchor_r13)); + physicalConfigDedicated2_NB_IoT->carrierConfigDedicated_r13->dl_CarrierConfig_r13.dl_GapNonAnchor_r13 = CALLOC(1,sizeof(struct LTE_DL_CarrierConfigDedicated_NB_r13__dl_GapNonAnchor_r13)); physicalConfigDedicated2_NB_IoT->carrierConfigDedicated_r13->dl_CarrierConfig_r13.dl_GapNonAnchor_r13->present = - DL_CarrierConfigDedicated_NB_r13__dl_GapNonAnchor_r13_PR_useNoGap_r13; + LTE_DL_CarrierConfigDedicated_NB_r13__dl_GapNonAnchor_r13_PR_useNoGap_r13; physicalConfigDedicated2_NB_IoT->carrierConfigDedicated_r13->dl_CarrierConfig_r13.inbandCarrierInfo_r13= NULL; @@ -877,8 +877,8 @@ uint8_t do_RRCConnectionSetup_NB_IoT( //Fill the rrcConnectionSetup-NB message rrcConnectionSetup_NB_IoT->rrc_TransactionIdentifier = Transaction_id; //input value - rrcConnectionSetup_NB_IoT->criticalExtensions.present = RRCConnectionSetup_NB__criticalExtensions_PR_c1; - rrcConnectionSetup_NB_IoT->criticalExtensions.choice.c1.present =RRCConnectionSetup_NB__criticalExtensions__c1_PR_rrcConnectionSetup_r13 ; + rrcConnectionSetup_NB_IoT->criticalExtensions.present = LTE_RRCConnectionSetup_NB__criticalExtensions_PR_c1; + rrcConnectionSetup_NB_IoT->criticalExtensions.choice.c1.present =LTE_RRCConnectionSetup_NB__criticalExtensions__c1_PR_rrcConnectionSetup_r13 ; //MP: carry only SRB1bis at the moment and phyConfigDedicated rrcConnectionSetup_NB_IoT->criticalExtensions.choice.c1.choice.rrcConnectionSetup_r13.radioResourceConfigDedicated_r13.srb_ToAddModList_r13 = *SRB_configList_NB_IoT; rrcConnectionSetup_NB_IoT->criticalExtensions.choice.c1.choice.rrcConnectionSetup_r13.radioResourceConfigDedicated_r13.drb_ToAddModList_r13 = NULL; @@ -888,9 +888,9 @@ uint8_t do_RRCConnectionSetup_NB_IoT( rrcConnectionSetup_NB_IoT->criticalExtensions.choice.c1.choice.rrcConnectionSetup_r13.radioResourceConfigDedicated_r13.mac_MainConfig_r13 = NULL; if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) { - xer_fprint(stdout, &asn_DEF_DL_CCCH_Message_NB, (void*)&dl_ccch_msg_NB_IoT); + xer_fprint(stdout, &asn_DEF_LTE_DL_CCCH_Message_NB, (void*)&dl_ccch_msg_NB_IoT); } - enc_rval = uper_encode_to_buffer(&asn_DEF_DL_CCCH_Message_NB, + enc_rval = uper_encode_to_buffer(&asn_DEF_LTE_DL_CCCH_Message_NB, NULL, (void*)&dl_ccch_msg_NB_IoT, buffer, @@ -917,32 +917,32 @@ uint8_t do_SecurityModeCommand_NB_IoT( const uint8_t cipheringAlgorithm, const uint8_t integrityProtAlgorithm) { - DL_DCCH_Message_NB_t dl_dcch_msg_NB_IoT; + LTE_DL_DCCH_Message_NB_t dl_dcch_msg_NB_IoT; asn_enc_rval_t enc_rval; - memset(&dl_dcch_msg_NB_IoT,0,sizeof(DL_DCCH_Message_NB_t)); + memset(&dl_dcch_msg_NB_IoT,0,sizeof(LTE_DL_DCCH_Message_NB_t)); - dl_dcch_msg_NB_IoT.message.present = DL_DCCH_MessageType_NB_PR_c1; - dl_dcch_msg_NB_IoT.message.choice.c1.present = DL_DCCH_MessageType_NB__c1_PR_securityModeCommand_r13; + dl_dcch_msg_NB_IoT.message.present = LTE_DL_DCCH_MessageType_NB_PR_c1; + dl_dcch_msg_NB_IoT.message.choice.c1.present = LTE_DL_DCCH_MessageType_NB__c1_PR_securityModeCommand_r13; dl_dcch_msg_NB_IoT.message.choice.c1.choice.securityModeCommand_r13.rrc_TransactionIdentifier = Transaction_id; - dl_dcch_msg_NB_IoT.message.choice.c1.choice.securityModeCommand_r13.criticalExtensions.present = SecurityModeCommand__criticalExtensions_PR_c1; + dl_dcch_msg_NB_IoT.message.choice.c1.choice.securityModeCommand_r13.criticalExtensions.present = LTE_SecurityModeCommand__criticalExtensions_PR_c1; dl_dcch_msg_NB_IoT.message.choice.c1.choice.securityModeCommand_r13.criticalExtensions.choice.c1.present = - SecurityModeCommand__criticalExtensions__c1_PR_securityModeCommand_r8; + LTE_SecurityModeCommand__criticalExtensions__c1_PR_securityModeCommand_r8; // the two following information could be based on the mod_id dl_dcch_msg_NB_IoT.message.choice.c1.choice.securityModeCommand_r13.criticalExtensions.choice.c1.choice.securityModeCommand_r8.securityConfigSMC.securityAlgorithmConfig.cipheringAlgorithm - = (CipheringAlgorithm_r12_t)cipheringAlgorithm; //bug solved + = (LTE_CipheringAlgorithm_r12_t)cipheringAlgorithm; //bug solved dl_dcch_msg_NB_IoT.message.choice.c1.choice.securityModeCommand_r13.criticalExtensions.choice.c1.choice.securityModeCommand_r8.securityConfigSMC.securityAlgorithmConfig.integrityProtAlgorithm - = (e_SecurityAlgorithmConfig__integrityProtAlgorithm)integrityProtAlgorithm; + = (e_LTE_SecurityAlgorithmConfig__integrityProtAlgorithm)integrityProtAlgorithm; //only changed "asn_DEF_DL_DCCH_Message_NB" if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) { - xer_fprint(stdout, &asn_DEF_DL_DCCH_Message_NB, (void*)&dl_dcch_msg_NB_IoT); + xer_fprint(stdout, &asn_DEF_LTE_DL_DCCH_Message_NB, (void*)&dl_dcch_msg_NB_IoT); } - enc_rval = uper_encode_to_buffer(&asn_DEF_DL_DCCH_Message_NB, + enc_rval = uper_encode_to_buffer(&asn_DEF_LTE_DL_DCCH_Message_NB, NULL, (void*)&dl_dcch_msg_NB_IoT, buffer, @@ -983,28 +983,28 @@ uint8_t do_UECapabilityEnquiry_NB_IoT( { - DL_DCCH_Message_NB_t dl_dcch_msg_NB_IoT; + LTE_DL_DCCH_Message_NB_t dl_dcch_msg_NB_IoT; //no RAT type in NB-IoT asn_enc_rval_t enc_rval; - memset(&dl_dcch_msg_NB_IoT,0,sizeof(DL_DCCH_Message_NB_t)); + memset(&dl_dcch_msg_NB_IoT,0,sizeof(LTE_DL_DCCH_Message_NB_t)); - dl_dcch_msg_NB_IoT.message.present = DL_DCCH_MessageType_NB_PR_c1; - dl_dcch_msg_NB_IoT.message.choice.c1.present = DL_DCCH_MessageType_NB__c1_PR_ueCapabilityEnquiry_r13; + dl_dcch_msg_NB_IoT.message.present = LTE_DL_DCCH_MessageType_NB_PR_c1; + dl_dcch_msg_NB_IoT.message.choice.c1.present = LTE_DL_DCCH_MessageType_NB__c1_PR_ueCapabilityEnquiry_r13; dl_dcch_msg_NB_IoT.message.choice.c1.choice.ueCapabilityEnquiry_r13.rrc_TransactionIdentifier = Transaction_id; - dl_dcch_msg_NB_IoT.message.choice.c1.choice.ueCapabilityEnquiry_r13.criticalExtensions.present = UECapabilityEnquiry_NB__criticalExtensions_PR_c1; + dl_dcch_msg_NB_IoT.message.choice.c1.choice.ueCapabilityEnquiry_r13.criticalExtensions.present = LTE_UECapabilityEnquiry_NB__criticalExtensions_PR_c1; dl_dcch_msg_NB_IoT.message.choice.c1.choice.ueCapabilityEnquiry_r13.criticalExtensions.choice.c1.present = - UECapabilityEnquiry_NB__criticalExtensions__c1_PR_ueCapabilityEnquiry_r13; + LTE_UECapabilityEnquiry_NB__criticalExtensions__c1_PR_ueCapabilityEnquiry_r13; //no ue_CapabilityRequest (list of RAT_Type) //only changed "asn_DEF_DL_DCCH_Message_NB" if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) { - xer_fprint(stdout, &asn_DEF_DL_DCCH_Message_NB, (void*)&dl_dcch_msg_NB_IoT); + xer_fprint(stdout, &asn_DEF_LTE_DL_DCCH_Message_NB, (void*)&dl_dcch_msg_NB_IoT); } - enc_rval = uper_encode_to_buffer(&asn_DEF_DL_DCCH_Message_NB, + enc_rval = uper_encode_to_buffer(&asn_DEF_LTE_DL_DCCH_Message_NB, NULL, (void*)&dl_dcch_msg_NB_IoT, buffer, @@ -1042,32 +1042,32 @@ uint16_t do_RRCConnectionReconfiguration_NB_IoT( const protocol_ctxt_t* const ctxt_pP, uint8_t *buffer, uint8_t Transaction_id, - SRB_ToAddModList_NB_r13_t *SRB1_list_NB, //SRB_ConfigList2 (default)--> only SRB1 - DRB_ToAddModList_NB_r13_t *DRB_list_NB_IoT, //DRB_ConfigList (default) - DRB_ToReleaseList_NB_r13_t *DRB_list2_NB_IoT, //is NULL when passed - struct PhysicalConfigDedicated_NB_r13 *physicalConfigDedicated_NB_IoT, - MAC_MainConfig_NB_r13_t *mac_MainConfig_NB_IoT, - struct RRCConnectionReconfiguration_NB_r13_IEs__dedicatedInfoNASList_r13* dedicatedInfoNASList_NB_IoT) + LTE_SRB_ToAddModList_NB_r13_t *SRB1_list_NB, //SRB_ConfigList2 (default)--> only SRB1 + LTE_DRB_ToAddModList_NB_r13_t *DRB_list_NB_IoT, //DRB_ConfigList (default) + LTE_DRB_ToReleaseList_NB_r13_t *DRB_list2_NB_IoT, //is NULL when passed + struct LTE_PhysicalConfigDedicated_NB_r13 *physicalConfigDedicated_NB_IoT, + LTE_MAC_MainConfig_NB_r13_t *mac_MainConfig_NB_IoT, + struct LTE_RRCConnectionReconfiguration_NB_r13_IEs__dedicatedInfoNASList_r13* dedicatedInfoNASList_NB_IoT) { //check on DRB_list if contains more than 2 DRB? asn_enc_rval_t enc_rval; - DL_DCCH_Message_NB_t dl_dcch_msg_NB_IoT; - RRCConnectionReconfiguration_NB_t *rrcConnectionReconfiguration_NB; + LTE_DL_DCCH_Message_NB_t dl_dcch_msg_NB_IoT; + LTE_RRCConnectionReconfiguration_NB_t *rrcConnectionReconfiguration_NB; - memset(&dl_dcch_msg_NB_IoT,0,sizeof(DL_DCCH_Message_NB_t)); + memset(&dl_dcch_msg_NB_IoT,0,sizeof(LTE_DL_DCCH_Message_NB_t)); - dl_dcch_msg_NB_IoT.message.present = DL_DCCH_MessageType_NB_PR_c1; - dl_dcch_msg_NB_IoT.message.choice.c1.present = DL_DCCH_MessageType_NB__c1_PR_rrcConnectionReconfiguration_r13; + dl_dcch_msg_NB_IoT.message.present = LTE_DL_DCCH_MessageType_NB_PR_c1; + dl_dcch_msg_NB_IoT.message.choice.c1.present = LTE_DL_DCCH_MessageType_NB__c1_PR_rrcConnectionReconfiguration_r13; rrcConnectionReconfiguration_NB = &dl_dcch_msg_NB_IoT.message.choice.c1.choice.rrcConnectionReconfiguration_r13; // RRCConnectionReconfiguration rrcConnectionReconfiguration_NB->rrc_TransactionIdentifier = Transaction_id; - rrcConnectionReconfiguration_NB->criticalExtensions.present = RRCConnectionReconfiguration_NB__criticalExtensions_PR_c1; - rrcConnectionReconfiguration_NB->criticalExtensions.choice.c1.present =RRCConnectionReconfiguration_NB__criticalExtensions__c1_PR_rrcConnectionReconfiguration_r13 ; + rrcConnectionReconfiguration_NB->criticalExtensions.present = LTE_RRCConnectionReconfiguration_NB__criticalExtensions_PR_c1; + rrcConnectionReconfiguration_NB->criticalExtensions.choice.c1.present =LTE_RRCConnectionReconfiguration_NB__criticalExtensions__c1_PR_rrcConnectionReconfiguration_r13 ; //RAdioResourceconfigDedicated rrcConnectionReconfiguration_NB->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r13.radioResourceConfigDedicated_r13 = @@ -1083,7 +1083,7 @@ uint16_t do_RRCConnectionReconfiguration_NB_IoT( rrcConnectionReconfiguration_NB->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r13.radioResourceConfigDedicated_r13->mac_MainConfig_r13 = CALLOC(1, sizeof(*rrcConnectionReconfiguration_NB->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r13.radioResourceConfigDedicated_r13->mac_MainConfig_r13)); rrcConnectionReconfiguration_NB->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r13.radioResourceConfigDedicated_r13->mac_MainConfig_r13->present - =RadioResourceConfigDedicated_NB_r13__mac_MainConfig_r13_PR_explicitValue_r13; + =LTE_RadioResourceConfigDedicated_NB_r13__mac_MainConfig_r13_PR_explicitValue_r13; //why memcopy only this one? memcpy(&rrcConnectionReconfiguration_NB->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r13.radioResourceConfigDedicated_r13->mac_MainConfig_r13->choice.explicitValue_r13, mac_MainConfig_NB_IoT, sizeof(*mac_MainConfig_NB_IoT)); @@ -1099,7 +1099,7 @@ uint16_t do_RRCConnectionReconfiguration_NB_IoT( //mainly used for cell-reselection/handover purposes?? rrcConnectionReconfiguration_NB->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r13.fullConfig_r13 = NULL; - enc_rval = uper_encode_to_buffer(&asn_DEF_DL_DCCH_Message_NB, + enc_rval = uper_encode_to_buffer(&asn_DEF_LTE_DL_DCCH_Message_NB, NULL, (void*)&dl_dcch_msg_NB_IoT, buffer, @@ -1111,7 +1111,7 @@ uint16_t do_RRCConnectionReconfiguration_NB_IoT( //changed only asn_DEF_DL_DCCH_Message_NB if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) { - xer_fprint(stdout,&asn_DEF_DL_DCCH_Message_NB,(void*)&dl_dcch_msg_NB_IoT); + xer_fprint(stdout,&asn_DEF_LTE_DL_DCCH_Message_NB,(void*)&dl_dcch_msg_NB_IoT); } //#if defined(ENABLE_ITTI) @@ -1131,22 +1131,22 @@ uint8_t do_RRCConnectionReestablishmentReject_NB_IoT( asn_enc_rval_t enc_rval; - DL_CCCH_Message_NB_t dl_ccch_msg_NB_IoT; - RRCConnectionReestablishmentReject_t *rrcConnectionReestablishmentReject; + LTE_DL_CCCH_Message_NB_t dl_ccch_msg_NB_IoT; + LTE_RRCConnectionReestablishmentReject_t *rrcConnectionReestablishmentReject; - memset((void *)&dl_ccch_msg_NB_IoT,0,sizeof(DL_CCCH_Message_NB_t)); - dl_ccch_msg_NB_IoT.message.present = DL_CCCH_MessageType_NB_PR_c1; - dl_ccch_msg_NB_IoT.message.choice.c1.present = DL_CCCH_MessageType_NB__c1_PR_rrcConnectionReestablishmentReject_r13; + memset((void *)&dl_ccch_msg_NB_IoT,0,sizeof(LTE_DL_CCCH_Message_NB_t)); + dl_ccch_msg_NB_IoT.message.present = LTE_DL_CCCH_MessageType_NB_PR_c1; + dl_ccch_msg_NB_IoT.message.choice.c1.present = LTE_DL_CCCH_MessageType_NB__c1_PR_rrcConnectionReestablishmentReject_r13; rrcConnectionReestablishmentReject = &dl_ccch_msg_NB_IoT.message.choice.c1.choice.rrcConnectionReestablishmentReject_r13; // RRCConnectionReestablishmentReject //exactly the same as LTE - rrcConnectionReestablishmentReject->criticalExtensions.present = RRCConnectionReestablishmentReject__criticalExtensions_PR_rrcConnectionReestablishmentReject_r8; + rrcConnectionReestablishmentReject->criticalExtensions.present = LTE_RRCConnectionReestablishmentReject__criticalExtensions_PR_rrcConnectionReestablishmentReject_r8; //Only change in "asn_DEF_DL_CCCH_Message_NB" if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) { - xer_fprint(stdout, &asn_DEF_DL_CCCH_Message_NB, (void*)&dl_ccch_msg_NB_IoT); + xer_fprint(stdout, &asn_DEF_LTE_DL_CCCH_Message_NB, (void*)&dl_ccch_msg_NB_IoT); } - enc_rval = uper_encode_to_buffer(&asn_DEF_DL_CCCH_Message_NB, + enc_rval = uper_encode_to_buffer(&asn_DEF_LTE_DL_CCCH_Message_NB, NULL, (void*)&dl_ccch_msg_NB_IoT, buffer, @@ -1163,7 +1163,7 @@ uint8_t do_RRCConnectionReestablishmentReject_NB_IoT( char message_string[20000]; size_t message_string_size; - if ((message_string_size = xer_sprint(message_string, sizeof(message_string), &asn_DEF_DL_CCCH_Message_NB, (void *) &dl_ccch_msg_NB_IoT)) > 0) { + if ((message_string_size = xer_sprint(message_string, sizeof(message_string), &asn_DEF_LTE_DL_CCCH_Message_NB, (void *) &dl_ccch_msg_NB_IoT)) > 0) { MessageDef *msg_p; msg_p = itti_alloc_new_message_sized (TASK_RRC_ENB_NB_IoT, RRC_DL_CCCH, message_string_size + sizeof (IttiMsgText)); @@ -1193,17 +1193,17 @@ uint8_t do_RRCConnectionReject_NB_IoT( asn_enc_rval_t enc_rval; - DL_CCCH_Message_NB_t dl_ccch_msg_NB_IoT; - RRCConnectionReject_NB_t *rrcConnectionReject_NB_IoT; + LTE_DL_CCCH_Message_NB_t dl_ccch_msg_NB_IoT; + LTE_RRCConnectionReject_NB_t *rrcConnectionReject_NB_IoT; - memset((void *)&dl_ccch_msg_NB_IoT,0,sizeof(DL_CCCH_Message_NB_t)); - dl_ccch_msg_NB_IoT.message.present = DL_CCCH_MessageType_NB_PR_c1; - dl_ccch_msg_NB_IoT.message.choice.c1.present = DL_CCCH_MessageType_NB__c1_PR_rrcConnectionReject_r13; + memset((void *)&dl_ccch_msg_NB_IoT,0,sizeof(LTE_DL_CCCH_Message_NB_t)); + dl_ccch_msg_NB_IoT.message.present = LTE_DL_CCCH_MessageType_NB_PR_c1; + dl_ccch_msg_NB_IoT.message.choice.c1.present = LTE_DL_CCCH_MessageType_NB__c1_PR_rrcConnectionReject_r13; rrcConnectionReject_NB_IoT = &dl_ccch_msg_NB_IoT.message.choice.c1.choice.rrcConnectionReject_r13; // RRCConnectionReject-NB_IoT - rrcConnectionReject_NB_IoT->criticalExtensions.present = RRCConnectionReject_NB__criticalExtensions_PR_c1; - rrcConnectionReject_NB_IoT->criticalExtensions.choice.c1.present = RRCConnectionReject_NB__criticalExtensions__c1_PR_rrcConnectionReject_r13; + rrcConnectionReject_NB_IoT->criticalExtensions.present = LTE_RRCConnectionReject_NB__criticalExtensions_PR_c1; + rrcConnectionReject_NB_IoT->criticalExtensions.choice.c1.present = LTE_RRCConnectionReject_NB__criticalExtensions__c1_PR_rrcConnectionReject_r13; /* let's put an extended wait time of 1s for the moment */ rrcConnectionReject_NB_IoT->criticalExtensions.choice.c1.choice.rrcConnectionReject_r13.extendedWaitTime_r13 = 1; //new-use of suspend indication @@ -1211,13 +1211,13 @@ uint8_t do_RRCConnectionReject_NB_IoT( rrcConnectionReject_NB_IoT->criticalExtensions.choice.c1.choice.rrcConnectionReject_r13.rrc_SuspendIndication_r13= CALLOC(1, sizeof(long)); *(rrcConnectionReject_NB_IoT->criticalExtensions.choice.c1.choice.rrcConnectionReject_r13.rrc_SuspendIndication_r13)= - RRCConnectionReject_NB_r13_IEs__rrc_SuspendIndication_r13_true; + LTE_RRCConnectionReject_NB_r13_IEs__rrc_SuspendIndication_r13_true; //Only Modified "asn_DEF_DL_CCCH_Message_NB" if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) { - xer_fprint(stdout, &asn_DEF_DL_CCCH_Message_NB, (void*)&dl_ccch_msg_NB_IoT); + xer_fprint(stdout, &asn_DEF_LTE_DL_CCCH_Message_NB, (void*)&dl_ccch_msg_NB_IoT); } - enc_rval = uper_encode_to_buffer(&asn_DEF_DL_CCCH_Message_NB, + enc_rval = uper_encode_to_buffer(&asn_DEF_LTE_DL_CCCH_Message_NB, NULL, (void*)&dl_ccch_msg_NB_IoT, buffer, @@ -1233,7 +1233,7 @@ uint8_t do_RRCConnectionReject_NB_IoT( char message_string[20000]; size_t message_string_size; - if ((message_string_size = xer_sprint(message_string, sizeof(message_string), &asn_DEF_DL_CCCH_Message_NB, (void *) &dl_ccch_msg_NB_IoT)) > 0) { + if ((message_string_size = xer_sprint(message_string, sizeof(message_string), &asn_DEF_LTE_DL_CCCH_Message_NB, (void *) &dl_ccch_msg_NB_IoT)) > 0) { MessageDef *msg_p; msg_p = itti_alloc_new_message_sized (TASK_RRC_ENB_NB_IoT, RRC_DL_CCCH, message_string_size + sizeof (IttiMsgText)); @@ -1269,19 +1269,19 @@ uint8_t do_DLInformationTransfer_NB_IoT( { ssize_t encoded; - DL_DCCH_Message_NB_t dl_dcch_msg_NB_IoT; + LTE_DL_DCCH_Message_NB_t dl_dcch_msg_NB_IoT; - memset(&dl_dcch_msg_NB_IoT, 0, sizeof(DL_DCCH_Message_NB_t)); + memset(&dl_dcch_msg_NB_IoT, 0, sizeof(LTE_DL_DCCH_Message_NB_t)); - dl_dcch_msg_NB_IoT.message.present = DL_DCCH_MessageType_NB_PR_c1; - dl_dcch_msg_NB_IoT.message.choice.c1.present = DL_DCCH_MessageType_NB__c1_PR_dlInformationTransfer_r13; + dl_dcch_msg_NB_IoT.message.present = LTE_DL_DCCH_MessageType_NB_PR_c1; + dl_dcch_msg_NB_IoT.message.choice.c1.present = LTE_DL_DCCH_MessageType_NB__c1_PR_dlInformationTransfer_r13; dl_dcch_msg_NB_IoT.message.choice.c1.choice.dlInformationTransfer_r13.rrc_TransactionIdentifier = transaction_id; - dl_dcch_msg_NB_IoT.message.choice.c1.choice.dlInformationTransfer_r13.criticalExtensions.present = DLInformationTransfer_NB__criticalExtensions_PR_c1; - dl_dcch_msg_NB_IoT.message.choice.c1.choice.dlInformationTransfer_r13.criticalExtensions.choice.c1.present = DLInformationTransfer_NB__criticalExtensions__c1_PR_dlInformationTransfer_r13; + dl_dcch_msg_NB_IoT.message.choice.c1.choice.dlInformationTransfer_r13.criticalExtensions.present = LTE_DLInformationTransfer_NB__criticalExtensions_PR_c1; + dl_dcch_msg_NB_IoT.message.choice.c1.choice.dlInformationTransfer_r13.criticalExtensions.choice.c1.present = LTE_DLInformationTransfer_NB__criticalExtensions__c1_PR_dlInformationTransfer_r13; dl_dcch_msg_NB_IoT.message.choice.c1.choice.dlInformationTransfer_r13.criticalExtensions.choice.c1.choice.dlInformationTransfer_r13.dedicatedInfoNAS_r13.size = pdu_length; dl_dcch_msg_NB_IoT.message.choice.c1.choice.dlInformationTransfer_r13.criticalExtensions.choice.c1.choice.dlInformationTransfer_r13.dedicatedInfoNAS_r13.buf = pdu_buffer; - encoded = uper_encode_to_new_buffer (&asn_DEF_DL_DCCH_Message_NB, NULL, (void*) &dl_dcch_msg_NB_IoT, (void **) buffer); + encoded = uper_encode_to_new_buffer (&asn_DEF_LTE_DL_DCCH_Message_NB, NULL, (void*) &dl_dcch_msg_NB_IoT, (void **) buffer); //only change in "asn_DEF_DL_DCCH_Message_NB" #if defined(ENABLE_ITTI) @@ -1290,7 +1290,7 @@ uint8_t do_DLInformationTransfer_NB_IoT( char message_string[10000]; size_t message_string_size; - if ((message_string_size = xer_sprint(message_string, sizeof(message_string), &asn_DEF_DL_DCCH_Message_NB, (void *)&dl_dcch_msg_NB_IoT)) > 0) { + if ((message_string_size = xer_sprint(message_string, sizeof(message_string), &asn_DEF_LTE_DL_DCCH_Message_NB, (void *)&dl_dcch_msg_NB_IoT)) > 0) { MessageDef *msg_p; msg_p = itti_alloc_new_message_sized (TASK_RRC_ENB_NB_IoT, RRC_DL_DCCH, message_string_size + sizeof (IttiMsgText)); @@ -1317,23 +1317,23 @@ uint8_t do_RRCConnectionReestablishment_NB_IoT( uint8_t* const buffer, const uint8_t Transaction_id, const NB_IoT_DL_FRAME_PARMS* const frame_parms, //to be changed - SRB_ToAddModList_NB_r13_t* SRB_list_NB_IoT) //should contain SRB1 already configured? + LTE_SRB_ToAddModList_NB_r13_t* SRB_list_NB_IoT) //should contain SRB1 already configured? { asn_enc_rval_t enc_rval; - DL_CCCH_Message_NB_t dl_ccch_msg_NB_IoT; - RRCConnectionReestablishment_NB_t* rrcConnectionReestablishment_NB_IoT; + LTE_DL_CCCH_Message_NB_t dl_ccch_msg_NB_IoT; + LTE_RRCConnectionReestablishment_NB_t* rrcConnectionReestablishment_NB_IoT; - memset(&dl_ccch_msg_NB_IoT, 0, sizeof(DL_CCCH_Message_NB_t)); + memset(&dl_ccch_msg_NB_IoT, 0, sizeof(LTE_DL_CCCH_Message_NB_t)); - dl_ccch_msg_NB_IoT.message.present = DL_CCCH_MessageType_NB_PR_c1; - dl_ccch_msg_NB_IoT.message.choice.c1.present = DL_CCCH_MessageType_NB__c1_PR_rrcConnectionReestablishment_r13; + dl_ccch_msg_NB_IoT.message.present = LTE_DL_CCCH_MessageType_NB_PR_c1; + dl_ccch_msg_NB_IoT.message.choice.c1.present = LTE_DL_CCCH_MessageType_NB__c1_PR_rrcConnectionReestablishment_r13; rrcConnectionReestablishment_NB_IoT = &dl_ccch_msg_NB_IoT.message.choice.c1.choice.rrcConnectionReestablishment_r13; //rrcConnectionReestablishment_NB rrcConnectionReestablishment_NB_IoT->rrc_TransactionIdentifier = Transaction_id; - rrcConnectionReestablishment_NB_IoT->criticalExtensions.present = RRCConnectionReestablishment_NB__criticalExtensions_PR_c1; - rrcConnectionReestablishment_NB_IoT->criticalExtensions.choice.c1.present = RRCConnectionReestablishment_NB__criticalExtensions__c1_PR_rrcConnectionReestablishment_r13; + rrcConnectionReestablishment_NB_IoT->criticalExtensions.present = LTE_RRCConnectionReestablishment_NB__criticalExtensions_PR_c1; + rrcConnectionReestablishment_NB_IoT->criticalExtensions.choice.c1.present = LTE_RRCConnectionReestablishment_NB__criticalExtensions__c1_PR_rrcConnectionReestablishment_r13; rrcConnectionReestablishment_NB_IoT->criticalExtensions.choice.c1.choice.rrcConnectionReestablishment_r13.radioResourceConfigDedicated_r13.srb_ToAddModList_r13 = SRB_list_NB_IoT; rrcConnectionReestablishment_NB_IoT->criticalExtensions.choice.c1.choice.rrcConnectionReestablishment_r13.radioResourceConfigDedicated_r13.drb_ToAddModList_r13 = NULL; @@ -1344,7 +1344,7 @@ uint8_t do_RRCConnectionReestablishment_NB_IoT( rrcConnectionReestablishment_NB_IoT->criticalExtensions.choice.c1.choice.rrcConnectionReestablishment_r13.nextHopChainingCount_r13=0; - enc_rval = uper_encode_to_buffer(&asn_DEF_DL_CCCH_Message_NB, + enc_rval = uper_encode_to_buffer(&asn_DEF_LTE_DL_CCCH_Message_NB, NULL, (void*)&dl_ccch_msg_NB_IoT, buffer, @@ -1356,7 +1356,7 @@ uint8_t do_RRCConnectionReestablishment_NB_IoT( } if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) { - xer_fprint(stdout,&asn_DEF_DL_CCCH_Message_NB,(void*)&dl_ccch_msg_NB_IoT); + xer_fprint(stdout,&asn_DEF_LTE_DL_CCCH_Message_NB,(void*)&dl_ccch_msg_NB_IoT); } #if defined(ENABLE_ITTI) @@ -1365,7 +1365,7 @@ uint8_t do_RRCConnectionReestablishment_NB_IoT( char message_string[30000]; size_t message_string_size; - if ((message_string_size = xer_sprint(message_string, sizeof(message_string), &asn_DEF_DL_CCCH_Message_NB, (void *) &dl_ccch_msg_NB_IoT)) > 0) { + if ((message_string_size = xer_sprint(message_string, sizeof(message_string), &asn_DEF_LTE_DL_CCCH_Message_NB, (void *) &dl_ccch_msg_NB_IoT)) > 0) { MessageDef *msg_p; msg_p = itti_alloc_new_message_sized (TASK_RRC_ENB_NB_IoT, RRC_DL_CCCH, message_string_size + sizeof (IttiMsgText)); @@ -1391,22 +1391,22 @@ uint8_t do_RRCConnectionRelease_NB_IoT( asn_enc_rval_t enc_rval; - DL_DCCH_Message_NB_t dl_dcch_msg_NB_IoT; - RRCConnectionRelease_NB_t *rrcConnectionRelease_NB_IoT; + LTE_DL_DCCH_Message_NB_t dl_dcch_msg_NB_IoT; + LTE_RRCConnectionRelease_NB_t *rrcConnectionRelease_NB_IoT; - memset(&dl_dcch_msg_NB_IoT,0,sizeof(DL_DCCH_Message_NB_t)); + memset(&dl_dcch_msg_NB_IoT,0,sizeof(LTE_DL_DCCH_Message_NB_t)); - dl_dcch_msg_NB_IoT.message.present = DL_DCCH_MessageType_NB_PR_c1; - dl_dcch_msg_NB_IoT.message.choice.c1.present = DL_DCCH_MessageType_NB__c1_PR_rrcConnectionRelease_r13; + dl_dcch_msg_NB_IoT.message.present = LTE_DL_DCCH_MessageType_NB_PR_c1; + dl_dcch_msg_NB_IoT.message.choice.c1.present = LTE_DL_DCCH_MessageType_NB__c1_PR_rrcConnectionRelease_r13; rrcConnectionRelease_NB_IoT = &dl_dcch_msg_NB_IoT.message.choice.c1.choice.rrcConnectionRelease_r13; // RRCConnectionRelease rrcConnectionRelease_NB_IoT->rrc_TransactionIdentifier = Transaction_id; - rrcConnectionRelease_NB_IoT->criticalExtensions.present = RRCConnectionRelease_NB__criticalExtensions_PR_c1; - rrcConnectionRelease_NB_IoT->criticalExtensions.choice.c1.present =RRCConnectionRelease_NB__criticalExtensions__c1_PR_rrcConnectionRelease_r13 ; + rrcConnectionRelease_NB_IoT->criticalExtensions.present = LTE_RRCConnectionRelease_NB__criticalExtensions_PR_c1; + rrcConnectionRelease_NB_IoT->criticalExtensions.choice.c1.present = LTE_RRCConnectionRelease_NB__criticalExtensions__c1_PR_rrcConnectionRelease_r13 ; - rrcConnectionRelease_NB_IoT->criticalExtensions.choice.c1.choice.rrcConnectionRelease_r13.releaseCause_r13 = ReleaseCause_NB_r13_other; + rrcConnectionRelease_NB_IoT->criticalExtensions.choice.c1.choice.rrcConnectionRelease_r13.releaseCause_r13 = LTE_ReleaseCause_NB_r13_other; rrcConnectionRelease_NB_IoT->criticalExtensions.choice.c1.choice.rrcConnectionRelease_r13.redirectedCarrierInfo_r13 = NULL; rrcConnectionRelease_NB_IoT->criticalExtensions.choice.c1.choice.rrcConnectionRelease_r13.extendedWaitTime_r13 = NULL; @@ -1414,7 +1414,7 @@ uint8_t do_RRCConnectionRelease_NB_IoT( rrcConnectionRelease_NB_IoT->criticalExtensions.choice.c1.choice.rrcConnectionRelease_r13.nonCriticalExtension=CALLOC(1, sizeof(*rrcConnectionRelease_NB_IoT->criticalExtensions.choice.c1.choice.rrcConnectionRelease_r13.nonCriticalExtension)); - enc_rval = uper_encode_to_buffer(&asn_DEF_DL_DCCH_Message_NB, + enc_rval = uper_encode_to_buffer(&asn_DEF_LTE_DL_DCCH_Message_NB, NULL, (void*)&dl_dcch_msg_NB_IoT, buffer, diff --git a/openair2/RRC/LTE/defs_NB_IoT.h b/openair2/RRC/LTE/defs_NB_IoT.h index 0cc8a37bc0..160d92a610 100644 --- a/openair2/RRC/LTE/defs_NB_IoT.h +++ b/openair2/RRC/LTE/defs_NB_IoT.h @@ -50,17 +50,17 @@ //#include "SystemInformationBlockType1-NB.h" //#include "SystemInformation-NB.h" -#include "RRCConnectionReconfiguration-NB.h" -#include "RRCConnectionReconfigurationComplete-NB.h" -#include "RRCConnectionSetup-NB.h" -#include "RRCConnectionSetupComplete-NB.h" -#include "RRCConnectionRequest-NB.h" -#include "RRCConnectionReestablishmentRequest-NB.h" -#include "BCCH-DL-SCH-Message-NB.h" -#include "BCCH-BCH-Message-NB.h" -#include "AS-Config-NB.h" -#include "AS-Context-NB.h" -#include "UE-Capability-NB-r13.h" //equivalent of UE-EUTRA-Capability.h +#include "LTE_RRCConnectionReconfiguration-NB.h" +#include "LTE_RRCConnectionReconfigurationComplete-NB.h" +#include "LTE_RRCConnectionSetup-NB.h" +#include "LTE_RRCConnectionSetupComplete-NB.h" +#include "LTE_RRCConnectionRequest-NB.h" +#include "LTE_RRCConnectionReestablishmentRequest-NB.h" +#include "LTE_BCCH-DL-SCH-Message-NB.h" +#include "LTE_BCCH-BCH-Message-NB.h" +#include "LTE_AS-Config-NB.h" +#include "LTE_AS-Context-NB.h" +#include "LTE_UE-Capability-NB-r13.h" //equivalent of UE-EUTRA-Capability.h //------------------- #if defined(ENABLE_ITTI) @@ -122,7 +122,7 @@ typedef struct UE_RRC_INFO_NB_IoT_s { uint8_t SIB1systemInfoValueTag; uint32_t SIStatus; uint32_t SIcnt; -#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) uint8_t MCCHStatus[8]; // MAX_MBSFN_AREA #endif uint8_t SIwindowsize; //!< Corresponds to the SIB1 si-WindowLength parameter. The unit is ms. Possible values are (final): 1,2,5,10,15,20,40 @@ -235,14 +235,14 @@ typedef struct SRB_INFO_TABLE_ENTRY_NB_IoT_s { //MEAS_REPORT_LIST_s not implemented in NB-IoT but is used at UE side //HANDOVER_INFO_UE not implemented in NB-IoT typedef struct HANDOVER_INFO_UE_NB_IoT_s { - PhysCellId_t targetCellId; + LTE_PhysCellId_t targetCellId; uint8_t measFlag; } HANDOVER_INFO_UE_NB_IoT; //NB-IoT eNB_RRC_UE_NB_IoT_s--(used as a context in eNB --> ue_context in rrc_eNB_ue_context)------ typedef struct eNB_RRC_UE_NB_IoT_s { - EstablishmentCause_t establishment_cause; + LTE_EstablishmentCause_t establishment_cause; uint8_t primaryCC_id; //in NB-IoT only SRB0, SRB1 and SRB1bis (until AS security activation) exist @@ -256,14 +256,14 @@ typedef struct eNB_RRC_UE_NB_IoT_s { * message previously sent by the eNB (e.g. RRCConnectionSetup -- RRCConnectionSetupComplete) * this because it could happen that more messages are transmitted at the same time */ - SRB_ToAddModList_NB_r13_t* SRB_configList;//for SRB1 and SRB1bis - SRB_ToAddModList_NB_r13_t* SRB_configList2[RRC_TRANSACTION_IDENTIFIER_NUMBER]; - DRB_ToAddModList_NB_r13_t* DRB_configList; //for all the DRBs - DRB_ToAddModList_NB_r13_t* DRB_configList2[RRC_TRANSACTION_IDENTIFIER_NUMBER]; //for the configured DRBs of a xid + LTE_SRB_ToAddModList_NB_r13_t* SRB_configList;//for SRB1 and SRB1bis + LTE_SRB_ToAddModList_NB_r13_t* SRB_configList2[RRC_TRANSACTION_IDENTIFIER_NUMBER]; + LTE_DRB_ToAddModList_NB_r13_t* DRB_configList; //for all the DRBs + LTE_DRB_ToAddModList_NB_r13_t* DRB_configList2[RRC_TRANSACTION_IDENTIFIER_NUMBER]; //for the configured DRBs of a xid uint8_t DRB_active[2];//in LTE was 8 --> at most 2 for NB-IoT - struct PhysicalConfigDedicated_NB_r13* physicalConfigDedicated_NB_IoT; - MAC_MainConfig_NB_r13_t* mac_MainConfig_NB_IoT; + struct LTE_PhysicalConfigDedicated_NB_r13* physicalConfigDedicated_NB_IoT; + LTE_MAC_MainConfig_NB_r13_t* mac_MainConfig_NB_IoT; //No SPS(semi-persistent scheduling) in NB-IoT //No Measurement report in NB-IoT @@ -279,8 +279,8 @@ typedef struct eNB_RRC_UE_NB_IoT_s { #endif /* Used integrity/ciphering algorithms--> maintained the same for NB-IoT */ - e_CipheringAlgorithm_r12 ciphering_algorithm; //Specs. TS 36.331 V14.1.0 pag 432 Change position of chipering enumerative w.r.t previous version - e_SecurityAlgorithmConfig__integrityProtAlgorithm integrity_algorithm; + e_LTE_CipheringAlgorithm_r12 ciphering_algorithm; //Specs. TS 36.331 V14.1.0 pag 432 Change position of chipering enumerative w.r.t previous version + e_LTE_SecurityAlgorithmConfig__integrityProtAlgorithm integrity_algorithm; uint8_t Status; rnti_t rnti; @@ -290,10 +290,10 @@ typedef struct eNB_RRC_UE_NB_IoT_s { /* Information from UE RRC ConnectionRequest-NB-r13_IE--> NB-IoT */ UE_S_TMSI_NB_IoT Initialue_identity_s_TMSI; - EstablishmentCause_NB_r13_t establishment_cause_NB_IoT; //different set for NB-IoT + LTE_EstablishmentCause_NB_r13_t establishment_cause_NB_IoT; //different set for NB-IoT /* Information from UE RRC ConnectionReestablishmentRequest-NB--> NB-IoT */ - ReestablishmentCause_NB_r13_t reestablishment_cause_NB_IoT; //different set for NB_IoT + LTE_ReestablishmentCause_NB_r13_t reestablishment_cause_NB_IoT; //different set for NB_IoT /* UE id for initial connection to S1AP */ uint16_t ue_initial_id; @@ -389,18 +389,18 @@ typedef struct { uint16_t physCellId; //not stored in the MIB-NB but is getting through NPSS/NSSS //are the only static one (memory has been already allocated) - BCCH_BCH_Message_NB_t mib_NB_IoT; - BCCH_DL_SCH_Message_NB_t siblock1_NB_IoT; //SIB1-NB - BCCH_DL_SCH_Message_NB_t systemInformation_NB_IoT; //SI + LTE_BCCH_BCH_Message_NB_t mib_NB_IoT; + LTE_BCCH_DL_SCH_Message_NB_t siblock1_NB_IoT; //SIB1-NB + LTE_BCCH_DL_SCH_Message_NB_t systemInformation_NB_IoT; //SI - SystemInformationBlockType1_NB_t *sib1_NB_IoT; - SystemInformationBlockType2_NB_r13_t *sib2_NB_IoT; - SystemInformationBlockType3_NB_r13_t *sib3_NB_IoT; + LTE_SystemInformationBlockType1_NB_t *sib1_NB_IoT; + LTE_SystemInformationBlockType2_NB_r13_t *sib2_NB_IoT; + LTE_SystemInformationBlockType3_NB_r13_t *sib3_NB_IoT; //not implemented yet - SystemInformationBlockType4_NB_r13_t *sib4_NB_IoT; - SystemInformationBlockType5_NB_r13_t *sib5_NB_IoT; - SystemInformationBlockType14_NB_r13_t *sib14_NB_IoT; - SystemInformationBlockType16_NB_r13_t *sib16_NB_IoT; + LTE_SystemInformationBlockType4_NB_r13_t *sib4_NB_IoT; + LTE_SystemInformationBlockType5_NB_r13_t *sib5_NB_IoT; + LTE_SystemInformationBlockType14_NB_r13_t *sib14_NB_IoT; + LTE_SystemInformationBlockType16_NB_r13_t *sib16_NB_IoT; SRB_INFO_NB_IoT SI; @@ -466,7 +466,7 @@ typedef struct OAI_UECapability_NB_IoT_s { uint8_t sdu[MAX_UE_CAPABILITY_SIZE_NB_IoT]; uint8_t sdu_size; ////NB-IoT------ - UE_Capability_NB_r13_t UE_Capability_NB_IoT; //replace the UE_EUTRA_Capability of LTE + LTE_UE_Capability_NB_r13_t UE_Capability_NB_IoT; //replace the UE_EUTRA_Capability of LTE } OAI_UECapability_NB_IoT_t; #define RRC_BUFFER_SIZE_MAX_NB_IoT 1024 @@ -501,7 +501,7 @@ typedef struct UE_RRC_INST_NB_IoT_s { SystemInformationBlockType1_t *sib1[NB_CNX_UE]; SystemInformation_t *si[NB_CNX_UE]; //!< Temporary storage for an SI message. Decoding happens in decode_SI(). */ - SystemInformationBlockType2_t *sib2[NB_CNX_UE]; + LTE_SystemInformationBlockType2_t *sib2[NB_CNX_UE]; /* SystemInformationBlockType3_t *sib3[NB_CNX_UE]; SystemInformationBlockType4_t *sib4[NB_CNX_UE]; @@ -513,7 +513,7 @@ typedef struct UE_RRC_INST_NB_IoT_s { SystemInformationBlockType10_t *sib10[NB_CNX_UE]; SystemInformationBlockType11_t *sib11[NB_CNX_UE]; -#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) uint8_t MBMS_flag; uint8_t *MCCH_MESSAGE[NB_CNX_UE]; uint8_t sizeof_MCCH_MESSAGE[NB_CNX_UE]; diff --git a/openair2/RRC/LTE/extern_NB_IoT.h b/openair2/RRC/LTE/extern_NB_IoT.h index f136b57b47..f240e8b215 100644 --- a/openair2/RRC/LTE/extern_NB_IoT.h +++ b/openair2/RRC/LTE/extern_NB_IoT.h @@ -33,7 +33,7 @@ #include "RRC/LTE/defs_NB_IoT.h" #include "PHY_INTERFACE/IF_Module_NB_IoT.h" #include "LAYER2/RLC/rlc.h" -#include "LogicalChannelConfig-NB-r13.h" +#include "LTE_LogicalChannelConfig-NB-r13.h" #include "LAYER2/MAC/defs_NB_IoT.h" #include "common/ran_context.h" @@ -48,8 +48,8 @@ extern PHY_Config_NB_IoT_t *config_INFO; extern rlc_info_t Rlc_info_am_NB_IoT,Rlc_info_am_config_NB_IoT; extern uint8_t DRB2LCHAN_NB_IoT[2]; -extern LogicalChannelConfig_NB_r13_t SRB1bis_logicalChannelConfig_defaultValue_NB_IoT; -extern LogicalChannelConfig_NB_r13_t SRB1_logicalChannelConfig_defaultValue_NB_IoT; +extern LTE_LogicalChannelConfig_NB_r13_t SRB1bis_logicalChannelConfig_defaultValue_NB_IoT; +extern LTE_LogicalChannelConfig_NB_r13_t SRB1_logicalChannelConfig_defaultValue_NB_IoT; extern uint16_t T300_NB_IoT[8]; extern uint16_t T301_NB_IoT[8]; diff --git a/openair2/RRC/LTE/proto_NB_IoT.h b/openair2/RRC/LTE/proto_NB_IoT.h index de09d39fab..e5c5d8056b 100644 --- a/openair2/RRC/LTE/proto_NB_IoT.h +++ b/openair2/RRC/LTE/proto_NB_IoT.h @@ -203,7 +203,7 @@ rrc_eNB_generate_dedicatedRRCConnectionReconfiguration_NB_IoT( void rrc_eNB_process_RRCConnectionSetupComplete_NB_IoT( const protocol_ctxt_t* const ctxt_pP, rrc_eNB_ue_context_NB_IoT_t* ue_context_pP, - RRCConnectionSetupComplete_NB_r13_IEs_t * rrcConnectionSetupComplete_NB + LTE_RRCConnectionSetupComplete_NB_r13_IEs_t * rrcConnectionSetupComplete_NB ); void rrc_eNB_generate_SecurityModeCommand_NB_IoT( diff --git a/openair2/RRC/LTE/rrc_UE.c b/openair2/RRC/LTE/rrc_UE.c index b111f77871..5a35f7aafe 100644 --- a/openair2/RRC/LTE/rrc_UE.c +++ b/openair2/RRC/LTE/rrc_UE.c @@ -46,23 +46,23 @@ #ifndef CELLULAR #include "RRC/LTE/MESSAGES/asn1_msg.h" #endif -#include "RRCConnectionRequest.h" -#include "RRCConnectionReconfiguration.h" -#include "UL-CCCH-Message.h" -#include "DL-CCCH-Message.h" -#include "UL-DCCH-Message.h" -#include "DL-DCCH-Message.h" -#include "BCCH-DL-SCH-Message.h" -#include "PCCH-Message.h" -#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) -#include "MCCH-Message.h" +#include "LTE_RRCConnectionRequest.h" +#include "LTE_RRCConnectionReconfiguration.h" +#include "LTE_UL-CCCH-Message.h" +#include "LTE_DL-CCCH-Message.h" +#include "LTE_UL-DCCH-Message.h" +#include "LTE_DL-DCCH-Message.h" +#include "LTE_BCCH-DL-SCH-Message.h" +#include "LTE_PCCH-Message.h" +#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) +#include "LTE_MCCH-Message.h" #endif -#include "MeasConfig.h" -#include "MeasGapConfig.h" -#include "MeasObjectEUTRA.h" -#include "TDD-Config.h" -#include "UECapabilityEnquiry.h" -#include "UE-CapabilityRequest.h" +#include "LTE_MeasConfig.h" +#include "LTE_MeasGapConfig.h" +#include "LTE_MeasObjectEUTRA.h" +#include "LTE_TDD-Config.h" +#include "LTE_UECapabilityEnquiry.h" +#include "LTE_UE-CapabilityRequest.h" #include "RRC/NAS/nas_config.h" #include "RRC/NAS/rb_config.h" #if ENABLE_RAL @@ -85,8 +85,8 @@ #include "openair2/LAYER2/MAC/mac_extern.h" -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) -#include "SL-Preconfiguration-r12.h" +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#include "LTE_SL-Preconfiguration-r12.h" //for D2D int ctrl_sock_fd; @@ -111,7 +111,7 @@ extern void pdcp_config_set_security( // internal prototypes -void rrc_ue_process_securityModeCommand( const protocol_ctxt_t* const ctxt_pP, SecurityModeCommand_t* const securityModeCommand, const uint8_t eNB_index ); +void rrc_ue_process_securityModeCommand( const protocol_ctxt_t* const ctxt_pP, LTE_SecurityModeCommand_t* const securityModeCommand, const uint8_t eNB_index ); static int decode_SI( const protocol_ctxt_t* const ctxt_pP, const uint8_t eNB_index ); @@ -139,12 +139,12 @@ static uint8_t check_trigger_meas_event( uint8_t eNB_index, uint8_t ue_cnx_index, uint8_t 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); + LTE_Q_OffsetRange_t ofn, LTE_Q_OffsetRange_t ocn, LTE_Hysteresis_t hys, + LTE_Q_OffsetRange_t ofs, LTE_Q_OffsetRange_t ocs, long a3_offset, LTE_TimeToTrigger_t ttt); -#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) static void decode_MBSFNAreaConfiguration(module_id_t module_idP, uint8_t eNB_index, frame_t frameP,uint8_t mbsfn_sync_area); -uint8_t rrc_ue_generate_SidelinkUEInformation( const protocol_ctxt_t* const ctxt_pP, const uint8_t eNB_index,SL_DestinationInfoList_r12_t *destinationInfoList, long *discTxResourceReq, SL_TRIGGER_t mode); +uint8_t rrc_ue_generate_SidelinkUEInformation( const protocol_ctxt_t* const ctxt_pP, const uint8_t eNB_index,LTE_SL_DestinationInfoList_r12_t *destinationInfoList, long *discTxResourceReq, SL_TRIGGER_t mode); #endif @@ -267,69 +267,69 @@ static void init_SI_UE( const protocol_ctxt_t* const ctxt_pP, const uint8_t eNB_ UE_rrc_inst[ctxt_pP->module_id].sizeof_SIB1[eNB_index] = 0; UE_rrc_inst[ctxt_pP->module_id].sizeof_SI[eNB_index] = 0; UE_rrc_inst[ctxt_pP->module_id].SIB1[eNB_index] = (uint8_t*)malloc16_clear( 32 ); - UE_rrc_inst[ctxt_pP->module_id].sib1[eNB_index] = malloc16_clear( sizeof(SystemInformationBlockType1_t) ); - UE_rrc_inst[ctxt_pP->module_id].sib2[eNB_index] = malloc16_clear( sizeof(SystemInformationBlockType2_t) ); - UE_rrc_inst[ctxt_pP->module_id].sib3[eNB_index] = malloc16_clear( sizeof(SystemInformationBlockType3_t) ); - UE_rrc_inst[ctxt_pP->module_id].sib4[eNB_index] = malloc16_clear( sizeof(SystemInformationBlockType4_t) ); - UE_rrc_inst[ctxt_pP->module_id].sib5[eNB_index] = malloc16_clear( sizeof(SystemInformationBlockType5_t) ); - UE_rrc_inst[ctxt_pP->module_id].sib6[eNB_index] = malloc16_clear( sizeof(SystemInformationBlockType6_t) ); - UE_rrc_inst[ctxt_pP->module_id].sib7[eNB_index] = malloc16_clear( sizeof(SystemInformationBlockType7_t) ); - UE_rrc_inst[ctxt_pP->module_id].sib8[eNB_index] = malloc16_clear( sizeof(SystemInformationBlockType8_t) ); - UE_rrc_inst[ctxt_pP->module_id].sib9[eNB_index] = malloc16_clear( sizeof(SystemInformationBlockType9_t) ); - UE_rrc_inst[ctxt_pP->module_id].sib10[eNB_index] = malloc16_clear( sizeof(SystemInformationBlockType10_t) ); - UE_rrc_inst[ctxt_pP->module_id].sib11[eNB_index] = malloc16_clear( sizeof(SystemInformationBlockType11_t) ); -#if (RRC_VERSION >= MAKE_VERSION(9, 0, 0)) - UE_rrc_inst[ctxt_pP->module_id].sib12[eNB_index] = malloc16_clear( sizeof(SystemInformationBlockType12_r9_t) ); - UE_rrc_inst[ctxt_pP->module_id].sib13[eNB_index] = malloc16_clear( sizeof(SystemInformationBlockType13_r9_t) ); - UE_rrc_inst[ctxt_pP->module_id].sib18[eNB_index] = malloc16_clear( sizeof(SystemInformationBlockType18_r12_t) ); - UE_rrc_inst[ctxt_pP->module_id].sib19[eNB_index] = malloc16_clear( sizeof(SystemInformationBlockType19_r12_t) ); - UE_rrc_inst[ctxt_pP->module_id].sib21[eNB_index] = malloc16_clear( sizeof(SystemInformationBlockType21_r14_t) ); + UE_rrc_inst[ctxt_pP->module_id].sib1[eNB_index] = malloc16_clear( sizeof(LTE_SystemInformationBlockType1_t) ); + UE_rrc_inst[ctxt_pP->module_id].sib2[eNB_index] = malloc16_clear( sizeof(LTE_SystemInformationBlockType2_t) ); + UE_rrc_inst[ctxt_pP->module_id].sib3[eNB_index] = malloc16_clear( sizeof(LTE_SystemInformationBlockType3_t) ); + UE_rrc_inst[ctxt_pP->module_id].sib4[eNB_index] = malloc16_clear( sizeof(LTE_SystemInformationBlockType4_t) ); + UE_rrc_inst[ctxt_pP->module_id].sib5[eNB_index] = malloc16_clear( sizeof(LTE_SystemInformationBlockType5_t) ); + UE_rrc_inst[ctxt_pP->module_id].sib6[eNB_index] = malloc16_clear( sizeof(LTE_SystemInformationBlockType6_t) ); + UE_rrc_inst[ctxt_pP->module_id].sib7[eNB_index] = malloc16_clear( sizeof(LTE_SystemInformationBlockType7_t) ); + UE_rrc_inst[ctxt_pP->module_id].sib8[eNB_index] = malloc16_clear( sizeof(LTE_SystemInformationBlockType8_t) ); + UE_rrc_inst[ctxt_pP->module_id].sib9[eNB_index] = malloc16_clear( sizeof(LTE_SystemInformationBlockType9_t) ); + UE_rrc_inst[ctxt_pP->module_id].sib10[eNB_index] = malloc16_clear( sizeof(LTE_SystemInformationBlockType10_t) ); + UE_rrc_inst[ctxt_pP->module_id].sib11[eNB_index] = malloc16_clear( sizeof(LTE_SystemInformationBlockType11_t) ); +#if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) + UE_rrc_inst[ctxt_pP->module_id].sib12[eNB_index] = malloc16_clear( sizeof(LTE_SystemInformationBlockType12_r9_t) ); + UE_rrc_inst[ctxt_pP->module_id].sib13[eNB_index] = malloc16_clear( sizeof(LTE_SystemInformationBlockType13_r9_t) ); + UE_rrc_inst[ctxt_pP->module_id].sib18[eNB_index] = malloc16_clear( sizeof(LTE_SystemInformationBlockType18_r12_t) ); + UE_rrc_inst[ctxt_pP->module_id].sib19[eNB_index] = malloc16_clear( sizeof(LTE_SystemInformationBlockType19_r12_t) ); + UE_rrc_inst[ctxt_pP->module_id].sib21[eNB_index] = malloc16_clear( sizeof(LTE_SystemInformationBlockType21_r14_t) ); #endif UE_rrc_inst[ctxt_pP->module_id].SI[eNB_index] = (uint8_t*)malloc16_clear( 64 ); - UE_rrc_inst[ctxt_pP->module_id].si[eNB_index] = (SystemInformation_t*)malloc16_clear( sizeof(SystemInformation_t) ); + UE_rrc_inst[ctxt_pP->module_id].si[eNB_index] = (LTE_SystemInformation_t*)malloc16_clear( sizeof(LTE_SystemInformation_t) ); UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIStatus = 0; UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIcnt = 0; } -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) void init_SL_preconfig(UE_RRC_INST *UE, const uint8_t eNB_index ) { LOG_I(RRC,"Initializing Sidelink Pre-configuration for UE\n"); - UE->SL_Preconfiguration[eNB_index] = malloc16_clear( sizeof(struct SL_Preconfiguration_r12) ); + UE->SL_Preconfiguration[eNB_index] = malloc16_clear( sizeof(struct LTE_SL_Preconfiguration_r12) ); UE->SL_Preconfiguration[eNB_index]->preconfigGeneral_r12.rohc_Profiles_r12.profile0x0001_r12 = true; UE->SL_Preconfiguration[eNB_index]->preconfigGeneral_r12.carrierFreq_r12 = 3350; UE->SL_Preconfiguration[eNB_index]->preconfigGeneral_r12.maxTxPower_r12 = 0; UE->SL_Preconfiguration[eNB_index]->preconfigGeneral_r12.additionalSpectrumEmission_r12 = 0; - UE->SL_Preconfiguration[eNB_index]->preconfigGeneral_r12.sl_bandwidth_r12 = SL_PreconfigGeneral_r12__sl_bandwidth_r12_n50; - UE->SL_Preconfiguration[eNB_index]->preconfigGeneral_r12.tdd_ConfigSL_r12.subframeAssignmentSL_r12 = TDD_ConfigSL_r12__subframeAssignmentSL_r12_none; + UE->SL_Preconfiguration[eNB_index]->preconfigGeneral_r12.sl_bandwidth_r12 = LTE_SL_PreconfigGeneral_r12__sl_bandwidth_r12_n50; + UE->SL_Preconfiguration[eNB_index]->preconfigGeneral_r12.tdd_ConfigSL_r12.subframeAssignmentSL_r12 = LTE_TDD_ConfigSL_r12__subframeAssignmentSL_r12_none; - UE->SL_Preconfiguration[eNB_index]->preconfigSync_r12.syncCP_Len_r12 = SL_CP_Len_r12_normal; + UE->SL_Preconfiguration[eNB_index]->preconfigSync_r12.syncCP_Len_r12 = LTE_SL_CP_Len_r12_normal; UE->SL_Preconfiguration[eNB_index]->preconfigSync_r12.syncOffsetIndicator1_r12 = 0; UE->SL_Preconfiguration[eNB_index]->preconfigSync_r12.syncOffsetIndicator2_r12 = 0; UE->SL_Preconfiguration[eNB_index]->preconfigSync_r12.syncTxParameters_r12 = 0; UE->SL_Preconfiguration[eNB_index]->preconfigSync_r12.syncTxThreshOoC_r12 = 0; - UE->SL_Preconfiguration[eNB_index]->preconfigSync_r12.filterCoefficient_r12 = FilterCoefficient_fc0; - UE->SL_Preconfiguration[eNB_index]->preconfigSync_r12.syncRefMinHyst_r12 = SL_PreconfigSync_r12__syncRefMinHyst_r12_dB0; - UE->SL_Preconfiguration[eNB_index]->preconfigSync_r12.syncRefDiffHyst_r12 = SL_PreconfigSync_r12__syncRefDiffHyst_r12_dB0; - UE->SL_Preconfiguration[eNB_index]->preconfigSync_r12.ext1 = malloc16_clear(sizeof(struct SL_PreconfigSync_r12__ext1)); + UE->SL_Preconfiguration[eNB_index]->preconfigSync_r12.filterCoefficient_r12 = LTE_FilterCoefficient_fc0; + UE->SL_Preconfiguration[eNB_index]->preconfigSync_r12.syncRefMinHyst_r12 = LTE_SL_PreconfigSync_r12__syncRefMinHyst_r12_dB0; + UE->SL_Preconfiguration[eNB_index]->preconfigSync_r12.syncRefDiffHyst_r12 = LTE_SL_PreconfigSync_r12__syncRefDiffHyst_r12_dB0; + UE->SL_Preconfiguration[eNB_index]->preconfigSync_r12.ext1 = malloc16_clear(sizeof(struct LTE_SL_PreconfigSync_r12__ext1)); UE->SL_Preconfiguration[eNB_index]->preconfigSync_r12.ext1->syncTxPeriodic_r13 = NULL; - struct SL_PreconfigCommPool_r12 *preconfigpool = malloc16_clear(sizeof(struct SL_PreconfigCommPool_r12)); - preconfigpool->sc_CP_Len_r12 = SL_CP_Len_r12_normal; - preconfigpool->sc_Period_r12 = SL_PeriodComm_r12_sf40; + struct LTE_SL_PreconfigCommPool_r12 *preconfigpool = malloc16_clear(sizeof(struct LTE_SL_PreconfigCommPool_r12)); + preconfigpool->sc_CP_Len_r12 = LTE_SL_CP_Len_r12_normal; + preconfigpool->sc_Period_r12 = LTE_SL_PeriodComm_r12_sf40; // 20 PRBs for SL communications preconfigpool->sc_TF_ResourceConfig_r12.prb_Num_r12 = 20; preconfigpool->sc_TF_ResourceConfig_r12.prb_Start_r12 = 5; preconfigpool->sc_TF_ResourceConfig_r12.prb_End_r12 = 44; // Offset set to 0 subframes - preconfigpool->sc_TF_ResourceConfig_r12.offsetIndicator_r12.present = SL_OffsetIndicator_r12_PR_small_r12; + preconfigpool->sc_TF_ResourceConfig_r12.offsetIndicator_r12.present = LTE_SL_OffsetIndicator_r12_PR_small_r12; preconfigpool->sc_TF_ResourceConfig_r12.offsetIndicator_r12.choice.small_r12 = 0; // 40 ms SL Period - preconfigpool->sc_TF_ResourceConfig_r12.subframeBitmap_r12.present = SubframeBitmapSL_r12_PR_bs40_r12; + preconfigpool->sc_TF_ResourceConfig_r12.subframeBitmap_r12.present = LTE_SubframeBitmapSL_r12_PR_bs40_r12; preconfigpool->sc_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs40_r12.buf = CALLOC(1,5); preconfigpool->sc_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs40_r12.size = 5; preconfigpool->sc_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs40_r12.bits_unused = 0; @@ -341,16 +341,16 @@ void init_SL_preconfig(UE_RRC_INST *UE, const uint8_t eNB_index ) preconfigpool->sc_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs40_r12.buf[4] = 0; preconfigpool->sc_TxParameters_r12 = 0; - preconfigpool->data_CP_Len_r12 = SL_CP_Len_r12_normal; + preconfigpool->data_CP_Len_r12 = LTE_SL_CP_Len_r12_normal; // 20 PRBs for SL communications preconfigpool->data_TF_ResourceConfig_r12.prb_Num_r12 = 20; preconfigpool->data_TF_ResourceConfig_r12.prb_Start_r12 = 5; preconfigpool->data_TF_ResourceConfig_r12.prb_End_r12 = 44; // Offset set to 0 subframes - preconfigpool->data_TF_ResourceConfig_r12.offsetIndicator_r12.present = SL_OffsetIndicator_r12_PR_small_r12; + preconfigpool->data_TF_ResourceConfig_r12.offsetIndicator_r12.present = LTE_SL_OffsetIndicator_r12_PR_small_r12; preconfigpool->data_TF_ResourceConfig_r12.offsetIndicator_r12.choice.small_r12 = 0; // 40 ms SL Period - preconfigpool->data_TF_ResourceConfig_r12.subframeBitmap_r12.present = SubframeBitmapSL_r12_PR_bs40_r12; + preconfigpool->data_TF_ResourceConfig_r12.subframeBitmap_r12.present = LTE_SubframeBitmapSL_r12_PR_bs40_r12; preconfigpool->data_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs40_r12.buf = CALLOC(1,5); preconfigpool->data_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs40_r12.size = 5; preconfigpool->data_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs40_r12.bits_unused = 0; @@ -362,7 +362,7 @@ void init_SL_preconfig(UE_RRC_INST *UE, const uint8_t eNB_index ) preconfigpool->data_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs40_r12.buf[5] = 0xFF; preconfigpool->dataHoppingConfig_r12.hoppingParameter_r12 = 0; - preconfigpool->dataHoppingConfig_r12.numSubbands_r12 = SL_HoppingConfigComm_r12__numSubbands_r12_ns1; + preconfigpool->dataHoppingConfig_r12.numSubbands_r12 = LTE_SL_HoppingConfigComm_r12__numSubbands_r12_ns1; preconfigpool->dataHoppingConfig_r12.rb_Offset_r12 = 0; preconfigpool->dataTxParameters_r12 = 0; @@ -450,8 +450,8 @@ void init_SL_preconfig(UE_RRC_INST *UE, const uint8_t eNB_index ) UE->DRB_configList, (DRB_ToReleaseList_t*) NULL, 0xff, NULL, NULL, NULL -#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) - , (PMCH_InfoList_r9_t *) NULL +#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) + , (LTE_PMCH_InfoList_r9_t *) NULL #endif ,NULL); @@ -459,8 +459,8 @@ void init_SL_preconfig(UE_RRC_INST *UE, const uint8_t eNB_index ) (SRB_ToAddModList_t*)NULL, UE->DRB_configList, (DRB_ToReleaseList_t*)NULL -#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) - ,(PMCH_InfoList_r9_t *)NULL +#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) + ,(LTE_PMCH_InfoList_r9_t *)NULL #endif ); */ @@ -510,11 +510,11 @@ char openair_rrc_ue_init( const module_id_t ue_mod_idP, const unsigned char eNB_ UE_rrc_inst[ctxt.module_id].Srb1[eNB_index].Active=0; UE_rrc_inst[ctxt.module_id].Srb2[eNB_index].Active=0; UE_rrc_inst[ctxt.module_id].HandoverInfoUe.measFlag=1; - UE_rrc_inst[ctxt.module_id].ciphering_algorithm = CipheringAlgorithm_r12_eea0; -#if (RRC_VERSION >= MAKE_VERSION(9, 2, 0)) - UE_rrc_inst[ctxt.module_id].integrity_algorithm = SecurityAlgorithmConfig__integrityProtAlgorithm_eia0_v920; + UE_rrc_inst[ctxt.module_id].ciphering_algorithm = LTE_CipheringAlgorithm_r12_eea0; +#if (LTE_RRC_VERSION >= MAKE_VERSION(9, 2, 0)) + UE_rrc_inst[ctxt.module_id].integrity_algorithm = LTE_SecurityAlgorithmConfig__integrityProtAlgorithm_eia0_v920; #else - UE_rrc_inst[ctxt.module_id].integrity_algorithm = SecurityAlgorithmConfig__integrityProtAlgorithm_reserved; + UE_rrc_inst[ctxt.module_id].integrity_algorithm = LTE_SecurityAlgorithmConfig__integrityProtAlgorithm_reserved; #endif openair_rrc_ue_init_security(&ctxt); @@ -715,7 +715,7 @@ void rrc_ue_generate_RRCConnectionReconfigurationComplete( const protocol_ctxt_t // Called by L2 interface (MAC) int rrc_ue_decode_ccch( const protocol_ctxt_t* const ctxt_pP, const SRB_INFO* const Srb_info, const uint8_t eNB_index ) { - DL_CCCH_Message_t* dl_ccch_msg=NULL; + LTE_DL_CCCH_Message_t* dl_ccch_msg=NULL; asn_dec_rval_t dec_rval; int rval=0; @@ -724,13 +724,13 @@ int rrc_ue_decode_ccch( const protocol_ctxt_t* const ctxt_pP, const SRB_INFO* co // UE_rrc_inst[ue_mod_idP].Info[eNB_index].State); dec_rval = uper_decode(NULL, - &asn_DEF_DL_CCCH_Message, + &asn_DEF_LTE_DL_CCCH_Message, (void**)&dl_ccch_msg, (uint8_t*)Srb_info->Rx_buffer.Payload, 100,0,0); if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) { - xer_fprint(stdout,&asn_DEF_DL_CCCH_Message,(void*)dl_ccch_msg); + xer_fprint(stdout,&asn_DEF_LTE_DL_CCCH_Message,(void*)dl_ccch_msg); } #if defined(ENABLE_ITTI) @@ -748,7 +748,7 @@ int rrc_ue_decode_ccch( const protocol_ctxt_t* const ctxt_pP, const SRB_INFO* co char message_string[10000]; size_t message_string_size; - if ((message_string_size = xer_sprint(message_string, sizeof(message_string), &asn_DEF_DL_CCCH_Message, (void *)dl_ccch_msg)) > 0) { + if ((message_string_size = xer_sprint(message_string, sizeof(message_string), &asn_DEF_LTE_DL_CCCH_Message, (void *)dl_ccch_msg)) > 0) { MessageDef *msg_p; msg_p = itti_alloc_new_message_sized (TASK_RRC_UE, RRC_DL_CCCH, message_string_size + sizeof (IttiMsgText)); @@ -767,20 +767,20 @@ int rrc_ue_decode_ccch( const protocol_ctxt_t* const ctxt_pP, const SRB_INFO* co return -1; } - if (dl_ccch_msg->message.present == DL_CCCH_MessageType_PR_c1) { + if (dl_ccch_msg->message.present == LTE_DL_CCCH_MessageType_PR_c1) { if (UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].State == RRC_SI_RECEIVED) { switch (dl_ccch_msg->message.choice.c1.present) { - case DL_CCCH_MessageType__c1_PR_NOTHING: + case LTE_DL_CCCH_MessageType__c1_PR_NOTHING: LOG_I(RRC, "[UE%d] Frame %d : Received PR_NOTHING on DL-CCCH-Message\n", ctxt_pP->module_id, ctxt_pP->frame); rval = 0; break; - case DL_CCCH_MessageType__c1_PR_rrcConnectionReestablishment: + case LTE_DL_CCCH_MessageType__c1_PR_rrcConnectionReestablishment: LOG_I(RRC, "[UE%d] Frame %d : Logical Channel DL-CCCH (SRB0), Received RRCConnectionReestablishment\n", ctxt_pP->module_id, @@ -788,7 +788,7 @@ int rrc_ue_decode_ccch( const protocol_ctxt_t* const ctxt_pP, const SRB_INFO* co rval = 0; break; - case DL_CCCH_MessageType__c1_PR_rrcConnectionReestablishmentReject: + case LTE_DL_CCCH_MessageType__c1_PR_rrcConnectionReestablishmentReject: LOG_I(RRC, "[UE%d] Frame %d : Logical Channel DL-CCCH (SRB0), Received RRCConnectionReestablishmentReject\n", ctxt_pP->module_id, @@ -796,7 +796,7 @@ int rrc_ue_decode_ccch( const protocol_ctxt_t* const ctxt_pP, const SRB_INFO* co rval = 0; break; - case DL_CCCH_MessageType__c1_PR_rrcConnectionReject: + case LTE_DL_CCCH_MessageType__c1_PR_rrcConnectionReject: LOG_I(RRC, "[UE%d] Frame %d : Logical Channel DL-CCCH (SRB0), Received RRCConnectionReject \n", ctxt_pP->module_id, @@ -804,7 +804,7 @@ int rrc_ue_decode_ccch( const protocol_ctxt_t* const ctxt_pP, const SRB_INFO* co rval = 0; break; - case DL_CCCH_MessageType__c1_PR_rrcConnectionSetup: + case LTE_DL_CCCH_MessageType__c1_PR_rrcConnectionSetup: LOG_I(RRC, "[UE%d][RAPROC] Frame %d : Logical Channel DL-CCCH (SRB0), Received RRCConnectionSetup RNTI %x\n", ctxt_pP->module_id, @@ -850,7 +850,7 @@ rrc_ue_establish_srb1( module_id_t ue_mod_idP, frame_t frameP, uint8_t eNB_index, - struct SRB_ToAddMod* SRB_config + struct LTE_SRB_ToAddMod* SRB_config ) //----------------------------------------------------------------------------- { @@ -883,7 +883,7 @@ rrc_ue_establish_srb2( module_id_t ue_mod_idP, frame_t frameP, uint8_t eNB_index, - struct SRB_ToAddMod* SRB_config + struct LTE_SRB_ToAddMod* SRB_config ) //----------------------------------------------------------------------------- { @@ -916,7 +916,7 @@ rrc_ue_establish_drb( module_id_t ue_mod_idP, frame_t frameP, uint8_t eNB_index, - struct DRB_ToAddMod* DRB_config + struct LTE_DRB_ToAddMod* DRB_config ) //----------------------------------------------------------------------------- { @@ -977,7 +977,7 @@ void rrc_ue_process_measConfig( const protocol_ctxt_t* const ctxt_pP, const uint8_t eNB_index, - MeasConfig_t* const measConfig + LTE_MeasConfig_t* const measConfig ) //----------------------------------------------------------------------------- { @@ -985,7 +985,7 @@ rrc_ue_process_measConfig( // This is the procedure described in 36.331 Section 5.5.2.1 int i; long ind; - MeasObjectToAddMod_t *measObj; + LTE_MeasObjectToAddMod_t *measObj; if (measConfig->measObjectToRemoveList != NULL) { for (i=0; imeasObjectToRemoveList->list.count; i++) { @@ -1005,11 +1005,11 @@ rrc_ue_process_measConfig( LOG_D(RRC,"Modifying measurement object %ld\n",ind); memcpy((char*)UE_rrc_inst[ctxt_pP->module_id].MeasObj[eNB_index][ind-1], (char*)measObj, - sizeof(MeasObjectToAddMod_t)); + sizeof(LTE_MeasObjectToAddMod_t)); } else { LOG_I(RRC,"Adding measurement object %ld\n",ind); - if (measObj->measObject.present == MeasObjectToAddMod__measObject_PR_measObjectEUTRA) { + if (measObj->measObject.present == LTE_MeasObjectToAddMod__measObject_PR_measObjectEUTRA) { LOG_I(RRC,"EUTRA Measurement : carrierFreq %ld, allowedMeasBandwidth %ld,presenceAntennaPort1 %d, neighCellConfig %d\n", measObj->measObject.choice.measObjectEUTRA.carrierFreq, measObj->measObject.choice.measObjectEUTRA.allowedMeasBandwidth, @@ -1023,29 +1023,29 @@ rrc_ue_process_measConfig( LOG_I(RRC,"call rrc_mac_config_req \n"); rrc_mac_config_req_ue(ctxt_pP->module_id,0,eNB_index, - (RadioResourceConfigCommonSIB_t *)NULL, - (struct PhysicalConfigDedicated *)NULL, -#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) - (SCellToAddMod_r10_t *)NULL, + (LTE_RadioResourceConfigCommonSIB_t *)NULL, + (struct LTE_PhysicalConfigDedicated *)NULL, +#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) + (LTE_SCellToAddMod_r10_t *)NULL, //struct PhysicalConfigDedicatedSCell_r10 *physicalConfigDedicatedSCell_r10, #endif UE_rrc_inst[ctxt_pP->module_id].MeasObj[eNB_index], - (MAC_MainConfig_t *)NULL, + (LTE_MAC_MainConfig_t *)NULL, 0, - (struct LogicalChannelConfig *)NULL, - (MeasGapConfig_t *)NULL, - (TDD_Config_t *)NULL, - (MobilityControlInfo_t *)NULL, + (struct LTE_LogicalChannelConfig *)NULL, + (LTE_MeasGapConfig_t *)NULL, + (LTE_TDD_Config_t *)NULL, + (LTE_MobilityControlInfo_t *)NULL, NULL, NULL, NULL, NULL, NULL, NULL -#if (RRC_VERSION >= MAKE_VERSION(9, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) ,0, - (MBSFN_AreaInfoList_r9_t *)NULL, - (PMCH_InfoList_r9_t *)NULL + (LTE_MBSFN_AreaInfoList_r9_t *)NULL, + (LTE_PMCH_InfoList_r9_t *)NULL #endif #ifdef CBA @@ -1053,7 +1053,7 @@ rrc_ue_process_measConfig( 0, 0 #endif -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) , 0, NULL, @@ -1079,7 +1079,7 @@ rrc_ue_process_measConfig( LOG_I(RRC,"Modifying Report Configuration %ld\n",ind-1); memcpy((char*)UE_rrc_inst[ctxt_pP->module_id].ReportConfig[eNB_index][ind-1], (char*)measConfig->reportConfigToAddModList->list.array[i], - sizeof(ReportConfigToAddMod_t)); + sizeof(LTE_ReportConfigToAddMod_t)); } else { LOG_D(RRC,"Adding Report Configuration %ld %p \n",ind-1,measConfig->reportConfigToAddModList->list.array[i]); UE_rrc_inst[ctxt_pP->module_id].ReportConfig[eNB_index][ind-1] = measConfig->reportConfigToAddModList->list.array[i]; @@ -1092,7 +1092,7 @@ rrc_ue_process_measConfig( LOG_D(RRC,"Modifying Quantity Configuration \n"); memcpy((char*)UE_rrc_inst[ctxt_pP->module_id].QuantityConfig[eNB_index], (char*)measConfig->quantityConfig, - sizeof(QuantityConfig_t)); + sizeof(LTE_QuantityConfig_t)); } else { LOG_D(RRC,"Adding Quantity configuration\n"); UE_rrc_inst[ctxt_pP->module_id].QuantityConfig[eNB_index] = measConfig->quantityConfig; @@ -1114,7 +1114,7 @@ rrc_ue_process_measConfig( LOG_D(RRC,"Modifying Measurement ID %ld\n",ind-1); memcpy((char*)UE_rrc_inst[ctxt_pP->module_id].MeasId[eNB_index][ind-1], (char*)measConfig->measIdToAddModList->list.array[i], - sizeof(MeasIdToAddMod_t)); + sizeof(LTE_MeasIdToAddMod_t)); } else { LOG_D(RRC,"Adding Measurement ID %ld %p\n",ind-1,measConfig->measIdToAddModList->list.array[i]); UE_rrc_inst[ctxt_pP->module_id].MeasId[eNB_index][ind-1] = measConfig->measIdToAddModList->list.array[i]; @@ -1126,7 +1126,7 @@ rrc_ue_process_measConfig( if (UE_rrc_inst[ctxt_pP->module_id].measGapConfig[eNB_index]) { memcpy((char*)UE_rrc_inst[ctxt_pP->module_id].measGapConfig[eNB_index], (char*)measConfig->measGapConfig, - sizeof(MeasGapConfig_t)); + sizeof(LTE_MeasGapConfig_t)); } else { UE_rrc_inst[ctxt_pP->module_id].measGapConfig[eNB_index] = measConfig->measGapConfig; } @@ -1137,7 +1137,7 @@ rrc_ue_process_measConfig( LOG_I(RRC,"Modifying Quantity Configuration \n"); memcpy((char*)UE_rrc_inst[ctxt_pP->module_id].QuantityConfig[eNB_index], (char*)measConfig->quantityConfig, - sizeof(QuantityConfig_t)); + sizeof(LTE_QuantityConfig_t)); } else { LOG_I(RRC,"Adding Quantity configuration\n"); UE_rrc_inst[ctxt_pP->module_id].QuantityConfig[eNB_index] = measConfig->quantityConfig; @@ -1162,7 +1162,7 @@ rrc_ue_process_measConfig( if (measConfig->speedStatePars != NULL) { if (UE_rrc_inst[ctxt_pP->module_id].speedStatePars) { - memcpy((char*)UE_rrc_inst[ctxt_pP->module_id].speedStatePars,(char*)measConfig->speedStatePars,sizeof(struct MeasConfig__speedStatePars)); + memcpy((char*)UE_rrc_inst[ctxt_pP->module_id].speedStatePars,(char*)measConfig->speedStatePars,sizeof(struct LTE_MeasConfig__speedStatePars)); } else { UE_rrc_inst[ctxt_pP->module_id].speedStatePars = measConfig->speedStatePars; } @@ -1174,11 +1174,11 @@ rrc_ue_process_measConfig( void -rrc_ue_update_radioResourceConfigDedicated(RadioResourceConfigDedicated_t* radioResourceConfigDedicated, +rrc_ue_update_radioResourceConfigDedicated(LTE_RadioResourceConfigDedicated_t* radioResourceConfigDedicated, const protocol_ctxt_t* const ctxt_pP, uint8_t eNB_index) { - PhysicalConfigDedicated_t* physicalConfigDedicated2 = NULL; + LTE_PhysicalConfigDedicated_t* physicalConfigDedicated2 = NULL; physicalConfigDedicated2 = CALLOC(1,sizeof(*physicalConfigDedicated2)); physicalConfigDedicated2->pdsch_ConfigDedicated = CALLOC(1,sizeof(*physicalConfigDedicated2->pdsch_ConfigDedicated)); @@ -1201,7 +1201,7 @@ rrc_ue_update_radioResourceConfigDedicated(RadioResourceConfigDedicated_t* radio LOG_I(RRC,"Update pdsch_ConfigDedicated config \n"); if(UE_rrc_inst[ctxt_pP->module_id].physicalConfigDedicated[eNB_index]->pdsch_ConfigDedicated == NULL) - UE_rrc_inst[ctxt_pP->module_id].physicalConfigDedicated[eNB_index]->pdsch_ConfigDedicated = CALLOC(1,sizeof(PDSCH_ConfigDedicated_t)); + UE_rrc_inst[ctxt_pP->module_id].physicalConfigDedicated[eNB_index]->pdsch_ConfigDedicated = CALLOC(1,sizeof(LTE_PDSCH_ConfigDedicated_t)); memcpy((char*)UE_rrc_inst[ctxt_pP->module_id].physicalConfigDedicated[eNB_index]->pdsch_ConfigDedicated, (char*)radioResourceConfigDedicated->physicalConfigDedicated->pdsch_ConfigDedicated, @@ -1218,7 +1218,7 @@ rrc_ue_update_radioResourceConfigDedicated(RadioResourceConfigDedicated_t* radio LOG_I(RRC,"Update pusch_ConfigDedicated config \n"); if(UE_rrc_inst[ctxt_pP->module_id].physicalConfigDedicated[eNB_index]->pusch_ConfigDedicated == NULL) - UE_rrc_inst[ctxt_pP->module_id].physicalConfigDedicated[eNB_index]->pusch_ConfigDedicated = CALLOC(1,sizeof(PUSCH_ConfigDedicated_t)); + UE_rrc_inst[ctxt_pP->module_id].physicalConfigDedicated[eNB_index]->pusch_ConfigDedicated = CALLOC(1,sizeof(LTE_PUSCH_ConfigDedicated_t)); memcpy((char*)UE_rrc_inst[ctxt_pP->module_id].physicalConfigDedicated[eNB_index]->pusch_ConfigDedicated, (char*)radioResourceConfigDedicated->physicalConfigDedicated->pusch_ConfigDedicated, @@ -1234,7 +1234,7 @@ rrc_ue_update_radioResourceConfigDedicated(RadioResourceConfigDedicated_t* radio { LOG_I(RRC,"Update pucch_ConfigDedicated config \n"); if(UE_rrc_inst[ctxt_pP->module_id].physicalConfigDedicated[eNB_index]->pucch_ConfigDedicated == NULL) - UE_rrc_inst[ctxt_pP->module_id].physicalConfigDedicated[eNB_index]->pucch_ConfigDedicated = CALLOC(1,sizeof(PUCCH_ConfigDedicated_t)); + UE_rrc_inst[ctxt_pP->module_id].physicalConfigDedicated[eNB_index]->pucch_ConfigDedicated = CALLOC(1,sizeof(LTE_PUCCH_ConfigDedicated_t)); memcpy((char*)UE_rrc_inst[ctxt_pP->module_id].physicalConfigDedicated[eNB_index]->pucch_ConfigDedicated, (char*)radioResourceConfigDedicated->physicalConfigDedicated->pucch_ConfigDedicated, @@ -1248,20 +1248,20 @@ rrc_ue_update_radioResourceConfigDedicated(RadioResourceConfigDedicated_t* radio // Update cqi_ReportConfig if(radioResourceConfigDedicated->physicalConfigDedicated->cqi_ReportConfig != NULL) { - LOG_I(RRC,"Update cqi_ReportConfig config (size=%zu,%zu)\n", sizeof(*physicalConfigDedicated2->cqi_ReportConfig), sizeof(CQI_ReportConfig_t)); + LOG_I(RRC,"Update cqi_ReportConfig config (size=%zu,%zu)\n", sizeof(*physicalConfigDedicated2->cqi_ReportConfig), sizeof(LTE_CQI_ReportConfig_t)); if(UE_rrc_inst[ctxt_pP->module_id].physicalConfigDedicated[eNB_index]->cqi_ReportConfig == NULL) - UE_rrc_inst[ctxt_pP->module_id].physicalConfigDedicated[eNB_index]->cqi_ReportConfig = CALLOC(1,sizeof(CQI_ReportConfig_t)); + UE_rrc_inst[ctxt_pP->module_id].physicalConfigDedicated[eNB_index]->cqi_ReportConfig = CALLOC(1,sizeof(LTE_CQI_ReportConfig_t)); memcpy((char*)UE_rrc_inst[ctxt_pP->module_id].physicalConfigDedicated[eNB_index]->cqi_ReportConfig, (char*)radioResourceConfigDedicated->physicalConfigDedicated->cqi_ReportConfig, sizeof(*physicalConfigDedicated2->cqi_ReportConfig)); if (radioResourceConfigDedicated->physicalConfigDedicated->cqi_ReportConfig->cqi_ReportPeriodic != NULL) { - LOG_I(RRC,"Update cqi_ReportPeriodic config (size=%zu,%zu)\n", sizeof(*physicalConfigDedicated2->cqi_ReportConfig->cqi_ReportPeriodic), sizeof(CQI_ReportPeriodic_t)); + LOG_I(RRC,"Update cqi_ReportPeriodic config (size=%zu,%zu)\n", sizeof(*physicalConfigDedicated2->cqi_ReportConfig->cqi_ReportPeriodic), sizeof(LTE_CQI_ReportPeriodic_t)); if(UE_rrc_inst[ctxt_pP->module_id].physicalConfigDedicated[eNB_index]->cqi_ReportConfig->cqi_ReportPeriodic == NULL) - UE_rrc_inst[ctxt_pP->module_id].physicalConfigDedicated[eNB_index]->cqi_ReportConfig->cqi_ReportPeriodic = CALLOC(1,sizeof(CQI_ReportPeriodic_t)); + UE_rrc_inst[ctxt_pP->module_id].physicalConfigDedicated[eNB_index]->cqi_ReportConfig->cqi_ReportPeriodic = CALLOC(1,sizeof(LTE_CQI_ReportPeriodic_t)); memcpy((char*)UE_rrc_inst[ctxt_pP->module_id].physicalConfigDedicated[eNB_index]->cqi_ReportConfig->cqi_ReportPeriodic, (char*)radioResourceConfigDedicated->physicalConfigDedicated->cqi_ReportConfig->cqi_ReportPeriodic, @@ -1279,7 +1279,7 @@ rrc_ue_update_radioResourceConfigDedicated(RadioResourceConfigDedicated_t* radio LOG_I(RRC,"Update schedulingRequestConfig config \n"); if(UE_rrc_inst[ctxt_pP->module_id].physicalConfigDedicated[eNB_index]->schedulingRequestConfig == NULL) - UE_rrc_inst[ctxt_pP->module_id].physicalConfigDedicated[eNB_index]->schedulingRequestConfig = CALLOC(1,sizeof(SchedulingRequestConfig_t)); + UE_rrc_inst[ctxt_pP->module_id].physicalConfigDedicated[eNB_index]->schedulingRequestConfig = CALLOC(1,sizeof(LTE_SchedulingRequestConfig_t)); memcpy((char*)UE_rrc_inst[ctxt_pP->module_id].physicalConfigDedicated[eNB_index]->schedulingRequestConfig, (char*)radioResourceConfigDedicated->physicalConfigDedicated->schedulingRequestConfig, @@ -1296,7 +1296,7 @@ rrc_ue_update_radioResourceConfigDedicated(RadioResourceConfigDedicated_t* radio LOG_I(RRC,"Update soundingRS_UL_ConfigDedicated config \n"); if(UE_rrc_inst[ctxt_pP->module_id].physicalConfigDedicated[eNB_index]->soundingRS_UL_ConfigDedicated == NULL) - UE_rrc_inst[ctxt_pP->module_id].physicalConfigDedicated[eNB_index]->soundingRS_UL_ConfigDedicated = CALLOC(1,sizeof(SoundingRS_UL_ConfigDedicated_t)); + UE_rrc_inst[ctxt_pP->module_id].physicalConfigDedicated[eNB_index]->soundingRS_UL_ConfigDedicated = CALLOC(1,sizeof(LTE_SoundingRS_UL_ConfigDedicated_t)); memcpy((char*)UE_rrc_inst[ctxt_pP->module_id].physicalConfigDedicated[eNB_index]->soundingRS_UL_ConfigDedicated, (char*)radioResourceConfigDedicated->physicalConfigDedicated->soundingRS_UL_ConfigDedicated, @@ -1313,7 +1313,7 @@ rrc_ue_update_radioResourceConfigDedicated(RadioResourceConfigDedicated_t* radio LOG_I(RRC,"Update antennaInfo config \n"); if(UE_rrc_inst[ctxt_pP->module_id].physicalConfigDedicated[eNB_index]->antennaInfo == NULL) - UE_rrc_inst[ctxt_pP->module_id].physicalConfigDedicated[eNB_index]->antennaInfo = CALLOC(1,sizeof(struct PhysicalConfigDedicated__antennaInfo)); + UE_rrc_inst[ctxt_pP->module_id].physicalConfigDedicated[eNB_index]->antennaInfo = CALLOC(1,sizeof(struct LTE_PhysicalConfigDedicated__antennaInfo)); memcpy((char*)UE_rrc_inst[ctxt_pP->module_id].physicalConfigDedicated[eNB_index]->antennaInfo, (char*)radioResourceConfigDedicated->physicalConfigDedicated->antennaInfo, @@ -1342,7 +1342,7 @@ rrc_ue_update_radioResourceConfigDedicated(RadioResourceConfigDedicated_t* radio LOG_I(RRC,"Update uplinkPowerControlDedicated config \n"); if(UE_rrc_inst[ctxt_pP->module_id].physicalConfigDedicated[eNB_index]->uplinkPowerControlDedicated == NULL) - UE_rrc_inst[ctxt_pP->module_id].physicalConfigDedicated[eNB_index]->uplinkPowerControlDedicated = CALLOC(1,sizeof(UplinkPowerControlDedicated_t)); + UE_rrc_inst[ctxt_pP->module_id].physicalConfigDedicated[eNB_index]->uplinkPowerControlDedicated = CALLOC(1,sizeof(LTE_UplinkPowerControlDedicated_t)); memcpy((char*)UE_rrc_inst[ctxt_pP->module_id].physicalConfigDedicated[eNB_index]->uplinkPowerControlDedicated, (char*)radioResourceConfigDedicated->physicalConfigDedicated->uplinkPowerControlDedicated, @@ -1359,7 +1359,7 @@ rrc_ue_update_radioResourceConfigDedicated(RadioResourceConfigDedicated_t* radio LOG_I(RRC,"Update tpc_PDCCH_ConfigPUCCH config \n"); if(UE_rrc_inst[ctxt_pP->module_id].physicalConfigDedicated[eNB_index]->tpc_PDCCH_ConfigPUCCH == NULL) - UE_rrc_inst[ctxt_pP->module_id].physicalConfigDedicated[eNB_index]->tpc_PDCCH_ConfigPUCCH = CALLOC(1,sizeof(TPC_PDCCH_Config_t)); + UE_rrc_inst[ctxt_pP->module_id].physicalConfigDedicated[eNB_index]->tpc_PDCCH_ConfigPUCCH = CALLOC(1,sizeof(LTE_TPC_PDCCH_Config_t)); memcpy((char*)UE_rrc_inst[ctxt_pP->module_id].physicalConfigDedicated[eNB_index]->tpc_PDCCH_ConfigPUCCH, (char*)radioResourceConfigDedicated->physicalConfigDedicated->tpc_PDCCH_ConfigPUCCH, @@ -1376,7 +1376,7 @@ rrc_ue_update_radioResourceConfigDedicated(RadioResourceConfigDedicated_t* radio LOG_I(RRC,"Update tpc_PDCCH_ConfigPUSCH config \n"); if(UE_rrc_inst[ctxt_pP->module_id].physicalConfigDedicated[eNB_index]->tpc_PDCCH_ConfigPUSCH == NULL) - UE_rrc_inst[ctxt_pP->module_id].physicalConfigDedicated[eNB_index]->tpc_PDCCH_ConfigPUSCH = CALLOC(1,sizeof(TPC_PDCCH_Config_t)); + UE_rrc_inst[ctxt_pP->module_id].physicalConfigDedicated[eNB_index]->tpc_PDCCH_ConfigPUSCH = CALLOC(1,sizeof(LTE_TPC_PDCCH_Config_t)); memcpy((char*)UE_rrc_inst[ctxt_pP->module_id].physicalConfigDedicated[eNB_index]->tpc_PDCCH_ConfigPUSCH, (char*)radioResourceConfigDedicated->physicalConfigDedicated->tpc_PDCCH_ConfigPUSCH, @@ -1394,14 +1394,14 @@ void rrc_ue_process_radioResourceConfigDedicated( const protocol_ctxt_t* const ctxt_pP, uint8_t eNB_index, - RadioResourceConfigDedicated_t* radioResourceConfigDedicated + LTE_RadioResourceConfigDedicated_t* radioResourceConfigDedicated ) //----------------------------------------------------------------------------- { long SRB_id,DRB_id; int i,cnt; - LogicalChannelConfig_t *SRB1_logicalChannelConfig,*SRB2_logicalChannelConfig; + LTE_LogicalChannelConfig_t *SRB1_logicalChannelConfig,*SRB2_logicalChannelConfig; #ifdef CBA uint8_t cba_found = 0; uint16_t cba_RNTI; @@ -1426,10 +1426,10 @@ rrc_ue_process_radioResourceConfigDedicated( // Apply macMainConfig if present if (radioResourceConfigDedicated->mac_MainConfig) { - if (radioResourceConfigDedicated->mac_MainConfig->present == RadioResourceConfigDedicated__mac_MainConfig_PR_explicitValue) { + if (radioResourceConfigDedicated->mac_MainConfig->present == LTE_RadioResourceConfigDedicated__mac_MainConfig_PR_explicitValue) { if (UE_rrc_inst[ctxt_pP->module_id].mac_MainConfig[eNB_index]) { memcpy((char*)UE_rrc_inst[ctxt_pP->module_id].mac_MainConfig[eNB_index],(char*)&radioResourceConfigDedicated->mac_MainConfig->choice.explicitValue, - sizeof(MAC_MainConfig_t)); + sizeof(LTE_MAC_MainConfig_t)); } else { UE_rrc_inst[ctxt_pP->module_id].mac_MainConfig[eNB_index] = &radioResourceConfigDedicated->mac_MainConfig->choice.explicitValue; } @@ -1440,7 +1440,7 @@ rrc_ue_process_radioResourceConfigDedicated( if (radioResourceConfigDedicated->sps_Config) { if (UE_rrc_inst[ctxt_pP->module_id].sps_Config[eNB_index]) { memcpy(UE_rrc_inst[ctxt_pP->module_id].sps_Config[eNB_index],radioResourceConfigDedicated->sps_Config, - sizeof(struct SPS_Config)); + sizeof(struct LTE_SPS_Config)); } else { UE_rrc_inst[ctxt_pP->module_id].sps_Config[eNB_index] = radioResourceConfigDedicated->sps_Config; } @@ -1486,25 +1486,25 @@ rrc_ue_process_radioResourceConfigDedicated( // Refresh SRBs rrc_pdcp_config_asn1_req(ctxt_pP, radioResourceConfigDedicated->srb_ToAddModList, - (DRB_ToAddModList_t*)NULL, - (DRB_ToReleaseList_t*)NULL, + (LTE_DRB_ToAddModList_t*)NULL, + (LTE_DRB_ToReleaseList_t*)NULL, UE_rrc_inst[ctxt_pP->module_id].ciphering_algorithm | (UE_rrc_inst[ctxt_pP->module_id].integrity_algorithm << 4), kRRCenc, kRRCint, NULL -#if (RRC_VERSION >= MAKE_VERSION(9, 0, 0)) - ,(PMCH_InfoList_r9_t *)NULL +#if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) + ,(LTE_PMCH_InfoList_r9_t *)NULL #endif ,NULL); // Refresh SRBs rrc_rlc_config_asn1_req(ctxt_pP, radioResourceConfigDedicated->srb_ToAddModList, - (DRB_ToAddModList_t*)NULL, - (DRB_ToReleaseList_t*)NULL -#if (RRC_VERSION >= MAKE_VERSION(9, 0, 0)) - ,(PMCH_InfoList_r9_t *)NULL + (LTE_DRB_ToAddModList_t*)NULL, + (LTE_DRB_ToReleaseList_t*)NULL +#if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) + ,(LTE_PMCH_InfoList_r9_t *)NULL , 0, 0 #endif ); @@ -1522,13 +1522,13 @@ rrc_ue_process_radioResourceConfigDedicated( if (SRB_id == 1) { if (UE_rrc_inst[ctxt_pP->module_id].SRB1_config[eNB_index]) { memcpy(UE_rrc_inst[ctxt_pP->module_id].SRB1_config[eNB_index],radioResourceConfigDedicated->srb_ToAddModList->list.array[cnt], - sizeof(struct SRB_ToAddMod)); + sizeof(struct LTE_SRB_ToAddMod)); } else { UE_rrc_inst[ctxt_pP->module_id].SRB1_config[eNB_index] = radioResourceConfigDedicated->srb_ToAddModList->list.array[cnt]; rrc_ue_establish_srb1(ctxt_pP->module_id,ctxt_pP->frame,eNB_index,radioResourceConfigDedicated->srb_ToAddModList->list.array[cnt]); if (UE_rrc_inst[ctxt_pP->module_id].SRB1_config[eNB_index]->logicalChannelConfig) { - if (UE_rrc_inst[ctxt_pP->module_id].SRB1_config[eNB_index]->logicalChannelConfig->present == SRB_ToAddMod__logicalChannelConfig_PR_explicitValue) { + if (UE_rrc_inst[ctxt_pP->module_id].SRB1_config[eNB_index]->logicalChannelConfig->present == LTE_SRB_ToAddMod__logicalChannelConfig_PR_explicitValue) { SRB1_logicalChannelConfig = &UE_rrc_inst[ctxt_pP->module_id].SRB1_config[eNB_index]->logicalChannelConfig->choice.explicitValue; } else { @@ -1542,17 +1542,17 @@ rrc_ue_process_radioResourceConfigDedicated( ctxt_pP->frame, ctxt_pP->module_id, eNB_index, ctxt_pP->module_id); rrc_mac_config_req_ue(ctxt_pP->module_id,0,eNB_index, - (RadioResourceConfigCommonSIB_t *)NULL, + (LTE_RadioResourceConfigCommonSIB_t *)NULL, UE_rrc_inst[ctxt_pP->module_id].physicalConfigDedicated[eNB_index], -#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) - (SCellToAddMod_r10_t *)NULL, +#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) + (LTE_SCellToAddMod_r10_t *)NULL, //struct PhysicalConfigDedicatedSCell_r10 *physicalConfigDedicatedSCell_r10, #endif - (MeasObjectToAddMod_t **)NULL, + (LTE_MeasObjectToAddMod_t **)NULL, UE_rrc_inst[ctxt_pP->module_id].mac_MainConfig[eNB_index], 1, SRB1_logicalChannelConfig, - (MeasGapConfig_t *)NULL, + (LTE_MeasGapConfig_t *)NULL, NULL, NULL, NULL, @@ -1561,18 +1561,18 @@ rrc_ue_process_radioResourceConfigDedicated( NULL, NULL, NULL -#if (RRC_VERSION >= MAKE_VERSION(9, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) , 0, - (MBSFN_AreaInfoList_r9_t *)NULL, - (PMCH_InfoList_r9_t *)NULL + (LTE_MBSFN_AreaInfoList_r9_t *)NULL, + (LTE_PMCH_InfoList_r9_t *)NULL #endif #ifdef CBA , 0, 0 #endif -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) , 0, NULL, @@ -1583,13 +1583,13 @@ rrc_ue_process_radioResourceConfigDedicated( } else { if (UE_rrc_inst[ctxt_pP->module_id].SRB2_config[eNB_index]) { memcpy(UE_rrc_inst[ctxt_pP->module_id].SRB2_config[eNB_index],radioResourceConfigDedicated->srb_ToAddModList->list.array[cnt], - sizeof(struct SRB_ToAddMod)); + sizeof(struct LTE_SRB_ToAddMod)); } else { UE_rrc_inst[ctxt_pP->module_id].SRB2_config[eNB_index] = radioResourceConfigDedicated->srb_ToAddModList->list.array[cnt]; rrc_ue_establish_srb2(ctxt_pP->module_id,ctxt_pP->frame,eNB_index,radioResourceConfigDedicated->srb_ToAddModList->list.array[cnt]); if (UE_rrc_inst[ctxt_pP->module_id].SRB2_config[eNB_index]->logicalChannelConfig) { - if (UE_rrc_inst[ctxt_pP->module_id].SRB2_config[eNB_index]->logicalChannelConfig->present == SRB_ToAddMod__logicalChannelConfig_PR_explicitValue) { + if (UE_rrc_inst[ctxt_pP->module_id].SRB2_config[eNB_index]->logicalChannelConfig->present == LTE_SRB_ToAddMod__logicalChannelConfig_PR_explicitValue) { LOG_I(RRC,"Applying Explicit SRB2 logicalChannelConfig\n"); SRB2_logicalChannelConfig = &UE_rrc_inst[ctxt_pP->module_id].SRB2_config[eNB_index]->logicalChannelConfig->choice.explicitValue; } else { @@ -1606,30 +1606,30 @@ rrc_ue_process_radioResourceConfigDedicated( eNB_index, ctxt_pP->module_id); rrc_mac_config_req_ue(ctxt_pP->module_id,0,eNB_index, - (RadioResourceConfigCommonSIB_t *)NULL, + (LTE_RadioResourceConfigCommonSIB_t *)NULL, UE_rrc_inst[ctxt_pP->module_id].physicalConfigDedicated[eNB_index], -#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) - (SCellToAddMod_r10_t *)NULL, +#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) + (LTE_SCellToAddMod_r10_t *)NULL, //struct PhysicalConfigDedicatedSCell_r10 *physicalConfigDedicatedSCell_r10, #endif - (MeasObjectToAddMod_t **)NULL, + (LTE_MeasObjectToAddMod_t **)NULL, UE_rrc_inst[ctxt_pP->module_id].mac_MainConfig[eNB_index], 2, SRB2_logicalChannelConfig, UE_rrc_inst[ctxt_pP->module_id].measGapConfig[eNB_index], - (TDD_Config_t *)NULL, - (MobilityControlInfo_t *)NULL, + (LTE_TDD_Config_t *)NULL, + (LTE_MobilityControlInfo_t *)NULL, NULL, NULL, NULL, NULL, NULL, NULL -#if (RRC_VERSION >= MAKE_VERSION(9, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) , 0, - (MBSFN_AreaInfoList_r9_t *)NULL, - (PMCH_InfoList_r9_t *)NULL + (LTE_MBSFN_AreaInfoList_r9_t *)NULL, + (LTE_PMCH_InfoList_r9_t *)NULL #endif #ifdef CBA @@ -1637,7 +1637,7 @@ rrc_ue_process_radioResourceConfigDedicated( 0, 0 #endif -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) , 0, NULL, @@ -1680,26 +1680,26 @@ rrc_ue_process_radioResourceConfigDedicated( // Refresh DRBs rrc_pdcp_config_asn1_req(ctxt_pP, - (SRB_ToAddModList_t*)NULL, + (LTE_SRB_ToAddModList_t*)NULL, radioResourceConfigDedicated->drb_ToAddModList, - (DRB_ToReleaseList_t*)NULL, + (LTE_DRB_ToReleaseList_t*)NULL, UE_rrc_inst[ctxt_pP->module_id].ciphering_algorithm | (UE_rrc_inst[ctxt_pP->module_id].integrity_algorithm << 4), NULL, NULL, kUPenc -#if (RRC_VERSION >= MAKE_VERSION(9, 0, 0)) - ,(PMCH_InfoList_r9_t *)NULL +#if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) + ,(LTE_PMCH_InfoList_r9_t *)NULL #endif , UE_rrc_inst[ctxt_pP->module_id].defaultDRB); // Refresh DRBs rrc_rlc_config_asn1_req(ctxt_pP, - (SRB_ToAddModList_t*)NULL, + (LTE_SRB_ToAddModList_t*)NULL, radioResourceConfigDedicated->drb_ToAddModList, - (DRB_ToReleaseList_t*)NULL -#if (RRC_VERSION >= MAKE_VERSION(9, 0, 0)) - ,(PMCH_InfoList_r9_t *)NULL + (LTE_DRB_ToReleaseList_t*)NULL +#if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) + ,(LTE_PMCH_InfoList_r9_t *)NULL , 0, 0 #endif ); @@ -1710,7 +1710,7 @@ rrc_ue_process_radioResourceConfigDedicated( if (UE_rrc_inst[ctxt_pP->module_id].DRB_config[eNB_index][DRB_id]) { memcpy(UE_rrc_inst[ctxt_pP->module_id].DRB_config[eNB_index][DRB_id], radioResourceConfigDedicated->drb_ToAddModList->list.array[i], - sizeof(struct DRB_ToAddMod)); + sizeof(struct LTE_DRB_ToAddMod)); } else { UE_rrc_inst[ctxt_pP->module_id].DRB_config[eNB_index][DRB_id] = radioResourceConfigDedicated->drb_ToAddModList->list.array[i]; rrc_ue_establish_drb(ctxt_pP->module_id,ctxt_pP->frame,eNB_index,radioResourceConfigDedicated->drb_ToAddModList->list.array[i]); @@ -1721,37 +1721,37 @@ rrc_ue_process_radioResourceConfigDedicated( eNB_index, ctxt_pP->module_id); rrc_mac_config_req_ue(ctxt_pP->module_id,0,eNB_index, - (RadioResourceConfigCommonSIB_t *)NULL, + (LTE_RadioResourceConfigCommonSIB_t *)NULL, UE_rrc_inst[ctxt_pP->module_id].physicalConfigDedicated[eNB_index], -#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) - (SCellToAddMod_r10_t *)NULL, +#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) + (LTE_SCellToAddMod_r10_t *)NULL, //struct PhysicalConfigDedicatedSCell_r10 *physicalConfigDedicatedSCell_r10, #endif - (MeasObjectToAddMod_t **)NULL, + (LTE_MeasObjectToAddMod_t **)NULL, UE_rrc_inst[ctxt_pP->module_id].mac_MainConfig[eNB_index], *UE_rrc_inst[ctxt_pP->module_id].DRB_config[eNB_index][DRB_id]->logicalChannelIdentity, UE_rrc_inst[ctxt_pP->module_id].DRB_config[eNB_index][DRB_id]->logicalChannelConfig, UE_rrc_inst[ctxt_pP->module_id].measGapConfig[eNB_index], - (TDD_Config_t*)NULL, - (MobilityControlInfo_t *)NULL, + (LTE_TDD_Config_t*)NULL, + (LTE_MobilityControlInfo_t *)NULL, NULL, NULL, NULL, NULL, NULL, NULL -#if (RRC_VERSION >= MAKE_VERSION(9, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) , 0, - (MBSFN_AreaInfoList_r9_t *)NULL, - (PMCH_InfoList_r9_t *)NULL + (LTE_MBSFN_AreaInfoList_r9_t *)NULL, + (LTE_PMCH_InfoList_r9_t *)NULL #endif #ifdef CBA , UE_rrc_inst[ue_mod_idP].num_active_cba_groups, // UE_rrc_inst[ue_mod_idP].cba_rnti[0] #endif -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) , 0, NULL, @@ -1772,7 +1772,7 @@ rrc_ue_process_radioResourceConfigDedicated( void rrc_ue_process_securityModeCommand( const protocol_ctxt_t* const ctxt_pP, - SecurityModeCommand_t* const securityModeCommand, + LTE_SecurityModeCommand_t* const securityModeCommand, const uint8_t eNB_index ) //----------------------------------------------------------------------------- @@ -1780,7 +1780,7 @@ rrc_ue_process_securityModeCommand( asn_enc_rval_t enc_rval; - UL_DCCH_Message_t ul_dcch_msg; + LTE_UL_DCCH_Message_t ul_dcch_msg; // SecurityModeCommand_t SecurityModeCommand; uint8_t buffer[200]; int i, securityMode; @@ -1789,36 +1789,36 @@ rrc_ue_process_securityModeCommand( ctxt_pP->module_id,ctxt_pP->frame, ctxt_pP->subframe, eNB_index); switch (securityModeCommand->criticalExtensions.choice.c1.choice.securityModeCommand_r8.securityConfigSMC.securityAlgorithmConfig.cipheringAlgorithm) { - case CipheringAlgorithm_r12_eea0: + case LTE_CipheringAlgorithm_r12_eea0: LOG_I(RRC,"[UE %d] Security algorithm is set to eea0\n", ctxt_pP->module_id); - securityMode= CipheringAlgorithm_r12_eea0; + securityMode= LTE_CipheringAlgorithm_r12_eea0; break; - case CipheringAlgorithm_r12_eea1: + case LTE_CipheringAlgorithm_r12_eea1: LOG_I(RRC,"[UE %d] Security algorithm is set to eea1\n",ctxt_pP->module_id); - securityMode= CipheringAlgorithm_r12_eea1; + securityMode= LTE_CipheringAlgorithm_r12_eea1; break; - case CipheringAlgorithm_r12_eea2: + case LTE_CipheringAlgorithm_r12_eea2: LOG_I(RRC,"[UE %d] Security algorithm is set to eea2\n", ctxt_pP->module_id); - securityMode = CipheringAlgorithm_r12_eea2; + securityMode = LTE_CipheringAlgorithm_r12_eea2; break; default: LOG_I(RRC,"[UE %d] Security algorithm is set to none\n",ctxt_pP->module_id); - securityMode = CipheringAlgorithm_r12_spare1; + securityMode = LTE_CipheringAlgorithm_r12_spare1; break; } switch (securityModeCommand->criticalExtensions.choice.c1.choice.securityModeCommand_r8.securityConfigSMC.securityAlgorithmConfig.integrityProtAlgorithm) { - case SecurityAlgorithmConfig__integrityProtAlgorithm_eia1: + case LTE_SecurityAlgorithmConfig__integrityProtAlgorithm_eia1: LOG_I(RRC,"[UE %d] Integrity protection algorithm is set to eia1\n",ctxt_pP->module_id); securityMode |= 1 << 5; break; - case SecurityAlgorithmConfig__integrityProtAlgorithm_eia2: + case LTE_SecurityAlgorithmConfig__integrityProtAlgorithm_eia2: LOG_I(RRC,"[UE %d] Integrity protection algorithm is set to eia2\n",ctxt_pP->module_id); securityMode |= 1 << 6; break; @@ -1837,17 +1837,17 @@ rrc_ue_process_securityModeCommand( UE_rrc_inst[ctxt_pP->module_id].integrity_algorithm = securityModeCommand->criticalExtensions.choice.c1.choice.securityModeCommand_r8.securityConfigSMC.securityAlgorithmConfig.integrityProtAlgorithm; - memset((void *)&ul_dcch_msg,0,sizeof(UL_DCCH_Message_t)); + memset((void *)&ul_dcch_msg,0,sizeof(LTE_UL_DCCH_Message_t)); //memset((void *)&SecurityModeCommand,0,sizeof(SecurityModeCommand_t)); - ul_dcch_msg.message.present = UL_DCCH_MessageType_PR_c1; + ul_dcch_msg.message.present = LTE_UL_DCCH_MessageType_PR_c1; if (securityMode >= NO_SECURITY_MODE) { LOG_I(RRC, "rrc_ue_process_securityModeCommand, security mode complete case \n"); - ul_dcch_msg.message.choice.c1.present = UL_DCCH_MessageType__c1_PR_securityModeComplete; + ul_dcch_msg.message.choice.c1.present = LTE_UL_DCCH_MessageType__c1_PR_securityModeComplete; } else { LOG_I(RRC, "rrc_ue_process_securityModeCommand, security mode failure case \n"); - ul_dcch_msg.message.choice.c1.present = UL_DCCH_MessageType__c1_PR_securityModeFailure; + ul_dcch_msg.message.choice.c1.present = LTE_UL_DCCH_MessageType__c1_PR_securityModeFailure; } @@ -1906,20 +1906,20 @@ rrc_ue_process_securityModeCommand( #endif //#if defined(ENABLE_SECURITY) - if (securityModeCommand->criticalExtensions.present == SecurityModeCommand__criticalExtensions_PR_c1) { - if (securityModeCommand->criticalExtensions.choice.c1.present != SecurityModeCommand__criticalExtensions__c1_PR_securityModeCommand_r8) + if (securityModeCommand->criticalExtensions.present == LTE_SecurityModeCommand__criticalExtensions_PR_c1) { + if (securityModeCommand->criticalExtensions.choice.c1.present != LTE_SecurityModeCommand__criticalExtensions__c1_PR_securityModeCommand_r8) LOG_W(RRC,"securityModeCommand->criticalExtensions.choice.c1.present (%d) != SecurityModeCommand__criticalExtensions__c1_PR_securityModeCommand_r8\n", securityModeCommand->criticalExtensions.choice.c1.present); ul_dcch_msg.message.choice.c1.choice.securityModeComplete.rrc_TransactionIdentifier = securityModeCommand->rrc_TransactionIdentifier; - ul_dcch_msg.message.choice.c1.choice.securityModeComplete.criticalExtensions.present = SecurityModeCommand__criticalExtensions_PR_c1; + ul_dcch_msg.message.choice.c1.choice.securityModeComplete.criticalExtensions.present = LTE_SecurityModeCommand__criticalExtensions_PR_c1; ul_dcch_msg.message.choice.c1.choice.securityModeComplete.criticalExtensions.choice.securityModeComplete_r8.nonCriticalExtension =NULL; LOG_I(RRC,"[UE %d] SFN/SF %d/%d: Receiving from SRB1 (DL-DCCH), encoding securityModeComplete (eNB %d), rrc_TransactionIdentifier: %ld\n", ctxt_pP->module_id,ctxt_pP->frame, ctxt_pP->subframe, eNB_index, securityModeCommand->rrc_TransactionIdentifier); - enc_rval = uper_encode_to_buffer(&asn_DEF_UL_DCCH_Message, + enc_rval = uper_encode_to_buffer(&asn_DEF_LTE_UL_DCCH_Message, NULL, (void*)&ul_dcch_msg, buffer, @@ -1928,7 +1928,7 @@ rrc_ue_process_securityModeCommand( enc_rval.failed_type->name, enc_rval.encoded); if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) { - xer_fprint(stdout, &asn_DEF_UL_DCCH_Message, (void*)&ul_dcch_msg); + xer_fprint(stdout, &asn_DEF_LTE_UL_DCCH_Message, (void*)&ul_dcch_msg); } #if defined(ENABLE_ITTI) @@ -1937,7 +1937,7 @@ rrc_ue_process_securityModeCommand( char message_string[20000]; size_t message_string_size; - if ((message_string_size = xer_sprint(message_string, sizeof(message_string), &asn_DEF_UL_DCCH_Message, (void *) &ul_dcch_msg)) > 0) { + if ((message_string_size = xer_sprint(message_string, sizeof(message_string), &asn_DEF_LTE_UL_DCCH_Message, (void *) &ul_dcch_msg)) > 0) { MessageDef *msg_p; msg_p = itti_alloc_new_message_sized (TASK_RRC_UE, RRC_UL_DCCH, message_string_size + sizeof (IttiMsgText)); @@ -1975,7 +1975,7 @@ rrc_ue_process_securityModeCommand( void rrc_ue_process_ueCapabilityEnquiry( const protocol_ctxt_t* const ctxt_pP, - UECapabilityEnquiry_t* UECapabilityEnquiry, + LTE_UECapabilityEnquiry_t* UECapabilityEnquiry, uint8_t eNB_index ) //----------------------------------------------------------------------------- @@ -1983,10 +1983,10 @@ rrc_ue_process_ueCapabilityEnquiry( asn_enc_rval_t enc_rval; - UL_DCCH_Message_t ul_dcch_msg; + LTE_UL_DCCH_Message_t ul_dcch_msg; - UE_CapabilityRAT_Container_t ue_CapabilityRAT_Container; + LTE_UE_CapabilityRAT_Container_t ue_CapabilityRAT_Container; uint8_t buffer[200]; int i; @@ -1997,14 +1997,14 @@ rrc_ue_process_ueCapabilityEnquiry( eNB_index); - memset((void *)&ul_dcch_msg,0,sizeof(UL_DCCH_Message_t)); - memset((void *)&ue_CapabilityRAT_Container,0,sizeof(UE_CapabilityRAT_Container_t)); + memset((void *)&ul_dcch_msg,0,sizeof(LTE_UL_DCCH_Message_t)); + memset((void *)&ue_CapabilityRAT_Container,0,sizeof(LTE_UE_CapabilityRAT_Container_t)); - ul_dcch_msg.message.present = UL_DCCH_MessageType_PR_c1; - ul_dcch_msg.message.choice.c1.present = UL_DCCH_MessageType__c1_PR_ueCapabilityInformation; + ul_dcch_msg.message.present = LTE_UL_DCCH_MessageType_PR_c1; + ul_dcch_msg.message.choice.c1.present = LTE_UL_DCCH_MessageType__c1_PR_ueCapabilityInformation; ul_dcch_msg.message.choice.c1.choice.ueCapabilityInformation.rrc_TransactionIdentifier = UECapabilityEnquiry->rrc_TransactionIdentifier; - ue_CapabilityRAT_Container.rat_Type = RAT_Type_eutra; + ue_CapabilityRAT_Container.rat_Type = LTE_RAT_Type_eutra; OCTET_STRING_fromBuf(&ue_CapabilityRAT_Container.ueCapabilityRAT_Container, (const char*)UE_rrc_inst[ctxt_pP->module_id].UECapability, UE_rrc_inst[ctxt_pP->module_id].UECapability_size); @@ -2012,34 +2012,34 @@ rrc_ue_process_ueCapabilityEnquiry( // ue_CapabilityRAT_Container.ueCapabilityRAT_Container.size = UE_rrc_inst[ue_mod_idP].UECapability_size; - AssertFatal(UECapabilityEnquiry->criticalExtensions.present == UECapabilityEnquiry__criticalExtensions_PR_c1, + AssertFatal(UECapabilityEnquiry->criticalExtensions.present == LTE_UECapabilityEnquiry__criticalExtensions_PR_c1, "UECapabilityEnquiry->criticalExtensions.present (%d) != UECapabilityEnquiry__criticalExtensions_PR_c1 (%d)\n", - UECapabilityEnquiry->criticalExtensions.present,UECapabilityEnquiry__criticalExtensions_PR_c1); + UECapabilityEnquiry->criticalExtensions.present,LTE_UECapabilityEnquiry__criticalExtensions_PR_c1); - if (UECapabilityEnquiry->criticalExtensions.choice.c1.present != UECapabilityEnquiry__criticalExtensions__c1_PR_ueCapabilityEnquiry_r8) + if (UECapabilityEnquiry->criticalExtensions.choice.c1.present != LTE_UECapabilityEnquiry__criticalExtensions__c1_PR_ueCapabilityEnquiry_r8) LOG_I(RRC,"UECapabilityEnquiry->criticalExtensions.choice.c1.present (%d) != UECapabilityEnquiry__criticalExtensions__c1_PR_ueCapabilityEnquiry_r8)\n", UECapabilityEnquiry->criticalExtensions.choice.c1.present); - ul_dcch_msg.message.choice.c1.choice.ueCapabilityInformation.criticalExtensions.present = UECapabilityInformation__criticalExtensions_PR_c1; + ul_dcch_msg.message.choice.c1.choice.ueCapabilityInformation.criticalExtensions.present = LTE_UECapabilityInformation__criticalExtensions_PR_c1; ul_dcch_msg.message.choice.c1.choice.ueCapabilityInformation.criticalExtensions.choice.c1.present = - UECapabilityInformation__criticalExtensions__c1_PR_ueCapabilityInformation_r8; + LTE_UECapabilityInformation__criticalExtensions__c1_PR_ueCapabilityInformation_r8; ul_dcch_msg.message.choice.c1.choice.ueCapabilityInformation.criticalExtensions.choice.c1.choice.ueCapabilityInformation_r8.ue_CapabilityRAT_ContainerList.list.count =0; for (i=0; icriticalExtensions.choice.c1.choice.ueCapabilityEnquiry_r8.ue_CapabilityRequest.list.count; i++) { if (*UECapabilityEnquiry->criticalExtensions.choice.c1.choice.ueCapabilityEnquiry_r8.ue_CapabilityRequest.list.array[i] - == RAT_Type_eutra) { + == LTE_RAT_Type_eutra) { ASN_SEQUENCE_ADD( &ul_dcch_msg.message.choice.c1.choice.ueCapabilityInformation.criticalExtensions.choice.c1.choice.ueCapabilityInformation_r8.ue_CapabilityRAT_ContainerList.list, &ue_CapabilityRAT_Container); - enc_rval = uper_encode_to_buffer(&asn_DEF_UL_DCCH_Message, NULL, (void*) &ul_dcch_msg, buffer, 100); + enc_rval = uper_encode_to_buffer(&asn_DEF_LTE_UL_DCCH_Message, NULL, (void*) &ul_dcch_msg, buffer, 100); AssertFatal (enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %jd)!\n", enc_rval.failed_type->name, enc_rval.encoded); if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) { - xer_fprint(stdout, &asn_DEF_UL_DCCH_Message, (void*)&ul_dcch_msg); + xer_fprint(stdout, &asn_DEF_LTE_UL_DCCH_Message, (void*)&ul_dcch_msg); } #if defined(ENABLE_ITTI) @@ -2048,7 +2048,7 @@ rrc_ue_process_ueCapabilityEnquiry( char message_string[20000]; size_t message_string_size; - if ((message_string_size = xer_sprint(message_string, sizeof(message_string), &asn_DEF_UL_DCCH_Message, (void *) &ul_dcch_msg)) > 0) { + if ((message_string_size = xer_sprint(message_string, sizeof(message_string), &asn_DEF_LTE_UL_DCCH_Message, (void *) &ul_dcch_msg)) > 0) { MessageDef *msg_p; msg_p = itti_alloc_new_message_sized (TASK_RRC_UE, RRC_UL_DCCH, message_string_size + sizeof (IttiMsgText)); @@ -2086,7 +2086,7 @@ rrc_ue_process_ueCapabilityEnquiry( void rrc_ue_process_rrcConnectionReconfiguration( const protocol_ctxt_t* const ctxt_pP, - RRCConnectionReconfiguration_t *rrcConnectionReconfiguration, + LTE_RRCConnectionReconfiguration_t *rrcConnectionReconfiguration, uint8_t eNB_index ) //----------------------------------------------------------------------------- @@ -2095,10 +2095,10 @@ rrc_ue_process_rrcConnectionReconfiguration( LOG_I(RRC,"[UE %d] Frame %d: Receiving from SRB1 (DL-DCCH), Processing RRCConnectionReconfiguration (eNB %d)\n", ctxt_pP->module_id,ctxt_pP->frame,eNB_index); - if (rrcConnectionReconfiguration->criticalExtensions.present == RRCConnectionReconfiguration__criticalExtensions_PR_c1) { + if (rrcConnectionReconfiguration->criticalExtensions.present == LTE_RRCConnectionReconfiguration__criticalExtensions_PR_c1) { if (rrcConnectionReconfiguration->criticalExtensions.choice.c1.present == - RRCConnectionReconfiguration__criticalExtensions__c1_PR_rrcConnectionReconfiguration_r8) { - RRCConnectionReconfiguration_r8_IEs_t* rrcConnectionReconfiguration_r8 = + LTE_RRCConnectionReconfiguration__criticalExtensions__c1_PR_rrcConnectionReconfiguration_r8) { + LTE_RRCConnectionReconfiguration_r8_IEs_t* rrcConnectionReconfiguration_r8 = &rrcConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8; if (rrcConnectionReconfiguration_r8->mobilityControlInfo) { @@ -2134,14 +2134,14 @@ rrc_ue_process_rrcConnectionReconfiguration( != NULL) && (rrcConnectionReconfiguration_r8->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->sl_CommConfig_r12 != NULL)) { - if (rrcConnectionReconfiguration_r8->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->sl_CommConfig_r12->commTxResources_r12->present != SL_CommConfig_r12__commTxResources_r12_PR_NOTHING){ + if (rrcConnectionReconfiguration_r8->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->sl_CommConfig_r12->commTxResources_r12->present != LTE_SL_CommConfig_r12__commTxResources_r12_PR_NOTHING){ LOG_I(RRC,"sl-CommConfig is present\n"); //process sl-CommConfig rrc_ue_process_sidelink_radioResourceConfig(ctxt_pP->module_id,eNB_index, - (SystemInformationBlockType18_r12_t *)NULL, - (SystemInformationBlockType19_r12_t *)NULL, + (LTE_SystemInformationBlockType18_r12_t *)NULL, + (LTE_SystemInformationBlockType19_r12_t *)NULL, rrcConnectionReconfiguration_r8->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->sl_CommConfig_r12, - (SL_DiscConfig_r12_t *)NULL + (LTE_SL_DiscConfig_r12_t *)NULL ); } } @@ -2240,7 +2240,7 @@ void rrc_ue_process_mobilityControlInfo( const protocol_ctxt_t* const ctxt_pP, const uint8_t eNB_index, - struct MobilityControlInfo* const mobilityControlInfo + struct LTE_MobilityControlInfo* const mobilityControlInfo ) //----------------------------------------------------------------------------- { @@ -2282,7 +2282,7 @@ rrc_ue_process_mobilityControlInfo( NULL, // key rrc encryption NULL, // key rrc integrity NULL // key encryption -#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) ,NULL #endif ,NULL); @@ -2291,7 +2291,7 @@ rrc_ue_process_mobilityControlInfo( NULL,// SRB_ToAddModList NULL,// DRB_ToAddModList drb2release_list // DRB_ToReleaseList -#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) ,NULL #endif ,NULL); @@ -2324,18 +2324,18 @@ rrc_ue_process_mobilityControlInfo( rrc_mac_config_req_ue(ctxt_pP->module_id, 0, eNB_index, - (RadioResourceConfigCommonSIB_t *)NULL, - (struct PhysicalConfigDedicated *)NULL, -#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) - (SCellToAddMod_r10_t *)NULL, + (LTE_RadioResourceConfigCommonSIB_t *)NULL, + (struct LTE_PhysicalConfigDedicated *)NULL, +#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) + (LTE_SCellToAddMod_r10_t *)NULL, //(struct PhysicalConfigDedicatedSCell_r10 *)NULL, #endif - (MeasObjectToAddMod_t **)NULL, - (MAC_MainConfig_t *)NULL, + (LTE_MeasObjectToAddMod_t **)NULL, + (LTE_MAC_MainConfig_t *)NULL, 0, - (struct LogicalChannelConfig *)NULL, - (MeasGapConfig_t *)NULL, - (TDD_Config_t *)NULL, + (struct LTE_LogicalChannelConfig *)NULL, + (LTE_MeasGapConfig_t *)NULL, + (LTE_TDD_Config_t *)NULL, mobilityControlInfo, (uint8_t *)NULL, (uint16_t *)NULL, @@ -2343,16 +2343,16 @@ rrc_ue_process_mobilityControlInfo( NULL, NULL, NULL -#if (RRC_VERSION >= MAKE_VERSION(9, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) ,0, - (MBSFN_AreaInfoList_r9_t *)NULL, - (PMCH_InfoList_r9_t *)NULL + (LTE_MBSFN_AreaInfoList_r9_t *)NULL, + (LTE_PMCH_InfoList_r9_t *)NULL #endif #ifdef CBA ,0, 0 #endif -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) , 0, NULL, @@ -2396,7 +2396,7 @@ rrc_ue_decode_dcch( { //DL_DCCH_Message_t dldcchmsg; - DL_DCCH_Message_t *dl_dcch_msg=NULL;//&dldcchmsg; + LTE_DL_DCCH_Message_t *dl_dcch_msg=NULL;//&dldcchmsg; // asn_dec_rval_t dec_rval; // int i; uint8_t target_eNB_index=0xFF; @@ -2420,13 +2420,13 @@ rrc_ue_decode_dcch( LOG_T(RRC, "\n"); */ uper_decode(NULL, - &asn_DEF_DL_DCCH_Message, + &asn_DEF_LTE_DL_DCCH_Message, (void**)&dl_dcch_msg, (uint8_t*)Buffer, RRC_BUF_SIZE,0,0); if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) { - xer_fprint(stdout,&asn_DEF_DL_DCCH_Message,(void*)dl_dcch_msg); + xer_fprint(stdout,&asn_DEF_LTE_DL_DCCH_Message,(void*)dl_dcch_msg); } #if defined(ENABLE_ITTI) @@ -2442,7 +2442,7 @@ rrc_ue_decode_dcch( char message_string[30000]; size_t message_string_size; - if ((message_string_size = xer_sprint(message_string, sizeof(message_string), &asn_DEF_DL_DCCH_Message, (void *)dl_dcch_msg)) > 0) { + if ((message_string_size = xer_sprint(message_string, sizeof(message_string), &asn_DEF_LTE_DL_DCCH_Message, (void *)dl_dcch_msg)) > 0) { msg_p = itti_alloc_new_message_sized (TASK_RRC_UE, RRC_DL_DCCH, message_string_size + sizeof (IttiMsgText)); msg_p->ittiMsg.rrc_dl_dcch.size = message_string_size; memcpy(&msg_p->ittiMsg.rrc_dl_dcch.text, message_string, message_string_size); @@ -2453,31 +2453,31 @@ rrc_ue_decode_dcch( # endif #endif - if (dl_dcch_msg->message.present == DL_DCCH_MessageType_PR_c1) { + if (dl_dcch_msg->message.present == LTE_DL_DCCH_MessageType_PR_c1) { if (UE_rrc_inst[ctxt_pP->module_id].Info[eNB_indexP].State >= RRC_CONNECTED) { switch (dl_dcch_msg->message.choice.c1.present) { - case DL_DCCH_MessageType__c1_PR_NOTHING: + case LTE_DL_DCCH_MessageType__c1_PR_NOTHING: LOG_I(RRC, "[UE %d] Frame %d : Received PR_NOTHING on DL-DCCH-Message\n", ctxt_pP->module_id, ctxt_pP->frame); return; - case DL_DCCH_MessageType__c1_PR_csfbParametersResponseCDMA2000: + case LTE_DL_DCCH_MessageType__c1_PR_csfbParametersResponseCDMA2000: break; - case DL_DCCH_MessageType__c1_PR_dlInformationTransfer: { + case LTE_DL_DCCH_MessageType__c1_PR_dlInformationTransfer: { #if defined(ENABLE_ITTI) - DLInformationTransfer_t *dlInformationTransfer = &dl_dcch_msg->message.choice.c1.choice.dlInformationTransfer; + LTE_DLInformationTransfer_t *dlInformationTransfer = &dl_dcch_msg->message.choice.c1.choice.dlInformationTransfer; - if ((dlInformationTransfer->criticalExtensions.present == DLInformationTransfer__criticalExtensions_PR_c1) + if ((dlInformationTransfer->criticalExtensions.present == LTE_DLInformationTransfer__criticalExtensions_PR_c1) && (dlInformationTransfer->criticalExtensions.choice.c1.present - == DLInformationTransfer__criticalExtensions__c1_PR_dlInformationTransfer_r8) + == LTE_DLInformationTransfer__criticalExtensions__c1_PR_dlInformationTransfer_r8) && (dlInformationTransfer->criticalExtensions.choice.c1.choice.dlInformationTransfer_r8.dedicatedInfoType.present - == DLInformationTransfer_r8_IEs__dedicatedInfoType_PR_dedicatedInfoNAS)) { + == LTE_DLInformationTransfer_r8_IEs__dedicatedInfoType_PR_dedicatedInfoNAS)) { /* This message hold a dedicated info NAS payload, forward it to NAS */ - struct DLInformationTransfer_r8_IEs__dedicatedInfoType *dedicatedInfoType = + struct LTE_DLInformationTransfer_r8_IEs__dedicatedInfoType *dedicatedInfoType = &dlInformationTransfer->criticalExtensions.choice.c1.choice.dlInformationTransfer_r8.dedicatedInfoType; uint32_t pdu_length; uint8_t *pdu_buffer; @@ -2498,13 +2498,13 @@ rrc_ue_decode_dcch( break; } - case DL_DCCH_MessageType__c1_PR_handoverFromEUTRAPreparationRequest: + case LTE_DL_DCCH_MessageType__c1_PR_handoverFromEUTRAPreparationRequest: break; - case DL_DCCH_MessageType__c1_PR_mobilityFromEUTRACommand: + case LTE_DL_DCCH_MessageType__c1_PR_mobilityFromEUTRACommand: break; - case DL_DCCH_MessageType__c1_PR_rrcConnectionReconfiguration: + case LTE_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 @@ -2661,8 +2661,8 @@ rrc_ue_decode_dcch( if (send_ue_information == 0) { LOG_I(RRC, "TEST SidelinkUEInformation [UE %d] Received (eNB %d)\n", ctxt_pP->module_id, eNB_indexP); - SL_DestinationInfoList_r12_t *destinationInfoList = CALLOC(1, sizeof(SL_DestinationInfoList_r12_t)); - SL_DestinationIdentity_r12_t *sl_destination_identity = CALLOC(1, sizeof(SL_DestinationIdentity_r12_t)); + LTE_SL_DestinationInfoList_r12_t *destinationInfoList = CALLOC(1, sizeof(LTE_SL_DestinationInfoList_r12_t)); + LTE_SL_DestinationIdentity_r12_t *sl_destination_identity = CALLOC(1, sizeof(LTE_SL_DestinationIdentity_r12_t)); sl_destination_identity->size = 3; sl_destination_identity->buf = CALLOC(1,3); sl_destination_identity->buf[0] = 0x00; @@ -2675,14 +2675,14 @@ rrc_ue_decode_dcch( } break; - case DL_DCCH_MessageType__c1_PR_rrcConnectionRelease: + case LTE_DL_DCCH_MessageType__c1_PR_rrcConnectionRelease: #if defined(ENABLE_ITTI) msg_p = itti_alloc_new_message(TASK_RRC_UE, NAS_CONN_RELEASE_IND); if ((dl_dcch_msg->message.choice.c1.choice.rrcConnectionRelease.criticalExtensions.present - == RRCConnectionRelease__criticalExtensions_PR_c1) + == LTE_RRCConnectionRelease__criticalExtensions_PR_c1) && (dl_dcch_msg->message.choice.c1.choice.rrcConnectionRelease.criticalExtensions.choice.c1.present - == RRCConnectionRelease__criticalExtensions__c1_PR_rrcConnectionRelease_r8)) { + == LTE_RRCConnectionRelease__criticalExtensions__c1_PR_rrcConnectionRelease_r8)) { NAS_CONN_RELEASE_IND(msg_p).cause = dl_dcch_msg->message.choice.c1.choice.rrcConnectionRelease.criticalExtensions.choice.c1.choice.rrcConnectionRelease_r8.releaseCause; } @@ -2696,7 +2696,7 @@ rrc_ue_decode_dcch( #endif break; - case DL_DCCH_MessageType__c1_PR_securityModeCommand: + case LTE_DL_DCCH_MessageType__c1_PR_securityModeCommand: LOG_I(RRC, "[UE %d] Received securityModeCommand (eNB %d)\n", ctxt_pP->module_id, eNB_indexP); rrc_ue_process_securityModeCommand( @@ -2705,7 +2705,7 @@ rrc_ue_decode_dcch( eNB_indexP); break; - case DL_DCCH_MessageType__c1_PR_ueCapabilityEnquiry: + case LTE_DL_DCCH_MessageType__c1_PR_ueCapabilityEnquiry: LOG_I(RRC, "[UE %d] Received Capability Enquiry (eNB %d)\n", ctxt_pP->module_id, eNB_indexP); @@ -2715,26 +2715,26 @@ rrc_ue_decode_dcch( eNB_indexP); break; - case DL_DCCH_MessageType__c1_PR_counterCheck: + case LTE_DL_DCCH_MessageType__c1_PR_counterCheck: break; -#if (RRC_VERSION >= MAKE_VERSION(9, 0, 0)) - case DL_DCCH_MessageType__c1_PR_ueInformationRequest_r9: +#if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) + case LTE_DL_DCCH_MessageType__c1_PR_ueInformationRequest_r9: break; #endif -#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) - case DL_DCCH_MessageType__c1_PR_loggedMeasurementConfiguration_r10: +#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) + case LTE_DL_DCCH_MessageType__c1_PR_loggedMeasurementConfiguration_r10: break; - case DL_DCCH_MessageType__c1_PR_rnReconfiguration_r10: + case LTE_DL_DCCH_MessageType__c1_PR_rnReconfiguration_r10: break; #endif - case DL_DCCH_MessageType__c1_PR_spare1: - case DL_DCCH_MessageType__c1_PR_spare2: - case DL_DCCH_MessageType__c1_PR_spare3: -#if (RRC_VERSION < MAKE_VERSION(14, 0, 0)) - case DL_DCCH_MessageType__c1_PR_spare4: + case LTE_DL_DCCH_MessageType__c1_PR_spare1: + case LTE_DL_DCCH_MessageType__c1_PR_spare2: + case LTE_DL_DCCH_MessageType__c1_PR_spare3: +#if (LTE_RRC_VERSION < MAKE_VERSION(14, 0, 0)) + case LTE_DL_DCCH_MessageType__c1_PR_spare4: #endif break; @@ -2789,13 +2789,13 @@ const char* SIBallowed( long value ) const char* SIB2SoundingPresent( int value ) { switch (value) { - case SoundingRS_UL_ConfigCommon_PR_NOTHING: + case LTE_SoundingRS_UL_ConfigCommon_PR_NOTHING: return "NOTHING"; - case SoundingRS_UL_ConfigCommon_PR_release: + case LTE_SoundingRS_UL_ConfigCommon_PR_release: return "release"; - case SoundingRS_UL_ConfigCommon_PR_setup: + case LTE_SoundingRS_UL_ConfigCommon_PR_setup: return "setup"; } @@ -2927,8 +2927,8 @@ int decode_BCCH_DLSCH_Message( const uint8_t rsrq, const uint8_t rsrp ) { - BCCH_DL_SCH_Message_t *bcch_message = NULL; - SystemInformationBlockType1_t* sib1 = UE_rrc_inst[ctxt_pP->module_id].sib1[eNB_index]; + LTE_BCCH_DL_SCH_Message_t *bcch_message = NULL; + LTE_SystemInformationBlockType1_t* sib1 = UE_rrc_inst[ctxt_pP->module_id].sib1[eNB_index]; int i; VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_UE_DECODE_BCCH, VCD_FUNCTION_IN ); @@ -2944,7 +2944,7 @@ int decode_BCCH_DLSCH_Message( rrc_set_sub_state( ctxt_pP->module_id, RRC_SUB_STATE_IDLE_RECEIVING_SIB ); asn_dec_rval_t dec_rval = uper_decode_complete( NULL, - &asn_DEF_BCCH_DL_SCH_Message, + &asn_DEF_LTE_BCCH_DL_SCH_Message, (void **)&bcch_message, (const void *)Sdu, Sdu_len ); @@ -2957,7 +2957,7 @@ int decode_BCCH_DLSCH_Message( printf("%02x ",Sdu[i]); printf("\n"); // free the memory - SEQUENCE_free( &asn_DEF_BCCH_DL_SCH_Message, (void*)bcch_message, 1 ); + SEQUENCE_free( &asn_DEF_LTE_BCCH_DL_SCH_Message, (void*)bcch_message, 1 ); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_UE_DECODE_BCCH, VCD_FUNCTION_OUT ); return -1; } @@ -2977,7 +2977,7 @@ int decode_BCCH_DLSCH_Message( char message_string[15000]; size_t message_string_size; - if ((message_string_size = xer_sprint(message_string, sizeof(message_string), &asn_DEF_BCCH_DL_SCH_Message, (void *)bcch_message)) > 0) { + if ((message_string_size = xer_sprint(message_string, sizeof(message_string), &asn_DEF_LTE_BCCH_DL_SCH_Message, (void *)bcch_message)) > 0) { MessageDef *msg_p; msg_p = itti_alloc_new_message_sized (TASK_RRC_UE, RRC_DL_BCCH, message_string_size + sizeof (IttiMsgText)); @@ -2990,16 +2990,16 @@ int decode_BCCH_DLSCH_Message( # endif #endif - if (bcch_message->message.present == BCCH_DL_SCH_MessageType_PR_c1) { + if (bcch_message->message.present == LTE_BCCH_DL_SCH_MessageType_PR_c1) { switch (bcch_message->message.choice.c1.present) { - case BCCH_DL_SCH_MessageType__c1_PR_systemInformationBlockType1: + case LTE_BCCH_DL_SCH_MessageType__c1_PR_systemInformationBlockType1: if ((ctxt_pP->frame % 2) == 0) { // even frame if ((UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIStatus&1) == 0) { - SystemInformationBlockType1_t* sib1 = UE_rrc_inst[ctxt_pP->module_id].sib1[eNB_index]; + LTE_SystemInformationBlockType1_t* sib1 = UE_rrc_inst[ctxt_pP->module_id].sib1[eNB_index]; memcpy( (void*)sib1, (void*)&bcch_message->message.choice.c1.choice.systemInformationBlockType1, - sizeof(SystemInformationBlockType1_t) ); + sizeof(LTE_SystemInformationBlockType1_t) ); LOG_D( RRC, "[UE %"PRIu8"] Decoding First SIB1\n", ctxt_pP->module_id ); decode_SIB1( ctxt_pP, eNB_index, rsrq, rsrp ); @@ -3008,14 +3008,14 @@ int decode_BCCH_DLSCH_Message( break; - case BCCH_DL_SCH_MessageType__c1_PR_systemInformation: + case LTE_BCCH_DL_SCH_MessageType__c1_PR_systemInformation: if ((UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIStatus&1) == 1) { // SIB1 with schedulingInfoList is available - SystemInformation_t* si = UE_rrc_inst[ctxt_pP->module_id].si[eNB_index]; + LTE_SystemInformation_t* si = UE_rrc_inst[ctxt_pP->module_id].si[eNB_index]; memcpy( si, &bcch_message->message.choice.c1.choice.systemInformation, - sizeof(SystemInformation_t) ); + sizeof(LTE_SystemInformation_t) ); LOG_I( RRC, "[UE %"PRIu8"] Decoding SI for frameP %"PRIu32"\n", ctxt_pP->module_id, @@ -3027,7 +3027,7 @@ int decode_BCCH_DLSCH_Message( break; - case BCCH_DL_SCH_MessageType__c1_PR_NOTHING: + case LTE_BCCH_DL_SCH_MessageType__c1_PR_NOTHING: default: break; } @@ -3054,13 +3054,13 @@ int decode_PCCH_DLSCH_Message( uint8_t* const Sdu, const uint8_t Sdu_len) { - PCCH_Message_t *pcch_message = NULL; + LTE_PCCH_Message_t *pcch_message = NULL; int i; VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_UE_DECODE_PCCH, VCD_FUNCTION_IN ); asn_dec_rval_t dec_rval = uper_decode_complete( NULL, - &asn_DEF_PCCH_Message, + &asn_DEF_LTE_PCCH_Message, (void **)&pcch_message, (const void *)Sdu, Sdu_len ); @@ -3073,7 +3073,7 @@ int decode_PCCH_DLSCH_Message( printf("%02x ",Sdu[i]); printf("\n"); // free the memory - SEQUENCE_free( &asn_DEF_PCCH_Message, (void*)pcch_message, 1 ); + SEQUENCE_free( &asn_DEF_LTE_PCCH_Message, (void*)pcch_message, 1 ); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_UE_DECODE_PCCH, VCD_FUNCTION_OUT ); return -1; } @@ -3084,13 +3084,13 @@ int decode_PCCH_DLSCH_Message( //----------------------------------------------------------------------------- int decode_SIB1( const protocol_ctxt_t* const ctxt_pP, const uint8_t eNB_index, const uint8_t rsrq, const uint8_t rsrp ) { - SystemInformationBlockType1_t* sib1 = UE_rrc_inst[ctxt_pP->module_id].sib1[eNB_index]; + LTE_SystemInformationBlockType1_t* sib1 = UE_rrc_inst[ctxt_pP->module_id].sib1[eNB_index]; VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_RRC_UE_DECODE_SIB1, VCD_FUNCTION_IN ); LOG_I( RRC, "[UE %d] : Dumping SIB 1\n", ctxt_pP->module_id ); - PLMN_Identity_t *PLMN_identity = &sib1->cellAccessRelatedInfo.plmn_IdentityList.list.array[0]->plmn_Identity; + LTE_PLMN_Identity_t *PLMN_identity = &sib1->cellAccessRelatedInfo.plmn_IdentityList.list.array[0]->plmn_Identity; int mccdigits = PLMN_identity->mcc->list.count; int mncdigits = PLMN_identity->mnc.list.count; @@ -3196,29 +3196,29 @@ int decode_SIB1( const protocol_ctxt_t* const ctxt_pP, const uint8_t eNB_index, ctxt_pP->module_id, eNB_index, ctxt_pP->module_id ); rrc_mac_config_req_ue(ctxt_pP->module_id, 0, eNB_index, - (RadioResourceConfigCommonSIB_t *)NULL, - (struct PhysicalConfigDedicated *)NULL, -#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) - (SCellToAddMod_r10_t *)NULL, + (LTE_RadioResourceConfigCommonSIB_t *)NULL, + (struct LTE_PhysicalConfigDedicated *)NULL, +#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) + (LTE_SCellToAddMod_r10_t *)NULL, //(struct PhysicalConfigDedicatedSCell_r10 *)NULL, #endif - (MeasObjectToAddMod_t **)NULL, - (MAC_MainConfig_t *)NULL, + (LTE_MeasObjectToAddMod_t **)NULL, + (LTE_MAC_MainConfig_t *)NULL, 0, - (struct LogicalChannelConfig *)NULL, - (MeasGapConfig_t *)NULL, + (struct LTE_LogicalChannelConfig *)NULL, + (LTE_MeasGapConfig_t *)NULL, UE_rrc_inst[ctxt_pP->module_id].sib1[eNB_index]->tdd_Config, - (MobilityControlInfo_t *) NULL, + (LTE_MobilityControlInfo_t *) NULL, &UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIwindowsize, &UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIperiod, NULL, NULL, NULL, - (MBSFN_SubframeConfigList_t *)NULL -#if (RRC_VERSION >= MAKE_VERSION(9, 0, 0)) + (LTE_MBSFN_SubframeConfigList_t *)NULL +#if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) ,0, - (MBSFN_AreaInfoList_r9_t *)NULL, - (PMCH_InfoList_r9_t *)NULL + (LTE_MBSFN_AreaInfoList_r9_t *)NULL, + (LTE_PMCH_InfoList_r9_t *)NULL #endif #ifdef CBA @@ -3226,7 +3226,7 @@ int decode_SIB1( const protocol_ctxt_t* const ctxt_pP, const uint8_t eNB_index, 0, 0 #endif -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) , 0, NULL, @@ -3242,7 +3242,7 @@ int decode_SIB1( const protocol_ctxt_t* const ctxt_pP, const uint8_t eNB_index, { int cell_valid = 0; - if (sib1->cellAccessRelatedInfo.cellBarred == SystemInformationBlockType1__cellAccessRelatedInfo__cellBarred_notBarred) { + if (sib1->cellAccessRelatedInfo.cellBarred == LTE_SystemInformationBlockType1__cellAccessRelatedInfo__cellBarred_notBarred) { /* Cell is not barred */ int plmn; int plmn_number; @@ -3251,7 +3251,7 @@ int decode_SIB1( const protocol_ctxt_t* const ctxt_pP, const uint8_t eNB_index, /* Compare requested PLMN and PLMNs from SIB1*/ for (plmn = 0; plmn < plmn_number; plmn++) { - PLMN_Identity_t *plmn_Identity; + LTE_PLMN_Identity_t *plmn_Identity; plmn_Identity = &sib1->cellAccessRelatedInfo.plmn_IdentityList.list.array[plmn]->plmn_Identity; @@ -3312,7 +3312,7 @@ int decode_SIB1( const protocol_ctxt_t* const ctxt_pP, const uint8_t eNB_index, //----------------------------------------------------------------------------- - void dump_sib2( SystemInformationBlockType2_t *sib2 ) + void dump_sib2( LTE_SystemInformationBlockType2_t *sib2 ) { // ac_BarringInfo if (sib2->ac_BarringInfo) { @@ -3441,7 +3441,7 @@ int decode_SIB1( const protocol_ctxt_t* const ctxt_pP, const uint8_t eNB_index, sib2->radioResourceConfigCommon.soundingRS_UL_ConfigCommon.present, SIB2SoundingPresent(sib2->radioResourceConfigCommon.soundingRS_UL_ConfigCommon.present) ); - if (sib2->radioResourceConfigCommon.soundingRS_UL_ConfigCommon.present == SoundingRS_UL_ConfigCommon_PR_setup) { + if (sib2->radioResourceConfigCommon.soundingRS_UL_ConfigCommon.present == LTE_SoundingRS_UL_ConfigCommon_PR_setup) { LOG_I( RRC, "radioResourceConfigCommon.soundingRS_UL_ConfigCommon.choice.setup.srs_BandwidthConfig : %ld\n", sib2->radioResourceConfigCommon.soundingRS_UL_ConfigCommon.choice.setup.srs_BandwidthConfig ); LOG_I( RRC, "radioResourceConfigCommon.soundingRS_UL_ConfigCommon.choice.setup.srs_SubframeConfig : %ld\n", @@ -3480,7 +3480,7 @@ int decode_SIB1( const protocol_ctxt_t* const ctxt_pP, const uint8_t eNB_index, LOG_I( RRC, "radioResourceConfigCommon.ul_CyclicPrefixLength : %ld\n", sib2->radioResourceConfigCommon.ul_CyclicPrefixLength ); -#if (RRC_VERSION >= MAKE_VERSION(10, 2, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 2, 0)) // UplinkPowerControlCommon_v1020 // ... #endif @@ -3512,14 +3512,14 @@ int decode_SIB1( const protocol_ctxt_t* const ctxt_pP, const uint8_t eNB_index, LOG_I( RRC, "timeAlignmentTimerCommon : %ld\n", sib2->timeAlignmentTimerCommon ); -#if (RRC_VERSION >= MAKE_VERSION(9, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) if (sib2->lateNonCriticalExtension) { LOG_I( RRC, "lateNonCriticalExtension : %p\n", sib2->lateNonCriticalExtension ); } else LOG_I( RRC, "lateNonCriticalExtension : not defined\n" ); #endif -#if (RRC_VERSION >= MAKE_VERSION(9, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) if (sib2->ext1 && sib2->ext1->ssac_BarringForMMTEL_Voice_r9) { LOG_I( RRC, "ssac_BarringForMMTEL_Voice_r9->ac_BarringFactor : %ld\n", sib2->ext1->ssac_BarringForMMTEL_Voice_r9->ac_BarringFactor ); @@ -3541,7 +3541,7 @@ int decode_SIB1( const protocol_ctxt_t* const ctxt_pP, const uint8_t eNB_index, LOG_I( RRC, "ssac_BarringForMMTEL_Video_r9 : not defined\n" ); #endif -#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) if (sib2->ext2 && sib2->ext2->ac_BarringForCSFB_r10) { LOG_I( RRC, "ac_BarringForCSFB_r10->ac_BarringFactor : %ld\n", sib2->ext2->ac_BarringForCSFB_r10->ac_BarringFactor ); @@ -3556,7 +3556,7 @@ int decode_SIB1( const protocol_ctxt_t* const ctxt_pP, const uint8_t eNB_index, } //----------------------------------------------------------------------------- - void dump_sib3( SystemInformationBlockType3_t *sib3 ) + void dump_sib3( LTE_SystemInformationBlockType3_t *sib3 ) { LOG_I( RRC, "Dumping SIB3 (see TS36.331 V8.21.0)\n" ); @@ -3703,11 +3703,11 @@ uint64_t arfcn_to_freq(long arfcn) { exit(1); } } - void dump_sib5( SystemInformationBlockType5_t *sib5 ) + void dump_sib5( LTE_SystemInformationBlockType5_t *sib5 ) { - InterFreqCarrierFreqList_t interFreqCarrierFreqList = sib5->interFreqCarrierFreqList; + LTE_InterFreqCarrierFreqList_t interFreqCarrierFreqList = sib5->interFreqCarrierFreqList; int i,j; - InterFreqCarrierFreqInfo_t *ifcfInfo; + LTE_InterFreqCarrierFreqInfo_t *ifcfInfo; LOG_I( RRC, "Dumping SIB5 (see TS36.331 V8.21.0)\n" ); @@ -3729,22 +3729,22 @@ uint64_t arfcn_to_freq(long arfcn) { LOG_I(RRC," threshX_High : %ld\n",ifcfInfo->threshX_High); LOG_I(RRC," threshX_Low : %ld\n",ifcfInfo->threshX_Low); switch(ifcfInfo->allowedMeasBandwidth) { - case AllowedMeasBandwidth_mbw6: + case LTE_AllowedMeasBandwidth_mbw6: LOG_I(RRC," AllowedMeasBandwidth : 6\n"); break; - case AllowedMeasBandwidth_mbw15: + case LTE_AllowedMeasBandwidth_mbw15: LOG_I(RRC," AllowedMeasBandwidth : 15\n"); break; - case AllowedMeasBandwidth_mbw25: + case LTE_AllowedMeasBandwidth_mbw25: LOG_I(RRC," AllowedMeasBandwidth : 25\n"); break; - case AllowedMeasBandwidth_mbw50: + case LTE_AllowedMeasBandwidth_mbw50: LOG_I(RRC," AllowedMeasBandwidth : 50\n"); break; - case AllowedMeasBandwidth_mbw75: + case LTE_AllowedMeasBandwidth_mbw75: LOG_I(RRC," AllowedMeasBandwidth : 75\n"); break; - case AllowedMeasBandwidth_mbw100: + case LTE_AllowedMeasBandwidth_mbw100: LOG_I(RRC," AllowedMeasBandwidth : 100\n"); break; } @@ -3782,7 +3782,7 @@ uint64_t arfcn_to_freq(long arfcn) { } } } -#if (RRC_VERSION >= MAKE_VERSION(9, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) if (ifcfInfo->ext1 && ifcfInfo->ext1->q_QualMin_r9) LOG_I(RRC," Q_QualMin_r9 : %ld\n",*ifcfInfo->ext1->q_QualMin_r9); @@ -3795,8 +3795,8 @@ uint64_t arfcn_to_freq(long arfcn) { } -#if (RRC_VERSION >= MAKE_VERSION(9, 0, 0)) - void dump_sib13( SystemInformationBlockType13_r9_t *sib13 ) +#if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) + void dump_sib13( LTE_SystemInformationBlockType13_r9_t *sib13 ) { LOG_I( RRC, "[UE] Dumping SIB13\n" ); LOG_I( RRC, "[UE] dumping sib13 second time\n" ); @@ -3808,7 +3808,7 @@ uint64_t arfcn_to_freq(long arfcn) { //TTN - SIB18 //----------------------------------------------------------------------------- - void dump_sib18(SystemInformationBlockType18_r12_t *sib18){ + void dump_sib18(LTE_SystemInformationBlockType18_r12_t *sib18){ LOG_I( RRC, "[UE] Dumping SIB18\n" ); for (int i = 0; i < sib18->commConfig_r12->commRxPool_r12.list.count; i++) { LOG_I(RRC, " Contents of SIB18 %d/%d \n", i+1, sib18->commConfig_r12->commRxPool_r12.list.count); @@ -3824,7 +3824,7 @@ uint64_t arfcn_to_freq(long arfcn) { //TTN - SIB19 //----------------------------------------------------------------------------- - void dump_sib19(SystemInformationBlockType19_r12_t *sib19){ + void dump_sib19(LTE_SystemInformationBlockType19_r12_t *sib19){ LOG_I( RRC, "[UE] Dumping SIB19\n" ); for (int i = 0; i < sib19->discConfig_r12->discRxPool_r12.list.count; i++) { LOG_I(RRC, " Contents of SIB19 %d/%d \n", i+1, sib19->discConfig_r12->discRxPool_r12.list.count); @@ -3839,7 +3839,7 @@ uint64_t arfcn_to_freq(long arfcn) { } } - void dump_sib21(SystemInformationBlockType21_r14_t *sib21){ + void dump_sib21(LTE_SystemInformationBlockType21_r14_t *sib21){ if ((sib21->sl_V2X_ConfigCommon_r14 != NULL) && (sib21->sl_V2X_ConfigCommon_r14->v2x_CommRxPool_r14 !=NULL) ){ for (int i = 0; i < sib21->sl_V2X_ConfigCommon_r14->v2x_CommRxPool_r14->list.count; i++) { LOG_I(RRC, " Contents of SIB21 %d/%d \n", i+1, sib21->sl_V2X_ConfigCommon_r14->v2x_CommRxPool_r14->list.count); @@ -3858,15 +3858,19 @@ uint64_t arfcn_to_freq(long arfcn) { //----------------------------------------------------------------------------- int decode_SI( const protocol_ctxt_t* const ctxt_pP, const uint8_t eNB_index ) { - SystemInformation_t** si = &UE_rrc_inst[ctxt_pP->module_id].si[eNB_index]; + LTE_SystemInformation_t** si = &UE_rrc_inst[ctxt_pP->module_id].si[eNB_index]; int new_sib = 0; - SystemInformationBlockType1_t* sib1 = UE_rrc_inst[ctxt_pP->module_id].sib1[eNB_index]; + LTE_SystemInformationBlockType1_t* sib1 = UE_rrc_inst[ctxt_pP->module_id].sib1[eNB_index]; VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_RRC_UE_DECODE_SI, VCD_FUNCTION_IN ); // Dump contents - if ((*si)->criticalExtensions.present == SystemInformation__criticalExtensions_PR_systemInformation_r8 || - (*si)->criticalExtensions.present == SystemInformation__criticalExtensions_PR_criticalExtensionsFuture) { + if ((*si)->criticalExtensions.present == LTE_SystemInformation__criticalExtensions_PR_systemInformation_r8 || +#if (LTE_RRC_VERSION >= MAKE_VERSION(15, 3, 0)) + (*si)->criticalExtensions.present == LTE_SystemInformation__criticalExtensions_PR_criticalExtensionsFuture_r15) { +#else + (*si)->criticalExtensions.present == LTE_SystemInformation__criticalExtensions_PR_criticalExtensionsFuture) { +#endif LOG_D( RRC, "[UE] (*si)->criticalExtensions.choice.systemInformation_r8.sib_TypeAndInfo.list.count %d\n", (*si)->criticalExtensions.choice.systemInformation_r8.sib_TypeAndInfo.list.count ); } else { @@ -3875,15 +3879,15 @@ uint64_t arfcn_to_freq(long arfcn) { } for (int i=0; i<(*si)->criticalExtensions.choice.systemInformation_r8.sib_TypeAndInfo.list.count; i++) { - struct SystemInformation_r8_IEs__sib_TypeAndInfo__Member *typeandinfo; + struct LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member *typeandinfo; typeandinfo = (*si)->criticalExtensions.choice.systemInformation_r8.sib_TypeAndInfo.list.array[i]; switch(typeandinfo->present) { - case SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib2: + case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib2: if ((UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIStatus&2) == 0) { UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIStatus|=2; new_sib=1; - memcpy( UE_rrc_inst[ctxt_pP->module_id].sib2[eNB_index], &typeandinfo->choice.sib2, sizeof(SystemInformationBlockType2_t) ); + memcpy( UE_rrc_inst[ctxt_pP->module_id].sib2[eNB_index], &typeandinfo->choice.sib2, sizeof(LTE_SystemInformationBlockType2_t) ); LOG_I( RRC, "[UE %"PRIu8"] Frame %"PRIu32" Found SIB2 from eNB %"PRIu8"\n", ctxt_pP->module_id, ctxt_pP->frame, eNB_index ); dump_sib2( UE_rrc_inst[ctxt_pP->module_id].sib2[eNB_index] ); LOG_I( RRC, "[FRAME %05"PRIu32"][RRC_UE][MOD %02"PRIu8"][][--- MAC_CONFIG_REQ (SIB2 params eNB %"PRIu8") --->][MAC_UE][MOD %02"PRIu8"][]\n", @@ -3891,34 +3895,34 @@ uint64_t arfcn_to_freq(long arfcn) { rrc_mac_config_req_ue(ctxt_pP->module_id, 0, eNB_index, &UE_rrc_inst[ctxt_pP->module_id].sib2[eNB_index]->radioResourceConfigCommon, - (struct PhysicalConfigDedicated *)NULL, -#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) - (SCellToAddMod_r10_t *)NULL, + (struct LTE_PhysicalConfigDedicated *)NULL, +#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) + (LTE_SCellToAddMod_r10_t *)NULL, #endif - (MeasObjectToAddMod_t **)NULL, - (MAC_MainConfig_t *)NULL, + (LTE_MeasObjectToAddMod_t **)NULL, + (LTE_MAC_MainConfig_t *)NULL, 0, - (struct LogicalChannelConfig *)NULL, - (MeasGapConfig_t *)NULL, - (TDD_Config_t *)NULL, - (MobilityControlInfo_t *)NULL, + (struct LTE_LogicalChannelConfig *)NULL, + (LTE_MeasGapConfig_t *)NULL, + (LTE_TDD_Config_t *)NULL, + (LTE_MobilityControlInfo_t *)NULL, NULL, NULL, UE_rrc_inst[ctxt_pP->module_id].sib2[eNB_index]->freqInfo.ul_CarrierFreq, UE_rrc_inst[ctxt_pP->module_id].sib2[eNB_index]->freqInfo.ul_Bandwidth, &UE_rrc_inst[ctxt_pP->module_id].sib2[eNB_index]->freqInfo.additionalSpectrumEmission, UE_rrc_inst[ctxt_pP->module_id].sib2[eNB_index]->mbsfn_SubframeConfigList -#if (RRC_VERSION >= MAKE_VERSION(9, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) ,0, - (MBSFN_AreaInfoList_r9_t *)NULL, - (PMCH_InfoList_r9_t *)NULL + (LTE_MBSFN_AreaInfoList_r9_t *)NULL, + (LTE_PMCH_InfoList_r9_t *)NULL #endif #ifdef CBA ,0, 0 #endif -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) , 0, NULL, @@ -3926,7 +3930,7 @@ uint64_t arfcn_to_freq(long arfcn) { #endif ); // After SI is received, prepare RRCConnectionRequest -#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) if (UE_rrc_inst[ctxt_pP->module_id].MBMS_flag < 3) // see -Q option #endif @@ -3968,142 +3972,140 @@ uint64_t arfcn_to_freq(long arfcn) { } break; // case SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib2 - case SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib3: + case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib3: if ((UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIStatus&4) == 0) { UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIStatus|=4; new_sib=1; - memcpy( UE_rrc_inst[ctxt_pP->module_id].sib3[eNB_index], &typeandinfo->choice.sib3, sizeof(SystemInformationBlockType3_t) ); + memcpy( UE_rrc_inst[ctxt_pP->module_id].sib3[eNB_index], &typeandinfo->choice.sib3, sizeof(LTE_SystemInformationBlockType3_t) ); LOG_I( RRC, "[UE %"PRIu8"] Frame %"PRIu32" Found SIB3 from eNB %"PRIu8"\n", ctxt_pP->module_id, ctxt_pP->frame, eNB_index ); dump_sib3( UE_rrc_inst[ctxt_pP->module_id].sib3[eNB_index] ); } break; - case SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib4: + case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib4: if ((UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIStatus&8) == 0) { UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIStatus|=8; new_sib=1; - memcpy( UE_rrc_inst[ctxt_pP->module_id].sib4[eNB_index], &typeandinfo->choice.sib4, sizeof(SystemInformationBlockType4_t) ); + memcpy( UE_rrc_inst[ctxt_pP->module_id].sib4[eNB_index], &typeandinfo->choice.sib4, sizeof(LTE_SystemInformationBlockType4_t) ); LOG_I( RRC, "[UE %"PRIu8"] Frame %"PRIu32" Found SIB4 from eNB %"PRIu8"\n", ctxt_pP->module_id, ctxt_pP->frame, eNB_index ); } break; - case SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib5: + case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib5: if ((UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIStatus&16) == 0) { UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIStatus|=16; new_sib=1; - - memcpy( UE_rrc_inst[ctxt_pP->module_id].sib5[eNB_index], &typeandinfo->choice.sib5, sizeof(SystemInformationBlockType5_t) ); + memcpy( UE_rrc_inst[ctxt_pP->module_id].sib5[eNB_index], &typeandinfo->choice.sib5, sizeof(LTE_SystemInformationBlockType5_t) ); LOG_I( RRC, "[UE %"PRIu8"] Frame %"PRIu32" Found SIB5 from eNB %"PRIu8"\n", ctxt_pP->module_id, ctxt_pP->frame, eNB_index ); dump_sib5(UE_rrc_inst[ctxt_pP->module_id].sib5[eNB_index]); } break; - case SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib6: + case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib6: if ((UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIStatus&32) == 0) { UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIStatus|=32; new_sib=1; - memcpy( UE_rrc_inst[ctxt_pP->module_id].sib6[eNB_index], &typeandinfo->choice.sib6, sizeof(SystemInformationBlockType6_t) ); + memcpy( UE_rrc_inst[ctxt_pP->module_id].sib6[eNB_index], &typeandinfo->choice.sib6, sizeof(LTE_SystemInformationBlockType6_t) ); LOG_I( RRC, "[UE %"PRIu8"] Frame %"PRIu32" Found SIB6 from eNB %"PRIu8"\n", ctxt_pP->module_id, ctxt_pP->frame, eNB_index ); } break; - case SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib7: + case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib7: if ((UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIStatus&64) == 0) { UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIStatus|=64; new_sib=1; - memcpy( UE_rrc_inst[ctxt_pP->module_id].sib7[eNB_index], &typeandinfo->choice.sib7, sizeof(SystemInformationBlockType7_t) ); + memcpy( UE_rrc_inst[ctxt_pP->module_id].sib7[eNB_index], &typeandinfo->choice.sib7, sizeof(LTE_SystemInformationBlockType7_t) ); LOG_I( RRC, "[UE %"PRIu8"] Frame %"PRIu32" Found SIB7 from eNB %"PRIu8"\n", ctxt_pP->module_id, ctxt_pP->frame, eNB_index ); } break; - case SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib8: + case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib8: if ((UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIStatus&128) == 0) { UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIStatus|=128; new_sib=1; - memcpy( UE_rrc_inst[ctxt_pP->module_id].sib8[eNB_index], &typeandinfo->choice.sib8, sizeof(SystemInformationBlockType8_t) ); + memcpy( UE_rrc_inst[ctxt_pP->module_id].sib8[eNB_index], &typeandinfo->choice.sib8, sizeof(LTE_SystemInformationBlockType8_t) ); LOG_I( RRC, "[UE %"PRIu8"] Frame %"PRIu32" Found SIB8 from eNB %"PRIu8"\n", ctxt_pP->module_id, ctxt_pP->frame, eNB_index ); } break; - case SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib9: + case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib9: if ((UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIStatus&256) == 0) { UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIStatus|=256; new_sib=1; - - memcpy( UE_rrc_inst[ctxt_pP->module_id].sib9[eNB_index], &typeandinfo->choice.sib9, sizeof(SystemInformationBlockType9_t) ); + memcpy( UE_rrc_inst[ctxt_pP->module_id].sib9[eNB_index], &typeandinfo->choice.sib9, sizeof(LTE_SystemInformationBlockType9_t) ); LOG_I( RRC, "[UE %"PRIu8"] Frame %"PRIu32" Found SIB9 from eNB %"PRIu8"\n", ctxt_pP->module_id, ctxt_pP->frame, eNB_index ); } break; - case SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib10: + case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib10: if ((UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIStatus&512) == 0) { UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIStatus|=512; new_sib=1; - memcpy( UE_rrc_inst[ctxt_pP->module_id].sib10[eNB_index], &typeandinfo->choice.sib10, sizeof(SystemInformationBlockType10_t) ); + memcpy( UE_rrc_inst[ctxt_pP->module_id].sib10[eNB_index], &typeandinfo->choice.sib10, sizeof(LTE_SystemInformationBlockType10_t) ); LOG_I( RRC, "[UE %"PRIu8"] Frame %"PRIu32" Found SIB10 from eNB %"PRIu8"\n", ctxt_pP->module_id, ctxt_pP->frame, eNB_index ); } break; - case SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib11: + case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib11: if ((UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIStatus&1024) == 0) { UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIStatus|=1024; new_sib=1; - memcpy( UE_rrc_inst[ctxt_pP->module_id].sib11[eNB_index], &typeandinfo->choice.sib11, sizeof(SystemInformationBlockType11_t) ); + memcpy( UE_rrc_inst[ctxt_pP->module_id].sib11[eNB_index], &typeandinfo->choice.sib11, sizeof(LTE_SystemInformationBlockType11_t) ); LOG_I( RRC, "[UE %"PRIu8"] Frame %"PRIu32" Found SIB11 from eNB %"PRIu8"\n", ctxt_pP->module_id, ctxt_pP->frame, eNB_index ); } break; -#if (RRC_VERSION >= MAKE_VERSION(9, 2, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(9, 2, 0)) - case SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib12_v920: + case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib12_v920: if ((UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIStatus&2048) == 0) { UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIStatus|=2048; new_sib=1; - memcpy( UE_rrc_inst[ctxt_pP->module_id].sib12[eNB_index], &typeandinfo->choice.sib12_v920, sizeof(SystemInformationBlockType12_r9_t) ); + memcpy( UE_rrc_inst[ctxt_pP->module_id].sib12[eNB_index], &typeandinfo->choice.sib12_v920, sizeof(LTE_SystemInformationBlockType12_r9_t) ); LOG_I( RRC, "[UE %"PRIu8"] Frame %"PRIu32" Found SIB12 from eNB %"PRIu8"\n", ctxt_pP->module_id, ctxt_pP->frame, eNB_index ); } break; - case SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib13_v920: + case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib13_v920: if ((UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIStatus&4096) == 0) { UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIStatus|=4096; new_sib=1; - memcpy( UE_rrc_inst[ctxt_pP->module_id].sib13[eNB_index], &typeandinfo->choice.sib13_v920, sizeof(SystemInformationBlockType13_r9_t) ); + memcpy( UE_rrc_inst[ctxt_pP->module_id].sib13[eNB_index], &typeandinfo->choice.sib13_v920, sizeof(LTE_SystemInformationBlockType13_r9_t) ); LOG_I( RRC, "[UE %"PRIu8"] Frame %"PRIu32" Found SIB13 from eNB %"PRIu8"\n", ctxt_pP->module_id, ctxt_pP->frame, eNB_index ); dump_sib13( UE_rrc_inst[ctxt_pP->module_id].sib13[eNB_index] ); // adding here function to store necessary parameters for using in decode_MCCH_Message + maybe transfer to PHY layer LOG_I( RRC, "[FRAME %05"PRIu32"][RRC_UE][MOD %02"PRIu8"][][--- MAC_CONFIG_REQ (SIB13 params eNB %"PRIu8") --->][MAC_UE][MOD %02"PRIu8"][]\n", ctxt_pP->frame, ctxt_pP->module_id, eNB_index, ctxt_pP->module_id); rrc_mac_config_req_ue(ctxt_pP->module_id,0,eNB_index, - (RadioResourceConfigCommonSIB_t *)NULL, - (struct PhysicalConfigDedicated *)NULL, - (SCellToAddMod_r10_t *)NULL, - (MeasObjectToAddMod_t **)NULL, - (MAC_MainConfig_t *)NULL, + (LTE_RadioResourceConfigCommonSIB_t *)NULL, + (struct LTE_PhysicalConfigDedicated *)NULL, + (LTE_SCellToAddMod_r10_t *)NULL, + (LTE_MeasObjectToAddMod_t **)NULL, + (LTE_MAC_MainConfig_t *)NULL, 0, - (struct LogicalChannelConfig *)NULL, - (MeasGapConfig_t *)NULL, - (TDD_Config_t *)NULL, - (MobilityControlInfo_t *)NULL, + (struct LTE_LogicalChannelConfig *)NULL, + (LTE_MeasGapConfig_t *)NULL, + (LTE_TDD_Config_t *)NULL, + (LTE_MobilityControlInfo_t *)NULL, NULL, NULL, NULL, NULL, NULL, - (MBSFN_SubframeConfigList_t *)NULL, + (LTE_MBSFN_SubframeConfigList_t *)NULL, 0, &UE_rrc_inst[ctxt_pP->module_id].sib13[eNB_index]->mbsfn_AreaInfoList_r9, - (PMCH_InfoList_r9_t *)NULL + (LTE_PMCH_InfoList_r9_t *)NULL #ifdef CBA ,0, 0 #endif -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) , 0, NULL, @@ -4114,14 +4116,14 @@ uint64_t arfcn_to_freq(long arfcn) { } #endif -#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) //SIB18 - case SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib18_v1250: + case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib18_v1250: if ((UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIStatus&8192) == 0) { UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIStatus|=8192; new_sib=1; - memcpy( UE_rrc_inst[ctxt_pP->module_id].sib18[eNB_index], &typeandinfo->choice.sib18_v1250, sizeof(SystemInformationBlockType18_r12_t) ); + memcpy( UE_rrc_inst[ctxt_pP->module_id].sib18[eNB_index], &typeandinfo->choice.sib18_v1250, sizeof(LTE_SystemInformationBlockType18_r12_t) ); LOG_I( RRC, "[UE %"PRIu8"] Frame %"PRIu32" Found SIB18 from eNB %"PRIu8"\n", ctxt_pP->module_id, ctxt_pP->frame, eNB_index ); dump_sib18( UE_rrc_inst[ctxt_pP->module_id].sib18[eNB_index] ); // adding here function to store necessary parameters to transfer to PHY layer @@ -4131,21 +4133,21 @@ uint64_t arfcn_to_freq(long arfcn) { //process SIB18 to transfer SL-related parameters to PHY rrc_ue_process_sidelink_radioResourceConfig(ctxt_pP->module_id,eNB_index, UE_rrc_inst[ctxt_pP->module_id].sib18[eNB_index], - (SystemInformationBlockType19_r12_t *)NULL, - (SL_CommConfig_r12_t *)NULL, - (SL_DiscConfig_r12_t *)NULL + (LTE_SystemInformationBlockType19_r12_t *)NULL, + (LTE_SL_CommConfig_r12_t *)NULL, + (LTE_SL_DiscConfig_r12_t *)NULL ); } break; //SIB19 - case SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib19_v1250: + case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib19_v1250: if ((UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIStatus&16384) == 0) { UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIStatus|=16384; new_sib=1; - memcpy( UE_rrc_inst[ctxt_pP->module_id].sib19[eNB_index], &typeandinfo->choice.sib19_v1250, sizeof(SystemInformationBlockType19_r12_t) ); + memcpy( UE_rrc_inst[ctxt_pP->module_id].sib19[eNB_index], &typeandinfo->choice.sib19_v1250, sizeof(LTE_SystemInformationBlockType19_r12_t) ); LOG_I( RRC, "[UE %"PRIu8"] Frame %"PRIu32" Found SIB19 from eNB %"PRIu8"\n", ctxt_pP->module_id, ctxt_pP->frame, eNB_index ); dump_sib19( UE_rrc_inst[ctxt_pP->module_id].sib19[eNB_index] ); // adding here function to store necessary parameters to transfer to PHY layer @@ -4153,22 +4155,22 @@ uint64_t arfcn_to_freq(long arfcn) { ctxt_pP->frame, ctxt_pP->module_id, eNB_index, ctxt_pP->module_id); //process SIB19 to transfer SL-related parameters to PHY rrc_ue_process_sidelink_radioResourceConfig(ctxt_pP->module_id,eNB_index, - (SystemInformationBlockType18_r12_t *)NULL, + (LTE_SystemInformationBlockType18_r12_t *)NULL, UE_rrc_inst[ctxt_pP->module_id].sib19[eNB_index], - (SL_CommConfig_r12_t *)NULL, - (SL_DiscConfig_r12_t *)NULL + (LTE_SL_CommConfig_r12_t *)NULL, + (LTE_SL_DiscConfig_r12_t *)NULL ); } break; //SIB21 - case SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib21_v1430: + case LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib21_v1430: if ((UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIStatus&32768) == 0) { UE_rrc_inst[ctxt_pP->module_id].Info[eNB_index].SIStatus|=32768; new_sib=1; - memcpy( UE_rrc_inst[ctxt_pP->module_id].sib21[eNB_index], &typeandinfo->choice.sib21_v1430, sizeof(SystemInformationBlockType21_r14_t) ); + memcpy( UE_rrc_inst[ctxt_pP->module_id].sib21[eNB_index], &typeandinfo->choice.sib21_v1430, sizeof(LTE_SystemInformationBlockType21_r14_t) ); LOG_I( RRC, "[UE %"PRIu8"] Frame %"PRIu32" Found SIB21 from eNB %"PRIu8"\n", ctxt_pP->module_id, ctxt_pP->frame, eNB_index ); dump_sib21( UE_rrc_inst[ctxt_pP->module_id].sib21[eNB_index] ); // adding here function to store necessary parameters to transfer to PHY layer @@ -4271,8 +4273,8 @@ void ue_meas_filtering( const protocol_ctxt_t* const ctxt_pP, const uint8_t eNB_ uint8_t buffer[32], size; uint8_t i; uint8_t target_eNB_offset; - MeasId_t measId; - PhysCellId_t targetCellId; + LTE_MeasId_t measId; + LTE_PhysCellId_t targetCellId; long rsrp_t,rsrq_t; long rsrp_s,rsrq_s; long nElem, nElem1; @@ -4333,7 +4335,7 @@ void ue_meas_filtering( const protocol_ctxt_t* const ctxt_pP, const uint8_t eNB_ LOG_I(RRC, "[UE %d] Frame %d : Generating Measurement Report for eNB %d\n", ctxt_pP->module_id, ctxt_pP->frame, eNB_index); result = pdcp_data_req(ctxt_pP, SRB_FLAG_YES, DCCH, rrc_mui++, 0, size, buffer, PDCP_TRANSMISSION_MODE_DATA -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) ,NULL, NULL #endif ); @@ -4352,15 +4354,15 @@ void ue_meas_filtering( const protocol_ctxt_t* const ctxt_pP, const uint8_t eNB_ void ue_measurement_report_triggering(protocol_ctxt_t* const ctxt_pP, const uint8_t eNB_index ) { uint8_t i,j; - Hysteresis_t hys; - TimeToTrigger_t ttt_ms; - Q_OffsetRange_t ofn; - Q_OffsetRange_t ocn; - Q_OffsetRange_t ofs = 0; - Q_OffsetRange_t ocs = 0; + LTE_Hysteresis_t hys; + LTE_TimeToTrigger_t ttt_ms; + LTE_Q_OffsetRange_t ofn; + LTE_Q_OffsetRange_t ocn; + LTE_Q_OffsetRange_t ofs = 0; + LTE_Q_OffsetRange_t ocs = 0; long a3_offset; - MeasObjectId_t measObjId; - ReportConfigId_t reportConfigId; + LTE_MeasObjectId_t measObjId; + LTE_ReportConfigId_t reportConfigId; for(i=0 ; imodule_id].MeasId[i][j]->reportConfigId; if( /*UE_rrc_inst[ctxt_pP->module_id].MeasId[i][j] != NULL && */ UE_rrc_inst[ctxt_pP->module_id].MeasObj[i][measObjId-1] != NULL) { - if(UE_rrc_inst[ctxt_pP->module_id].MeasObj[i][measObjId-1]->measObject.present == MeasObjectToAddMod__measObject_PR_measObjectEUTRA) { + if(UE_rrc_inst[ctxt_pP->module_id].MeasObj[i][measObjId-1]->measObject.present == LTE_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[ctxt_pP->module_id].ReportConfig[i][reportConfigId-1]); if((UE_rrc_inst[ctxt_pP->module_id].ReportConfig[i][reportConfigId-1] != NULL) && - (UE_rrc_inst[ctxt_pP->module_id].ReportConfig[i][reportConfigId-1]->reportConfig.present==ReportConfigToAddMod__reportConfig_PR_reportConfigEUTRA) && + (UE_rrc_inst[ctxt_pP->module_id].ReportConfig[i][reportConfigId-1]->reportConfig.present == LTE_ReportConfigToAddMod__reportConfig_PR_reportConfigEUTRA) && (UE_rrc_inst[ctxt_pP->module_id].ReportConfig[i][reportConfigId-1]->reportConfig.choice.reportConfigEUTRA.triggerType.present == - ReportConfigEUTRA__triggerType_PR_event)) { + LTE_ReportConfigEUTRA__triggerType_PR_event)) { hys = UE_rrc_inst[ctxt_pP->module_id].ReportConfig[i][reportConfigId-1]->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.hysteresis; ttt_ms = timeToTrigger_ms[UE_rrc_inst[ctxt_pP->module_id].ReportConfig[i][reportConfigId -1]->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.timeToTrigger]; @@ -4390,17 +4392,17 @@ void ue_measurement_report_triggering(protocol_ctxt_t* const ctxt_pP, const uint -1]->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.choice.eventA3.a3_Offset; switch (UE_rrc_inst[ctxt_pP->module_id].ReportConfig[i][reportConfigId-1]->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.present) { - case ReportConfigEUTRA__triggerType__event__eventId_PR_eventA1: + case LTE_ReportConfigEUTRA__triggerType__event__eventId_PR_eventA1: LOG_D(RRC,"[UE %d] Frame %d : A1 event: check if serving becomes better than threshold\n", ctxt_pP->module_id, ctxt_pP->frame); break; - case ReportConfigEUTRA__triggerType__event__eventId_PR_eventA2: + case LTE_ReportConfigEUTRA__triggerType__event__eventId_PR_eventA2: LOG_D(RRC,"[UE %d] Frame %d : A2 event, check if serving becomes worse than a threshold\n", ctxt_pP->module_id, ctxt_pP->frame); break; - case ReportConfigEUTRA__triggerType__event__eventId_PR_eventA3: + case LTE_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", ctxt_pP->module_id, ctxt_pP->frame); @@ -4435,12 +4437,12 @@ void ue_measurement_report_triggering(protocol_ctxt_t* const ctxt_pP, const uint break; - case ReportConfigEUTRA__triggerType__event__eventId_PR_eventA4: + case LTE_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", ctxt_pP->module_id, ctxt_pP->frame); break; - case ReportConfigEUTRA__triggerType__event__eventId_PR_eventA5: + case LTE_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", ctxt_pP->module_id, ctxt_pP->frame); break; @@ -4467,13 +4469,13 @@ void ue_measurement_report_triggering(protocol_ctxt_t* const ctxt_pP, const uint uint8_t eNB_index, uint8_t ue_cnx_index, uint8_t meas_index, - Q_OffsetRange_t ofn, - Q_OffsetRange_t ocn, - Hysteresis_t hys, - Q_OffsetRange_t ofs, - Q_OffsetRange_t ocs, + LTE_Q_OffsetRange_t ofn, + LTE_Q_OffsetRange_t ocn, + LTE_Hysteresis_t hys, + LTE_Q_OffsetRange_t ofs, + LTE_Q_OffsetRange_t ocs, long a3_offset, - TimeToTrigger_t ttt ) + LTE_TimeToTrigger_t ttt ) { uint8_t eNB_offset; // uint8_t currentCellIndex = frame_parms->Nid_cell; @@ -4524,13 +4526,13 @@ void ue_measurement_report_triggering(protocol_ctxt_t* const ctxt_pP, const uint return 0; } -#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) //----------------------------------------------------------------------------- int decode_MCCH_Message( const protocol_ctxt_t* const ctxt_pP, const uint8_t eNB_index, const uint8_t* const Sdu, const uint8_t Sdu_len, const uint8_t mbsfn_sync_area ) { - MCCH_Message_t *mcch=NULL; - MBSFNAreaConfiguration_r9_t** mcch_message=&UE_rrc_inst[ctxt_pP->module_id].mcch_message[eNB_index]; + LTE_MCCH_Message_t *mcch=NULL; + LTE_MBSFNAreaConfiguration_r9_t** mcch_message=&UE_rrc_inst[ctxt_pP->module_id].mcch_message[eNB_index]; asn_dec_rval_t dec_rval; @@ -4542,7 +4544,7 @@ int decode_MCCH_Message( const protocol_ctxt_t* const ctxt_pP, const uint8_t eNB return 0; // avoid decoding to prevent memory bloating } else { dec_rval = uper_decode_complete(NULL, - &asn_DEF_MCCH_Message, + &asn_DEF_LTE_MCCH_Message, (void **)&mcch, (const void *)Sdu, Sdu_len); @@ -4552,19 +4554,19 @@ int decode_MCCH_Message( const protocol_ctxt_t* const ctxt_pP, const uint8_t eNB ctxt_pP->module_id, dec_rval.consumed); //free the memory - SEQUENCE_free(&asn_DEF_MCCH_Message, (void*)mcch, 1); + SEQUENCE_free(&asn_DEF_LTE_MCCH_Message, (void*)mcch, 1); return -1; } if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) { - xer_fprint(stdout, &asn_DEF_MCCH_Message, (void*)mcch); + xer_fprint(stdout, &asn_DEF_LTE_MCCH_Message, (void*)mcch); } - if (mcch->message.present == MCCH_MessageType_PR_c1) { + if (mcch->message.present == LTE_MCCH_MessageType_PR_c1) { LOG_D(RRC,"[UE %d] Found mcch message \n", ctxt_pP->module_id); - if(mcch->message.choice.c1.present == MCCH_MessageType__c1_PR_mbsfnAreaConfiguration_r9) { + if(mcch->message.choice.c1.present == LTE_MCCH_MessageType__c1_PR_mbsfnAreaConfiguration_r9) { /* memcpy((void*)*mcch_message, (void*)&mcch->message.choice.c1.choice.mbsfnAreaConfiguration_r9, @@ -4617,29 +4619,29 @@ int decode_MCCH_Message( const protocol_ctxt_t* const ctxt_pP, const uint8_t eNB // store to MAC/PHY necessary parameters for receiving MTCHs rrc_mac_config_req_ue(ue_mod_idP,0,eNB_index, - (RadioResourceConfigCommonSIB_t *)NULL, - (struct PhysicalConfigDedicated *)NULL, -#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) - (SCellToAddMod_r10_t *)NULL, + (LTE_RadioResourceConfigCommonSIB_t *)NULL, + (struct LTE_PhysicalConfigDedicated *)NULL, +#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) + (LTE_SCellToAddMod_r10_t *)NULL, //(struct PhysicalConfigDedicatedSCell_r10 *)NULL, #endif - (MeasObjectToAddMod_t **)NULL, - (MAC_MainConfig_t *)NULL, + (LTE_MeasObjectToAddMod_t **)NULL, + (LTE_MAC_MainConfig_t *)NULL, 0, - (struct LogicalChannelConfig *)NULL, - (MeasGapConfig_t *)NULL, - (TDD_Config_t *)NULL, - (MobilityControlInfo_t *)NULL, + (struct LTE_LogicalChannelConfig *)NULL, + (LTE_MeasGapConfig_t *)NULL, + (LTE_TDD_Config_t *)NULL, + (LTE_MobilityControlInfo_t *)NULL, NULL, NULL, NULL, NULL, NULL, - (MBSFN_SubframeConfigList_t *)NULL -#if (RRC_VERSION >= MAKE_VERSION(9, 0, 0)) + (LTE_MBSFN_SubframeConfigList_t *)NULL +#if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) , 0, - (MBSFN_AreaInfoList_r9_t *)NULL, + (LTE_MBSFN_AreaInfoList_r9_t *)NULL, &UE_rrc_inst[ue_mod_idP].mcch_message[eNB_index]->pmch_InfoList_r9 #endif @@ -4648,7 +4650,7 @@ int decode_MCCH_Message( const protocol_ctxt_t* const ctxt_pP, const uint8_t eNB 0, 0 #endif -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) , 0, NULL, @@ -4664,12 +4666,12 @@ int decode_MCCH_Message( const protocol_ctxt_t* const ctxt_pP, const uint8_t eNB rrc_pdcp_config_asn1_req(&ctxt, NULL, // SRB_ToAddModList NULL, // DRB_ToAddModList - (DRB_ToReleaseList_t*)NULL, + (LTE_DRB_ToReleaseList_t*)NULL, 0, // security mode NULL, // key rrc encryption NULL, // key rrc integrity NULL // key encryption -#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) ,&(UE_rrc_inst[ue_mod_idP].mcch_message[eNB_index]->pmch_InfoList_r9) #endif ,NULL); @@ -4678,7 +4680,7 @@ int decode_MCCH_Message( const protocol_ctxt_t* const ctxt_pP, const uint8_t eNB NULL,// SRB_ToAddModList NULL,// DRB_ToAddModList NULL,// DRB_ToReleaseList -#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) &(UE_rrc_inst[ue_mod_idP].mcch_message[eNB_index]->pmch_InfoList_r9) , 0, 0 #endif @@ -4781,7 +4783,7 @@ void *rrc_ue_task( void *args_p ) RRC_MAC_CCCH_DATA_IND (msg_p).enb_index); break; -#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) case RRC_MAC_MCCH_DATA_IND: LOG_D(RRC, "[UE %d] Received %s: frameP %d, eNB %d, mbsfn SA %d\n", ue_mod_id, ITTI_MSG_NAME (msg_p), @@ -5213,7 +5215,7 @@ openair_rrc_top_init_ue( UE_rrc_inst[module_id].UECapability_size = UECap->sdu_size; } -#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) LOG_I(RRC,"[UE] eMBMS active state is %d \n", eMBMS_active); for (module_id=0; module_id= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) /* TODO: this is disabled for the moment because the standard UE * crashes when calling this function. */ @@ -5250,7 +5252,7 @@ rrc_top_cleanup_ue( //----------------------------------------------------------------------------- -uint8_t rrc_ue_generate_SidelinkUEInformation( const protocol_ctxt_t* const ctxt_pP, const uint8_t eNB_index,SL_DestinationInfoList_r12_t *destinationInfoList, long *discTxResourceReq, SL_TRIGGER_t mode) +uint8_t rrc_ue_generate_SidelinkUEInformation( const protocol_ctxt_t* const ctxt_pP, const uint8_t eNB_index,LTE_SL_DestinationInfoList_r12_t *destinationInfoList, long *discTxResourceReq, SL_TRIGGER_t mode) { uint8_t size=0; uint8_t buffer[100]; @@ -5282,7 +5284,7 @@ uint8_t rrc_ue_generate_SidelinkUEInformation( const protocol_ctxt_t* const ctxt // 3GPP 36.331 (Section 5.10.7.3) -uint8_t fill_SLSS(const protocol_ctxt_t* const ctxt_pP, const uint8_t eNB_index, SLSSID_r12_t *slss_id, uint8_t *subframe, uint8_t mode) +uint8_t fill_SLSS(const protocol_ctxt_t* const ctxt_pP, const uint8_t eNB_index, LTE_SLSSID_r12_t *slss_id, uint8_t *subframe, uint8_t mode) { long syncOffsetIndicator = 0; switch(mode) { @@ -5334,10 +5336,10 @@ void rrc_ue_process_sidelink_radioResourceConfig( module_id_t Mod_idP, uint8_t eNB_index, - SystemInformationBlockType18_r12_t *sib18, - SystemInformationBlockType19_r12_t *sib19, - SL_CommConfig_r12_t* sl_CommConfig, - SL_DiscConfig_r12_t* sl_DiscConfig + LTE_SystemInformationBlockType18_r12_t *sib18, + LTE_SystemInformationBlockType19_r12_t *sib19, + LTE_SL_CommConfig_r12_t* sl_CommConfig, + LTE_SL_DiscConfig_r12_t* sl_DiscConfig ) //----------------------------------------------------------------------------- { @@ -5377,8 +5379,8 @@ rrc_ue_process_sidelink_radioResourceConfig( if (sl_CommConfig->commTxResources_r12 != NULL) { switch (sl_CommConfig->commTxResources_r12->present){ - case SL_CommConfig_r12__commTxResources_r12_PR_setup: - if (sl_CommConfig->commTxResources_r12->choice.setup.present == SL_CommConfig_r12__commTxResources_r12__setup_PR_scheduled_r12 ){ + case LTE_SL_CommConfig_r12__commTxResources_r12_PR_setup: + if (sl_CommConfig->commTxResources_r12->choice.setup.present == LTE_SL_CommConfig_r12__commTxResources_r12__setup_PR_scheduled_r12 ){ LOG_I(RRC,"[UE %d][RRC_UE] scheduled resource for SL, sl_RNTI size %lu \n", Mod_idP, sl_CommConfig->commTxResources_r12->choice.setup.choice.scheduled_r12.sl_RNTI_r12.size ); @@ -5390,7 +5392,7 @@ rrc_ue_process_sidelink_radioResourceConfig( Mod_idP, sl_CommConfig->commTxResources_r12->choice.setup.choice.scheduled_r12.mac_MainConfig_r12.retx_BSR_TimerSL ); //configure scheduled resource for SL //TODO - } else if (sl_CommConfig->commTxResources_r12->choice.setup.present == SL_CommConfig_r12__commTxResources_r12__setup_PR_ue_Selected_r12){ + } else if (sl_CommConfig->commTxResources_r12->choice.setup.present == LTE_SL_CommConfig_r12__commTxResources_r12__setup_PR_ue_Selected_r12){ //configure dedicated resources (commTxPoolNormalDedicated) for SL from which UE can autonomously select //sl_CommConfig->commTxResources_r12->choice.setup.choice.ue_Selected_r12.commTxPoolNormalDedicated_r12; @@ -5401,11 +5403,11 @@ rrc_ue_process_sidelink_radioResourceConfig( } break; - case SL_CommConfig_r12__commTxResources_r12_PR_release: + case LTE_SL_CommConfig_r12__commTxResources_r12_PR_release: //release dedicated resources for SL communication break; - case SL_CommConfig_r12__commTxResources_r12_PR_NOTHING: /* No components present */ + case LTE_SL_CommConfig_r12__commTxResources_r12_PR_NOTHING: /* No components present */ break; default: @@ -5421,21 +5423,21 @@ rrc_ue_process_sidelink_radioResourceConfig( if (sl_DiscConfig->discTxResources_r12 != NULL) { switch (sl_DiscConfig->discTxResources_r12->present) { - case SL_DiscConfig_r12__discTxResources_r12_PR_setup: - if (sl_DiscConfig->discTxResources_r12->choice.setup.present == SL_DiscConfig_r12__discTxResources_r12__setup_PR_scheduled_r12) { + case LTE_SL_DiscConfig_r12__discTxResources_r12_PR_setup: + if (sl_DiscConfig->discTxResources_r12->choice.setup.present == LTE_SL_DiscConfig_r12__discTxResources_r12__setup_PR_scheduled_r12) { //sl_DiscConfig->discTxResources_r12->choice.setup.choice.scheduled_r12.discHoppingConfig_r12; //sl_DiscConfig->discTxResources_r12->choice.setup.choice.scheduled_r12.discTF_IndexList_r12; //sl_DiscConfig->discTxResources_r12->choice.setup.choice.scheduled_r12.discTxConfig_r12; - } else if (sl_DiscConfig->discTxResources_r12->choice.setup.present == SL_DiscConfig_r12__discTxResources_r12__setup_PR_ue_Selected_r12) { + } else if (sl_DiscConfig->discTxResources_r12->choice.setup.present == LTE_SL_DiscConfig_r12__discTxResources_r12__setup_PR_ue_Selected_r12) { //sl_DiscConfig->discTxResources_r12->choice.setup.choice.ue_Selected_r12.discTxPoolDedicated_r12; } else { //SL_DiscConfig_r12__discTxResources_r12__setup_PR_NOTHING, /* No components present */ } break; - case SL_DiscConfig_r12__discTxResources_r12_PR_release: + case LTE_SL_DiscConfig_r12__discTxResources_r12_PR_release: //release dedicated resources for SL discovery break; - case SL_DiscConfig_r12__discTxResources_r12_PR_NOTHING: /* No components present */ + case LTE_SL_DiscConfig_r12__discTxResources_r12_PR_NOTHING: /* No components present */ break; default: break; @@ -5445,20 +5447,20 @@ rrc_ue_process_sidelink_radioResourceConfig( //dedicated resources for transmitting PS related discovery if (sl_DiscConfig->ext2->discTxResourcesPS_r13 != NULL){ switch (sl_DiscConfig->ext2->discTxResourcesPS_r13->present) { - case SL_DiscConfig_r12__ext2__discTxResourcesPS_r13_PR_setup: - if (sl_DiscConfig->ext2->discTxResourcesPS_r13->choice.setup.present == SL_DiscConfig_r12__ext2__discTxResourcesPS_r13__setup_PR_scheduled_r13) { + case LTE_SL_DiscConfig_r12__ext2__discTxResourcesPS_r13_PR_setup: + if (sl_DiscConfig->ext2->discTxResourcesPS_r13->choice.setup.present == LTE_SL_DiscConfig_r12__ext2__discTxResourcesPS_r13__setup_PR_scheduled_r13) { //sl_DiscConfig->ext2->discTxResourcesPS_r13->choice.setup.choice.scheduled_r13.discHoppingConfig_r13; //sl_DiscConfig->ext2->discTxResourcesPS_r13->choice.setup.choice.scheduled_r13.discTxConfig_r13 - } else if (sl_DiscConfig->ext2->discTxResourcesPS_r13->choice.setup.present == SL_DiscConfig_r12__ext2__discTxResourcesPS_r13__setup_PR_ue_Selected_r13) { + } else if (sl_DiscConfig->ext2->discTxResourcesPS_r13->choice.setup.present == LTE_SL_DiscConfig_r12__ext2__discTxResourcesPS_r13__setup_PR_ue_Selected_r13) { //sl_DiscConfig->ext2->discTxResourcesPS_r13->choice.setup.choice.ue_Selected_r13.discTxPoolPS_Dedicated_r13; } else { //SL_DiscConfig_r12__ext2__discTxResourcesPS_r13__setup_PR_NOTHING, /* No components present */ } break; - case SL_DiscConfig_r12__ext2__discTxResourcesPS_r13_PR_release: + case LTE_SL_DiscConfig_r12__ext2__discTxResourcesPS_r13_PR_release: break; - case SL_DiscConfig_r12__ext2__discTxResourcesPS_r13_PR_NOTHING: + case LTE_SL_DiscConfig_r12__ext2__discTxResourcesPS_r13_PR_NOTHING: /* No components present */ break; default: @@ -5468,7 +5470,7 @@ rrc_ue_process_sidelink_radioResourceConfig( } } -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) //----------------------------------------------------------- void rrc_control_socket_init(){ @@ -5543,11 +5545,11 @@ void *rrc_control_socket_thread_fct(void *arg) uint8_t type; UE_RRC_INST *UE = NULL; protocol_ctxt_t ctxt; - struct RLC_Config *DRB_rlc_config = NULL; - struct PDCP_Config *DRB_pdcp_config = NULL; - struct PDCP_Config__rlc_UM *PDCP_rlc_UM = NULL; - struct LogicalChannelConfig *DRB_lchan_config = NULL; - struct LogicalChannelConfig__ul_SpecificParameters *DRB_ul_SpecificParameters = NULL; + struct LTE_RLC_Config *DRB_rlc_config = NULL; + struct LTE_PDCP_Config *DRB_pdcp_config = NULL; + struct LTE_PDCP_Config__rlc_UM *PDCP_rlc_UM = NULL; + struct LTE_LogicalChannelConfig *DRB_lchan_config = NULL; + struct LTE_LogicalChannelConfig__ul_SpecificParameters *DRB_ul_SpecificParameters = NULL; long *logicalchannelgroup_drb = NULL; int j = 0; int i = 0; @@ -5639,7 +5641,7 @@ void *rrc_control_socket_thread_fct(void *arg) UE = &UE_rrc_inst[module_id]; PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, 0, ENB_FLAG_NO, 0x1234, 0, 0,0); - UE->DRB_config[0][0] = CALLOC(1,sizeof(struct DRB_ToAddMod)); + UE->DRB_config[0][0] = CALLOC(1,sizeof(struct LTE_DRB_ToAddMod)); UE->DRB_config[0][0]->eps_BearerIdentity = CALLOC(1, sizeof(long)); UE->DRB_config[0][0]->drb_Identity = 3; UE->DRB_config[0][0]->eps_BearerIdentity = CALLOC(1, sizeof(long)); @@ -5648,23 +5650,23 @@ void *rrc_control_socket_thread_fct(void *arg) UE->DRB_config[0][0]->logicalChannelIdentity = CALLOC(1, sizeof(long)); *(UE->DRB_config[0][0]->logicalChannelIdentity) = UE->DRB_config[0][0]->drb_Identity; //(long) (ue_context_pP->ue_context.e_rab[i].param.e_rab_id + 2); // value : x+2 - DRB_rlc_config = CALLOC(1,sizeof(struct RLC_Config)); - DRB_pdcp_config = CALLOC(1,sizeof(struct PDCP_Config)); - PDCP_rlc_UM = CALLOC(1,sizeof(struct PDCP_Config__rlc_UM)); - DRB_lchan_config = CALLOC(1,sizeof(struct LogicalChannelConfig)); - DRB_ul_SpecificParameters = CALLOC(1, sizeof(struct LogicalChannelConfig__ul_SpecificParameters)); + DRB_rlc_config = CALLOC(1,sizeof(struct LTE_RLC_Config)); + DRB_pdcp_config = CALLOC(1,sizeof(struct LTE_PDCP_Config)); + PDCP_rlc_UM = CALLOC(1,sizeof(struct LTE_PDCP_Config__rlc_UM)); + DRB_lchan_config = CALLOC(1,sizeof(struct LTE_LogicalChannelConfig)); + DRB_ul_SpecificParameters = CALLOC(1, sizeof(struct LTE_LogicalChannelConfig__ul_SpecificParameters)); logicalchannelgroup_drb = CALLOC(1, sizeof(long)); - 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_ms35; + DRB_rlc_config->present = LTE_RLC_Config_PR_um_Bi_Directional; + DRB_rlc_config->choice.um_Bi_Directional.ul_UM_RLC.sn_FieldLength = LTE_SN_FieldLength_size10; + DRB_rlc_config->choice.um_Bi_Directional.dl_UM_RLC.sn_FieldLength = LTE_SN_FieldLength_size10; + DRB_rlc_config->choice.um_Bi_Directional.dl_UM_RLC.t_Reordering = LTE_T_Reordering_ms35; UE->DRB_config[0][0]->rlc_Config = DRB_rlc_config; DRB_pdcp_config = CALLOC(1, sizeof(*DRB_pdcp_config)); UE->DRB_config[0][0]->pdcp_Config = DRB_pdcp_config; DRB_pdcp_config->discardTimer = CALLOC(1, sizeof(long)); - *DRB_pdcp_config->discardTimer = PDCP_Config__discardTimer_infinity; + *DRB_pdcp_config->discardTimer = LTE_PDCP_Config__discardTimer_infinity; DRB_pdcp_config->rlc_AM = NULL; DRB_pdcp_config->rlc_UM = NULL; @@ -5672,54 +5674,54 @@ void *rrc_control_socket_thread_fct(void *arg) (void)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; + PDCP_rlc_UM->pdcp_SN_Size = LTE_PDCP_Config__rlc_UM__pdcp_SN_Size_len12bits; + DRB_pdcp_config->headerCompression.present = LTE_PDCP_Config__headerCompression_PR_notUsed; UE->DRB_config[0][0]->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 = 12; // lower priority than srb1, srb2 and other dedicated bearer - DRB_ul_SpecificParameters->prioritisedBitRate =LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_kBps8 ; + DRB_ul_SpecificParameters->prioritisedBitRate =LTE_LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_kBps8 ; //LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_infinity; DRB_ul_SpecificParameters->bucketSizeDuration = - LogicalChannelConfig__ul_SpecificParameters__bucketSizeDuration_ms50; + LTE_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 = 1; DRB_ul_SpecificParameters->logicalChannelGroup = logicalchannelgroup_drb; - UE->DRB_configList = CALLOC(1,sizeof(DRB_ToAddModList_t)); + UE->DRB_configList = CALLOC(1,sizeof(LTE_DRB_ToAddModList_t)); ASN_SEQUENCE_ADD(&UE->DRB_configList->list,UE->DRB_config[0][0]); rrc_pdcp_config_asn1_req(&ctxt, - (SRB_ToAddModList_t *) NULL, + (LTE_SRB_ToAddModList_t *) NULL, UE->DRB_configList, - (DRB_ToReleaseList_t*) NULL, + (LTE_DRB_ToReleaseList_t*) NULL, 0xff, NULL, NULL, NULL -#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) - , (PMCH_InfoList_r9_t *) NULL +#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) + , (LTE_PMCH_InfoList_r9_t *) NULL #endif ,NULL); rrc_rlc_config_asn1_req(&ctxt, - (SRB_ToAddModList_t*)NULL, + (LTE_SRB_ToAddModList_t*)NULL, UE->DRB_configList, - (DRB_ToReleaseList_t*)NULL -#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) - ,(PMCH_InfoList_r9_t *)NULL + (LTE_DRB_ToReleaseList_t*)NULL +#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) + ,(LTE_PMCH_InfoList_r9_t *)NULL , 0, 0 #endif ); rrc_rlc_config_asn1_req(&ctxt, - (SRB_ToAddModList_t*)NULL, + (LTE_SRB_ToAddModList_t*)NULL, UE->DRB_configList, - (DRB_ToReleaseList_t*)NULL -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - ,(PMCH_InfoList_r9_t *)NULL + (LTE_DRB_ToReleaseList_t*)NULL +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + ,(LTE_PMCH_InfoList_r9_t *)NULL , sourceL2Id, groupL2Id #endif ); @@ -5727,29 +5729,29 @@ void *rrc_control_socket_thread_fct(void *arg) //configure MAC with sourceL2Id/groupL2ID rrc_mac_config_req_ue(module_id,0,0, //eNB_index =0 - (RadioResourceConfigCommonSIB_t *)NULL, - (struct PhysicalConfigDedicated *)NULL, -#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) - (SCellToAddMod_r10_t *)NULL, + (LTE_RadioResourceConfigCommonSIB_t *)NULL, + (struct LTE_PhysicalConfigDedicated *)NULL, +#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) + (LTE_SCellToAddMod_r10_t *)NULL, //struct PhysicalConfigDedicatedSCell_r10 *physicalConfigDedicatedSCell_r10, #endif - (MeasObjectToAddMod_t **)NULL, - (MAC_MainConfig_t *)NULL, + (LTE_MeasObjectToAddMod_t **)NULL, + (LTE_MAC_MainConfig_t *)NULL, 3, //LCID - (struct LogicalChannelConfig *)NULL, - (MeasGapConfig_t *)NULL, - (TDD_Config_t *)NULL, - (MobilityControlInfo_t *)NULL, + (struct LTE_LogicalChannelConfig *)NULL, + (LTE_MeasGapConfig_t *)NULL, + (LTE_TDD_Config_t *)NULL, + (LTE_MobilityControlInfo_t *)NULL, NULL, NULL, NULL, NULL, NULL, NULL -#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) ,0, - (MBSFN_AreaInfoList_r9_t *)NULL, - (PMCH_InfoList_r9_t *)NULL + (LTE_MBSFN_AreaInfoList_r9_t *)NULL, + (LTE_PMCH_InfoList_r9_t *)NULL #endif #ifdef CBA @@ -5757,7 +5759,7 @@ void *rrc_control_socket_thread_fct(void *arg) 0, 0 #endif -#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) ,CONFIG_ACTION_ADD, &sourceL2Id, &groupL2Id @@ -5799,29 +5801,29 @@ void *rrc_control_socket_thread_fct(void *arg) sourceL2Id = UE_rrc_inst[module_id].sourceL2Id; rrc_mac_config_req_ue(module_id,0,0, //eNB_index =0 - (RadioResourceConfigCommonSIB_t *)NULL, - (struct PhysicalConfigDedicated *)NULL, - #if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) - (SCellToAddMod_r10_t *)NULL, + (LTE_RadioResourceConfigCommonSIB_t *)NULL, + (struct LTE_PhysicalConfigDedicated *)NULL, + #if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) + (LTE_SCellToAddMod_r10_t *)NULL, //struct PhysicalConfigDedicatedSCell_r10 *physicalConfigDedicatedSCell_r10, #endif - (MeasObjectToAddMod_t **)NULL, - (MAC_MainConfig_t *)NULL, + (LTE_MeasObjectToAddMod_t **)NULL, + (LTE_MAC_MainConfig_t *)NULL, 0, - (struct LogicalChannelConfig *)NULL, - (MeasGapConfig_t *)NULL, - (TDD_Config_t *)NULL, - (MobilityControlInfo_t *)NULL, + (struct LTE_LogicalChannelConfig *)NULL, + (LTE_MeasGapConfig_t *)NULL, + (LTE_TDD_Config_t *)NULL, + (LTE_MobilityControlInfo_t *)NULL, NULL, NULL, NULL, NULL, NULL, NULL - #if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) + #if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) ,0, - (MBSFN_AreaInfoList_r9_t *)NULL, - (PMCH_InfoList_r9_t *)NULL + (LTE_MBSFN_AreaInfoList_r9_t *)NULL, + (LTE_PMCH_InfoList_r9_t *)NULL #endif #ifdef CBA @@ -5829,7 +5831,7 @@ void *rrc_control_socket_thread_fct(void *arg) 0, 0 #endif - #if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) + #if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) ,CONFIG_ACTION_REMOVE, &sourceL2Id, &destinationL2Id @@ -5887,7 +5889,7 @@ void *rrc_control_socket_thread_fct(void *arg) UE = &UE_rrc_inst[module_id]; PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, 0, ENB_FLAG_NO, 0x1234, 0, 0,0); - UE->DRB_config[0][0] = CALLOC(1,sizeof(struct DRB_ToAddMod)); + UE->DRB_config[0][0] = CALLOC(1,sizeof(struct LTE_DRB_ToAddMod)); UE->DRB_config[0][0]->eps_BearerIdentity = CALLOC(1, sizeof(long)); UE->DRB_config[0][0]->drb_Identity = 3; UE->DRB_config[0][0]->eps_BearerIdentity = CALLOC(1, sizeof(long)); @@ -5896,23 +5898,23 @@ void *rrc_control_socket_thread_fct(void *arg) UE->DRB_config[0][0]->logicalChannelIdentity = CALLOC(1, sizeof(long)); *(UE->DRB_config[0][0]->logicalChannelIdentity) = UE->DRB_config[0][0]->drb_Identity; //(long) (ue_context_pP->ue_context.e_rab[i].param.e_rab_id + 2); // value : x+2 - DRB_rlc_config = CALLOC(1,sizeof(struct RLC_Config)); - DRB_pdcp_config = CALLOC(1,sizeof(struct PDCP_Config)); - PDCP_rlc_UM = CALLOC(1,sizeof(struct PDCP_Config__rlc_UM)); - DRB_lchan_config = CALLOC(1,sizeof(struct LogicalChannelConfig)); - DRB_ul_SpecificParameters = CALLOC(1, sizeof(struct LogicalChannelConfig__ul_SpecificParameters)); + DRB_rlc_config = CALLOC(1,sizeof(struct LTE_RLC_Config)); + DRB_pdcp_config = CALLOC(1,sizeof(struct LTE_PDCP_Config)); + PDCP_rlc_UM = CALLOC(1,sizeof(struct LTE_PDCP_Config__rlc_UM)); + DRB_lchan_config = CALLOC(1,sizeof(struct LTE_LogicalChannelConfig)); + DRB_ul_SpecificParameters = CALLOC(1, sizeof(struct LTE_LogicalChannelConfig__ul_SpecificParameters)); logicalchannelgroup_drb = CALLOC(1, sizeof(long)); - 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_ms35; + DRB_rlc_config->present = LTE_RLC_Config_PR_um_Bi_Directional; + DRB_rlc_config->choice.um_Bi_Directional.ul_UM_RLC.sn_FieldLength = LTE_SN_FieldLength_size10; + DRB_rlc_config->choice.um_Bi_Directional.dl_UM_RLC.sn_FieldLength = LTE_SN_FieldLength_size10; + DRB_rlc_config->choice.um_Bi_Directional.dl_UM_RLC.t_Reordering = LTE_T_Reordering_ms35; UE->DRB_config[0][0]->rlc_Config = DRB_rlc_config; DRB_pdcp_config = CALLOC(1, sizeof(*DRB_pdcp_config)); UE->DRB_config[0][0]->pdcp_Config = DRB_pdcp_config; DRB_pdcp_config->discardTimer = CALLOC(1, sizeof(long)); - *DRB_pdcp_config->discardTimer = PDCP_Config__discardTimer_infinity; + *DRB_pdcp_config->discardTimer = LTE_PDCP_Config__discardTimer_infinity; DRB_pdcp_config->rlc_AM = NULL; DRB_pdcp_config->rlc_UM = NULL; @@ -5920,54 +5922,54 @@ void *rrc_control_socket_thread_fct(void *arg) (void)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; + PDCP_rlc_UM->pdcp_SN_Size = LTE_PDCP_Config__rlc_UM__pdcp_SN_Size_len12bits; + DRB_pdcp_config->headerCompression.present = LTE_PDCP_Config__headerCompression_PR_notUsed; UE->DRB_config[0][0]->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 = 12; // lower priority than srb1, srb2 and other dedicated bearer - DRB_ul_SpecificParameters->prioritisedBitRate =LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_kBps8 ; + DRB_ul_SpecificParameters->prioritisedBitRate =LTE_LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_kBps8 ; //LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_infinity; DRB_ul_SpecificParameters->bucketSizeDuration = - LogicalChannelConfig__ul_SpecificParameters__bucketSizeDuration_ms50; + LTE_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 = 1; DRB_ul_SpecificParameters->logicalChannelGroup = logicalchannelgroup_drb; - UE->DRB_configList = CALLOC(1,sizeof(DRB_ToAddModList_t)); + UE->DRB_configList = CALLOC(1,sizeof(LTE_DRB_ToAddModList_t)); ASN_SEQUENCE_ADD(&UE->DRB_configList->list,UE->DRB_config[0][0]); rrc_pdcp_config_asn1_req(&ctxt, - (SRB_ToAddModList_t *) NULL, + (LTE_SRB_ToAddModList_t *) NULL, UE->DRB_configList, - (DRB_ToReleaseList_t*) NULL, + (LTE_DRB_ToReleaseList_t*) NULL, 0xff, NULL, NULL, NULL -#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) - , (PMCH_InfoList_r9_t *) NULL +#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) + , (LTE_PMCH_InfoList_r9_t *) NULL #endif ,NULL); rrc_rlc_config_asn1_req(&ctxt, - (SRB_ToAddModList_t*)NULL, + (LTE_SRB_ToAddModList_t*)NULL, UE->DRB_configList, - (DRB_ToReleaseList_t*)NULL -#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) - ,(PMCH_InfoList_r9_t *)NULL + (LTE_DRB_ToReleaseList_t*)NULL +#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) + ,(LTE_PMCH_InfoList_r9_t *)NULL , 0, 0 #endif ); rrc_rlc_config_asn1_req(&ctxt, - (SRB_ToAddModList_t*)NULL, + (LTE_SRB_ToAddModList_t*)NULL, UE->DRB_configList, - (DRB_ToReleaseList_t*)NULL -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - ,(PMCH_InfoList_r9_t *)NULL + (LTE_DRB_ToReleaseList_t*)NULL +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + ,(LTE_PMCH_InfoList_r9_t *)NULL , sourceL2Id, destinationL2Id #endif ); @@ -5975,29 +5977,29 @@ void *rrc_control_socket_thread_fct(void *arg) //configure MAC with sourceL2Id/destinationL2Id rrc_mac_config_req_ue(module_id,0,0, //eNB_index =0 - (RadioResourceConfigCommonSIB_t *)NULL, - (struct PhysicalConfigDedicated *)NULL, -#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) - (SCellToAddMod_r10_t *)NULL, + (LTE_RadioResourceConfigCommonSIB_t *)NULL, + (struct LTE_PhysicalConfigDedicated *)NULL, +#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) + (LTE_SCellToAddMod_r10_t *)NULL, //struct PhysicalConfigDedicatedSCell_r10 *physicalConfigDedicatedSCell_r10, #endif - (MeasObjectToAddMod_t **)NULL, - (MAC_MainConfig_t *)NULL, + (LTE_MeasObjectToAddMod_t **)NULL, + (LTE_MAC_MainConfig_t *)NULL, 3, //LCID - (struct LogicalChannelConfig *)NULL, - (MeasGapConfig_t *)NULL, - (TDD_Config_t *)NULL, - (MobilityControlInfo_t *)NULL, + (struct LTE_LogicalChannelConfig *)NULL, + (LTE_MeasGapConfig_t *)NULL, + (LTE_TDD_Config_t *)NULL, + (LTE_MobilityControlInfo_t *)NULL, NULL, NULL, NULL, NULL, NULL, NULL -#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) ,0, - (MBSFN_AreaInfoList_r9_t *)NULL, - (PMCH_InfoList_r9_t *)NULL + (LTE_MBSFN_AreaInfoList_r9_t *)NULL, + (LTE_PMCH_InfoList_r9_t *)NULL #endif #ifdef CBA @@ -6005,7 +6007,7 @@ void *rrc_control_socket_thread_fct(void *arg) 0, 0 #endif -#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) ,CONFIG_ACTION_ADD, &sourceL2Id, &destinationL2Id @@ -6072,7 +6074,7 @@ void *rrc_control_socket_thread_fct(void *arg) UE = &UE_rrc_inst[module_id]; PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, 0, ENB_FLAG_NO, 0x1234, 0, 0,0); - UE->DRB_config[0][0] = CALLOC(1,sizeof(struct DRB_ToAddMod)); + UE->DRB_config[0][0] = CALLOC(1,sizeof(struct LTE_DRB_ToAddMod)); UE->DRB_config[0][0]->eps_BearerIdentity = CALLOC(1, sizeof(long)); UE->DRB_config[0][0]->drb_Identity = 10; UE->DRB_config[0][0]->eps_BearerIdentity = CALLOC(1, sizeof(long)); @@ -6081,23 +6083,23 @@ void *rrc_control_socket_thread_fct(void *arg) UE->DRB_config[0][0]->logicalChannelIdentity = CALLOC(1, sizeof(long)); *(UE->DRB_config[0][0]->logicalChannelIdentity) = UE->DRB_config[0][0]->drb_Identity; //(long) (ue_context_pP->ue_context.e_rab[i].param.e_rab_id + 2); // value : x+2 - DRB_rlc_config = CALLOC(1,sizeof(struct RLC_Config)); - DRB_pdcp_config = CALLOC(1,sizeof(struct PDCP_Config)); - PDCP_rlc_UM = CALLOC(1,sizeof(struct PDCP_Config__rlc_UM)); - DRB_lchan_config = CALLOC(1,sizeof(struct LogicalChannelConfig)); - DRB_ul_SpecificParameters = CALLOC(1, sizeof(struct LogicalChannelConfig__ul_SpecificParameters)); + DRB_rlc_config = CALLOC(1,sizeof(struct LTE_RLC_Config)); + DRB_pdcp_config = CALLOC(1,sizeof(struct LTE_PDCP_Config)); + PDCP_rlc_UM = CALLOC(1,sizeof(struct LTE_PDCP_Config__rlc_UM)); + DRB_lchan_config = CALLOC(1,sizeof(struct LTE_LogicalChannelConfig)); + DRB_ul_SpecificParameters = CALLOC(1, sizeof(struct LTE_LogicalChannelConfig__ul_SpecificParameters)); logicalchannelgroup_drb = CALLOC(1, sizeof(long)); - 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_ms35; + DRB_rlc_config->present = LTE_RLC_Config_PR_um_Bi_Directional; + DRB_rlc_config->choice.um_Bi_Directional.ul_UM_RLC.sn_FieldLength = LTE_SN_FieldLength_size10; + DRB_rlc_config->choice.um_Bi_Directional.dl_UM_RLC.sn_FieldLength = LTE_SN_FieldLength_size10; + DRB_rlc_config->choice.um_Bi_Directional.dl_UM_RLC.t_Reordering = LTE_T_Reordering_ms35; UE->DRB_config[0][0]->rlc_Config = DRB_rlc_config; DRB_pdcp_config = CALLOC(1, sizeof(*DRB_pdcp_config)); UE->DRB_config[0][0]->pdcp_Config = DRB_pdcp_config; DRB_pdcp_config->discardTimer = CALLOC(1, sizeof(long)); - *DRB_pdcp_config->discardTimer = PDCP_Config__discardTimer_infinity; + *DRB_pdcp_config->discardTimer = LTE_PDCP_Config__discardTimer_infinity; DRB_pdcp_config->rlc_AM = NULL; DRB_pdcp_config->rlc_UM = NULL; @@ -6105,44 +6107,44 @@ void *rrc_control_socket_thread_fct(void *arg) (void)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; + PDCP_rlc_UM->pdcp_SN_Size = LTE_PDCP_Config__rlc_UM__pdcp_SN_Size_len12bits; + DRB_pdcp_config->headerCompression.present = LTE_PDCP_Config__headerCompression_PR_notUsed; UE->DRB_config[0][0]->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 = 12; // lower priority than srb1, srb2 and other dedicated bearer - DRB_ul_SpecificParameters->prioritisedBitRate =LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_kBps8 ; + DRB_ul_SpecificParameters->prioritisedBitRate = LTE_LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_kBps8 ; //LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_infinity; DRB_ul_SpecificParameters->bucketSizeDuration = - LogicalChannelConfig__ul_SpecificParameters__bucketSizeDuration_ms50; + LTE_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 = 1; DRB_ul_SpecificParameters->logicalChannelGroup = logicalchannelgroup_drb; - UE->DRB_configList = CALLOC(1,sizeof(DRB_ToAddModList_t)); + UE->DRB_configList = CALLOC(1,sizeof(LTE_DRB_ToAddModList_t)); ASN_SEQUENCE_ADD(&UE->DRB_configList->list,UE->DRB_config[0][0]); rrc_pdcp_config_asn1_req(&ctxt, - (SRB_ToAddModList_t *) NULL, + (LTE_SRB_ToAddModList_t *) NULL, UE->DRB_configList, - (DRB_ToReleaseList_t*) NULL, + (LTE_DRB_ToReleaseList_t*) NULL, 0xff, NULL, NULL, NULL -#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) - , (PMCH_InfoList_r9_t *) NULL +#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) + , (LTE_PMCH_InfoList_r9_t *) NULL #endif ,NULL); rrc_rlc_config_asn1_req(&ctxt, - (SRB_ToAddModList_t*)NULL, + (LTE_SRB_ToAddModList_t*)NULL, UE->DRB_configList, - (DRB_ToReleaseList_t*)NULL -#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) - ,(PMCH_InfoList_r9_t *)NULL + (LTE_DRB_ToReleaseList_t*)NULL +#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) + ,(LTE_PMCH_InfoList_r9_t *)NULL , 0, 0 #endif ); @@ -6150,40 +6152,40 @@ void *rrc_control_socket_thread_fct(void *arg) //TX if (type > 0) { rrc_rlc_config_asn1_req(&ctxt, - (SRB_ToAddModList_t*)NULL, + (LTE_SRB_ToAddModList_t*)NULL, UE->DRB_configList, - (DRB_ToReleaseList_t*)NULL -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - ,(PMCH_InfoList_r9_t *)NULL + (LTE_DRB_ToReleaseList_t*)NULL +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + ,(LTE_PMCH_InfoList_r9_t *)NULL , sourceL2Id, destinationL2Id #endif ); //configure MAC with sourceL2Id/groupL2ID rrc_mac_config_req_ue(module_id,0,0, //eNB_index =0 - (RadioResourceConfigCommonSIB_t *)NULL, - (struct PhysicalConfigDedicated *)NULL, -#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) - (SCellToAddMod_r10_t *)NULL, + (LTE_RadioResourceConfigCommonSIB_t *)NULL, + (struct LTE_PhysicalConfigDedicated *)NULL, +#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) + (LTE_SCellToAddMod_r10_t *)NULL, //struct PhysicalConfigDedicatedSCell_r10 *physicalConfigDedicatedSCell_r10, #endif - (MeasObjectToAddMod_t **)NULL, - (MAC_MainConfig_t *)NULL, + (LTE_MeasObjectToAddMod_t **)NULL, + (LTE_MAC_MainConfig_t *)NULL, 10, //LCID - (struct LogicalChannelConfig *)NULL, - (MeasGapConfig_t *)NULL, - (TDD_Config_t *)NULL, - (MobilityControlInfo_t *)NULL, + (struct LTE_LogicalChannelConfig *)NULL, + (LTE_MeasGapConfig_t *)NULL, + (LTE_TDD_Config_t *)NULL, + (LTE_MobilityControlInfo_t *)NULL, NULL, NULL, NULL, NULL, NULL, NULL -#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) ,0, - (MBSFN_AreaInfoList_r9_t *)NULL, - (PMCH_InfoList_r9_t *)NULL + (LTE_MBSFN_AreaInfoList_r9_t *)NULL, + (LTE_PMCH_InfoList_r9_t *)NULL #endif #ifdef CBA @@ -6191,7 +6193,7 @@ void *rrc_control_socket_thread_fct(void *arg) 0, 0 #endif -#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) ,CONFIG_ACTION_ADD, &sourceL2Id, &destinationL2Id @@ -6200,29 +6202,29 @@ void *rrc_control_socket_thread_fct(void *arg) } else {//RX //configure MAC with sourceL2Id/groupL2ID rrc_mac_config_req_ue(module_id,0,0, //eNB_index =0 - (RadioResourceConfigCommonSIB_t *)NULL, - (struct PhysicalConfigDedicated *)NULL, -#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) - (SCellToAddMod_r10_t *)NULL, + (LTE_RadioResourceConfigCommonSIB_t *)NULL, + (struct LTE_PhysicalConfigDedicated *)NULL, +#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) + (LTE_SCellToAddMod_r10_t *)NULL, //struct PhysicalConfigDedicatedSCell_r10 *physicalConfigDedicatedSCell_r10, #endif - (MeasObjectToAddMod_t **)NULL, - (MAC_MainConfig_t *)NULL, + (LTE_MeasObjectToAddMod_t **)NULL, + (LTE_MAC_MainConfig_t *)NULL, 10, //LCID - (struct LogicalChannelConfig *)NULL, - (MeasGapConfig_t *)NULL, - (TDD_Config_t *)NULL, - (MobilityControlInfo_t *)NULL, + (struct LTE_LogicalChannelConfig *)NULL, + (LTE_MeasGapConfig_t *)NULL, + (LTE_TDD_Config_t *)NULL, + (LTE_MobilityControlInfo_t *)NULL, NULL, NULL, NULL, NULL, NULL, NULL -#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) ,0, - (MBSFN_AreaInfoList_r9_t *)NULL, - (PMCH_InfoList_r9_t *)NULL + (LTE_MBSFN_AreaInfoList_r9_t *)NULL, + (LTE_PMCH_InfoList_r9_t *)NULL #endif #ifdef CBA @@ -6230,7 +6232,7 @@ void *rrc_control_socket_thread_fct(void *arg) 0, 0 #endif -#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) ,CONFIG_ACTION_ADD, &sourceL2Id, NULL diff --git a/openair2/RRC/LTE/rrc_defs.h b/openair2/RRC/LTE/rrc_defs.h index ae87075489..5e7beb7b76 100644 --- a/openair2/RRC/LTE/rrc_defs.h +++ b/openair2/RRC/LTE/rrc_defs.h @@ -170,30 +170,30 @@ void *send_UE_status_notification(void *); //#include #endif -#include "SystemInformationBlockType1.h" -#include "SystemInformation.h" -#include "RRCConnectionReconfiguration.h" -#include "RRCConnectionReconfigurationComplete.h" -#include "RRCConnectionSetup.h" -#include "RRCConnectionSetupComplete.h" -#include "RRCConnectionRequest.h" -#include "RRCConnectionReestablishmentRequest.h" -#include "BCCH-DL-SCH-Message.h" -#include "SBCCH-SL-BCH-MessageType.h" -#include "BCCH-BCH-Message.h" -#if (RRC_VERSION >= MAKE_VERSION(9, 0, 0)) -#include "MCCH-Message.h" -#include "MBSFNAreaConfiguration-r9.h" +#include "LTE_SystemInformationBlockType1.h" +#include "LTE_SystemInformation.h" +#include "LTE_RRCConnectionReconfiguration.h" +#include "LTE_RRCConnectionReconfigurationComplete.h" +#include "LTE_RRCConnectionSetup.h" +#include "LTE_RRCConnectionSetupComplete.h" +#include "LTE_RRCConnectionRequest.h" +#include "LTE_RRCConnectionReestablishmentRequest.h" +#include "LTE_BCCH-DL-SCH-Message.h" +#include "LTE_SBCCH-SL-BCH-MessageType.h" +#include "LTE_BCCH-BCH-Message.h" +#if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) +#include "LTE_MCCH-Message.h" +#include "LTE_MBSFNAreaConfiguration-r9.h" #endif -#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) -#include "SCellToAddMod-r10.h" +#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) +#include "LTE_SCellToAddMod-r10.h" #endif -#include "AS-Config.h" -#include "AS-Context.h" -#include "UE-EUTRA-Capability.h" -#include "MeasResults.h" -#if (RRC_VERSION >= MAKE_VERSION(12, 0, 0)) -#include "SidelinkUEInformation-r12.h" +#include "LTE_AS-Config.h" +#include "LTE_AS-Context.h" +#include "LTE_UE-EUTRA-Capability.h" +#include "LTE_MeasResults.h" +#if (LTE_RRC_VERSION >= MAKE_VERSION(12, 0, 0)) +#include "LTE_SidelinkUEInformation-r12.h" #endif /* for ImsiMobileIdentity_t */ @@ -202,7 +202,7 @@ void *send_UE_status_notification(void *); /* correct Rel(8|10)/Rel14 differences * the code is in favor of Rel14, those defines do the translation */ -#if (RRC_VERSION < MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION < MAKE_VERSION(14, 0, 0)) # define CipheringAlgorithm_r12_t e_SecurityAlgorithmConfig__cipheringAlgorithm # define CipheringAlgorithm_r12_eea0 SecurityAlgorithmConfig__cipheringAlgorithm_eea0 # define CipheringAlgorithm_r12_eea1 SecurityAlgorithmConfig__cipheringAlgorithm_eea1 @@ -251,7 +251,7 @@ void *send_UE_status_notification(void *); #endif // This corrects something generated by asn1c which is different between Rel8 and Rel10 -#if (RRC_VERSION <= MAKE_VERSION(10, 0, 0)) +#if (LTE_RRC_VERSION <= MAKE_VERSION(10, 0, 0)) #define SystemInformation_r8_IEs__sib_TypeAndInfo__Member SystemInformation_r8_IEs_sib_TypeAndInfo_Member #define SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib2 SystemInformation_r8_IEs_sib_TypeAndInfo_Member_PR_sib2 #define SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib3 SystemInformation_r8_IEs_sib_TypeAndInfo_Member_PR_sib3 @@ -272,7 +272,7 @@ void *send_UE_status_notification(void *); #define NB_CNX_UE 2//MAX_MANAGED_RG_PER_MOBILE /* -#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) #define SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib12_v920 SystemInformation_r8_IEs_sib_TypeAndInfo_Member_PR_sib12_v920 #define SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib13_v920 SystemInformation_r8_IEs_sib_TypeAndInfo_Member_PR_sib13_v920 #endif @@ -403,7 +403,7 @@ typedef struct UE_RRC_INFO_s { uint8_t SIB1systemInfoValueTag; uint32_t SIStatus; uint32_t SIcnt; -#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) uint8_t MCCHStatus[8]; // MAX_MBSFN_AREA #endif uint8_t SIwindowsize; //!< Corresponds to the SIB1 si-WindowLength parameter. The unit is ms. Possible values are (final): 1,2,5,10,15,20,40 @@ -456,8 +456,8 @@ typedef struct HANDOVER_INFO_s { uint8_t modid_t; //module_idP of target cell uint8_t ueid_s; //UE index in serving cell uint8_t 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 */ + LTE_AS_Config_t as_config; /* these two parameters are taken from 36.331 section 10.2.2: HandoverPreparationInformation-r8-IEs */ + LTE_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; @@ -501,44 +501,44 @@ typedef struct SRB_INFO_TABLE_ENTRY_s { } SRB_INFO_TABLE_ENTRY; typedef struct MEAS_REPORT_LIST_s { - MeasId_t measId; + LTE_MeasId_t measId; //CellsTriggeredList cellsTriggeredList;//OPTIONAL uint32_t numberOfReportsSent; } MEAS_REPORT_LIST; typedef struct HANDOVER_INFO_UE_s { - PhysCellId_t targetCellId; + LTE_PhysCellId_t targetCellId; uint8_t measFlag; } HANDOVER_INFO_UE; typedef struct eNB_RRC_UE_s { uint8_t primaryCC_id; -#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) - SCellToAddMod_r10_t sCell_config[2]; +#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) + LTE_SCellToAddMod_r10_t sCell_config[2]; #endif - SRB_ToAddModList_t* SRB_configList; - SRB_ToAddModList_t* SRB_configList2[RRC_TRANSACTION_IDENTIFIER_NUMBER]; - DRB_ToAddModList_t* DRB_configList; - DRB_ToAddModList_t* DRB_configList2[RRC_TRANSACTION_IDENTIFIER_NUMBER]; - DRB_ToReleaseList_t* DRB_Release_configList2[RRC_TRANSACTION_IDENTIFIER_NUMBER]; + LTE_SRB_ToAddModList_t* SRB_configList; + LTE_SRB_ToAddModList_t* SRB_configList2[RRC_TRANSACTION_IDENTIFIER_NUMBER]; + LTE_DRB_ToAddModList_t* DRB_configList; + LTE_DRB_ToAddModList_t* DRB_configList2[RRC_TRANSACTION_IDENTIFIER_NUMBER]; + LTE_DRB_ToReleaseList_t* DRB_Release_configList2[RRC_TRANSACTION_IDENTIFIER_NUMBER]; uint8_t DRB_active[8]; - struct PhysicalConfigDedicated* physicalConfigDedicated; - struct SPS_Config* sps_Config; - MeasObjectToAddMod_t* MeasObj[MAX_MEAS_OBJ]; - struct ReportConfigToAddMod* ReportConfig[MAX_MEAS_CONFIG]; - struct QuantityConfig* QuantityConfig; - struct MeasIdToAddMod* MeasId[MAX_MEAS_ID]; - MAC_MainConfig_t* mac_MainConfig; - MeasGapConfig_t* measGapConfig; + struct LTE_PhysicalConfigDedicated* physicalConfigDedicated; + struct LTE_SPS_Config* sps_Config; + LTE_MeasObjectToAddMod_t* MeasObj[MAX_MEAS_OBJ]; + struct LTE_ReportConfigToAddMod* ReportConfig[MAX_MEAS_CONFIG]; + struct LTE_QuantityConfig* QuantityConfig; + struct LTE_MeasIdToAddMod* MeasId[MAX_MEAS_ID]; + LTE_MAC_MainConfig_t* mac_MainConfig; + LTE_MeasGapConfig_t* measGapConfig; SRB_INFO SI; SRB_INFO Srb0; SRB_INFO_TABLE_ENTRY Srb1; SRB_INFO_TABLE_ENTRY Srb2; - MeasConfig_t* measConfig; + LTE_MeasConfig_t* measConfig; HANDOVER_INFO* handover_info; - MeasResults_t* measResults; + LTE_MeasResults_t* measResults; - UE_EUTRA_Capability_t* UE_Capability; + LTE_UE_EUTRA_Capability_t* UE_Capability; ImsiMobileIdentity_t imsi; #if defined(ENABLE_SECURITY) @@ -549,8 +549,8 @@ typedef struct eNB_RRC_UE_s { int8_t nh_ncc; #endif /* Used integrity/ciphering algorithms */ - CipheringAlgorithm_r12_t ciphering_algorithm; - e_SecurityAlgorithmConfig__integrityProtAlgorithm integrity_algorithm; + LTE_CipheringAlgorithm_r12_t ciphering_algorithm; + e_LTE_SecurityAlgorithmConfig__integrityProtAlgorithm integrity_algorithm; uint8_t Status; rnti_t rnti; @@ -559,10 +559,10 @@ typedef struct eNB_RRC_UE_s { #if defined(ENABLE_ITTI) /* Information from UE RRC ConnectionRequest */ UE_S_TMSI Initialue_identity_s_TMSI; - EstablishmentCause_t establishment_cause; + LTE_EstablishmentCause_t establishment_cause; /* Information from UE RRC ConnectionReestablishmentRequest */ - ReestablishmentCause_t reestablishment_cause; + LTE_ReestablishmentCause_t reestablishment_cause; /* UE id for initial connection to S1AP */ uint16_t ue_initial_id; @@ -628,7 +628,7 @@ typedef struct { uint8_t sizeof_SIB1; uint8_t *SIB23; uint8_t sizeof_SIB23; -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) uint8_t *SIB1_BR; uint8_t sizeof_SIB1_BR; uint8_t *SIB23_BR; @@ -640,32 +640,32 @@ typedef struct { uint32_t dl_CarrierFreq; uint32_t ul_CarrierFreq; uint32_t pbch_repetition; - BCCH_BCH_Message_t mib; - BCCH_DL_SCH_Message_t siblock1; - BCCH_DL_SCH_Message_t systemInformation; - // SystemInformation_t systemInformation; - SystemInformationBlockType1_t *sib1; - SystemInformationBlockType2_t *sib2; - SystemInformationBlockType3_t *sib3; -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - SystemInformationBlockType1_t *sib1_BR; - SystemInformationBlockType2_t *sib2_BR; - SystemInformationBlockType2_t *sib3_BR; + LTE_BCCH_BCH_Message_t mib; + LTE_BCCH_DL_SCH_Message_t siblock1; + LTE_BCCH_DL_SCH_Message_t systemInformation; + // SystemInformation_t systemInformation; + LTE_SystemInformationBlockType1_t *sib1; + LTE_SystemInformationBlockType2_t *sib2; + LTE_SystemInformationBlockType3_t *sib3; +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + LTE_SystemInformationBlockType1_t *sib1_BR; + LTE_SystemInformationBlockType2_t *sib2_BR; + LTE_SystemInformationBlockType2_t *sib3_BR; #endif -#if (RRC_VERSION >= MAKE_VERSION(9, 0, 0)) - SystemInformationBlockType13_r9_t *sib13; +#if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) + LTE_SystemInformationBlockType13_r9_t *sib13; uint8_t MBMS_flag; uint8_t num_mbsfn_sync_area; uint8_t **MCCH_MESSAGE; // MAX_MBSFN_AREA uint8_t sizeof_MCCH_MESSAGE[8];// MAX_MBSFN_AREA - MCCH_Message_t mcch; - MBSFNAreaConfiguration_r9_t *mcch_message; + LTE_MCCH_Message_t mcch; + LTE_MBSFNAreaConfiguration_r9_t *mcch_message; SRB_INFO MCCH_MESS[8];// MAX_MBSFN_AREA #endif //TTN - SIB 18,19,21 for D2D - SystemInformationBlockType18_r12_t *sib18; - SystemInformationBlockType19_r12_t *sib19; - SystemInformationBlockType21_r14_t *sib21; + LTE_SystemInformationBlockType18_r12_t *sib18; + LTE_SystemInformationBlockType19_r12_t *sib19; + LTE_SystemInformationBlockType21_r14_t *sib21; // End - TTN SRB_INFO SI; SRB_INFO Srb0; @@ -714,7 +714,7 @@ typedef struct eNB_RRC_INST_s { typedef struct OAI_UECapability_s { uint8_t sdu[MAX_UE_CAPABILITY_SIZE]; uint8_t sdu_size; - UE_EUTRA_Capability_t *UE_EUTRA_Capability; + LTE_UE_EUTRA_Capability_t *UE_EUTRA_Capability; } OAI_UECapability_t; typedef struct UE_RRC_INST_s { @@ -739,28 +739,28 @@ typedef struct UE_RRC_INST_s { uint8_t sizeof_SI[NB_CNX_UE]; uint8_t SIB1Status[NB_CNX_UE]; uint8_t SIStatus[NB_CNX_UE]; - SystemInformationBlockType1_t *sib1[NB_CNX_UE]; - SystemInformation_t *si[NB_CNX_UE]; //!< Temporary storage for an SI message. Decoding happens in decode_SI(). - SystemInformationBlockType2_t *sib2[NB_CNX_UE]; - SystemInformationBlockType3_t *sib3[NB_CNX_UE]; - SystemInformationBlockType4_t *sib4[NB_CNX_UE]; - SystemInformationBlockType5_t *sib5[NB_CNX_UE]; - SystemInformationBlockType6_t *sib6[NB_CNX_UE]; - SystemInformationBlockType7_t *sib7[NB_CNX_UE]; - SystemInformationBlockType8_t *sib8[NB_CNX_UE]; - SystemInformationBlockType9_t *sib9[NB_CNX_UE]; - SystemInformationBlockType10_t *sib10[NB_CNX_UE]; - SystemInformationBlockType11_t *sib11[NB_CNX_UE]; + LTE_SystemInformationBlockType1_t *sib1[NB_CNX_UE]; + LTE_SystemInformation_t *si[NB_CNX_UE]; //!< Temporary storage for an SI message. Decoding happens in decode_SI(). + LTE_SystemInformationBlockType2_t *sib2[NB_CNX_UE]; + LTE_SystemInformationBlockType3_t *sib3[NB_CNX_UE]; + LTE_SystemInformationBlockType4_t *sib4[NB_CNX_UE]; + LTE_SystemInformationBlockType5_t *sib5[NB_CNX_UE]; + LTE_SystemInformationBlockType6_t *sib6[NB_CNX_UE]; + LTE_SystemInformationBlockType7_t *sib7[NB_CNX_UE]; + LTE_SystemInformationBlockType8_t *sib8[NB_CNX_UE]; + LTE_SystemInformationBlockType9_t *sib9[NB_CNX_UE]; + LTE_SystemInformationBlockType10_t *sib10[NB_CNX_UE]; + LTE_SystemInformationBlockType11_t *sib11[NB_CNX_UE]; uint8_t *MIB; -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) //SIB18 - SystemInformationBlockType18_r12_t *sib18[NB_CNX_UE]; - SystemInformationBlockType19_r12_t *sib19[NB_CNX_UE]; - SystemInformationBlockType21_r14_t *sib21[NB_CNX_UE]; + LTE_SystemInformationBlockType18_r12_t *sib18[NB_CNX_UE]; + LTE_SystemInformationBlockType19_r12_t *sib19[NB_CNX_UE]; + LTE_SystemInformationBlockType21_r14_t *sib21[NB_CNX_UE]; - SBCCH_SL_BCH_MessageType_t mib_sl[NB_CNX_UE]; + LTE_SBCCH_SL_BCH_MessageType_t mib_sl[NB_CNX_UE]; /// Preconfiguration for Sidelink - struct SL_Preconfiguration_r12 *SL_Preconfiguration[NB_CNX_UE]; + struct LTE_SL_Preconfiguration_r12 *SL_Preconfiguration[NB_CNX_UE]; //source L2 Id uint32_t sourceL2Id; //group L2 Id @@ -773,36 +773,36 @@ typedef struct UE_RRC_INST_s { SRB_INFO SL_Discovery[NB_CNX_UE]; #endif -#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) uint8_t MBMS_flag; uint8_t *MCCH_MESSAGE[NB_CNX_UE]; uint8_t sizeof_MCCH_MESSAGE[NB_CNX_UE]; uint8_t MCCH_MESSAGEStatus[NB_CNX_UE]; - MBSFNAreaConfiguration_r9_t *mcch_message[NB_CNX_UE]; - SystemInformationBlockType12_r9_t *sib12[NB_CNX_UE]; - SystemInformationBlockType13_r9_t *sib13[NB_CNX_UE]; + LTE_MBSFNAreaConfiguration_r9_t *mcch_message[NB_CNX_UE]; + LTE_SystemInformationBlockType12_r9_t *sib12[NB_CNX_UE]; + LTE_SystemInformationBlockType13_r9_t *sib13[NB_CNX_UE]; #endif #ifdef CBA uint8_t num_active_cba_groups; uint16_t cba_rnti[NUM_MAX_CBA_GROUP]; #endif uint8_t num_srb; - struct SRB_ToAddMod *SRB1_config[NB_CNX_UE]; - struct SRB_ToAddMod *SRB2_config[NB_CNX_UE]; - struct DRB_ToAddMod *DRB_config[NB_CNX_UE][8]; + struct LTE_SRB_ToAddMod *SRB1_config[NB_CNX_UE]; + struct LTE_SRB_ToAddMod *SRB2_config[NB_CNX_UE]; + struct LTE_DRB_ToAddMod *DRB_config[NB_CNX_UE][8]; rb_id_t *defaultDRB; // remember the ID of the default DRB - MeasObjectToAddMod_t *MeasObj[NB_CNX_UE][MAX_MEAS_OBJ]; - 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]; - uint32_t 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]; + LTE_MeasObjectToAddMod_t *MeasObj[NB_CNX_UE][MAX_MEAS_OBJ]; + struct LTE_ReportConfigToAddMod *ReportConfig[NB_CNX_UE][MAX_MEAS_CONFIG]; + struct LTE_QuantityConfig *QuantityConfig[NB_CNX_UE]; + struct LTE_MeasIdToAddMod *MeasId[NB_CNX_UE][MAX_MEAS_ID]; + MEAS_REPORT_LIST *measReportList[NB_CNX_UE][MAX_MEAS_ID]; + uint32_t measTimer[NB_CNX_UE][MAX_MEAS_ID][6]; // 6 neighboring cells + LTE_RSRP_Range_t s_measure; + struct LTE_MeasConfig__speedStatePars *speedStatePars; + struct LTE_PhysicalConfigDedicated *physicalConfigDedicated[NB_CNX_UE]; + struct LTE_SPS_Config *sps_Config[NB_CNX_UE]; + LTE_MAC_MainConfig_t *mac_MainConfig[NB_CNX_UE]; + LTE_MeasGapConfig_t *measGapConfig[NB_CNX_UE]; double filter_coeff_rsrp; // [7] ??? double filter_coeff_rsrq; // [7] ??? float rsrp_db[7]; @@ -817,12 +817,12 @@ typedef struct UE_RRC_INST_s { #endif /* Used integrity/ciphering algorithms */ - CipheringAlgorithm_r12_t ciphering_algorithm; - e_SecurityAlgorithmConfig__integrityProtAlgorithm integrity_algorithm; + LTE_CipheringAlgorithm_r12_t ciphering_algorithm; + e_LTE_SecurityAlgorithmConfig__integrityProtAlgorithm integrity_algorithm; -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) /// Used for Sidelink Preconfiguration - DRB_ToAddModList_t *DRB_configList; + LTE_DRB_ToAddModList_t *DRB_configList; #endif } UE_RRC_INST; diff --git a/openair2/RRC/LTE/rrc_eNB.c b/openair2/RRC/LTE/rrc_eNB.c index 00f814b8b1..e8c52f72f5 100644 --- a/openair2/RRC/LTE/rrc_eNB.c +++ b/openair2/RRC/LTE/rrc_eNB.c @@ -44,29 +44,29 @@ #include "common/utils/LOG/log.h" #include "COMMON/mac_rrc_primitives.h" #include "RRC/LTE/MESSAGES/asn1_msg.h" -#include "RRCConnectionRequest.h" -#include "RRCConnectionReestablishmentRequest.h" +#include "LTE_RRCConnectionRequest.h" +#include "LTE_RRCConnectionReestablishmentRequest.h" //#include "ReestablishmentCause.h" -#include "BCCH-BCH-Message.h" -#include "UL-CCCH-Message.h" -#include "DL-CCCH-Message.h" -#include "UL-DCCH-Message.h" -#include "DL-DCCH-Message.h" -#include "TDD-Config.h" -#include "HandoverCommand.h" +#include "LTE_BCCH-BCH-Message.h" +#include "LTE_UL-CCCH-Message.h" +#include "LTE_DL-CCCH-Message.h" +#include "LTE_UL-DCCH-Message.h" +#include "LTE_DL-DCCH-Message.h" +#include "LTE_TDD-Config.h" +#include "LTE_HandoverCommand.h" #include "rlc.h" #include "rrc_eNB_UE_context.h" #include "platform_types.h" #include "msc.h" -#include "SL-CommConfig-r12.h" -#include "PeriodicBSR-Timer-r12.h" -#include "RetxBSR-Timer-r12.h" +#include "LTE_SL-CommConfig-r12.h" +#include "LTE_PeriodicBSR-Timer-r12.h" +#include "LTE_RetxBSR-Timer-r12.h" #include "common/utils/LOG/vcd_signal_dumper.h" #include "T.h" -//#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) -#include "MeasResults.h" +//#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) +#include "LTE_MeasResults.h" //#endif #include "RRC/NAS/nas_config.h" @@ -148,12 +148,12 @@ init_SI( ) //----------------------------------------------------------------------------- { -#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) int i; #endif -#if (RRC_VERSION >= MAKE_VERSION(13, 1, 0)) - SystemInformationBlockType1_v1310_IEs_t *sib1_v13ext=(SystemInformationBlockType1_v1310_IEs_t *)NULL; +#if (LTE_RRC_VERSION >= MAKE_VERSION(13, 1, 0)) + LTE_SystemInformationBlockType1_v1310_IEs_t *sib1_v13ext=(LTE_SystemInformationBlockType1_v1310_IEs_t *)NULL; #endif LOG_D(RRC,"%s()\n\n\n\n",__FUNCTION__); @@ -165,7 +165,7 @@ init_SI( RC.rrc[ctxt_pP->module_id]->carrier[CC_id].Ncp = configuration->prefix_type[CC_id]; RC.rrc[ctxt_pP->module_id]->carrier[CC_id].dl_CarrierFreq = configuration->downlink_frequency[CC_id]; RC.rrc[ctxt_pP->module_id]->carrier[CC_id].ul_CarrierFreq = configuration->downlink_frequency[CC_id]+ configuration->uplink_frequency_offset[CC_id]; -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) RC.rrc[ctxt_pP->module_id]->carrier[CC_id].pbch_repetition = configuration->pbch_repetition[CC_id]; #endif LOG_I(RRC, "Configuring MIB (N_RB_DL %d,phich_Resource %d,phich_Duration %d)\n", @@ -246,7 +246,7 @@ init_SI( RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib2->radioResourceConfigCommon.pusch_ConfigCommon. ul_ReferenceSignalsPUSCH.cyclicShift); -#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) if (RC.rrc[ctxt_pP->module_id]->carrier[CC_id].MBMS_flag > 0) { for (i = 0; i < RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib2->mbsfn_SubframeConfigList->list.count; i++) { @@ -267,7 +267,7 @@ init_SI( RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib2->mbsfn_SubframeConfigList->list.array[i]->radioframeAllocationOffset); } -#if (RRC_VERSION >= MAKE_VERSION(9, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) // SIB13 for (i = 0; i < RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib13->mbsfn_AreaInfoList_r9.list.count; i++) { LOG_D(RRC, PROTOCOL_RRC_CTXT_FMT" SIB13 contents for MBSFN sync area %d/%d (partial)\n", @@ -360,7 +360,7 @@ init_SI( PROTOCOL_RRC_CTXT_FMT" RRC_UE --- MAC_CONFIG_REQ (SIB1.tdd & SIB2 params) ---> MAC_UE\n", PROTOCOL_RRC_CTXT_ARGS(ctxt_pP)); -#if (RRC_VERSION >= MAKE_VERSION(13, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(13, 0, 0)) if ((RC.rrc[ctxt_pP->module_id]->carrier[CC_id].mib.message.schedulingInfoSIB1_BR_r13>0) && (RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib1_BR!=NULL)) { AssertFatal(RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib1_BR->nonCriticalExtension!=NULL, @@ -385,48 +385,48 @@ init_SI( RC.rrc[ctxt_pP->module_id]->carrier[CC_id].Ncp, RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib1->freqBandIndicator, RC.rrc[ctxt_pP->module_id]->carrier[CC_id].dl_CarrierFreq, -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) RC.rrc[ctxt_pP->module_id]->carrier[CC_id].pbch_repetition, #endif 0, // rnti - (BCCH_BCH_Message_t *) + (LTE_BCCH_BCH_Message_t *) &RC.rrc[ctxt_pP->module_id]->carrier[CC_id].mib, - (RadioResourceConfigCommonSIB_t *) & + (LTE_RadioResourceConfigCommonSIB_t *) & RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib2->radioResourceConfigCommon, -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - (RadioResourceConfigCommonSIB_t *) & +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + (LTE_RadioResourceConfigCommonSIB_t *) & RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib2_BR->radioResourceConfigCommon, #endif - (struct PhysicalConfigDedicated *)NULL, -#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) - (SCellToAddMod_r10_t *)NULL, - //(struct PhysicalConfigDedicatedSCell_r10 *)NULL, + (struct LTE_PhysicalConfigDedicated *)NULL, +#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) + (LTE_SCellToAddMod_r10_t *)NULL, + //(struct LTE_PhysicalConfigDedicatedSCell_r10 *)NULL, #endif - (MeasObjectToAddMod_t **) NULL, - (MAC_MainConfig_t *) NULL, 0, - (struct LogicalChannelConfig *)NULL, - (MeasGapConfig_t *) NULL, + (LTE_MeasObjectToAddMod_t **) NULL, + (LTE_MAC_MainConfig_t *) NULL, 0, + (struct LTE_LogicalChannelConfig *)NULL, + (LTE_MeasGapConfig_t *) NULL, RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib1->tdd_Config, NULL, &RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib1->schedulingInfoList, RC.rrc[ctxt_pP->module_id]->carrier[CC_id].ul_CarrierFreq, RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib2->freqInfo.ul_Bandwidth, &RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib2->freqInfo.additionalSpectrumEmission, - (MBSFN_SubframeConfigList_t*) RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib2->mbsfn_SubframeConfigList -#if (RRC_VERSION >= MAKE_VERSION(9, 0, 0)) + (LTE_MBSFN_SubframeConfigList_t*) RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib2->mbsfn_SubframeConfigList +#if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) , RC.rrc[ctxt_pP->module_id]->carrier[CC_id].MBMS_flag, - (MBSFN_AreaInfoList_r9_t*) & RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib13->mbsfn_AreaInfoList_r9, - (PMCH_InfoList_r9_t *) NULL + (LTE_MBSFN_AreaInfoList_r9_t*) & RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib13->mbsfn_AreaInfoList_r9, + (LTE_PMCH_InfoList_r9_t *) NULL #endif -#if (RRC_VERSION >= MAKE_VERSION(13, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(13, 0, 0)) , sib1_v13ext #endif ); } -#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) /*------------------------------------------------------------------------------*/ static void init_MCCH( @@ -484,38 +484,38 @@ init_MCCH( // LOG_I(RRC, "DUY: session ID is %d\n",RC.rrc[enb_mod_idP]->mcch_message->pmch_InfoList_r9.list.array[0]->mbms_SessionInfoList_r9.list.array[0]->sessionId_r9->buf[0]); rrc_mac_config_req_eNB(enb_mod_idP, CC_id, 0,0,0,0,0, -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) 0, #endif 0,//rnti - (BCCH_BCH_Message_t *)NULL, - (RadioResourceConfigCommonSIB_t *) NULL, -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - (RadioResourceConfigCommonSIB_t *) NULL, + (LTE_BCCH_BCH_Message_t *)NULL, + (LTE_RadioResourceConfigCommonSIB_t *) NULL, +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + (LTE_RadioResourceConfigCommonSIB_t *) NULL, #endif - (struct PhysicalConfigDedicated *)NULL, -#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) - (SCellToAddMod_r10_t *)NULL, - //(struct PhysicalConfigDedicatedSCell_r10 *)NULL, + (struct LTE_PhysicalConfigDedicated *)NULL, +#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) + (LTE_SCellToAddMod_r10_t *)NULL, + //(struct LTE_PhysicalConfigDedicatedSCell_r10 *)NULL, #endif - (MeasObjectToAddMod_t **) NULL, - (MAC_MainConfig_t *) NULL, + (LTE_MeasObjectToAddMod_t **) NULL, + (LTE_MAC_MainConfig_t *) NULL, 0, - (struct LogicalChannelConfig *)NULL, - (MeasGapConfig_t *) NULL, - (TDD_Config_t *) NULL, - (MobilityControlInfo_t *)NULL, - (SchedulingInfoList_t *) NULL, - 0, NULL, NULL, (MBSFN_SubframeConfigList_t *) NULL -#if (RRC_VERSION >= MAKE_VERSION(9, 0, 0)) + (struct LTE_LogicalChannelConfig *)NULL, + (LTE_MeasGapConfig_t *) NULL, + (LTE_TDD_Config_t *) NULL, + (LTE_MobilityControlInfo_t *)NULL, + (LTE_SchedulingInfoList_t *) NULL, + 0, NULL, NULL, (LTE_MBSFN_SubframeConfigList_t *) NULL +#if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) , 0, - (MBSFN_AreaInfoList_r9_t *) NULL, - (PMCH_InfoList_r9_t *) & (RC.rrc[enb_mod_idP]->carrier[CC_id].mcch_message->pmch_InfoList_r9) + (LTE_MBSFN_AreaInfoList_r9_t *) NULL, + (LTE_PMCH_InfoList_r9_t *) & (RC.rrc[enb_mod_idP]->carrier[CC_id].mcch_message->pmch_InfoList_r9) #endif -#if (RRC_VERSION >= MAKE_VERSION(13, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(13, 0, 0)) , - (SystemInformationBlockType1_v1310_IEs_t *)NULL + (LTE_SystemInformationBlockType1_v1310_IEs_t *)NULL #endif ); @@ -541,25 +541,25 @@ static void init_MBMS( // Configuring PDCP and RLC for MBMS Radio Bearer rrc_pdcp_config_asn1_req(&ctxt, - (SRB_ToAddModList_t *)NULL, // SRB_ToAddModList - (DRB_ToAddModList_t *)NULL, // DRB_ToAddModList - (DRB_ToReleaseList_t *)NULL, + (LTE_SRB_ToAddModList_t *)NULL, // LTE_SRB_ToAddModList + (LTE_DRB_ToAddModList_t *)NULL, // LTE_DRB_ToAddModList + (LTE_DRB_ToReleaseList_t *)NULL, 0, // security mode NULL, // key rrc encryption NULL, // key rrc integrity NULL // key encryption -#if (RRC_VERSION >= MAKE_VERSION(9, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) , &(RC.rrc[enb_mod_idP]->carrier[CC_id].mcch_message->pmch_InfoList_r9) #endif ,NULL); rrc_rlc_config_asn1_req(&ctxt, - NULL, // SRB_ToAddModList - NULL, // DRB_ToAddModList + NULL, // LTE_SRB_ToAddModList + NULL, // LTE_DRB_ToAddModList NULL, // DRB_ToReleaseList &(RC.rrc[enb_mod_idP]->carrier[CC_id].mcch_message->pmch_InfoList_r9) -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) ,0, 0 #endif ); @@ -715,13 +715,13 @@ rrc_eNB_free_mem_UE_context( PROTOCOL_RRC_CTXT_UE_FMT" Clearing UE context 0x%p (free internal structs)\n", PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP), ue_context_pP); -#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) - ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_SCellToAddMod_r10, &ue_context_pP->ue_context.sCell_config[0]); - ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_SCellToAddMod_r10, &ue_context_pP->ue_context.sCell_config[1]); +#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) + ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_LTE_SCellToAddMod_r10, &ue_context_pP->ue_context.sCell_config[0]); + ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_LTE_SCellToAddMod_r10, &ue_context_pP->ue_context.sCell_config[1]); #endif if (ue_context_pP->ue_context.SRB_configList) { - ASN_STRUCT_FREE(asn_DEF_SRB_ToAddModList, ue_context_pP->ue_context.SRB_configList); + ASN_STRUCT_FREE(asn_DEF_LTE_SRB_ToAddModList, ue_context_pP->ue_context.SRB_configList); ue_context_pP->ue_context.SRB_configList = NULL; } @@ -733,7 +733,7 @@ rrc_eNB_free_mem_UE_context( } if (ue_context_pP->ue_context.DRB_configList) { - ASN_STRUCT_FREE(asn_DEF_DRB_ToAddModList, ue_context_pP->ue_context.DRB_configList); + ASN_STRUCT_FREE(asn_DEF_LTE_DRB_ToAddModList, ue_context_pP->ue_context.DRB_configList); ue_context_pP->ue_context.DRB_configList = NULL; } @@ -751,45 +751,45 @@ rrc_eNB_free_mem_UE_context( memset(ue_context_pP->ue_context.DRB_active, 0, sizeof(ue_context_pP->ue_context.DRB_active)); if (ue_context_pP->ue_context.physicalConfigDedicated) { - ASN_STRUCT_FREE(asn_DEF_PhysicalConfigDedicated, ue_context_pP->ue_context.physicalConfigDedicated); + ASN_STRUCT_FREE(asn_DEF_LTE_PhysicalConfigDedicated, ue_context_pP->ue_context.physicalConfigDedicated); ue_context_pP->ue_context.physicalConfigDedicated = NULL; } if (ue_context_pP->ue_context.sps_Config) { - ASN_STRUCT_FREE(asn_DEF_SPS_Config, ue_context_pP->ue_context.sps_Config); + ASN_STRUCT_FREE(asn_DEF_LTE_SPS_Config, ue_context_pP->ue_context.sps_Config); ue_context_pP->ue_context.sps_Config = NULL; } for (i=0; i < MAX_MEAS_OBJ; i++) { if (ue_context_pP->ue_context.MeasObj[i] != NULL) { - ASN_STRUCT_FREE(asn_DEF_MeasObjectToAddMod, ue_context_pP->ue_context.MeasObj[i]); + ASN_STRUCT_FREE(asn_DEF_LTE_MeasObjectToAddMod, ue_context_pP->ue_context.MeasObj[i]); ue_context_pP->ue_context.MeasObj[i] = NULL; } } for (i=0; i < MAX_MEAS_CONFIG; i++) { if (ue_context_pP->ue_context.ReportConfig[i] != NULL) { - ASN_STRUCT_FREE(asn_DEF_ReportConfigToAddMod, ue_context_pP->ue_context.ReportConfig[i]); + ASN_STRUCT_FREE(asn_DEF_LTE_ReportConfigToAddMod, ue_context_pP->ue_context.ReportConfig[i]); ue_context_pP->ue_context.ReportConfig[i] = NULL; } } if (ue_context_pP->ue_context.QuantityConfig) { - ASN_STRUCT_FREE(asn_DEF_QuantityConfig, ue_context_pP->ue_context.QuantityConfig); + ASN_STRUCT_FREE(asn_DEF_LTE_QuantityConfig, ue_context_pP->ue_context.QuantityConfig); ue_context_pP->ue_context.QuantityConfig = NULL; } if (ue_context_pP->ue_context.mac_MainConfig) { - ASN_STRUCT_FREE(asn_DEF_MAC_MainConfig, ue_context_pP->ue_context.mac_MainConfig); + ASN_STRUCT_FREE(asn_DEF_LTE_MAC_MainConfig, ue_context_pP->ue_context.mac_MainConfig); ue_context_pP->ue_context.mac_MainConfig = NULL; } /* if (ue_context_pP->ue_context.measGapConfig) { - ASN_STRUCT_FREE(asn_DEF_MeasGapConfig, ue_context_pP->ue_context.measGapConfig); + ASN_STRUCT_FREE(asn_DEF_LTE_MeasGapConfig, ue_context_pP->ue_context.measGapConfig); ue_context_pP->ue_context.measGapConfig = NULL; }*/ if (ue_context_pP->ue_context.handover_info) { - ASN_STRUCT_FREE(asn_DEF_Handover, ue_context_pP->ue_context.handover_info); + ASN_STRUCT_FREE(asn_DEF_LTE_Handover, ue_context_pP->ue_context.handover_info); ue_context_pP->ue_context.handover_info = NULL; } @@ -798,12 +798,12 @@ rrc_eNB_free_mem_UE_context( //SRB_INFO_TABLE_ENTRY Srb1; //SRB_INFO_TABLE_ENTRY Srb2; if (ue_context_pP->ue_context.measConfig) { - ASN_STRUCT_FREE(asn_DEF_MeasConfig, ue_context_pP->ue_context.measConfig); + ASN_STRUCT_FREE(asn_DEF_LTE_MeasConfig, ue_context_pP->ue_context.measConfig); ue_context_pP->ue_context.measConfig = NULL; } if (ue_context_pP->ue_context.measConfig) { - ASN_STRUCT_FREE(asn_DEF_MeasConfig, ue_context_pP->ue_context.measConfig); + ASN_STRUCT_FREE(asn_DEF_LTE_MeasConfig, ue_context_pP->ue_context.measConfig); ue_context_pP->ue_context.measConfig = NULL; } @@ -1003,12 +1003,12 @@ void rrc_eNB_process_RRCConnectionSetupComplete( const protocol_ctxt_t* const ctxt_pP, rrc_eNB_ue_context_t* ue_context_pP, - RRCConnectionSetupComplete_r8_IEs_t * rrcConnectionSetupComplete + LTE_RRCConnectionSetupComplete_r8_IEs_t * rrcConnectionSetupComplete ) //----------------------------------------------------------------------------- { LOG_I(RRC, - PROTOCOL_RRC_CTXT_UE_FMT" [RAPROC] Logical Channel UL-DCCH, " "processing RRCConnectionSetupComplete from UE (SRB1 Active)\n", + PROTOCOL_RRC_CTXT_UE_FMT" [RAPROC] Logical Channel UL-DCCH, " "processing LTE_RRCConnectionSetupComplete from UE (SRB1 Active)\n", PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP)); ue_context_pP->ue_context.Srb1.Active=1; @@ -1169,13 +1169,13 @@ rrc_eNB_generate_RRCConnectionReject( MSC_RRC_UE, RC.rrc[ctxt_pP->module_id]->carrier[CC_id].Srb0.Tx_buffer.Header, RC.rrc[ctxt_pP->module_id]->carrier[CC_id].Srb0.Tx_buffer.payload_size, - MSC_AS_TIME_FMT" RRCConnectionReject UE %x size %u", + MSC_AS_TIME_FMT" LTE_RRCConnectionReject UE %x size %u", MSC_AS_TIME_ARGS(ctxt_pP), ue_context_pP == NULL ? -1 : ue_context_pP->ue_context.rnti, RC.rrc[ctxt_pP->module_id]->carrier[CC_id].Srb0.Tx_buffer.payload_size); LOG_I(RRC, - PROTOCOL_RRC_CTXT_UE_FMT" [RAPROC] Logical Channel DL-CCCH, Generating RRCConnectionReject (bytes %d)\n", + PROTOCOL_RRC_CTXT_UE_FMT" [RAPROC] Logical Channel DL-CCCH, Generating LTE_RRCConnectionReject (bytes %d)\n", PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP), RC.rrc[ctxt_pP->module_id]->carrier[CC_id].Srb0.Tx_buffer.payload_size); } @@ -1189,9 +1189,9 @@ rrc_eNB_generate_RRCConnectionReestablishment( ) //----------------------------------------------------------------------------- { - LogicalChannelConfig_t *SRB1_logicalChannelConfig; - SRB_ToAddModList_t **SRB_configList; - SRB_ToAddMod_t *SRB1_config; + LTE_LogicalChannelConfig_t *SRB1_logicalChannelConfig; + LTE_SRB_ToAddModList_t **SRB_configList; + LTE_SRB_ToAddMod_t *SRB1_config; int cnt; T(T_ENB_RRC_CONNECTION_REESTABLISHMENT, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame), @@ -1221,7 +1221,7 @@ rrc_eNB_generate_RRCConnectionReestablishment( if (SRB1_config->logicalChannelConfig) { if (SRB1_config->logicalChannelConfig->present == - SRB_ToAddMod__logicalChannelConfig_PR_explicitValue) { + LTE_SRB_ToAddMod__logicalChannelConfig_PR_explicitValue) { SRB1_logicalChannelConfig = &SRB1_config->logicalChannelConfig->choice.explicitValue; } else { SRB1_logicalChannelConfig = &SRB1_logicalChannelConfig_defaultValue; @@ -1236,34 +1236,34 @@ rrc_eNB_generate_RRCConnectionReestablishment( rrc_mac_config_req_eNB(ctxt_pP->module_id, ue_context_pP->ue_context.primaryCC_id, 0,0,0,0,0, -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) 0, #endif ctxt_pP->rnti, - (BCCH_BCH_Message_t *) NULL, - (RadioResourceConfigCommonSIB_t *) NULL, -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - (RadioResourceConfigCommonSIB_t *) NULL, + (LTE_BCCH_BCH_Message_t *) NULL, + (LTE_RadioResourceConfigCommonSIB_t *) NULL, +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + (LTE_RadioResourceConfigCommonSIB_t *) NULL, #endif - (struct PhysicalConfigDedicated* ) ue_context_pP->ue_context.physicalConfigDedicated, -#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) - (SCellToAddMod_r10_t *)NULL, - //(struct PhysicalConfigDedicatedSCell_r10 *)NULL, + (struct LTE_PhysicalConfigDedicated* ) ue_context_pP->ue_context.physicalConfigDedicated, +#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) + (LTE_SCellToAddMod_r10_t *)NULL, + //(struct LTE_PhysicalConfigDedicatedSCell_r10 *)NULL, #endif - (MeasObjectToAddMod_t **) NULL, + (LTE_MeasObjectToAddMod_t **) NULL, ue_context_pP->ue_context.mac_MainConfig, 1, SRB1_logicalChannelConfig, ue_context_pP->ue_context.measGapConfig, - (TDD_Config_t *) NULL, + (LTE_TDD_Config_t *) NULL, NULL, - (SchedulingInfoList_t *) NULL, - 0, NULL, NULL, (MBSFN_SubframeConfigList_t *) NULL -#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) - , 0, (MBSFN_AreaInfoList_r9_t *) NULL, (PMCH_InfoList_r9_t *) NULL + (LTE_SchedulingInfoList_t *) NULL, + 0, NULL, NULL, (LTE_MBSFN_SubframeConfigList_t *) NULL +#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) + , 0, (LTE_MBSFN_AreaInfoList_r9_t *) NULL, (LTE_PMCH_InfoList_r9_t *) NULL #endif -#if (RRC_VERSION >= MAKE_VERSION(13, 0, 0)) - ,(SystemInformationBlockType1_v1310_IEs_t *)NULL +#if (LTE_RRC_VERSION >= MAKE_VERSION(13, 0, 0)) + ,(LTE_SystemInformationBlockType1_v1310_IEs_t *)NULL #endif ); break; @@ -1275,13 +1275,13 @@ rrc_eNB_generate_RRCConnectionReestablishment( MSC_RRC_UE, RC.rrc[ctxt_pP->module_id]->carrier[CC_id].Srb0.Tx_buffer.Header, RC.rrc[ctxt_pP->module_id]->carrier[CC_id].Srb0.Tx_buffer.payload_size, - MSC_AS_TIME_FMT" RRCConnectionReestablishment UE %x size %u", + MSC_AS_TIME_FMT" LTE_RRCConnectionReestablishment UE %x size %u", MSC_AS_TIME_ARGS(ctxt_pP), ue_context_pP->ue_context.rnti, RC.rrc[ctxt_pP->module_id]->carrier[CC_id].Srb0.Tx_buffer.payload_size); LOG_I(RRC, - PROTOCOL_RRC_CTXT_UE_FMT" [RAPROC] Logical Channel DL-CCCH, Generating RRCConnectionReestablishment (bytes %d)\n", + PROTOCOL_RRC_CTXT_UE_FMT" [RAPROC] Logical Channel DL-CCCH, Generating LTE_RRCConnectionReestablishment (bytes %d)\n", PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP), RC.rrc[ctxt_pP->module_id]->carrier[CC_id].Srb0.Tx_buffer.payload_size); @@ -1289,16 +1289,16 @@ rrc_eNB_generate_RRCConnectionReestablishment( if(UE_id != -1){ // activate release timer, if RRCComplete not received after 100 frames, remove UE RC.mac[ctxt_pP->module_id]->UE_list.UE_sched_ctrl[UE_id].ue_reestablishment_reject_timer = 1; - // remove UE after 100 frames after RRCConnectionReestablishmentRelease is triggered + // remove UE after 100 frames after LTE_RRCConnectionReestablishmentRelease is triggered RC.mac[ctxt_pP->module_id]->UE_list.UE_sched_ctrl[UE_id].ue_reestablishment_reject_timer_thres = 1000; }else{ LOG_E(RRC, - PROTOCOL_RRC_CTXT_UE_FMT" Generating RRCConnectionReestablishment without UE_id(MAC) rnti %x\n", + PROTOCOL_RRC_CTXT_UE_FMT" Generating LTE_RRCConnectionReestablishment without UE_id(MAC) rnti %x\n", PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP),ctxt_pP->rnti); } // activate release timer, if RRCComplete not received after 100 frames, remove UE ue_context_pP->ue_context.ue_reestablishment_timer = 1; - // remove UE after 100 frames after RRCConnectionReestablishmentRelease is triggered + // remove UE after 100 frames after LTE_RRCConnectionReestablishmentRelease is triggered ue_context_pP->ue_context.ue_reestablishment_timer_thres = 1000; } @@ -1309,43 +1309,43 @@ rrc_eNB_process_RRCConnectionReestablishmentComplete( const rnti_t reestablish_rnti, rrc_eNB_ue_context_t* ue_context_pP, const uint8_t xid, - RRCConnectionReestablishmentComplete_r8_IEs_t * rrcConnectionReestablishmentComplete + LTE_RRCConnectionReestablishmentComplete_r8_IEs_t * LTE_RRCConnectionReestablishmentComplete ) //----------------------------------------------------------------------------- { LOG_I(RRC, - PROTOCOL_RRC_CTXT_UE_FMT" [RAPROC] Logical Channel UL-DCCH, processing RRCConnectionReestablishmentComplete from UE (SRB1 Active)\n", + PROTOCOL_RRC_CTXT_UE_FMT" [RAPROC] Logical Channel UL-DCCH, processing LTE_RRCConnectionReestablishmentComplete from UE (SRB1 Active)\n", PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP)); T(T_ENB_RRC_CONNECTION_REESTABLISHMENT_COMPLETE, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame), T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti)); - DRB_ToAddModList_t* DRB_configList = ue_context_pP->ue_context.DRB_configList; - SRB_ToAddModList_t* SRB_configList = ue_context_pP->ue_context.SRB_configList; - SRB_ToAddModList_t** SRB_configList2 = NULL; - DRB_ToAddModList_t** DRB_configList2 = NULL; - struct SRB_ToAddMod *SRB2_config = NULL; - struct DRB_ToAddMod *DRB_config = NULL; + LTE_DRB_ToAddModList_t* DRB_configList = ue_context_pP->ue_context.DRB_configList; + LTE_SRB_ToAddModList_t* SRB_configList = ue_context_pP->ue_context.SRB_configList; + LTE_SRB_ToAddModList_t** SRB_configList2 = NULL; + LTE_DRB_ToAddModList_t** DRB_configList2 = NULL; + struct LTE_SRB_ToAddMod *SRB2_config = NULL; + struct LTE_DRB_ToAddMod *DRB_config = NULL; int i = 0; uint8_t buffer[RRC_BUF_SIZE]; uint16_t size; - MeasObjectToAddModList_t *MeasObj_list = NULL; - MeasObjectToAddMod_t *MeasObj = NULL; - ReportConfigToAddModList_t *ReportConfig_list = NULL; - ReportConfigToAddMod_t *ReportConfig_per, *ReportConfig_A1, + LTE_MeasObjectToAddModList_t *MeasObj_list = NULL; + LTE_MeasObjectToAddMod_t *MeasObj = NULL; + LTE_ReportConfigToAddModList_t *ReportConfig_list = NULL; + LTE_ReportConfigToAddMod_t *ReportConfig_per, *ReportConfig_A1, *ReportConfig_A2, *ReportConfig_A3, *ReportConfig_A4, *ReportConfig_A5; - MeasIdToAddModList_t *MeasId_list = NULL; - MeasIdToAddMod_t *MeasId0, *MeasId1, *MeasId2, *MeasId3, *MeasId4, *MeasId5; - RSRP_Range_t *rsrp = NULL; - struct MeasConfig__speedStatePars *Sparams = NULL; - QuantityConfig_t *quantityConfig = NULL; - CellsToAddMod_t *CellToAdd = NULL; - CellsToAddModList_t *CellsToAddModList = NULL; - struct RRCConnectionReconfiguration_r8_IEs__dedicatedInfoNASList *dedicatedInfoNASList = NULL; - DedicatedInfoNAS_t *dedicatedInfoNas = NULL; + LTE_MeasIdToAddModList_t *MeasId_list = NULL; + LTE_MeasIdToAddMod_t *MeasId0, *MeasId1, *MeasId2, *MeasId3, *MeasId4, *MeasId5; + LTE_RSRP_Range_t *rsrp = NULL; + struct LTE_MeasConfig__speedStatePars *Sparams = NULL; + LTE_QuantityConfig_t *quantityConfig = NULL; + LTE_CellsToAddMod_t *CellToAdd = NULL; + LTE_CellsToAddModList_t *CellsToAddModList = NULL; + struct LTE_RRCConnectionReconfiguration_r8_IEs__dedicatedInfoNASList *dedicatedInfoNASList = NULL; + LTE_DedicatedInfoNAS_t *dedicatedInfoNas = NULL; /* for no gcc warnings */ (void)dedicatedInfoNas; - C_RNTI_t *cba_RNTI = NULL; + LTE_C_RNTI_t *cba_RNTI = NULL; uint8_t next_xid = rrc_eNB_get_next_transaction_identifier(ctxt_pP->module_id); ue_context_pP->ue_context.Status = RRC_CONNECTED; @@ -1410,7 +1410,7 @@ rrc_eNB_process_RRCConnectionReestablishmentComplete( for (i = 0; (i < DRB_configList->list.count) && (i < 3); i++) { DRB_config = DRB_configList->list.array[i]; - // Add DRB to DRB configuration list, for RRCConnectionReconfigurationComplete + // Add DRB to DRB configuration list, for LTE_RRCConnectionReconfigurationComplete ASN_SEQUENCE_ADD(&(*DRB_configList2)->list, DRB_config); } } @@ -1513,7 +1513,7 @@ rrc_eNB_process_RRCConnectionReestablishmentComplete( MeasId5->reportConfigId = 6; ASN_SEQUENCE_ADD(&MeasId_list->list, MeasId5); - // rrcConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.measConfig->measIdToAddModList = MeasId_list; + // LTE_RRCConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.measConfig->measIdToAddModList = MeasId_list; // Add one EUTRA Measurement Object MeasObj_list = CALLOC(1, sizeof(*MeasObj_list)); @@ -1525,10 +1525,10 @@ rrc_eNB_process_RRCConnectionReestablishmentComplete( memset((void *)MeasObj, 0, sizeof(*MeasObj)); MeasObj->measObjectId = 1; - MeasObj->measObject.present = MeasObjectToAddMod__measObject_PR_measObjectEUTRA; + MeasObj->measObject.present = LTE_MeasObjectToAddMod__measObject_PR_measObjectEUTRA; MeasObj->measObject.choice.measObjectEUTRA.carrierFreq = 3350; //band 7, 2.68GHz //MeasObj->measObject.choice.measObjectEUTRA.carrierFreq = 36090; //band 33, 1.909GHz - MeasObj->measObject.choice.measObjectEUTRA.allowedMeasBandwidth = AllowedMeasBandwidth_mbw25; + MeasObj->measObject.choice.measObjectEUTRA.allowedMeasBandwidth = LTE_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; @@ -1537,22 +1537,22 @@ rrc_eNB_process_RRCConnectionReestablishmentComplete( MeasObj->measObject.choice.measObjectEUTRA.offsetFreq = NULL; // Default is 15 or 0dB MeasObj->measObject.choice.measObjectEUTRA.cellsToAddModList = - (CellsToAddModList_t *) CALLOC(1, sizeof(*CellsToAddModList)); + (LTE_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 = (LTE_CellsToAddMod_t *) CALLOC(1, sizeof(*CellToAdd)); CellToAdd->cellIndex = i + 1; CellToAdd->physCellId = get_adjacent_cell_id(ctxt_pP->module_id, i); - CellToAdd->cellIndividualOffset = Q_OffsetRange_dB0; + CellToAdd->cellIndividualOffset = LTE_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; + // LTE_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)); @@ -1570,35 +1570,35 @@ rrc_eNB_process_RRCConnectionReestablishmentComplete( ReportConfig_A5 = CALLOC(1, sizeof(*ReportConfig_A5)); ReportConfig_per->reportConfigId = 1; - ReportConfig_per->reportConfig.present = ReportConfigToAddMod__reportConfig_PR_reportConfigEUTRA; + ReportConfig_per->reportConfig.present = LTE_ReportConfigToAddMod__reportConfig_PR_reportConfigEUTRA; ReportConfig_per->reportConfig.choice.reportConfigEUTRA.triggerType.present = - ReportConfigEUTRA__triggerType_PR_periodical; + LTE_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; + LTE_ReportConfigEUTRA__triggerType__periodical__purpose_reportStrongestCells; + ReportConfig_per->reportConfig.choice.reportConfigEUTRA.triggerQuantity = LTE_ReportConfigEUTRA__triggerQuantity_rsrp; + ReportConfig_per->reportConfig.choice.reportConfigEUTRA.reportQuantity = LTE_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 = LTE_ReportInterval_ms120; + ReportConfig_per->reportConfig.choice.reportConfigEUTRA.reportAmount = LTE_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.present = LTE_ReportConfigToAddMod__reportConfig_PR_reportConfigEUTRA; ReportConfig_A1->reportConfig.choice.reportConfigEUTRA.triggerType.present = - ReportConfigEUTRA__triggerType_PR_event; + LTE_ReportConfigEUTRA__triggerType_PR_event; ReportConfig_A1->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.present = - ReportConfigEUTRA__triggerType__event__eventId_PR_eventA1; + LTE_ReportConfigEUTRA__triggerType__event__eventId_PR_eventA1; ReportConfig_A1->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.choice.eventA1. - a1_Threshold.present = ThresholdEUTRA_PR_threshold_RSRP; + a1_Threshold.present = LTE_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.triggerQuantity = LTE_ReportConfigEUTRA__triggerQuantity_rsrp; + ReportConfig_A1->reportConfig.choice.reportConfigEUTRA.reportQuantity = LTE_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 = LTE_ReportInterval_ms120; + ReportConfig_A1->reportConfig.choice.reportConfigEUTRA.reportAmount = LTE_ReportConfigEUTRA__reportAmount_infinity; ASN_SEQUENCE_ADD(&ReportConfig_list->list, ReportConfig_A1); @@ -1606,108 +1606,108 @@ rrc_eNB_process_RRCConnectionReestablishmentComplete( LOG_I(RRC, "[eNB %d] frame %d: requesting A2, A3, A4, A5, and A6 event reporting\n", ctxt_pP->module_id, ctxt_pP->frame); ReportConfig_A2->reportConfigId = 3; - ReportConfig_A2->reportConfig.present = ReportConfigToAddMod__reportConfig_PR_reportConfigEUTRA; + ReportConfig_A2->reportConfig.present = LTE_ReportConfigToAddMod__reportConfig_PR_reportConfigEUTRA; ReportConfig_A2->reportConfig.choice.reportConfigEUTRA.triggerType.present = - ReportConfigEUTRA__triggerType_PR_event; + LTE_ReportConfigEUTRA__triggerType_PR_event; ReportConfig_A2->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.present = - ReportConfigEUTRA__triggerType__event__eventId_PR_eventA2; + LTE_ReportConfigEUTRA__triggerType__event__eventId_PR_eventA2; ReportConfig_A2->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.choice. - eventA2.a2_Threshold.present = ThresholdEUTRA_PR_threshold_RSRP; + eventA2.a2_Threshold.present = LTE_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; + LTE_ReportConfigEUTRA__triggerQuantity_rsrp; + ReportConfig_A2->reportConfig.choice.reportConfigEUTRA.reportQuantity = LTE_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; + ReportConfig_A2->reportConfig.choice.reportConfigEUTRA.reportInterval = LTE_ReportInterval_ms120; + ReportConfig_A2->reportConfig.choice.reportConfigEUTRA.reportAmount = LTE_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.present = LTE_ReportConfigToAddMod__reportConfig_PR_reportConfigEUTRA; ReportConfig_A3->reportConfig.choice.reportConfigEUTRA.triggerType.present = - ReportConfigEUTRA__triggerType_PR_event; + LTE_ReportConfigEUTRA__triggerType_PR_event; ReportConfig_A3->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.present = - ReportConfigEUTRA__triggerType__event__eventId_PR_eventA3; + LTE_ReportConfigEUTRA__triggerType__event__eventId_PR_eventA3; 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; + LTE_ReportConfigEUTRA__triggerQuantity_rsrp; + ReportConfig_A3->reportConfig.choice.reportConfigEUTRA.reportQuantity = LTE_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.reportInterval = LTE_ReportInterval_ms120; + ReportConfig_A3->reportConfig.choice.reportConfigEUTRA.reportAmount = LTE_ReportConfigEUTRA__reportAmount_infinity; ReportConfig_A3->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.hysteresis = 0.5; // FIXME ...hysteresis is of type long! ReportConfig_A3->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.timeToTrigger = - TimeToTrigger_ms40; + LTE_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.present = LTE_ReportConfigToAddMod__reportConfig_PR_reportConfigEUTRA; ReportConfig_A4->reportConfig.choice.reportConfigEUTRA.triggerType.present = - ReportConfigEUTRA__triggerType_PR_event; + LTE_ReportConfigEUTRA__triggerType_PR_event; ReportConfig_A4->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.present = - ReportConfigEUTRA__triggerType__event__eventId_PR_eventA4; + LTE_ReportConfigEUTRA__triggerType__event__eventId_PR_eventA4; ReportConfig_A4->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.choice. - eventA4.a4_Threshold.present = ThresholdEUTRA_PR_threshold_RSRP; + eventA4.a4_Threshold.present = LTE_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; + LTE_ReportConfigEUTRA__triggerQuantity_rsrp; + ReportConfig_A4->reportConfig.choice.reportConfigEUTRA.reportQuantity = LTE_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; + ReportConfig_A4->reportConfig.choice.reportConfigEUTRA.reportInterval = LTE_ReportInterval_ms120; + ReportConfig_A4->reportConfig.choice.reportConfigEUTRA.reportAmount = LTE_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.present = LTE_ReportConfigToAddMod__reportConfig_PR_reportConfigEUTRA; ReportConfig_A5->reportConfig.choice.reportConfigEUTRA.triggerType.present = - ReportConfigEUTRA__triggerType_PR_event; + LTE_ReportConfigEUTRA__triggerType_PR_event; ReportConfig_A5->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.present = - ReportConfigEUTRA__triggerType__event__eventId_PR_eventA5; + LTE_ReportConfigEUTRA__triggerType__event__eventId_PR_eventA5; ReportConfig_A5->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.choice. - eventA5.a5_Threshold1.present = ThresholdEUTRA_PR_threshold_RSRP; + eventA5.a5_Threshold1.present = LTE_ThresholdEUTRA_PR_threshold_RSRP; ReportConfig_A5->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.choice. - eventA5.a5_Threshold2.present = ThresholdEUTRA_PR_threshold_RSRP; + eventA5.a5_Threshold2.present = LTE_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; + LTE_ReportConfigEUTRA__triggerQuantity_rsrp; + ReportConfig_A5->reportConfig.choice.reportConfigEUTRA.reportQuantity = LTE_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; + ReportConfig_A5->reportConfig.choice.reportConfigEUTRA.reportInterval = LTE_ReportInterval_ms120; + ReportConfig_A5->reportConfig.choice.reportConfigEUTRA.reportAmount = LTE_ReportConfigEUTRA__reportAmount_infinity; ASN_SEQUENCE_ADD(&ReportConfig_list->list, ReportConfig_A5); - // rrcConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.measConfig->reportConfigToAddModList = ReportConfig_list; + // LTE_RRCConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.measConfig->reportConfigToAddModList = ReportConfig_list; - rsrp = CALLOC(1, sizeof(RSRP_Range_t)); + rsrp = CALLOC(1, sizeof(LTE_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->present = LTE_MeasConfig__speedStatePars_PR_setup; + Sparams->choice.setup.timeToTrigger_SF.sf_High = LTE_SpeedStateScaleFactors__sf_Medium_oDot75; + Sparams->choice.setup.timeToTrigger_SF.sf_Medium = LTE_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; + Sparams->choice.setup.mobilityStateParameters.t_Evaluation = LTE_MobilityStateParameters__t_Evaluation_s60; + Sparams->choice.setup.mobilityStateParameters.t_HystNormal = LTE_MobilityStateParameters__t_HystNormal_s120; quantityConfig = CALLOC(1, sizeof(*quantityConfig)); memset((void *)quantityConfig, 0, sizeof(*quantityConfig)); - quantityConfig->quantityConfigEUTRA = CALLOC(1, sizeof(struct QuantityConfigEUTRA)); + quantityConfig->quantityConfigEUTRA = CALLOC(1, sizeof(struct LTE_QuantityConfigEUTRA)); memset((void *)quantityConfig->quantityConfigEUTRA, 0, sizeof(*quantityConfig->quantityConfigEUTRA)); quantityConfig->quantityConfigCDMA2000 = NULL; quantityConfig->quantityConfigGERAN = NULL; @@ -1716,8 +1716,8 @@ rrc_eNB_process_RRCConnectionReestablishmentComplete( 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; + *quantityConfig->quantityConfigEUTRA->filterCoefficientRSRP = LTE_FilterCoefficient_fc4; + *quantityConfig->quantityConfigEUTRA->filterCoefficientRSRQ = LTE_FilterCoefficient_fc4; LOG_I(RRC, "[eNB %d] Frame %d: potential handover preparation: store the information in an intermediate structure in case of failure\n", @@ -1725,19 +1725,19 @@ rrc_eNB_process_RRCConnectionReestablishmentComplete( // store the information in an intermediate structure for Hanodver management //rrc_inst->handover_info.as_config.sourceRadioResourceConfig.srb_ToAddModList = CALLOC(1,sizeof()); ue_context_pP->ue_context.handover_info = CALLOC(1, sizeof(*(ue_context_pP->ue_context.handover_info))); - //memcpy((void *)rrc_inst->handover_info[ue_mod_idP]->as_config.sourceRadioResourceConfig.srb_ToAddModList,(void *)SRB_list,sizeof(SRB_ToAddModList_t)); + //memcpy((void *)rrc_inst->handover_info[ue_mod_idP]->as_config.sourceRadioResourceConfig.srb_ToAddModList,(void *)SRB_list,sizeof(LTE_SRB_ToAddModList_t)); ue_context_pP->ue_context.handover_info->as_config.sourceRadioResourceConfig.srb_ToAddModList = *SRB_configList2; - //memcpy((void *)rrc_inst->handover_info[ue_mod_idP]->as_config.sourceRadioResourceConfig.drb_ToAddModList,(void *)DRB_list,sizeof(DRB_ToAddModList_t)); + //memcpy((void *)rrc_inst->handover_info[ue_mod_idP]->as_config.sourceRadioResourceConfig.drb_ToAddModList,(void *)DRB_list,sizeof(LTE_DRB_ToAddModList_t)); ue_context_pP->ue_context.handover_info->as_config.sourceRadioResourceConfig.drb_ToAddModList = DRB_configList; ue_context_pP->ue_context.handover_info->as_config.sourceRadioResourceConfig.drb_ToReleaseList = NULL; ue_context_pP->ue_context.handover_info->as_config.sourceRadioResourceConfig.mac_MainConfig = CALLOC(1, sizeof(*ue_context_pP->ue_context.handover_info->as_config.sourceRadioResourceConfig.mac_MainConfig)); memcpy((void*)ue_context_pP->ue_context.handover_info->as_config.sourceRadioResourceConfig.mac_MainConfig, - (void *)ue_context_pP->ue_context.mac_MainConfig, sizeof(MAC_MainConfig_t)); + (void *)ue_context_pP->ue_context.mac_MainConfig, sizeof(LTE_MAC_MainConfig_t)); ue_context_pP->ue_context.handover_info->as_config.sourceRadioResourceConfig.physicalConfigDedicated = - CALLOC(1, sizeof(PhysicalConfigDedicated_t)); + CALLOC(1, sizeof(LTE_PhysicalConfigDedicated_t)); memcpy((void*)ue_context_pP->ue_context.handover_info->as_config.sourceRadioResourceConfig.physicalConfigDedicated, - (void*)ue_context_pP->ue_context.physicalConfigDedicated, sizeof(PhysicalConfigDedicated_t)); + (void*)ue_context_pP->ue_context.physicalConfigDedicated, sizeof(LTE_PhysicalConfigDedicated_t)); ue_context_pP->ue_context.handover_info->as_config.sourceRadioResourceConfig.sps_Config = NULL; //memcpy((void *)rrc_inst->handover_info[ue_mod_idP]->as_config.sourceRadioResourceConfig.sps_Config,(void *)rrc_inst->sps_Config[ue_mod_idP],sizeof(SPS_Config_t)); @@ -1746,7 +1746,7 @@ rrc_eNB_process_RRCConnectionReestablishmentComplete( #ifdef CBA //struct PUSCH_CBAConfigDedicated_vlola *pusch_CBAConfigDedicated_vlola; uint8_t *cba_RNTI_buf; - cba_RNTI = CALLOC(1, sizeof(C_RNTI_t)); + cba_RNTI = CALLOC(1, sizeof(LTE_C_RNTI_t)); cba_RNTI_buf = CALLOC(1, 2 * sizeof(uint8_t)); cba_RNTI->buf = cba_RNTI_buf; cba_RNTI->size = 2; @@ -1771,17 +1771,17 @@ rrc_eNB_process_RRCConnectionReestablishmentComplete( #if defined(ENABLE_ITTI) /* Initialize NAS list */ - dedicatedInfoNASList = CALLOC(1, sizeof(struct RRCConnectionReconfiguration_r8_IEs__dedicatedInfoNASList)); + dedicatedInfoNASList = CALLOC(1, sizeof(struct LTE_RRCConnectionReconfiguration_r8_IEs__dedicatedInfoNASList)); /* Add all NAS PDUs to the list */ for (i = 0; i < ue_context_pP->ue_context.nb_of_e_rabs; i++) { if (ue_context_pP->ue_context.e_rab[i].param.nas_pdu.buffer != NULL) { - dedicatedInfoNas = CALLOC(1, sizeof(DedicatedInfoNAS_t)); + dedicatedInfoNas = CALLOC(1, sizeof(LTE_DedicatedInfoNAS_t)); memset(dedicatedInfoNas, 0, sizeof(OCTET_STRING_t)); OCTET_STRING_fromBuf(dedicatedInfoNas, (char*)ue_context_pP->ue_context.e_rab[i].param.nas_pdu.buffer, ue_context_pP->ue_context.e_rab[i].param.nas_pdu.length); - LOG_D(RRC, "Add dedicatedInfoNas(%d) to dedicatedInfoNASList\n", i); + LOG_D(RRC, "Add LTE_DedicatedInfoNAS(%d) to LTE_DedicatedInfoNASList\n", i); ASN_SEQUENCE_ADD(&dedicatedInfoNASList->list, dedicatedInfoNas); } @@ -1806,36 +1806,36 @@ rrc_eNB_process_RRCConnectionReestablishmentComplete( #endif - // send RRCConnectionReconfiguration + // send LTE_RRCConnectionReconfiguration memset(buffer, 0, RRC_BUF_SIZE); size = do_RRCConnectionReconfiguration(ctxt_pP, buffer, next_xid, //Transaction_id, - (SRB_ToAddModList_t*)*SRB_configList2, // SRB_configList - (DRB_ToAddModList_t*)DRB_configList, - (DRB_ToReleaseList_t*)NULL, // DRB2_list, - (struct SPS_Config*)NULL, // maybe ue_context_pP->ue_context.sps_Config, - (struct PhysicalConfigDedicated*)ue_context_pP->ue_context.physicalConfigDedicated, + (LTE_SRB_ToAddModList_t*)*SRB_configList2, // SRB_configList + (LTE_DRB_ToAddModList_t*)DRB_configList, + (LTE_DRB_ToReleaseList_t*)NULL, // DRB2_list, + (struct LTE_SPS_Config*)NULL, // maybe ue_context_pP->ue_context.sps_Config, + (struct LTE_PhysicalConfigDedicated*)ue_context_pP->ue_context.physicalConfigDedicated, #ifdef EXMIMO_IOT NULL, NULL, NULL,NULL, #else - (MeasObjectToAddModList_t*)MeasObj_list, // MeasObj_list, - (ReportConfigToAddModList_t*)ReportConfig_list, // ReportConfig_list, - (QuantityConfig_t*)quantityConfig, //quantityConfig, - (MeasIdToAddModList_t*)NULL, + (LTE_MeasObjectToAddModList_t*)MeasObj_list, // MeasObj_list, + (LTE_ReportConfigToAddModList_t*)ReportConfig_list, // ReportConfig_list, + (LTE_QuantityConfig_t*)quantityConfig, //quantityConfig, + (LTE_MeasIdToAddModList_t*)NULL, #endif - (MAC_MainConfig_t*)ue_context_pP->ue_context.mac_MainConfig, - (MeasGapConfig_t*)NULL, - (MobilityControlInfo_t*)NULL, - (struct MeasConfig__speedStatePars*)Sparams, // Sparams, - (RSRP_Range_t*)rsrp, // rsrp, - (C_RNTI_t*)cba_RNTI, // cba_RNTI - (struct RRCConnectionReconfiguration_r8_IEs__dedicatedInfoNASList*)dedicatedInfoNASList, //dedicatedInfoNASList - (SL_CommConfig_r12_t*)NULL, - (SL_DiscConfig_r12_t*)NULL -#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) - , (SCellToAddMod_r10_t*)NULL + (LTE_MAC_MainConfig_t*)ue_context_pP->ue_context.mac_MainConfig, + (LTE_MeasGapConfig_t*)NULL, + (LTE_MobilityControlInfo_t*)NULL, + (struct LTE_MeasConfig__speedStatePars*)Sparams, // Sparams, + (LTE_RSRP_Range_t*)rsrp, // rsrp, + (LTE_C_RNTI_t*)cba_RNTI, // cba_RNTI + (struct LTE_RRCConnectionReconfiguration_r8_IEs__dedicatedInfoNASList*)dedicatedInfoNASList, //dedicatedInfoNASList + (LTE_SL_CommConfig_r12_t*)NULL, + (LTE_SL_DiscConfig_r12_t*)NULL +#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) + , (LTE_SCellToAddMod_r10_t*)NULL #endif ); LOG_DUMPMSG(RRC,DEBUG_RRC,(char *)buffer,size, @@ -1860,7 +1860,7 @@ rrc_eNB_process_RRCConnectionReestablishmentComplete( return; }else{ LOG_I(RRC, - "[eNB %d] Frame %d, Logical Channel DL-DCCH, Generate RRCConnectionReconfiguration (bytes %d, UE id %x)\n", + "[eNB %d] Frame %d, Logical Channel DL-DCCH, Generate LTE_RRCConnectionReconfiguration (bytes %d, UE id %x)\n", ctxt_pP->module_id, ctxt_pP->frame, size, ue_context_pP->ue_context.rnti); LOG_D(RRC, @@ -1872,7 +1872,7 @@ rrc_eNB_process_RRCConnectionReestablishmentComplete( MSC_RRC_UE, buffer, size, - MSC_AS_TIME_FMT" rrcConnectionReconfiguration UE %x MUI %d size %u", + MSC_AS_TIME_FMT" LTE_RRCConnectionReconfiguration UE %x MUI %d size %u", MSC_AS_TIME_ARGS(ctxt_pP), ue_context_pP->ue_context.rnti, rrc_eNB_mui, @@ -1946,7 +1946,7 @@ rrc_eNB_generate_RRCConnectionReestablishmentReject( RC.mac[ctxt_pP->module_id]->UE_list.UE_sched_ctrl[UE_id].ue_reestablishment_reject_timer_thres = 20; }else{ LOG_E(RRC, - PROTOCOL_RRC_CTXT_UE_FMT" Generating RRCConnectionReestablishmentReject without UE_id(MAC) rnti %x\n", + PROTOCOL_RRC_CTXT_UE_FMT" Generating LTE_RRCConnectionReestablishmentReject without UE_id(MAC) rnti %x\n", PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP),ctxt_pP->rnti); } @@ -1962,19 +1962,18 @@ rrc_eNB_generate_RRCConnectionReestablishmentReject( RC.rrc[ctxt_pP->module_id]->carrier[CC_id].Srb0.Tx_buffer.payload_size, "[MSG] RRCConnectionReestablishmentReject\n"); - MSC_LOG_TX_MESSAGE( MSC_RRC_ENB, MSC_RRC_UE, RC.rrc[ctxt_pP->module_id]->carrier[CC_id].Srb0.Tx_buffer.Header, RC.rrc[ctxt_pP->module_id]->carrier[CC_id].Srb0.Tx_buffer.payload_size, - MSC_AS_TIME_FMT" RRCConnectionReestablishmentReject UE %x size %u", + MSC_AS_TIME_FMT" LTE_RRCConnectionReestablishmentReject UE %x size %u", MSC_AS_TIME_ARGS(ctxt_pP), ue_context_pP == NULL ? -1 : ue_context_pP->ue_context.rnti, RC.rrc[ctxt_pP->module_id]->carrier[CC_id].Srb0.Tx_buffer.payload_size); LOG_I(RRC, - PROTOCOL_RRC_CTXT_UE_FMT" [RAPROC] Logical Channel DL-CCCH, Generating RRCConnectionReestablishmentReject (bytes %d)\n", + PROTOCOL_RRC_CTXT_UE_FMT" [RAPROC] Logical Channel DL-CCCH, Generating LTE_RRCConnectionReestablishmentReject (bytes %d)\n", PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP), RC.rrc[ctxt_pP->module_id]->carrier[CC_id].Srb0.Tx_buffer.payload_size); } @@ -1998,17 +1997,17 @@ rrc_eNB_generate_RRCConnectionRelease( size = do_RRCConnectionRelease(ctxt_pP->module_id, buffer,rrc_eNB_get_next_transaction_identifier(ctxt_pP->module_id)); // set release timer //ue_context_pP->ue_context.ue_release_timer=1; - // remove UE after 10 frames after RRCConnectionRelease is triggered + // remove UE after 10 frames after LTE_RRCConnectionRelease is triggered //ue_context_pP->ue_context.ue_release_timer_thres=100; // set release timer // ue_context_pP->ue_context.ue_release_timer_rrc = 1; - // remove UE after 10 frames after RRCConnectionRelease is triggered + // remove UE after 10 frames after LTE_RRCConnectionRelease is triggered // ue_context_pP->ue_context.ue_release_timer_thres_rrc = 100; ue_context_pP->ue_context.ue_reestablishment_timer = 0; ue_context_pP->ue_context.ue_release_timer = 0; //ue_context_pP->ue_context.ue_release_timer_s1 = 0; LOG_I(RRC, - PROTOCOL_RRC_CTXT_UE_FMT" Logical Channel DL-DCCH, Generate RRCConnectionRelease (bytes %d)\n", + PROTOCOL_RRC_CTXT_UE_FMT" Logical Channel DL-DCCH, Generate LTE_RRCConnectionRelease (bytes %d)\n", PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP), size); @@ -2024,7 +2023,7 @@ rrc_eNB_generate_RRCConnectionRelease( MSC_RRC_UE, buffer, size, - MSC_AS_TIME_FMT" rrcConnectionRelease UE %x MUI %d size %u", + MSC_AS_TIME_FMT" LTE_RRCConnectionRelease UE %x MUI %d size %u", MSC_AS_TIME_ARGS(ctxt_pP), ue_context_pP->ue_context.rnti, rrc_eNB_mui, @@ -2073,21 +2072,21 @@ rrc_eNB_generate_dedicatedRRCConnectionReconfiguration(const protocol_ctxt_t* co uint16_t size; int i; - struct DRB_ToAddMod *DRB_config = NULL; - struct RLC_Config *DRB_rlc_config = NULL; - struct PDCP_Config *DRB_pdcp_config = NULL; - struct PDCP_Config__rlc_AM *PDCP_rlc_AM = NULL; - struct PDCP_Config__rlc_UM *PDCP_rlc_UM = NULL; - struct LogicalChannelConfig *DRB_lchan_config = NULL; - struct LogicalChannelConfig__ul_SpecificParameters + struct LTE_DRB_ToAddMod *DRB_config = NULL; + struct LTE_RLC_Config *DRB_rlc_config = NULL; + struct LTE_PDCP_Config *DRB_pdcp_config = NULL; + struct LTE_PDCP_Config__rlc_AM *PDCP_rlc_AM = NULL; + struct LTE_PDCP_Config__rlc_UM *PDCP_rlc_UM = NULL; + struct LTE_LogicalChannelConfig *DRB_lchan_config = NULL; + struct LTE_LogicalChannelConfig__ul_SpecificParameters *DRB_ul_SpecificParameters = NULL; - // DRB_ToAddModList_t** DRB_configList=&ue_context_pP->ue_context.DRB_configList; - DRB_ToAddModList_t* DRB_configList=ue_context_pP->ue_context.DRB_configList; - DRB_ToAddModList_t** DRB_configList2=NULL; + // LTE_DRB_ToAddModList_t** DRB_configList=&ue_context_pP->ue_context.DRB_configList; + LTE_DRB_ToAddModList_t* DRB_configList=ue_context_pP->ue_context.DRB_configList; + LTE_DRB_ToAddModList_t** DRB_configList2=NULL; //DRB_ToAddModList_t** RRC_DRB_configList=&ue_context_pP->ue_context.DRB_configList; - struct RRCConnectionReconfiguration_r8_IEs__dedicatedInfoNASList *dedicatedInfoNASList = NULL; - DedicatedInfoNAS_t *dedicatedInfoNas = NULL; + struct LTE_RRCConnectionReconfiguration_r8_IEs__dedicatedInfoNASList *dedicatedInfoNASList = NULL; + LTE_DedicatedInfoNAS_t *dedicatedInfoNas = NULL; /* for no gcc warnings */ (void)dedicatedInfoNas; @@ -2102,7 +2101,7 @@ rrc_eNB_generate_dedicatedRRCConnectionReconfiguration(const protocol_ctxt_t* co //*DRB_configList = CALLOC(1, sizeof(*DRB_configList)); *DRB_configList2 = CALLOC(1, sizeof(**DRB_configList2)); /* Initialize NAS list */ - dedicatedInfoNASList = CALLOC(1, sizeof(struct RRCConnectionReconfiguration_r8_IEs__dedicatedInfoNASList)); + dedicatedInfoNASList = CALLOC(1, sizeof(struct LTE_RRCConnectionReconfiguration_r8_IEs__dedicatedInfoNASList)); int e_rab_done=0; @@ -2126,7 +2125,7 @@ rrc_eNB_generate_dedicatedRRCConnectionReconfiguration(const protocol_ctxt_t* co // allowed value 5..15, value : x+4 *(DRB_config->eps_BearerIdentity) = ue_context_pP->ue_context.e_rab[i].param.e_rab_id;//+ 4; // especial case generation - // DRB_config->drb_Identity = 1 + drb_identity_index + e_rab_done;// + i ;// (DRB_Identity_t) ue_context_pP->ue_context.e_rab[i].param.e_rab_id; + // DRB_config->drb_Identity = 1 + drb_identity_index + e_rab_done;// + i ;// (LTE_DRB_Identity_t) ue_context_pP->ue_context.e_rab[i].param.e_rab_id; // 1 + drb_identiy_index; DRB_config->drb_Identity = i+1; @@ -2139,7 +2138,7 @@ rrc_eNB_generate_dedicatedRRCConnectionReconfiguration(const protocol_ctxt_t* co DRB_pdcp_config = CALLOC(1, sizeof(*DRB_pdcp_config)); DRB_config->pdcp_Config = DRB_pdcp_config; DRB_pdcp_config->discardTimer = CALLOC(1, sizeof(long)); - *DRB_pdcp_config->discardTimer = PDCP_Config__discardTimer_infinity; + *DRB_pdcp_config->discardTimer = LTE_PDCP_Config__discardTimer_infinity; DRB_pdcp_config->rlc_AM = NULL; DRB_pdcp_config->rlc_UM = NULL; @@ -2158,14 +2157,14 @@ rrc_eNB_generate_dedicatedRRCConnectionReconfiguration(const protocol_ctxt_t* co case 65: // 75ms, 10^-2, p0.7, mission critical voice, GBR case 66: // 100ms, 10^-2, p2, non-mission critical voice , GBR // RLC - 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_ms35; + DRB_rlc_config->present = LTE_RLC_Config_PR_um_Bi_Directional; + DRB_rlc_config->choice.um_Bi_Directional.ul_UM_RLC.sn_FieldLength = LTE_SN_FieldLength_size10; + DRB_rlc_config->choice.um_Bi_Directional.dl_UM_RLC.sn_FieldLength = LTE_SN_FieldLength_size10; + DRB_rlc_config->choice.um_Bi_Directional.dl_UM_RLC.t_Reordering = LTE_T_Reordering_ms35; // PDCP 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; + PDCP_rlc_UM->pdcp_SN_Size = LTE_PDCP_Config__rlc_UM__pdcp_SN_Size_len12bits; break; /* @@ -2178,13 +2177,13 @@ rrc_eNB_generate_dedicatedRRCConnectionReconfiguration(const protocol_ctxt_t* co case 69: // 60ms, 10^-6, p0.5, mission critical delay sensitive data, Lowest Priority case 70: // 200ms, 10^-6, p5.5, mision critical data // RLC - DRB_rlc_config->present = RLC_Config_PR_am; - DRB_rlc_config->choice.am.ul_AM_RLC.t_PollRetransmit = T_PollRetransmit_ms50; - DRB_rlc_config->choice.am.ul_AM_RLC.pollPDU = PollPDU_p16; - DRB_rlc_config->choice.am.ul_AM_RLC.pollByte = PollByte_kBinfinity; - DRB_rlc_config->choice.am.ul_AM_RLC.maxRetxThreshold = UL_AM_RLC__maxRetxThreshold_t8; - DRB_rlc_config->choice.am.dl_AM_RLC.t_Reordering = T_Reordering_ms35; - DRB_rlc_config->choice.am.dl_AM_RLC.t_StatusProhibit = T_StatusProhibit_ms25; + DRB_rlc_config->present = LTE_RLC_Config_PR_am; + DRB_rlc_config->choice.am.ul_AM_RLC.t_PollRetransmit = LTE_T_PollRetransmit_ms50; + DRB_rlc_config->choice.am.ul_AM_RLC.pollPDU = LTE_PollPDU_p16; + DRB_rlc_config->choice.am.ul_AM_RLC.pollByte = LTE_PollByte_kBinfinity; + DRB_rlc_config->choice.am.ul_AM_RLC.maxRetxThreshold = LTE_UL_AM_RLC__maxRetxThreshold_t8; + DRB_rlc_config->choice.am.dl_AM_RLC.t_Reordering = LTE_T_Reordering_ms35; + DRB_rlc_config->choice.am.dl_AM_RLC.t_StatusProhibit = LTE_T_StatusProhibit_ms25; // PDCP PDCP_rlc_AM = CALLOC(1, sizeof(*PDCP_rlc_AM)); @@ -2200,7 +2199,7 @@ rrc_eNB_generate_dedicatedRRCConnectionReconfiguration(const protocol_ctxt_t* co continue; } - DRB_pdcp_config->headerCompression.present = PDCP_Config__headerCompression_PR_notUsed; + DRB_pdcp_config->headerCompression.present = LTE_PDCP_Config__headerCompression_PR_notUsed; DRB_lchan_config = CALLOC(1, sizeof(*DRB_lchan_config)); DRB_config->logicalChannelConfig = DRB_lchan_config; @@ -2213,10 +2212,10 @@ rrc_eNB_generate_dedicatedRRCConnectionReconfiguration(const protocol_ctxt_t* co else DRB_ul_SpecificParameters->priority= 4; - DRB_ul_SpecificParameters->prioritisedBitRate = LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_kBps8; + DRB_ul_SpecificParameters->prioritisedBitRate = LTE_LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_kBps8; //LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_infinity; DRB_ul_SpecificParameters->bucketSizeDuration = - LogicalChannelConfig__ul_SpecificParameters__bucketSizeDuration_ms50; + LTE_LogicalChannelConfig__ul_SpecificParameters__bucketSizeDuration_ms50; logicalchannelgroup_drb = CALLOC(1, sizeof(long)); *logicalchannelgroup_drb = 1;//(i+1) % 3; @@ -2241,7 +2240,7 @@ rrc_eNB_generate_dedicatedRRCConnectionReconfiguration(const protocol_ctxt_t* co { if (ue_context_pP->ue_context.e_rab[i].param.nas_pdu.buffer != NULL) { - dedicatedInfoNas = CALLOC(1, sizeof(DedicatedInfoNAS_t)); + dedicatedInfoNas = CALLOC(1, sizeof(LTE_DedicatedInfoNAS_t)); memset(dedicatedInfoNas, 0, sizeof(OCTET_STRING_t)); OCTET_STRING_fromBuf(dedicatedInfoNas, (char*)ue_context_pP->ue_context.e_rab[i].param.nas_pdu.buffer, @@ -2278,17 +2277,17 @@ rrc_eNB_generate_dedicatedRRCConnectionReconfiguration(const protocol_ctxt_t* co size = do_RRCConnectionReconfiguration(ctxt_pP, buffer, xid, - (SRB_ToAddModList_t*)NULL, - (DRB_ToAddModList_t*)*DRB_configList2, - (DRB_ToReleaseList_t*)NULL, // DRB2_list, - (struct SPS_Config*)NULL, // *sps_Config, + (LTE_SRB_ToAddModList_t*)NULL, + (LTE_DRB_ToAddModList_t*)*DRB_configList2, + (LTE_DRB_ToReleaseList_t*)NULL, // DRB2_list, + (struct LTE_SPS_Config*)NULL, // *sps_Config, NULL, NULL, NULL, NULL,NULL, NULL, NULL, NULL, NULL, NULL, NULL, - (struct RRCConnectionReconfiguration_r8_IEs__dedicatedInfoNASList*)dedicatedInfoNASList, - (SL_CommConfig_r12_t*)NULL, - (SL_DiscConfig_r12_t*)NULL -#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) - , (SCellToAddMod_r10_t*)NULL + (struct LTE_RRCConnectionReconfiguration_r8_IEs__dedicatedInfoNASList*)dedicatedInfoNASList, + (LTE_SL_CommConfig_r12_t*)NULL, + (LTE_SL_DiscConfig_r12_t*)NULL +#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) + , (LTE_SCellToAddMod_r10_t*)NULL #endif ); @@ -2308,7 +2307,7 @@ rrc_eNB_generate_dedicatedRRCConnectionReconfiguration(const protocol_ctxt_t* co #endif LOG_I(RRC, - "[eNB %d] Frame %d, Logical Channel DL-DCCH, Generate RRCConnectionReconfiguration (bytes %d, UE RNTI %x)\n", + "[eNB %d] Frame %d, Logical Channel DL-DCCH, Generate LTE_RRCConnectionReconfiguration (bytes %d, UE RNTI %x)\n", ctxt_pP->module_id, ctxt_pP->frame, size, ue_context_pP->ue_context.rnti); LOG_D(RRC, @@ -2320,7 +2319,7 @@ rrc_eNB_generate_dedicatedRRCConnectionReconfiguration(const protocol_ctxt_t* co MSC_RRC_UE, buffer, size, - MSC_AS_TIME_FMT" dedicated rrcConnectionReconfiguration UE %x MUI %d size %u", + MSC_AS_TIME_FMT" dedicated LTE_RRCConnectionReconfiguration UE %x MUI %d size %u", MSC_AS_TIME_ARGS(ctxt_pP), ue_context_pP->ue_context.rnti, rrc_eNB_mui, @@ -2348,26 +2347,26 @@ rrc_eNB_modify_dedicatedRRCConnectionReconfiguration(const protocol_ctxt_t* cons uint16_t size; int i, j; - struct DRB_ToAddMod *DRB_config = NULL; - struct RLC_Config *DRB_rlc_config = NULL; - struct PDCP_Config *DRB_pdcp_config = NULL; - struct PDCP_Config__rlc_AM *PDCP_rlc_AM = NULL; - struct PDCP_Config__rlc_UM *PDCP_rlc_UM = NULL; - struct LogicalChannelConfig *DRB_lchan_config = NULL; - struct LogicalChannelConfig__ul_SpecificParameters + struct LTE_DRB_ToAddMod *DRB_config = NULL; + struct LTE_RLC_Config *DRB_rlc_config = NULL; + struct LTE_PDCP_Config *DRB_pdcp_config = NULL; + struct LTE_PDCP_Config__rlc_AM *PDCP_rlc_AM = NULL; + struct LTE_PDCP_Config__rlc_UM *PDCP_rlc_UM = NULL; + struct LTE_LogicalChannelConfig *DRB_lchan_config = NULL; + struct LTE_LogicalChannelConfig__ul_SpecificParameters *DRB_ul_SpecificParameters = NULL; - DRB_ToAddModList_t* DRB_configList = ue_context_pP->ue_context.DRB_configList; - DRB_ToAddModList_t* DRB_configList2 = NULL; + LTE_DRB_ToAddModList_t* DRB_configList = ue_context_pP->ue_context.DRB_configList; + LTE_DRB_ToAddModList_t* DRB_configList2 = NULL; - struct RRCConnectionReconfiguration_r8_IEs__dedicatedInfoNASList *dedicatedInfoNASList = NULL; - DedicatedInfoNAS_t *dedicatedInfoNas = NULL; + struct LTE_RRCConnectionReconfiguration_r8_IEs__dedicatedInfoNASList *dedicatedInfoNASList = NULL; + LTE_DedicatedInfoNAS_t *dedicatedInfoNas = NULL; /* for no gcc warnings */ (void)dedicatedInfoNas; uint8_t xid = rrc_eNB_get_next_transaction_identifier(ctxt_pP->module_id); // Transaction_id, DRB_configList2 = CALLOC(1, sizeof(*DRB_configList2)); /* Initialize NAS list */ - dedicatedInfoNASList = CALLOC(1, sizeof(struct RRCConnectionReconfiguration_r8_IEs__dedicatedInfoNASList)); + dedicatedInfoNASList = CALLOC(1, sizeof(struct LTE_RRCConnectionReconfiguration_r8_IEs__dedicatedInfoNASList)); for (i = 0; i < ue_context_pP->ue_context.nb_of_modify_e_rabs; i++) { // bypass the new and already configured erabs @@ -2404,7 +2403,7 @@ rrc_eNB_modify_dedicatedRRCConnectionReconfiguration(const protocol_ctxt_t* cons DRB_rlc_config = DRB_config->rlc_Config; DRB_pdcp_config = DRB_config->pdcp_Config; - *DRB_pdcp_config->discardTimer = PDCP_Config__discardTimer_infinity; + *DRB_pdcp_config->discardTimer = LTE_PDCP_Config__discardTimer_infinity; switch (ue_context_pP->ue_context.modify_e_rab[i].param.qos.qci) { /* * type: realtime data with medium packer error rate @@ -2419,10 +2418,10 @@ rrc_eNB_modify_dedicatedRRCConnectionReconfiguration(const protocol_ctxt_t* cons case 65: // 75ms, 10^-2, p0.7, mission critical voice, GBR case 66: // 100ms, 10^-2, p2, non-mission critical voice , GBR // RLC - 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_ms35; + DRB_rlc_config->present = LTE_RLC_Config_PR_um_Bi_Directional; + DRB_rlc_config->choice.um_Bi_Directional.ul_UM_RLC.sn_FieldLength = LTE_SN_FieldLength_size10; + DRB_rlc_config->choice.um_Bi_Directional.dl_UM_RLC.sn_FieldLength = LTE_SN_FieldLength_size10; + DRB_rlc_config->choice.um_Bi_Directional.dl_UM_RLC.t_Reordering = LTE_T_Reordering_ms35; // PDCP if (DRB_pdcp_config->rlc_AM) { free(DRB_pdcp_config->rlc_AM); @@ -2434,7 +2433,7 @@ rrc_eNB_modify_dedicatedRRCConnectionReconfiguration(const protocol_ctxt_t* cons } 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; + PDCP_rlc_UM->pdcp_SN_Size = LTE_PDCP_Config__rlc_UM__pdcp_SN_Size_len12bits; break; /* @@ -2447,13 +2446,13 @@ rrc_eNB_modify_dedicatedRRCConnectionReconfiguration(const protocol_ctxt_t* cons case 69: // 60ms, 10^-6, p0.5, mission critical delay sensitive data, Lowest Priority case 70: // 200ms, 10^-6, p5.5, mision critical data // RLC - DRB_rlc_config->present = RLC_Config_PR_am; - DRB_rlc_config->choice.am.ul_AM_RLC.t_PollRetransmit = T_PollRetransmit_ms50; - DRB_rlc_config->choice.am.ul_AM_RLC.pollPDU = PollPDU_p16; - DRB_rlc_config->choice.am.ul_AM_RLC.pollByte = PollByte_kBinfinity; - DRB_rlc_config->choice.am.ul_AM_RLC.maxRetxThreshold = UL_AM_RLC__maxRetxThreshold_t8; - DRB_rlc_config->choice.am.dl_AM_RLC.t_Reordering = T_Reordering_ms35; - DRB_rlc_config->choice.am.dl_AM_RLC.t_StatusProhibit = T_StatusProhibit_ms25; + DRB_rlc_config->present = LTE_RLC_Config_PR_am; + DRB_rlc_config->choice.am.ul_AM_RLC.t_PollRetransmit = LTE_T_PollRetransmit_ms50; + DRB_rlc_config->choice.am.ul_AM_RLC.pollPDU = LTE_PollPDU_p16; + DRB_rlc_config->choice.am.ul_AM_RLC.pollByte = LTE_PollByte_kBinfinity; + DRB_rlc_config->choice.am.ul_AM_RLC.maxRetxThreshold = LTE_UL_AM_RLC__maxRetxThreshold_t8; + DRB_rlc_config->choice.am.dl_AM_RLC.t_Reordering = LTE_T_Reordering_ms35; + DRB_rlc_config->choice.am.dl_AM_RLC.t_StatusProhibit = LTE_T_StatusProhibit_ms25; // PDCP if (DRB_pdcp_config->rlc_AM) { @@ -2479,7 +2478,7 @@ rrc_eNB_modify_dedicatedRRCConnectionReconfiguration(const protocol_ctxt_t* cons continue; } - DRB_pdcp_config->headerCompression.present = PDCP_Config__headerCompression_PR_notUsed; + DRB_pdcp_config->headerCompression.present = LTE_PDCP_Config__headerCompression_PR_notUsed; DRB_lchan_config = DRB_config->logicalChannelConfig; DRB_ul_SpecificParameters = DRB_lchan_config->ul_SpecificParameters; @@ -2489,10 +2488,10 @@ rrc_eNB_modify_dedicatedRRCConnectionReconfiguration(const protocol_ctxt_t* cons else DRB_ul_SpecificParameters->priority= 4; - DRB_ul_SpecificParameters->prioritisedBitRate = LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_kBps8; + DRB_ul_SpecificParameters->prioritisedBitRate = LTE_LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_kBps8; DRB_ul_SpecificParameters->bucketSizeDuration = - LogicalChannelConfig__ul_SpecificParameters__bucketSizeDuration_ms50; + LTE_LogicalChannelConfig__ul_SpecificParameters__bucketSizeDuration_ms50; ASN_SEQUENCE_ADD(&(DRB_configList2)->list, DRB_config); @@ -2511,7 +2510,7 @@ rrc_eNB_modify_dedicatedRRCConnectionReconfiguration(const protocol_ctxt_t* cons { if (ue_context_pP->ue_context.modify_e_rab[i].param.nas_pdu.buffer != NULL) { - dedicatedInfoNas = CALLOC(1, sizeof(DedicatedInfoNAS_t)); + dedicatedInfoNas = CALLOC(1, sizeof(LTE_DedicatedInfoNAS_t)); memset(dedicatedInfoNas, 0, sizeof(OCTET_STRING_t)); OCTET_STRING_fromBuf(dedicatedInfoNas, (char*)ue_context_pP->ue_context.modify_e_rab[i].param.nas_pdu.buffer, @@ -2541,17 +2540,17 @@ rrc_eNB_modify_dedicatedRRCConnectionReconfiguration(const protocol_ctxt_t* cons size = do_RRCConnectionReconfiguration(ctxt_pP, buffer, xid, - (SRB_ToAddModList_t*)NULL, - (DRB_ToAddModList_t*)DRB_configList2, - (DRB_ToReleaseList_t*)NULL, // DRB2_list, - (struct SPS_Config*)NULL, // *sps_Config, + (LTE_SRB_ToAddModList_t*)NULL, + (LTE_DRB_ToAddModList_t*)DRB_configList2, + (LTE_DRB_ToReleaseList_t*)NULL, // DRB2_list, + (struct LTE_SPS_Config*)NULL, // *sps_Config, NULL, NULL, NULL, NULL,NULL, NULL, NULL, NULL, NULL, NULL, NULL, - (struct RRCConnectionReconfiguration_r8_IEs__dedicatedInfoNASList*)dedicatedInfoNASList, - (SL_CommConfig_r12_t*)NULL, - (SL_DiscConfig_r12_t*)NULL -#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) - , (SCellToAddMod_r10_t*)NULL + (struct LTE_RRCConnectionReconfiguration_r8_IEs__dedicatedInfoNASList*)dedicatedInfoNASList, + (LTE_SL_CommConfig_r12_t*)NULL, + (LTE_SL_DiscConfig_r12_t*)NULL +#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) + , (LTE_SCellToAddMod_r10_t*)NULL #endif ); @@ -2571,7 +2570,7 @@ rrc_eNB_modify_dedicatedRRCConnectionReconfiguration(const protocol_ctxt_t* cons #endif LOG_I(RRC, - "[eNB %d] Frame %d, Logical Channel DL-DCCH, Generate RRCConnectionReconfiguration (bytes %d, UE RNTI %x)\n", + "[eNB %d] Frame %d, Logical Channel DL-DCCH, Generate LTE_RRCConnectionReconfiguration (bytes %d, UE RNTI %x)\n", ctxt_pP->module_id, ctxt_pP->frame, size, ue_context_pP->ue_context.rnti); LOG_D(RRC, @@ -2583,7 +2582,7 @@ rrc_eNB_modify_dedicatedRRCConnectionReconfiguration(const protocol_ctxt_t* cons MSC_RRC_UE, buffer, size, - MSC_AS_TIME_FMT" dedicated rrcConnectionReconfiguration UE %x MUI %d size %u", + MSC_AS_TIME_FMT" dedicated LTE_RRCConnectionReconfiguration UE %x MUI %d size %u", MSC_AS_TIME_ARGS(ctxt_pP), ue_context_pP->ue_context.rnti, rrc_eNB_mui, @@ -2612,9 +2611,9 @@ rrc_eNB_generate_dedicatedRRCConnectionReconfiguration_release( const protocol_ uint8_t buffer[RRC_BUF_SIZE]; int i; uint16_t size = 0; - DRB_ToReleaseList_t** DRB_Release_configList2=NULL; - DRB_Identity_t* DRB_release; - struct RRCConnectionReconfiguration_r8_IEs__dedicatedInfoNASList *dedicatedInfoNASList = NULL; + LTE_DRB_ToReleaseList_t** DRB_Release_configList2=NULL; + LTE_DRB_Identity_t* DRB_release; + struct LTE_RRCConnectionReconfiguration_r8_IEs__dedicatedInfoNASList *dedicatedInfoNASList = NULL; DRB_Release_configList2=&ue_context_pP->ue_context.DRB_Release_configList2[xid]; if (*DRB_Release_configList2) { @@ -2624,7 +2623,7 @@ rrc_eNB_generate_dedicatedRRCConnectionReconfiguration_release( const protocol_ for(i = 0; i < NB_RB_MAX; i++){ if((ue_context_pP->ue_context.e_rab[i].status == E_RAB_STATUS_TORELEASE) && ue_context_pP->ue_context.e_rab[i].xid == xid){ - DRB_release = CALLOC(1, sizeof(DRB_Identity_t)); + DRB_release = CALLOC(1, sizeof(LTE_DRB_Identity_t)); *DRB_release = i+1; ASN_SEQUENCE_ADD(&(*DRB_Release_configList2)->list, DRB_release); //free(DRB_release); @@ -2633,9 +2632,9 @@ rrc_eNB_generate_dedicatedRRCConnectionReconfiguration_release( const protocol_ /* If list is empty free the list and reset the address */ if (nas_length > 0) { - DedicatedInfoNAS_t *dedicatedInfoNas = NULL; - dedicatedInfoNASList = CALLOC(1, sizeof(struct RRCConnectionReconfiguration_r8_IEs__dedicatedInfoNASList)); - dedicatedInfoNas = CALLOC(1, sizeof(DedicatedInfoNAS_t)); + LTE_DedicatedInfoNAS_t *dedicatedInfoNas = NULL; + dedicatedInfoNASList = CALLOC(1, sizeof(struct LTE_RRCConnectionReconfiguration_r8_IEs__dedicatedInfoNASList)); + dedicatedInfoNas = CALLOC(1, sizeof(LTE_DedicatedInfoNAS_t)); memset(dedicatedInfoNas, 0, sizeof(OCTET_STRING_t)); OCTET_STRING_fromBuf(dedicatedInfoNas, (char*)nas_buffer, @@ -2652,7 +2651,7 @@ rrc_eNB_generate_dedicatedRRCConnectionReconfiguration_release( const protocol_ xid, NULL, NULL, - (DRB_ToReleaseList_t*)*DRB_Release_configList2, + (LTE_DRB_ToReleaseList_t*)*DRB_Release_configList2, NULL, NULL, NULL, @@ -2665,11 +2664,11 @@ rrc_eNB_generate_dedicatedRRCConnectionReconfiguration_release( const protocol_ NULL, NULL, NULL, - (struct RRCConnectionReconfiguration_r8_IEs__dedicatedInfoNASList*)dedicatedInfoNASList, - (SL_CommConfig_r12_t*)NULL, - (SL_DiscConfig_r12_t*)NULL -#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) - , (SCellToAddMod_r10_t*)NULL + (struct LTE_RRCConnectionReconfiguration_r8_IEs__dedicatedInfoNASList*)dedicatedInfoNASList, + (LTE_SL_CommConfig_r12_t*)NULL, + (LTE_SL_DiscConfig_r12_t*)NULL +#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) + , (LTE_SCellToAddMod_r10_t*)NULL #endif ); ue_context_pP->ue_context.e_rab_release_command_flag = 1; @@ -2685,7 +2684,7 @@ rrc_eNB_generate_dedicatedRRCConnectionReconfiguration_release( const protocol_ #endif LOG_I(RRC, - "[eNB %d] Frame %d, Logical Channel DL-DCCH, Generate RRCConnectionReconfiguration (bytes %d, UE RNTI %x)\n", + "[eNB %d] Frame %d, Logical Channel DL-DCCH, Generate LTE_RRCConnectionReconfiguration (bytes %d, UE RNTI %x)\n", ctxt_pP->module_id, ctxt_pP->frame, size, ue_context_pP->ue_context.rnti); LOG_D(RRC, @@ -2697,7 +2696,7 @@ rrc_eNB_generate_dedicatedRRCConnectionReconfiguration_release( const protocol_ MSC_RRC_UE, buffer, size, - MSC_AS_TIME_FMT" dedicated rrcConnectionReconfiguration UE %x MUI %d size %u", + MSC_AS_TIME_FMT" dedicated LTE_RRCConnectionReconfiguration UE %x MUI %d size %u", MSC_AS_TIME_ARGS(ctxt_pP), ue_context_pP->ue_context.rnti, rrc_eNB_mui, @@ -2726,37 +2725,37 @@ rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt_t* cons uint16_t size; int i; - // configure SRB1/SRB2, PhysicalConfigDedicated, MAC_MainConfig for UE + // configure SRB1/SRB2, PhysicalConfigDedicated, LTE_MAC_MainConfig for UE eNB_RRC_INST* rrc_inst = RC.rrc[ctxt_pP->module_id]; - struct PhysicalConfigDedicated** physicalConfigDedicated = &ue_context_pP->ue_context.physicalConfigDedicated; + struct LTE_PhysicalConfigDedicated** physicalConfigDedicated = &ue_context_pP->ue_context.physicalConfigDedicated; - struct SRB_ToAddMod *SRB2_config = NULL; - struct SRB_ToAddMod__rlc_Config *SRB2_rlc_config = NULL; - struct SRB_ToAddMod__logicalChannelConfig *SRB2_lchan_config = NULL; - struct LogicalChannelConfig__ul_SpecificParameters + struct LTE_SRB_ToAddMod *SRB2_config = NULL; + struct LTE_SRB_ToAddMod__rlc_Config *SRB2_rlc_config = NULL; + struct LTE_SRB_ToAddMod__logicalChannelConfig *SRB2_lchan_config = NULL; + struct LTE_LogicalChannelConfig__ul_SpecificParameters *SRB2_ul_SpecificParameters = NULL; - SRB_ToAddModList_t* SRB_configList = ue_context_pP->ue_context.SRB_configList; - SRB_ToAddModList_t **SRB_configList2 = NULL; + LTE_SRB_ToAddModList_t* SRB_configList = ue_context_pP->ue_context.SRB_configList; + LTE_SRB_ToAddModList_t **SRB_configList2 = NULL; - struct DRB_ToAddMod *DRB_config = NULL; - struct RLC_Config *DRB_rlc_config = NULL; - struct PDCP_Config *DRB_pdcp_config = NULL; - struct PDCP_Config__rlc_AM *PDCP_rlc_AM = NULL; - struct PDCP_Config__rlc_UM *PDCP_rlc_UM = NULL; - struct LogicalChannelConfig *DRB_lchan_config = NULL; - struct LogicalChannelConfig__ul_SpecificParameters + struct LTE_DRB_ToAddMod *DRB_config = NULL; + struct LTE_RLC_Config *DRB_rlc_config = NULL; + struct LTE_PDCP_Config *DRB_pdcp_config = NULL; + struct LTE_PDCP_Config__rlc_AM *PDCP_rlc_AM = NULL; + struct LTE_PDCP_Config__rlc_UM *PDCP_rlc_UM = NULL; + struct LTE_LogicalChannelConfig *DRB_lchan_config = NULL; + struct LTE_LogicalChannelConfig__ul_SpecificParameters *DRB_ul_SpecificParameters = NULL; - DRB_ToAddModList_t** DRB_configList = &ue_context_pP->ue_context.DRB_configList; - DRB_ToAddModList_t** DRB_configList2 = NULL; - MAC_MainConfig_t *mac_MainConfig = NULL; - MeasObjectToAddModList_t *MeasObj_list = NULL; - MeasObjectToAddMod_t *MeasObj = NULL; - ReportConfigToAddModList_t *ReportConfig_list = NULL; - ReportConfigToAddMod_t *ReportConfig_per, *ReportConfig_A1, + LTE_DRB_ToAddModList_t** DRB_configList = &ue_context_pP->ue_context.DRB_configList; + LTE_DRB_ToAddModList_t** DRB_configList2 = NULL; + LTE_MAC_MainConfig_t *mac_MainConfig = NULL; + LTE_MeasObjectToAddModList_t *MeasObj_list = NULL; + LTE_MeasObjectToAddMod_t *MeasObj = NULL; + LTE_ReportConfigToAddModList_t *ReportConfig_list = NULL; + LTE_ReportConfigToAddMod_t *ReportConfig_per, *ReportConfig_A1, *ReportConfig_A2, *ReportConfig_A3, *ReportConfig_A4, *ReportConfig_A5; - MeasIdToAddModList_t *MeasId_list = NULL; - MeasIdToAddMod_t *MeasId0, *MeasId1, *MeasId2, *MeasId3, *MeasId4, *MeasId5; -#if (RRC_VERSION >= MAKE_VERSION(9, 0, 0)) + LTE_MeasIdToAddModList_t *MeasId_list = NULL; + LTE_MeasIdToAddMod_t *MeasId0, *MeasId1, *MeasId2, *MeasId3, *MeasId4, *MeasId5; +#if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) long *sr_ProhibitTimer_r9 = NULL; // uint8_t sCellIndexToAdd = rrc_find_free_SCell_index(enb_mod_idP, ue_mod_idP, 1); //uint8_t sCellIndexToAdd = 0; @@ -2765,24 +2764,24 @@ rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt_t* cons long *logicalchannelgroup, *logicalchannelgroup_drb; long *maxHARQ_Tx, *periodicBSR_Timer; - RSRP_Range_t *rsrp = NULL; - struct MeasConfig__speedStatePars *Sparams = NULL; - QuantityConfig_t *quantityConfig = NULL; - CellsToAddMod_t *CellToAdd = NULL; - CellsToAddModList_t *CellsToAddModList = NULL; - struct RRCConnectionReconfiguration_r8_IEs__dedicatedInfoNASList *dedicatedInfoNASList = NULL; - DedicatedInfoNAS_t *dedicatedInfoNas = NULL; + LTE_RSRP_Range_t *rsrp = NULL; + struct LTE_MeasConfig__speedStatePars *Sparams = NULL; + LTE_QuantityConfig_t *quantityConfig = NULL; + LTE_CellsToAddMod_t *CellToAdd = NULL; + LTE_CellsToAddModList_t *CellsToAddModList = NULL; + struct LTE_RRCConnectionReconfiguration_r8_IEs__dedicatedInfoNASList *dedicatedInfoNASList = NULL; + LTE_DedicatedInfoNAS_t *dedicatedInfoNas = NULL; /* for no gcc warnings */ (void)dedicatedInfoNas; - C_RNTI_t *cba_RNTI = NULL; + LTE_C_RNTI_t *cba_RNTI = NULL; uint8_t xid = rrc_eNB_get_next_transaction_identifier(ctxt_pP->module_id); //Transaction_id, #ifdef CBA //struct PUSCH_CBAConfigDedicated_vlola *pusch_CBAConfigDedicated_vlola; uint8_t *cba_RNTI_buf; - cba_RNTI = CALLOC(1, sizeof(C_RNTI_t)); + cba_RNTI = CALLOC(1, sizeof(LTE_C_RNTI_t)); cba_RNTI_buf = CALLOC(1, 2 * sizeof(uint8_t)); cba_RNTI->buf = cba_RNTI_buf; cba_RNTI->size = 2; @@ -2822,27 +2821,27 @@ rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt_t* cons 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_ms35; - SRB2_rlc_config->choice.explicitValue.choice.am.dl_AM_RLC.t_StatusProhibit = T_StatusProhibit_ms10; + SRB2_rlc_config->present = LTE_SRB_ToAddMod__rlc_Config_PR_explicitValue; + SRB2_rlc_config->choice.explicitValue.present = LTE_RLC_Config_PR_am; + SRB2_rlc_config->choice.explicitValue.choice.am.ul_AM_RLC.t_PollRetransmit = LTE_T_PollRetransmit_ms15; + SRB2_rlc_config->choice.explicitValue.choice.am.ul_AM_RLC.pollPDU = LTE_PollPDU_p8; + SRB2_rlc_config->choice.explicitValue.choice.am.ul_AM_RLC.pollByte = LTE_PollByte_kB1000; + SRB2_rlc_config->choice.explicitValue.choice.am.ul_AM_RLC.maxRetxThreshold = LTE_UL_AM_RLC__maxRetxThreshold_t32; + SRB2_rlc_config->choice.explicitValue.choice.am.dl_AM_RLC.t_Reordering = LTE_T_Reordering_ms35; + SRB2_rlc_config->choice.explicitValue.choice.am.dl_AM_RLC.t_StatusProhibit = LTE_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 = LTE_SRB_ToAddMod__logicalChannelConfig_PR_explicitValue; SRB2_ul_SpecificParameters = CALLOC(1, sizeof(*SRB2_ul_SpecificParameters)); SRB2_ul_SpecificParameters->priority = 3; // let some priority for SRB1 and dedicated DRBs SRB2_ul_SpecificParameters->prioritisedBitRate = - LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_infinity; + LTE_LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_infinity; SRB2_ul_SpecificParameters->bucketSizeDuration = - LogicalChannelConfig__ul_SpecificParameters__bucketSizeDuration_ms50; + LTE_LogicalChannelConfig__ul_SpecificParameters__bucketSizeDuration_ms50; // LCG for CCCH and DCCH is 0 as defined in 36331 logicalchannelgroup = CALLOC(1, sizeof(long)); @@ -2879,37 +2878,37 @@ rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt_t* cons DRB_config->eps_BearerIdentity = CALLOC(1, sizeof(long)); *(DRB_config->eps_BearerIdentity) = 5L; // LW set to first value, allowed value 5..15, value : x+4 - // DRB_config->drb_Identity = (DRB_Identity_t) 1; //allowed values 1..32 + // DRB_config->drb_Identity = (LTE_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_mod_idP+1); //allowed values 1..32, value: x + DRB_config->drb_Identity = (LTE_DRB_Identity_t) 1; // (ue_mod_idP+1); //allowed values 1..32, value: x DRB_config->logicalChannelIdentity = CALLOC(1, sizeof(long)); *(DRB_config->logicalChannelIdentity) = (long)3; // value : x+2 DRB_rlc_config = CALLOC(1, sizeof(*DRB_rlc_config)); DRB_config->rlc_Config = DRB_rlc_config; #ifdef RRC_DEFAULT_RAB_IS_AM - DRB_rlc_config->present = RLC_Config_PR_am; - DRB_rlc_config->choice.am.ul_AM_RLC.t_PollRetransmit = T_PollRetransmit_ms50; - DRB_rlc_config->choice.am.ul_AM_RLC.pollPDU = PollPDU_p16; - DRB_rlc_config->choice.am.ul_AM_RLC.pollByte = PollByte_kBinfinity; - DRB_rlc_config->choice.am.ul_AM_RLC.maxRetxThreshold = UL_AM_RLC__maxRetxThreshold_t8; - DRB_rlc_config->choice.am.dl_AM_RLC.t_Reordering = T_Reordering_ms35; - DRB_rlc_config->choice.am.dl_AM_RLC.t_StatusProhibit = T_StatusProhibit_ms25; + DRB_rlc_config->present = LTE_RLC_Config_PR_am; + DRB_rlc_config->choice.am.ul_AM_RLC.t_PollRetransmit = LTE_T_PollRetransmit_ms50; + DRB_rlc_config->choice.am.ul_AM_RLC.pollPDU = LTE_PollPDU_p16; + DRB_rlc_config->choice.am.ul_AM_RLC.pollByte = LTE_PollByte_kBinfinity; + DRB_rlc_config->choice.am.ul_AM_RLC.maxRetxThreshold = LTE_UL_AM_RLC__maxRetxThreshold_t8; + DRB_rlc_config->choice.am.dl_AM_RLC.t_Reordering = LTE_T_Reordering_ms35; + DRB_rlc_config->choice.am.dl_AM_RLC.t_StatusProhibit = LTE_T_StatusProhibit_ms25; #else - 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->present = LTE_RLC_Config_PR_um_Bi_Directional; + DRB_rlc_config->choice.um_Bi_Directional.ul_UM_RLC.sn_FieldLength = LTE_SN_FieldLength_size10; + DRB_rlc_config->choice.um_Bi_Directional.dl_UM_RLC.sn_FieldLength = LTE_SN_FieldLength_size10; #ifdef CBA - DRB_rlc_config->choice.um_Bi_Directional.dl_UM_RLC.t_Reordering = T_Reordering_ms5;//T_Reordering_ms25; + DRB_rlc_config->choice.um_Bi_Directional.dl_UM_RLC.t_Reordering = LTE_T_Reordering_ms5;//T_Reordering_ms25; #else - DRB_rlc_config->choice.um_Bi_Directional.dl_UM_RLC.t_Reordering = T_Reordering_ms35; + DRB_rlc_config->choice.um_Bi_Directional.dl_UM_RLC.t_Reordering = LTE_T_Reordering_ms35; #endif #endif DRB_pdcp_config = CALLOC(1, sizeof(*DRB_pdcp_config)); DRB_config->pdcp_Config = DRB_pdcp_config; DRB_pdcp_config->discardTimer = CALLOC(1, sizeof(long)); - *DRB_pdcp_config->discardTimer = PDCP_Config__discardTimer_infinity; + *DRB_pdcp_config->discardTimer = LTE_PDCP_Config__discardTimer_infinity; DRB_pdcp_config->rlc_AM = NULL; DRB_pdcp_config->rlc_UM = NULL; @@ -2924,9 +2923,9 @@ rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt_t* cons #else 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; + PDCP_rlc_UM->pdcp_SN_Size = LTE_PDCP_Config__rlc_UM__pdcp_SN_Size_len12bits; #endif - DRB_pdcp_config->headerCompression.present = PDCP_Config__headerCompression_PR_notUsed; + DRB_pdcp_config->headerCompression.present = LTE_PDCP_Config__headerCompression_PR_notUsed; DRB_lchan_config = CALLOC(1, sizeof(*DRB_lchan_config)); DRB_config->logicalChannelConfig = DRB_lchan_config; @@ -2934,10 +2933,10 @@ rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt_t* cons DRB_lchan_config->ul_SpecificParameters = DRB_ul_SpecificParameters; DRB_ul_SpecificParameters->priority = 12; // lower priority than srb1, srb2 and other dedicated bearer - DRB_ul_SpecificParameters->prioritisedBitRate =LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_kBps8 ; + DRB_ul_SpecificParameters->prioritisedBitRate =LTE_LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_kBps8 ; //LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_infinity; DRB_ul_SpecificParameters->bucketSizeDuration = - LogicalChannelConfig__ul_SpecificParameters__bucketSizeDuration_ms50; + LTE_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)); @@ -2955,31 +2954,31 @@ rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt_t* cons 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; + *maxHARQ_Tx = LTE_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 = PeriodicBSR_Timer_r12_sf64; + *periodicBSR_Timer = LTE_PeriodicBSR_Timer_r12_sf64; mac_MainConfig->ul_SCH_Config->periodicBSR_Timer = periodicBSR_Timer; - mac_MainConfig->ul_SCH_Config->retxBSR_Timer = RetxBSR_Timer_r12_sf320; + mac_MainConfig->ul_SCH_Config->retxBSR_Timer = LTE_RetxBSR_Timer_r12_sf320; mac_MainConfig->ul_SCH_Config->ttiBundling = 0; // FALSE - mac_MainConfig->timeAlignmentTimerDedicated = TimeAlignmentTimer_infinity; + mac_MainConfig->timeAlignmentTimerDedicated = LTE_TimeAlignmentTimer_infinity; 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->present = LTE_MAC_MainConfig__phr_Config_PR_setup; + mac_MainConfig->phr_Config->choice.setup.periodicPHR_Timer = LTE_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.prohibitPHR_Timer = LTE_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 + mac_MainConfig->phr_Config->choice.setup.dl_PathlossChange = LTE_MAC_MainConfig__phr_Config__setup__dl_PathlossChange_dB1; // Value dB1 =1 dB, dB3 = 3 dB -#if (RRC_VERSION >= MAKE_VERSION(9, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) 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->ext1 = CALLOC(1, sizeof(struct MAC_MainConfig__ext1)); + mac_MainConfig->ext1 = CALLOC(1, sizeof(struct LTE_MAC_MainConfig__ext1)); mac_MainConfig->ext1->sr_ProhibitTimer_r9 = sr_ProhibitTimer_r9; //sps_RA_ConfigList_rlola = NULL; #endif @@ -2991,42 +2990,42 @@ rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt_t* cons if ((*physicalConfigDedicated)->antennaInfo) { (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.transmissionMode = rrc_inst->configuration.ue_TransmissionMode[0]; LOG_D(RRC,"Setting transmission mode to %ld+1\n",rrc_inst->configuration.ue_TransmissionMode[0]); - if (rrc_inst->configuration.ue_TransmissionMode[0]==AntennaInfoDedicated__transmissionMode_tm3) { + if (rrc_inst->configuration.ue_TransmissionMode[0] == LTE_AntennaInfoDedicated__transmissionMode_tm3) { (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction= - CALLOC(1,sizeof(AntennaInfoDedicated__codebookSubsetRestriction_PR)); + CALLOC(1,sizeof(LTE_AntennaInfoDedicated__codebookSubsetRestriction_PR)); (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->present = - AntennaInfoDedicated__codebookSubsetRestriction_PR_n2TxAntenna_tm3; + LTE_AntennaInfoDedicated__codebookSubsetRestriction_PR_n2TxAntenna_tm3; (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm3.buf= MALLOC(1); (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm3.buf[0] = 0xc0; (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm3.size=1; (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm3.bits_unused=6; } - else if (rrc_inst->configuration.ue_TransmissionMode[0]==AntennaInfoDedicated__transmissionMode_tm4) { + else if (rrc_inst->configuration.ue_TransmissionMode[0] == LTE_AntennaInfoDedicated__transmissionMode_tm4) { (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction= - CALLOC(1,sizeof(AntennaInfoDedicated__codebookSubsetRestriction_PR)); + CALLOC(1,sizeof(LTE_AntennaInfoDedicated__codebookSubsetRestriction_PR)); (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->present = - AntennaInfoDedicated__codebookSubsetRestriction_PR_n2TxAntenna_tm4; + LTE_AntennaInfoDedicated__codebookSubsetRestriction_PR_n2TxAntenna_tm4; (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm4.buf= MALLOC(1); (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm4.buf[0] = 0xfc; (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm4.size=1; (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm4.bits_unused=2; } - else if (rrc_inst->configuration.ue_TransmissionMode[0]==AntennaInfoDedicated__transmissionMode_tm5) { + else if (rrc_inst->configuration.ue_TransmissionMode[0] == LTE_AntennaInfoDedicated__transmissionMode_tm5) { (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction= - CALLOC(1,sizeof(AntennaInfoDedicated__codebookSubsetRestriction_PR)); + CALLOC(1,sizeof(LTE_AntennaInfoDedicated__codebookSubsetRestriction_PR)); (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->present = - AntennaInfoDedicated__codebookSubsetRestriction_PR_n2TxAntenna_tm5; + LTE_AntennaInfoDedicated__codebookSubsetRestriction_PR_n2TxAntenna_tm5; (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm5.buf= MALLOC(1); (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm5.buf[0] = 0xf0; (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm5.size=1; (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm5.bits_unused=4; } - else if (rrc_inst->configuration.ue_TransmissionMode[0]==AntennaInfoDedicated__transmissionMode_tm6) { + else if (rrc_inst->configuration.ue_TransmissionMode[0] == LTE_AntennaInfoDedicated__transmissionMode_tm6) { (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction= - CALLOC(1,sizeof(AntennaInfoDedicated__codebookSubsetRestriction_PR)); + CALLOC(1,sizeof(LTE_AntennaInfoDedicated__codebookSubsetRestriction_PR)); (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->present = - AntennaInfoDedicated__codebookSubsetRestriction_PR_n2TxAntenna_tm6; + LTE_AntennaInfoDedicated__codebookSubsetRestriction_PR_n2TxAntenna_tm6; (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm6.buf= MALLOC(1); (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm6.buf[0] = 0xf0; (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm6.size=1; @@ -3037,16 +3036,16 @@ rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt_t* cons LOG_E(RRC,"antenna_info not present in physical_config_dedicated. Not reconfiguring!\n"); } if ((*physicalConfigDedicated)->cqi_ReportConfig) { - if ((rrc_inst->configuration.ue_TransmissionMode[0]==AntennaInfoDedicated__transmissionMode_tm4) || - (rrc_inst->configuration.ue_TransmissionMode[0]==AntennaInfoDedicated__transmissionMode_tm5) || - (rrc_inst->configuration.ue_TransmissionMode[0]==AntennaInfoDedicated__transmissionMode_tm6)) { + if ((rrc_inst->configuration.ue_TransmissionMode[0] == LTE_AntennaInfoDedicated__transmissionMode_tm4) || + (rrc_inst->configuration.ue_TransmissionMode[0] == LTE_AntennaInfoDedicated__transmissionMode_tm5) || + (rrc_inst->configuration.ue_TransmissionMode[0] == LTE_AntennaInfoDedicated__transmissionMode_tm6)) { //feedback mode needs to be set as well //TODO: I think this is taken into account in the PHY automatically based on the transmission mode variable printf("setting cqi reporting mode to rm31\n"); -#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) - *((*physicalConfigDedicated)->cqi_ReportConfig->cqi_ReportModeAperiodic)=CQI_ReportModeAperiodic_rm31; +#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) + *((*physicalConfigDedicated)->cqi_ReportConfig->cqi_ReportModeAperiodic)=LTE_CQI_ReportModeAperiodic_rm31; #else - *((*physicalConfigDedicated)->cqi_ReportConfig->cqi_ReportModeAperiodic)=CQI_ReportConfig__cqi_ReportModeAperiodic_rm31; // HLC CQI, no PMI + *((*physicalConfigDedicated)->cqi_ReportConfig->cqi_ReportModeAperiodic)=LTE_CQI_ReportConfig__cqi_ReportModeAperiodic_rm31; // HLC CQI, no PMI #endif } } @@ -3055,7 +3054,7 @@ rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt_t* cons } } else { - LOG_E(RRC,"physical_config_dedicated not present in RRCConnectionReconfiguration. Not reconfiguring!\n"); + LOG_E(RRC,"physical_config_dedicated not present in LTE_RRCConnectionReconfiguration. Not reconfiguring!\n"); } // Measurement ID list @@ -3098,7 +3097,7 @@ rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt_t* cons MeasId5->reportConfigId = 6; ASN_SEQUENCE_ADD(&MeasId_list->list, MeasId5); - // rrcConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.measConfig->measIdToAddModList = MeasId_list; + // LTE_RRCConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.measConfig->measIdToAddModList = MeasId_list; // Add one EUTRA Measurement Object MeasObj_list = CALLOC(1, sizeof(*MeasObj_list)); @@ -3110,10 +3109,10 @@ rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt_t* cons memset((void *)MeasObj, 0, sizeof(*MeasObj)); MeasObj->measObjectId = 1; - MeasObj->measObject.present = MeasObjectToAddMod__measObject_PR_measObjectEUTRA; + MeasObj->measObject.present = LTE_MeasObjectToAddMod__measObject_PR_measObjectEUTRA; MeasObj->measObject.choice.measObjectEUTRA.carrierFreq = 3350; //band 7, 2.68GHz //MeasObj->measObject.choice.measObjectEUTRA.carrierFreq = 36090; //band 33, 1.909GHz - MeasObj->measObject.choice.measObjectEUTRA.allowedMeasBandwidth = AllowedMeasBandwidth_mbw25; + MeasObj->measObject.choice.measObjectEUTRA.allowedMeasBandwidth = LTE_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; @@ -3122,22 +3121,22 @@ rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt_t* cons MeasObj->measObject.choice.measObjectEUTRA.offsetFreq = NULL; // Default is 15 or 0dB MeasObj->measObject.choice.measObjectEUTRA.cellsToAddModList = - (CellsToAddModList_t *) CALLOC(1, sizeof(*CellsToAddModList)); + (LTE_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 = (LTE_CellsToAddMod_t *) CALLOC(1, sizeof(*CellToAdd)); CellToAdd->cellIndex = i + 1; CellToAdd->physCellId = get_adjacent_cell_id(ctxt_pP->module_id, i); - CellToAdd->cellIndividualOffset = Q_OffsetRange_dB0; + CellToAdd->cellIndividualOffset = LTE_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; + // LTE_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)); @@ -3155,35 +3154,35 @@ rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt_t* cons ReportConfig_A5 = CALLOC(1, sizeof(*ReportConfig_A5)); ReportConfig_per->reportConfigId = 1; - ReportConfig_per->reportConfig.present = ReportConfigToAddMod__reportConfig_PR_reportConfigEUTRA; + ReportConfig_per->reportConfig.present = LTE_ReportConfigToAddMod__reportConfig_PR_reportConfigEUTRA; ReportConfig_per->reportConfig.choice.reportConfigEUTRA.triggerType.present = - ReportConfigEUTRA__triggerType_PR_periodical; + LTE_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; + LTE_ReportConfigEUTRA__triggerType__periodical__purpose_reportStrongestCells; + ReportConfig_per->reportConfig.choice.reportConfigEUTRA.triggerQuantity = LTE_ReportConfigEUTRA__triggerQuantity_rsrp; + ReportConfig_per->reportConfig.choice.reportConfigEUTRA.reportQuantity = LTE_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 = LTE_ReportInterval_ms120; + ReportConfig_per->reportConfig.choice.reportConfigEUTRA.reportAmount = LTE_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.present = LTE_ReportConfigToAddMod__reportConfig_PR_reportConfigEUTRA; ReportConfig_A1->reportConfig.choice.reportConfigEUTRA.triggerType.present = - ReportConfigEUTRA__triggerType_PR_event; + LTE_ReportConfigEUTRA__triggerType_PR_event; ReportConfig_A1->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.present = - ReportConfigEUTRA__triggerType__event__eventId_PR_eventA1; + LTE_ReportConfigEUTRA__triggerType__event__eventId_PR_eventA1; ReportConfig_A1->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.choice.eventA1. - a1_Threshold.present = ThresholdEUTRA_PR_threshold_RSRP; + a1_Threshold.present = LTE_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.triggerQuantity = LTE_ReportConfigEUTRA__triggerQuantity_rsrp; + ReportConfig_A1->reportConfig.choice.reportConfigEUTRA.reportQuantity = LTE_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 = LTE_ReportInterval_ms120; + ReportConfig_A1->reportConfig.choice.reportConfigEUTRA.reportAmount = LTE_ReportConfigEUTRA__reportAmount_infinity; ASN_SEQUENCE_ADD(&ReportConfig_list->list, ReportConfig_A1); @@ -3191,108 +3190,108 @@ rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt_t* cons LOG_I(RRC, "[eNB %d] frame %d: requesting A2, A3, A4, A5, and A6 event reporting\n", ctxt_pP->module_id, ctxt_pP->frame); ReportConfig_A2->reportConfigId = 3; - ReportConfig_A2->reportConfig.present = ReportConfigToAddMod__reportConfig_PR_reportConfigEUTRA; + ReportConfig_A2->reportConfig.present = LTE_ReportConfigToAddMod__reportConfig_PR_reportConfigEUTRA; ReportConfig_A2->reportConfig.choice.reportConfigEUTRA.triggerType.present = - ReportConfigEUTRA__triggerType_PR_event; + LTE_ReportConfigEUTRA__triggerType_PR_event; ReportConfig_A2->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.present = - ReportConfigEUTRA__triggerType__event__eventId_PR_eventA2; + LTE_ReportConfigEUTRA__triggerType__event__eventId_PR_eventA2; ReportConfig_A2->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.choice. - eventA2.a2_Threshold.present = ThresholdEUTRA_PR_threshold_RSRP; + eventA2.a2_Threshold.present = LTE_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; + LTE_ReportConfigEUTRA__triggerQuantity_rsrp; + ReportConfig_A2->reportConfig.choice.reportConfigEUTRA.reportQuantity = LTE_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; + ReportConfig_A2->reportConfig.choice.reportConfigEUTRA.reportInterval = LTE_ReportInterval_ms120; + ReportConfig_A2->reportConfig.choice.reportConfigEUTRA.reportAmount = LTE_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.present = LTE_ReportConfigToAddMod__reportConfig_PR_reportConfigEUTRA; ReportConfig_A3->reportConfig.choice.reportConfigEUTRA.triggerType.present = - ReportConfigEUTRA__triggerType_PR_event; + LTE_ReportConfigEUTRA__triggerType_PR_event; ReportConfig_A3->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.present = - ReportConfigEUTRA__triggerType__event__eventId_PR_eventA3; + LTE_ReportConfigEUTRA__triggerType__event__eventId_PR_eventA3; 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; + LTE_ReportConfigEUTRA__triggerQuantity_rsrp; + ReportConfig_A3->reportConfig.choice.reportConfigEUTRA.reportQuantity = LTE_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.reportInterval = LTE_ReportInterval_ms120; + ReportConfig_A3->reportConfig.choice.reportConfigEUTRA.reportAmount = LTE_ReportConfigEUTRA__reportAmount_infinity; ReportConfig_A3->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.hysteresis = 0.5; // FIXME ...hysteresis is of type long! ReportConfig_A3->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.timeToTrigger = - TimeToTrigger_ms40; + LTE_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.present = LTE_ReportConfigToAddMod__reportConfig_PR_reportConfigEUTRA; ReportConfig_A4->reportConfig.choice.reportConfigEUTRA.triggerType.present = - ReportConfigEUTRA__triggerType_PR_event; + LTE_ReportConfigEUTRA__triggerType_PR_event; ReportConfig_A4->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.present = - ReportConfigEUTRA__triggerType__event__eventId_PR_eventA4; + LTE_ReportConfigEUTRA__triggerType__event__eventId_PR_eventA4; ReportConfig_A4->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.choice. - eventA4.a4_Threshold.present = ThresholdEUTRA_PR_threshold_RSRP; + eventA4.a4_Threshold.present = LTE_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; + LTE_ReportConfigEUTRA__triggerQuantity_rsrp; + ReportConfig_A4->reportConfig.choice.reportConfigEUTRA.reportQuantity = LTE_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; + ReportConfig_A4->reportConfig.choice.reportConfigEUTRA.reportInterval = LTE_ReportInterval_ms120; + ReportConfig_A4->reportConfig.choice.reportConfigEUTRA.reportAmount = LTE_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.present = LTE_ReportConfigToAddMod__reportConfig_PR_reportConfigEUTRA; ReportConfig_A5->reportConfig.choice.reportConfigEUTRA.triggerType.present = - ReportConfigEUTRA__triggerType_PR_event; + LTE_ReportConfigEUTRA__triggerType_PR_event; ReportConfig_A5->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.present = - ReportConfigEUTRA__triggerType__event__eventId_PR_eventA5; + LTE_ReportConfigEUTRA__triggerType__event__eventId_PR_eventA5; ReportConfig_A5->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.choice. - eventA5.a5_Threshold1.present = ThresholdEUTRA_PR_threshold_RSRP; + eventA5.a5_Threshold1.present = LTE_ThresholdEUTRA_PR_threshold_RSRP; ReportConfig_A5->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.choice. - eventA5.a5_Threshold2.present = ThresholdEUTRA_PR_threshold_RSRP; + eventA5.a5_Threshold2.present = LTE_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; + LTE_ReportConfigEUTRA__triggerQuantity_rsrp; + ReportConfig_A5->reportConfig.choice.reportConfigEUTRA.reportQuantity = LTE_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; + ReportConfig_A5->reportConfig.choice.reportConfigEUTRA.reportInterval = LTE_ReportInterval_ms120; + ReportConfig_A5->reportConfig.choice.reportConfigEUTRA.reportAmount = LTE_ReportConfigEUTRA__reportAmount_infinity; ASN_SEQUENCE_ADD(&ReportConfig_list->list, ReportConfig_A5); - // rrcConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.measConfig->reportConfigToAddModList = ReportConfig_list; + // LTE_RRCConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.measConfig->reportConfigToAddModList = ReportConfig_list; - rsrp = CALLOC(1, sizeof(RSRP_Range_t)); + rsrp = CALLOC(1, sizeof(LTE_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->present = LTE_MeasConfig__speedStatePars_PR_setup; + Sparams->choice.setup.timeToTrigger_SF.sf_High = LTE_SpeedStateScaleFactors__sf_Medium_oDot75; + Sparams->choice.setup.timeToTrigger_SF.sf_Medium = LTE_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; + Sparams->choice.setup.mobilityStateParameters.t_Evaluation = LTE_MobilityStateParameters__t_Evaluation_s60; + Sparams->choice.setup.mobilityStateParameters.t_HystNormal = LTE_MobilityStateParameters__t_HystNormal_s120; quantityConfig = CALLOC(1, sizeof(*quantityConfig)); memset((void *)quantityConfig, 0, sizeof(*quantityConfig)); - quantityConfig->quantityConfigEUTRA = CALLOC(1, sizeof(struct QuantityConfigEUTRA)); + quantityConfig->quantityConfigEUTRA = CALLOC(1, sizeof(struct LTE_QuantityConfigEUTRA)); memset((void *)quantityConfig->quantityConfigEUTRA, 0, sizeof(*quantityConfig->quantityConfigEUTRA)); quantityConfig->quantityConfigCDMA2000 = NULL; quantityConfig->quantityConfigGERAN = NULL; @@ -3301,8 +3300,8 @@ rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt_t* cons 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; + *quantityConfig->quantityConfigEUTRA->filterCoefficientRSRP = LTE_FilterCoefficient_fc4; + *quantityConfig->quantityConfigEUTRA->filterCoefficientRSRQ = LTE_FilterCoefficient_fc4; LOG_I(RRC, "[eNB %d] Frame %d: potential handover preparation: store the information in an intermediate structure in case of failure\n", @@ -3310,19 +3309,19 @@ rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt_t* cons // store the information in an intermediate structure for Hanodver management //rrc_inst->handover_info.as_config.sourceRadioResourceConfig.srb_ToAddModList = CALLOC(1,sizeof()); ue_context_pP->ue_context.handover_info = CALLOC(1, sizeof(*(ue_context_pP->ue_context.handover_info))); - //memcpy((void *)rrc_inst->handover_info[ue_mod_idP]->as_config.sourceRadioResourceConfig.srb_ToAddModList,(void *)SRB_list,sizeof(SRB_ToAddModList_t)); + //memcpy((void *)rrc_inst->handover_info[ue_mod_idP]->as_config.sourceRadioResourceConfig.srb_ToAddModList,(void *)SRB_list,sizeof(LTE_SRB_ToAddModList_t)); ue_context_pP->ue_context.handover_info->as_config.sourceRadioResourceConfig.srb_ToAddModList = *SRB_configList2; - //memcpy((void *)rrc_inst->handover_info[ue_mod_idP]->as_config.sourceRadioResourceConfig.drb_ToAddModList,(void *)DRB_list,sizeof(DRB_ToAddModList_t)); + //memcpy((void *)rrc_inst->handover_info[ue_mod_idP]->as_config.sourceRadioResourceConfig.drb_ToAddModList,(void *)DRB_list,sizeof(LTE_DRB_ToAddModList_t)); ue_context_pP->ue_context.handover_info->as_config.sourceRadioResourceConfig.drb_ToAddModList = *DRB_configList; ue_context_pP->ue_context.handover_info->as_config.sourceRadioResourceConfig.drb_ToReleaseList = NULL; ue_context_pP->ue_context.handover_info->as_config.sourceRadioResourceConfig.mac_MainConfig = CALLOC(1, sizeof(*ue_context_pP->ue_context.handover_info->as_config.sourceRadioResourceConfig.mac_MainConfig)); memcpy((void*)ue_context_pP->ue_context.handover_info->as_config.sourceRadioResourceConfig.mac_MainConfig, - (void *)mac_MainConfig, sizeof(MAC_MainConfig_t)); + (void *)mac_MainConfig, sizeof(LTE_MAC_MainConfig_t)); ue_context_pP->ue_context.handover_info->as_config.sourceRadioResourceConfig.physicalConfigDedicated = - CALLOC(1, sizeof(PhysicalConfigDedicated_t)); + CALLOC(1, sizeof(LTE_PhysicalConfigDedicated_t)); memcpy((void*)ue_context_pP->ue_context.handover_info->as_config.sourceRadioResourceConfig.physicalConfigDedicated, - (void*)ue_context_pP->ue_context.physicalConfigDedicated, sizeof(PhysicalConfigDedicated_t)); + (void*)ue_context_pP->ue_context.physicalConfigDedicated, sizeof(LTE_PhysicalConfigDedicated_t)); ue_context_pP->ue_context.handover_info->as_config.sourceRadioResourceConfig.sps_Config = NULL; //memcpy((void *)rrc_inst->handover_info[ue_mod_idP]->as_config.sourceRadioResourceConfig.sps_Config,(void *)rrc_inst->sps_Config[ue_mod_idP],sizeof(SPS_Config_t)); @@ -3330,12 +3329,12 @@ rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt_t* cons #if defined(ENABLE_ITTI) /* Initialize NAS list */ - dedicatedInfoNASList = CALLOC(1, sizeof(struct RRCConnectionReconfiguration_r8_IEs__dedicatedInfoNASList)); + dedicatedInfoNASList = CALLOC(1, sizeof(struct LTE_RRCConnectionReconfiguration_r8_IEs__dedicatedInfoNASList)); /* Add all NAS PDUs to the list */ for (i = 0; i < ue_context_pP->ue_context.nb_of_e_rabs; i++) { if (ue_context_pP->ue_context.e_rab[i].param.nas_pdu.buffer != NULL) { - dedicatedInfoNas = CALLOC(1, sizeof(DedicatedInfoNAS_t)); + dedicatedInfoNas = CALLOC(1, sizeof(LTE_DedicatedInfoNAS_t)); memset(dedicatedInfoNas, 0, sizeof(OCTET_STRING_t)); OCTET_STRING_fromBuf(dedicatedInfoNas, (char*)ue_context_pP->ue_context.e_rab[i].param.nas_pdu.buffer, @@ -3369,30 +3368,30 @@ rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt_t* cons size = do_RRCConnectionReconfiguration(ctxt_pP, buffer, xid, //Transaction_id, - (SRB_ToAddModList_t*)*SRB_configList2, // SRB_configList - (DRB_ToAddModList_t*)*DRB_configList, - (DRB_ToReleaseList_t*)NULL, // DRB2_list, - (struct SPS_Config*)NULL, // *sps_Config, - (struct PhysicalConfigDedicated*)*physicalConfigDedicated, + (LTE_SRB_ToAddModList_t*)*SRB_configList2, // SRB_configList + (LTE_DRB_ToAddModList_t*)*DRB_configList, + (LTE_DRB_ToReleaseList_t*)NULL, // DRB2_list, + (struct LTE_SPS_Config*)NULL, // *sps_Config, + (struct LTE_PhysicalConfigDedicated*)*physicalConfigDedicated, #ifdef EXMIMO_IOT NULL, NULL, NULL,NULL, #else - (MeasObjectToAddModList_t*)MeasObj_list, - (ReportConfigToAddModList_t*)ReportConfig_list, - (QuantityConfig_t*)quantityConfig, - (MeasIdToAddModList_t*)MeasId_list, + (LTE_MeasObjectToAddModList_t*)MeasObj_list, + (LTE_ReportConfigToAddModList_t*)ReportConfig_list, + (LTE_QuantityConfig_t*)quantityConfig, + (LTE_MeasIdToAddModList_t*)MeasId_list, #endif - (MAC_MainConfig_t*)mac_MainConfig, - (MeasGapConfig_t*)NULL, - (MobilityControlInfo_t*)NULL, - (struct MeasConfig__speedStatePars*)Sparams, - (RSRP_Range_t*)rsrp, - (C_RNTI_t*)cba_RNTI, - (struct RRCConnectionReconfiguration_r8_IEs__dedicatedInfoNASList*)dedicatedInfoNASList, - (SL_CommConfig_r12_t*)NULL, - (SL_DiscConfig_r12_t*)NULL -#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) - , (SCellToAddMod_r10_t*)NULL + (LTE_MAC_MainConfig_t*)mac_MainConfig, + (LTE_MeasGapConfig_t*)NULL, + (LTE_MobilityControlInfo_t*)NULL, + (struct LTE_MeasConfig__speedStatePars*)Sparams, + (LTE_RSRP_Range_t*)rsrp, + (LTE_C_RNTI_t*)cba_RNTI, + (struct LTE_RRCConnectionReconfiguration_r8_IEs__dedicatedInfoNASList*)dedicatedInfoNASList, + (LTE_SL_CommConfig_r12_t*)NULL, + (LTE_SL_DiscConfig_r12_t*)NULL +#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) + , (LTE_SCellToAddMod_r10_t*)NULL #endif ); LOG_DUMPMSG(RRC,DEBUG_RRC,(char *)buffer,size, @@ -3412,7 +3411,7 @@ rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt_t* cons #endif LOG_I(RRC, - "[eNB %d] Frame %d, Logical Channel DL-DCCH, Generate RRCConnectionReconfiguration (bytes %d, UE id %x)\n", + "[eNB %d] Frame %d, Logical Channel DL-DCCH, Generate LTE_RRCConnectionReconfiguration (bytes %d, UE id %x)\n", ctxt_pP->module_id, ctxt_pP->frame, size, ue_context_pP->ue_context.rnti); LOG_D(RRC, @@ -3424,7 +3423,7 @@ rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt_t* cons MSC_RRC_UE, buffer, size, - MSC_AS_TIME_FMT" rrcConnectionReconfiguration UE %x MUI %d size %u", + MSC_AS_TIME_FMT" LTE_RRCConnectionReconfiguration UE %x MUI %d size %u", MSC_AS_TIME_ARGS(ctxt_pP), ue_context_pP->ue_context.rnti, rrc_eNB_mui, @@ -3453,37 +3452,37 @@ flexran_rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt uint16_t size; int i; - // configure SRB1/SRB2, PhysicalConfigDedicated, MAC_MainConfig for UE + // configure SRB1/SRB2, PhysicalConfigDedicated, LTE_MAC_MainConfig for UE eNB_RRC_INST* rrc_inst = RC.rrc[ctxt_pP->module_id]; - struct PhysicalConfigDedicated** physicalConfigDedicated = &ue_context_pP->ue_context.physicalConfigDedicated; + struct LTE_PhysicalConfigDedicated** physicalConfigDedicated = &ue_context_pP->ue_context.physicalConfigDedicated; - struct SRB_ToAddMod *SRB2_config = NULL; - struct SRB_ToAddMod__rlc_Config *SRB2_rlc_config = NULL; - struct SRB_ToAddMod__logicalChannelConfig *SRB2_lchan_config = NULL; - struct LogicalChannelConfig__ul_SpecificParameters + struct LTE_SRB_ToAddMod *SRB2_config = NULL; + struct LTE_SRB_ToAddMod__rlc_Config *SRB2_rlc_config = NULL; + struct LTE_SRB_ToAddMod__logicalChannelConfig *SRB2_lchan_config = NULL; + struct LTE_LogicalChannelConfig__ul_SpecificParameters *SRB2_ul_SpecificParameters = NULL; - SRB_ToAddModList_t* SRB_configList = ue_context_pP->ue_context.SRB_configList; - SRB_ToAddModList_t **SRB_configList2 = NULL; + LTE_SRB_ToAddModList_t* SRB_configList = ue_context_pP->ue_context.SRB_configList; + LTE_SRB_ToAddModList_t **SRB_configList2 = NULL; - struct DRB_ToAddMod *DRB_config = NULL; - struct RLC_Config *DRB_rlc_config = NULL; - struct PDCP_Config *DRB_pdcp_config = NULL; - struct PDCP_Config__rlc_AM *PDCP_rlc_AM = NULL; - struct PDCP_Config__rlc_UM *PDCP_rlc_UM = NULL; - struct LogicalChannelConfig *DRB_lchan_config = NULL; - struct LogicalChannelConfig__ul_SpecificParameters + struct LTE_DRB_ToAddMod *DRB_config = NULL; + struct LTE_RLC_Config *DRB_rlc_config = NULL; + struct LTE_PDCP_Config *DRB_pdcp_config = NULL; + struct LTE_PDCP_Config__rlc_AM *PDCP_rlc_AM = NULL; + struct LTE_PDCP_Config__rlc_UM *PDCP_rlc_UM = NULL; + struct LTE_LogicalChannelConfig *DRB_lchan_config = NULL; + struct LTE_LogicalChannelConfig__ul_SpecificParameters *DRB_ul_SpecificParameters = NULL; - DRB_ToAddModList_t** DRB_configList = &ue_context_pP->ue_context.DRB_configList; - DRB_ToAddModList_t** DRB_configList2 = NULL; - MAC_MainConfig_t *mac_MainConfig = NULL; - MeasObjectToAddModList_t *MeasObj_list = NULL; - MeasObjectToAddMod_t *MeasObj = NULL; - ReportConfigToAddModList_t *ReportConfig_list = NULL; - ReportConfigToAddMod_t *ReportConfig_per;//, *ReportConfig_A1, + LTE_DRB_ToAddModList_t** DRB_configList = &ue_context_pP->ue_context.DRB_configList; + LTE_DRB_ToAddModList_t** DRB_configList2 = NULL; + LTE_MAC_MainConfig_t *mac_MainConfig = NULL; + LTE_MeasObjectToAddModList_t *MeasObj_list = NULL; + LTE_MeasObjectToAddMod_t *MeasObj = NULL; + LTE_ReportConfigToAddModList_t *ReportConfig_list = NULL; + LTE_ReportConfigToAddMod_t *ReportConfig_per;//, *ReportConfig_A1, // *ReportConfig_A2, *ReportConfig_A3, *ReportConfig_A4, *ReportConfig_A5; - MeasIdToAddModList_t *MeasId_list = NULL; - MeasIdToAddMod_t *MeasId0; //, *MeasId1, *MeasId2, *MeasId3, *MeasId4, *MeasId5; -#if Rel10 + LTE_MeasIdToAddModList_t *MeasId_list = NULL; + LTE_MeasIdToAddMod_t *MeasId0; //, *MeasId1, *MeasId2, *MeasId3, *MeasId4, *MeasId5; +#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) long *sr_ProhibitTimer_r9 = NULL; // uint8_t sCellIndexToAdd = rrc_find_free_SCell_index(enb_mod_idP, ue_mod_idP, 1); //uint8_t sCellIndexToAdd = 0; @@ -3492,24 +3491,24 @@ flexran_rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt long *logicalchannelgroup, *logicalchannelgroup_drb; long *maxHARQ_Tx, *periodicBSR_Timer; - RSRP_Range_t *rsrp = NULL; - struct MeasConfig__speedStatePars *Sparams = NULL; - QuantityConfig_t *quantityConfig = NULL; - CellsToAddMod_t *CellToAdd = NULL; - CellsToAddModList_t *CellsToAddModList = NULL; - struct RRCConnectionReconfiguration_r8_IEs__dedicatedInfoNASList *dedicatedInfoNASList = NULL; - DedicatedInfoNAS_t *dedicatedInfoNas = NULL; + LTE_RSRP_Range_t *rsrp = NULL; + struct LTE_MeasConfig__speedStatePars *Sparams = NULL; + LTE_QuantityConfig_t *quantityConfig = NULL; + LTE_CellsToAddMod_t *CellToAdd = NULL; + LTE_CellsToAddModList_t *CellsToAddModList = NULL; + struct LTE_RRCConnectionReconfiguration_r8_IEs__dedicatedInfoNASList *dedicatedInfoNASList = NULL; + LTE_DedicatedInfoNAS_t *dedicatedInfoNas = NULL; /* for no gcc warnings */ (void)dedicatedInfoNas; - C_RNTI_t *cba_RNTI = NULL; + LTE_C_RNTI_t *cba_RNTI = NULL; uint8_t xid = rrc_eNB_get_next_transaction_identifier(ctxt_pP->module_id); //Transaction_id, #ifdef CBA //struct PUSCH_CBAConfigDedicated_vlola *pusch_CBAConfigDedicated_vlola; uint8_t *cba_RNTI_buf; - cba_RNTI = CALLOC(1, sizeof(C_RNTI_t)); + cba_RNTI = CALLOC(1, sizeof(LTE_C_RNTI_t)); cba_RNTI_buf = CALLOC(1, 2 * sizeof(uint8_t)); cba_RNTI->buf = cba_RNTI_buf; cba_RNTI->size = 2; @@ -3549,27 +3548,27 @@ flexran_rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt 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_ms35; - SRB2_rlc_config->choice.explicitValue.choice.am.dl_AM_RLC.t_StatusProhibit = T_StatusProhibit_ms10; + SRB2_rlc_config->present = LTE_SRB_ToAddMod__rlc_Config_PR_explicitValue; + SRB2_rlc_config->choice.explicitValue.present = LTE_RLC_Config_PR_am; + SRB2_rlc_config->choice.explicitValue.choice.am.ul_AM_RLC.t_PollRetransmit = LTE_T_PollRetransmit_ms15; + SRB2_rlc_config->choice.explicitValue.choice.am.ul_AM_RLC.pollPDU = LTE_PollPDU_p8; + SRB2_rlc_config->choice.explicitValue.choice.am.ul_AM_RLC.pollByte = LTE_PollByte_kB1000; + SRB2_rlc_config->choice.explicitValue.choice.am.ul_AM_RLC.maxRetxThreshold = LTE_UL_AM_RLC__maxRetxThreshold_t32; + SRB2_rlc_config->choice.explicitValue.choice.am.dl_AM_RLC.t_Reordering = LTE_T_Reordering_ms35; + SRB2_rlc_config->choice.explicitValue.choice.am.dl_AM_RLC.t_StatusProhibit = LTE_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 = LTE_SRB_ToAddMod__logicalChannelConfig_PR_explicitValue; SRB2_ul_SpecificParameters = CALLOC(1, sizeof(*SRB2_ul_SpecificParameters)); SRB2_ul_SpecificParameters->priority = 3; // let some priority for SRB1 and dedicated DRBs SRB2_ul_SpecificParameters->prioritisedBitRate = - LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_infinity; + LTE_LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_infinity; SRB2_ul_SpecificParameters->bucketSizeDuration = - LogicalChannelConfig__ul_SpecificParameters__bucketSizeDuration_ms50; + LTE_LogicalChannelConfig__ul_SpecificParameters__bucketSizeDuration_ms50; // LCG for CCCH and DCCH is 0 as defined in 36331 logicalchannelgroup = CALLOC(1, sizeof(long)); @@ -3606,37 +3605,37 @@ flexran_rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt DRB_config->eps_BearerIdentity = CALLOC(1, sizeof(long)); *(DRB_config->eps_BearerIdentity) = 5L; // LW set to first value, allowed value 5..15, value : x+4 - // DRB_config->drb_Identity = (DRB_Identity_t) 1; //allowed values 1..32 + // DRB_config->drb_Identity = (LTE_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_mod_idP+1); //allowed values 1..32, value: x + DRB_config->drb_Identity = (LTE_DRB_Identity_t) 1; // (ue_mod_idP+1); //allowed values 1..32, value: x DRB_config->logicalChannelIdentity = CALLOC(1, sizeof(long)); *(DRB_config->logicalChannelIdentity) = (long)3; // value : x+2 DRB_rlc_config = CALLOC(1, sizeof(*DRB_rlc_config)); DRB_config->rlc_Config = DRB_rlc_config; #ifdef RRC_DEFAULT_RAB_IS_AM - DRB_rlc_config->present = RLC_Config_PR_am; - DRB_rlc_config->choice.am.ul_AM_RLC.t_PollRetransmit = T_PollRetransmit_ms50; - DRB_rlc_config->choice.am.ul_AM_RLC.pollPDU = PollPDU_p16; - DRB_rlc_config->choice.am.ul_AM_RLC.pollByte = PollByte_kBinfinity; - DRB_rlc_config->choice.am.ul_AM_RLC.maxRetxThreshold = UL_AM_RLC__maxRetxThreshold_t8; - DRB_rlc_config->choice.am.dl_AM_RLC.t_Reordering = T_Reordering_ms35; - DRB_rlc_config->choice.am.dl_AM_RLC.t_StatusProhibit = T_StatusProhibit_ms25; + DRB_rlc_config->present = LTE_RLC_Config_PR_am; + DRB_rlc_config->choice.am.ul_AM_RLC.t_PollRetransmit = LTE_T_PollRetransmit_ms50; + DRB_rlc_config->choice.am.ul_AM_RLC.pollPDU = LTE_PollPDU_p16; + DRB_rlc_config->choice.am.ul_AM_RLC.pollByte = LTE_PollByte_kBinfinity; + DRB_rlc_config->choice.am.ul_AM_RLC.maxRetxThreshold = LTE_UL_AM_RLC__maxRetxThreshold_t8; + DRB_rlc_config->choice.am.dl_AM_RLC.t_Reordering = LTE_T_Reordering_ms35; + DRB_rlc_config->choice.am.dl_AM_RLC.t_StatusProhibit = LTE_T_StatusProhibit_ms25; #else - 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->present = LTE_RLC_Config_PR_um_Bi_Directional; + DRB_rlc_config->choice.um_Bi_Directional.ul_UM_RLC.sn_FieldLength = LTE_SN_FieldLength_size10; + DRB_rlc_config->choice.um_Bi_Directional.dl_UM_RLC.sn_FieldLength = LTE_SN_FieldLength_size10; #ifdef CBA - DRB_rlc_config->choice.um_Bi_Directional.dl_UM_RLC.t_Reordering = T_Reordering_ms5;//T_Reordering_ms25; + DRB_rlc_config->choice.um_Bi_Directional.dl_UM_RLC.t_Reordering = LTE_T_Reordering_ms5;//T_Reordering_ms25; #else - DRB_rlc_config->choice.um_Bi_Directional.dl_UM_RLC.t_Reordering = T_Reordering_ms35; + DRB_rlc_config->choice.um_Bi_Directional.dl_UM_RLC.t_Reordering = LTE_T_Reordering_ms35; #endif #endif DRB_pdcp_config = CALLOC(1, sizeof(*DRB_pdcp_config)); DRB_config->pdcp_Config = DRB_pdcp_config; DRB_pdcp_config->discardTimer = CALLOC(1, sizeof(long)); - *DRB_pdcp_config->discardTimer = PDCP_Config__discardTimer_infinity; + *DRB_pdcp_config->discardTimer = LTE_PDCP_Config__discardTimer_infinity; DRB_pdcp_config->rlc_AM = NULL; DRB_pdcp_config->rlc_UM = NULL; @@ -3651,9 +3650,9 @@ flexran_rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt #else 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; + PDCP_rlc_UM->pdcp_SN_Size = LTE_PDCP_Config__rlc_UM__pdcp_SN_Size_len12bits; #endif - DRB_pdcp_config->headerCompression.present = PDCP_Config__headerCompression_PR_notUsed; + DRB_pdcp_config->headerCompression.present = LTE_PDCP_Config__headerCompression_PR_notUsed; DRB_lchan_config = CALLOC(1, sizeof(*DRB_lchan_config)); DRB_config->logicalChannelConfig = DRB_lchan_config; @@ -3661,10 +3660,10 @@ flexran_rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt DRB_lchan_config->ul_SpecificParameters = DRB_ul_SpecificParameters; DRB_ul_SpecificParameters->priority = 12; // lower priority than srb1, srb2 and other dedicated bearer - DRB_ul_SpecificParameters->prioritisedBitRate =LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_kBps8 ; + DRB_ul_SpecificParameters->prioritisedBitRate = LTE_LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_kBps8 ; //LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_infinity; DRB_ul_SpecificParameters->bucketSizeDuration = - LogicalChannelConfig__ul_SpecificParameters__bucketSizeDuration_ms50; + LTE_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)); @@ -3677,36 +3676,36 @@ flexran_rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt //ue_context_pP->ue_context.DRB_configList2[0] = &(*DRB_configList); mac_MainConfig = CALLOC(1, sizeof(*mac_MainConfig)); - // ue_context_pP->ue_context.mac_MainConfig = mac_MainConfig; + // ue_context_pP->ue_context.mac_MainConfig = LTE_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; + *maxHARQ_Tx = LTE_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 = PeriodicBSR_Timer_r12_sf64; + *periodicBSR_Timer = LTE_PeriodicBSR_Timer_r12_sf64; mac_MainConfig->ul_SCH_Config->periodicBSR_Timer = periodicBSR_Timer; - mac_MainConfig->ul_SCH_Config->retxBSR_Timer = RetxBSR_Timer_r12_sf320; + mac_MainConfig->ul_SCH_Config->retxBSR_Timer = LTE_RetxBSR_Timer_r12_sf320; mac_MainConfig->ul_SCH_Config->ttiBundling = 0; // FALSE - mac_MainConfig->timeAlignmentTimerDedicated = TimeAlignmentTimer_infinity; + mac_MainConfig->timeAlignmentTimerDedicated = LTE_TimeAlignmentTimer_infinity; 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->present = LTE_MAC_MainConfig__phr_Config_PR_setup; + mac_MainConfig->phr_Config->choice.setup.periodicPHR_Timer = LTE_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.prohibitPHR_Timer = LTE_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 + mac_MainConfig->phr_Config->choice.setup.dl_PathlossChange = LTE_MAC_MainConfig__phr_Config__setup__dl_PathlossChange_dB1; // Value dB1 =1 dB, dB3 = 3 dB -#ifdef Rel10 +#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) 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->ext1 = CALLOC(1, sizeof(struct MAC_MainConfig__ext1)); + mac_MainConfig->ext1 = CALLOC(1, sizeof(struct LTE_MAC_MainConfig__ext1)); mac_MainConfig->ext1->sr_ProhibitTimer_r9 = sr_ProhibitTimer_r9; //sps_RA_ConfigList_rlola = NULL; #endif @@ -3718,42 +3717,42 @@ flexran_rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt if ((*physicalConfigDedicated)->antennaInfo) { (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.transmissionMode = rrc_inst->configuration.ue_TransmissionMode[0]; LOG_D(RRC,"Setting transmission mode to %ld+1\n",rrc_inst->configuration.ue_TransmissionMode[0]); - if (rrc_inst->configuration.ue_TransmissionMode[0]==AntennaInfoDedicated__transmissionMode_tm3) { + if (rrc_inst->configuration.ue_TransmissionMode[0] == LTE_AntennaInfoDedicated__transmissionMode_tm3) { (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction= - CALLOC(1,sizeof(AntennaInfoDedicated__codebookSubsetRestriction_PR)); + CALLOC(1,sizeof(LTE_AntennaInfoDedicated__codebookSubsetRestriction_PR)); (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->present = - AntennaInfoDedicated__codebookSubsetRestriction_PR_n2TxAntenna_tm3; + LTE_AntennaInfoDedicated__codebookSubsetRestriction_PR_n2TxAntenna_tm3; (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm3.buf= MALLOC(1); (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm3.buf[0] = 0xc0; (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm3.size=1; (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm3.bits_unused=6; } - else if (rrc_inst->configuration.ue_TransmissionMode[0]==AntennaInfoDedicated__transmissionMode_tm4) { + else if (rrc_inst->configuration.ue_TransmissionMode[0] == LTE_AntennaInfoDedicated__transmissionMode_tm4) { (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction= - CALLOC(1,sizeof(AntennaInfoDedicated__codebookSubsetRestriction_PR)); + CALLOC(1,sizeof(LTE_AntennaInfoDedicated__codebookSubsetRestriction_PR)); (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->present = - AntennaInfoDedicated__codebookSubsetRestriction_PR_n2TxAntenna_tm4; + LTE_AntennaInfoDedicated__codebookSubsetRestriction_PR_n2TxAntenna_tm4; (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm4.buf= MALLOC(1); (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm4.buf[0] = 0xfc; (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm4.size=1; (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm4.bits_unused=2; } - else if (rrc_inst->configuration.ue_TransmissionMode[0]==AntennaInfoDedicated__transmissionMode_tm5) { + else if (rrc_inst->configuration.ue_TransmissionMode[0] == LTE_AntennaInfoDedicated__transmissionMode_tm5) { (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction= - CALLOC(1,sizeof(AntennaInfoDedicated__codebookSubsetRestriction_PR)); + CALLOC(1,sizeof(LTE_AntennaInfoDedicated__codebookSubsetRestriction_PR)); (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->present = - AntennaInfoDedicated__codebookSubsetRestriction_PR_n2TxAntenna_tm5; + LTE_AntennaInfoDedicated__codebookSubsetRestriction_PR_n2TxAntenna_tm5; (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm5.buf= MALLOC(1); (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm5.buf[0] = 0xf0; (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm5.size=1; (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm5.bits_unused=4; } - else if (rrc_inst->configuration.ue_TransmissionMode[0]==AntennaInfoDedicated__transmissionMode_tm6) { + else if (rrc_inst->configuration.ue_TransmissionMode[0] == LTE_AntennaInfoDedicated__transmissionMode_tm6) { (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction= - CALLOC(1,sizeof(AntennaInfoDedicated__codebookSubsetRestriction_PR)); + CALLOC(1,sizeof(LTE_AntennaInfoDedicated__codebookSubsetRestriction_PR)); (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->present = - AntennaInfoDedicated__codebookSubsetRestriction_PR_n2TxAntenna_tm6; + LTE_AntennaInfoDedicated__codebookSubsetRestriction_PR_n2TxAntenna_tm6; (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm6.buf= MALLOC(1); (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm6.buf[0] = 0xf0; (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm6.size=1; @@ -3764,16 +3763,16 @@ flexran_rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt LOG_E(RRC,"antenna_info not present in physical_config_dedicated. Not reconfiguring!\n"); } if ((*physicalConfigDedicated)->cqi_ReportConfig) { - if ((rrc_inst->configuration.ue_TransmissionMode[0]==AntennaInfoDedicated__transmissionMode_tm4) || - (rrc_inst->configuration.ue_TransmissionMode[0]==AntennaInfoDedicated__transmissionMode_tm5) || - (rrc_inst->configuration.ue_TransmissionMode[0]==AntennaInfoDedicated__transmissionMode_tm6)) { + if ((rrc_inst->configuration.ue_TransmissionMode[0] == LTE_AntennaInfoDedicated__transmissionMode_tm4) || + (rrc_inst->configuration.ue_TransmissionMode[0] == LTE_AntennaInfoDedicated__transmissionMode_tm5) || + (rrc_inst->configuration.ue_TransmissionMode[0] == LTE_AntennaInfoDedicated__transmissionMode_tm6)) { //feedback mode needs to be set as well //TODO: I think this is taken into account in the PHY automatically based on the transmission mode variable printf("setting cqi reporting mode to rm31\n"); -#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) - *((*physicalConfigDedicated)->cqi_ReportConfig->cqi_ReportModeAperiodic)=CQI_ReportModeAperiodic_rm31; +#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) + *((*physicalConfigDedicated)->cqi_ReportConfig->cqi_ReportModeAperiodic)=LTE_CQI_ReportModeAperiodic_rm31; #else - *((*physicalConfigDedicated)->cqi_ReportConfig->cqi_ReportModeAperiodic)=CQI_ReportConfig__cqi_ReportModeAperiodic_rm31; // HLC CQI, no PMI + *((*physicalConfigDedicated)->cqi_ReportConfig->cqi_ReportModeAperiodic)=LTE_CQI_ReportConfig__cqi_ReportModeAperiodic_rm31; // HLC CQI, no PMI #endif } } @@ -3782,7 +3781,7 @@ flexran_rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt } } else { - LOG_E(RRC,"physical_config_dedicated not present in RRCConnectionReconfiguration. Not reconfiguring!\n"); + LOG_E(RRC,"physical_config_dedicated not present in LTE_RRCConnectionReconfiguration. Not reconfiguring!\n"); } // Measurement ID list @@ -3808,10 +3807,10 @@ flexran_rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt memset((void *)MeasObj, 0, sizeof(*MeasObj)); MeasObj->measObjectId = 1; - MeasObj->measObject.present = MeasObjectToAddMod__measObject_PR_measObjectEUTRA; + MeasObj->measObject.present = LTE_MeasObjectToAddMod__measObject_PR_measObjectEUTRA; MeasObj->measObject.choice.measObjectEUTRA.carrierFreq = 3350; //band 7, 2.68GHz //MeasObj->measObject.choice.measObjectEUTRA.carrierFreq = 36090; //band 33, 1.909GHz - MeasObj->measObject.choice.measObjectEUTRA.allowedMeasBandwidth = AllowedMeasBandwidth_mbw25; + MeasObj->measObject.choice.measObjectEUTRA.allowedMeasBandwidth = LTE_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; @@ -3820,22 +3819,22 @@ flexran_rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt MeasObj->measObject.choice.measObjectEUTRA.offsetFreq = NULL; // Default is 15 or 0dB MeasObj->measObject.choice.measObjectEUTRA.cellsToAddModList = - (CellsToAddModList_t *) CALLOC(1, sizeof(*CellsToAddModList)); + (LTE_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 = (LTE_CellsToAddMod_t *) CALLOC(1, sizeof(*CellToAdd)); CellToAdd->cellIndex = i + 1; CellToAdd->physCellId = get_adjacent_cell_id(ctxt_pP->module_id, i); - CellToAdd->cellIndividualOffset = Q_OffsetRange_dB0; + CellToAdd->cellIndividualOffset = LTE_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; + // LTE_RRCConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.measConfig->measObjectToAddModList = MeasObj_list; // Report Configurations for periodical, A1-A5 events @@ -3877,17 +3876,17 @@ flexran_rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt // Periodical Measurement Report ReportConfig_per->reportConfigId = 1; - ReportConfig_per->reportConfig.present = ReportConfigToAddMod__reportConfig_PR_reportConfigEUTRA; + ReportConfig_per->reportConfig.present = LTE_ReportConfigToAddMod__reportConfig_PR_reportConfigEUTRA; ReportConfig_per->reportConfig.choice.reportConfigEUTRA.triggerType.present = - ReportConfigEUTRA__triggerType_PR_periodical; + LTE_ReportConfigEUTRA__triggerType_PR_periodical; ReportConfig_per->reportConfig.choice.reportConfigEUTRA.triggerType.choice.periodical.purpose = - ReportConfigEUTRA__triggerType__periodical__purpose_reportStrongestCells; + LTE_ReportConfigEUTRA__triggerType__periodical__purpose_reportStrongestCells; // ReportConfig_per->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.timeToTrigger = TimeToTrigger_ms40; - ReportConfig_per->reportConfig.choice.reportConfigEUTRA.triggerQuantity = ReportConfigEUTRA__triggerQuantity_rsrp; - ReportConfig_per->reportConfig.choice.reportConfigEUTRA.reportQuantity = ReportConfigEUTRA__reportQuantity_both; + ReportConfig_per->reportConfig.choice.reportConfigEUTRA.triggerQuantity = LTE_ReportConfigEUTRA__triggerQuantity_rsrp; + ReportConfig_per->reportConfig.choice.reportConfigEUTRA.reportQuantity = LTE_ReportConfigEUTRA__reportQuantity_both; ReportConfig_per->reportConfig.choice.reportConfigEUTRA.maxReportCells = 2; ReportConfig_per->reportConfig.choice.reportConfigEUTRA.reportInterval = trig_param->report_interval ;//ReportInterval_ms2048; // RRC counter frame- ms1024 is 1ms @@ -3900,7 +3899,7 @@ flexran_rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt quantityConfig = CALLOC(1, sizeof(*quantityConfig)); memset((void *)quantityConfig, 0, sizeof(*quantityConfig)); - quantityConfig->quantityConfigEUTRA = CALLOC(1, sizeof(struct QuantityConfigEUTRA)); + quantityConfig->quantityConfigEUTRA = CALLOC(1, sizeof(struct LTE_QuantityConfigEUTRA)); memset((void *)quantityConfig->quantityConfigEUTRA, 0, sizeof(*quantityConfig->quantityConfigEUTRA)); quantityConfig->quantityConfigCDMA2000 = NULL; quantityConfig->quantityConfigGERAN = NULL; @@ -3909,18 +3908,18 @@ flexran_rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt 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; + *quantityConfig->quantityConfigEUTRA->filterCoefficientRSRP = LTE_FilterCoefficient_fc4; + *quantityConfig->quantityConfigEUTRA->filterCoefficientRSRQ = LTE_FilterCoefficient_fc4; #if defined(ENABLE_ITTI) /* Initialize NAS list */ - dedicatedInfoNASList = CALLOC(1, sizeof(struct RRCConnectionReconfiguration_r8_IEs__dedicatedInfoNASList)); + dedicatedInfoNASList = CALLOC(1, sizeof(struct LTE_RRCConnectionReconfiguration_r8_IEs__dedicatedInfoNASList)); /* Add all NAS PDUs to the list */ for (i = 0; i < ue_context_pP->ue_context.nb_of_e_rabs; i++) { if (ue_context_pP->ue_context.e_rab[i].param.nas_pdu.buffer != NULL) { - dedicatedInfoNas = CALLOC(1, sizeof(DedicatedInfoNAS_t)); + dedicatedInfoNas = CALLOC(1, sizeof(LTE_DedicatedInfoNAS_t)); memset(dedicatedInfoNas, 0, sizeof(OCTET_STRING_t)); OCTET_STRING_fromBuf(dedicatedInfoNas, (char*)ue_context_pP->ue_context.e_rab[i].param.nas_pdu.buffer, @@ -3954,30 +3953,30 @@ flexran_rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt size = do_RRCConnectionReconfiguration(ctxt_pP, buffer, xid, //Transaction_id, - (SRB_ToAddModList_t*)NULL, // SRB_configList - (DRB_ToAddModList_t*)NULL, - (DRB_ToReleaseList_t*)NULL, // DRB2_list, - (struct SPS_Config*)NULL, // *sps_Config, - (struct PhysicalConfigDedicated*)*physicalConfigDedicated, + (LTE_SRB_ToAddModList_t*)NULL, // SRB_configList + (LTE_DRB_ToAddModList_t*)NULL, + (LTE_DRB_ToReleaseList_t*)NULL, // DRB2_list, + (struct LTE_SPS_Config*)NULL, // *sps_Config, + (struct LTE_PhysicalConfigDedicated*)*physicalConfigDedicated, // #ifdef EXMIMO_IOT // NULL, NULL, NULL,NULL, // #else - (MeasObjectToAddModList_t*)MeasObj_list, - (ReportConfigToAddModList_t*)ReportConfig_list, - (QuantityConfig_t*)quantityConfig, - (MeasIdToAddModList_t*)MeasId_list, + (LTE_MeasObjectToAddModList_t*)MeasObj_list, + (LTE_ReportConfigToAddModList_t*)ReportConfig_list, + (LTE_QuantityConfig_t*)quantityConfig, + (LTE_MeasIdToAddModList_t*)MeasId_list, // #endif - (MAC_MainConfig_t*)mac_MainConfig, - (MeasGapConfig_t*)NULL, - (MobilityControlInfo_t*)NULL, - (struct MeasConfig__speedStatePars*)Sparams, - (RSRP_Range_t*)rsrp, - (C_RNTI_t*)cba_RNTI, - (struct RRCConnectionReconfiguration_r8_IEs__dedicatedInfoNASList*)dedicatedInfoNASList, - (SL_CommConfig_r12_t*)NULL, - (SL_DiscConfig_r12_t*)NULL -#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) - , (SCellToAddMod_r10_t*)NULL + (LTE_MAC_MainConfig_t*)mac_MainConfig, + (LTE_MeasGapConfig_t*)NULL, + (LTE_MobilityControlInfo_t*)NULL, + (struct LTE_MeasConfig__speedStatePars*)Sparams, + (LTE_RSRP_Range_t*)rsrp, + (LTE_C_RNTI_t*)cba_RNTI, + (struct LTE_RRCConnectionReconfiguration_r8_IEs__dedicatedInfoNASList*)dedicatedInfoNASList, + (LTE_SL_CommConfig_r12_t*)NULL, + (LTE_SL_DiscConfig_r12_t*)NULL +#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) + , (LTE_SCellToAddMod_r10_t*)NULL #endif ); LOG_DUMPMSG(RRC,DEBUG_RRC,(char *)buffer,size, @@ -3997,7 +3996,7 @@ flexran_rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt #endif LOG_I(RRC, - "[eNB %d] Frame %d, Logical Channel DL-DCCH, Generate RRCConnectionReconfiguration (bytes %d, UE id %x)\n", + "[eNB %d] Frame %d, Logical Channel DL-DCCH, Generate LTE_RRCConnectionReconfiguration (bytes %d, UE id %x)\n", ctxt_pP->module_id, ctxt_pP->frame, size, ue_context_pP->ue_context.rnti); LOG_D(RRC, @@ -4009,7 +4008,7 @@ flexran_rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt MSC_RRC_UE, buffer, size, - MSC_AS_TIME_FMT" rrcConnectionReconfiguration UE %x MUI %d size %u", + MSC_AS_TIME_FMT" LTE_RRCConnectionReconfiguration UE %x MUI %d size %u", MSC_AS_TIME_ARGS(ctxt_pP), ue_context_pP->ue_context.rnti, rrc_eNB_mui, @@ -4039,7 +4038,7 @@ rrc_eNB_generate_RRCConnectionReconfiguration_SCell( uint8_t size; uint8_t buffer[100]; -#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) uint8_t sCellIndexToAdd = 0; //one SCell so far // uint8_t sCellIndexToAdd; @@ -4056,30 +4055,30 @@ rrc_eNB_generate_RRCConnectionReconfiguration_SCell( size = do_RRCConnectionReconfiguration(ctxt_pP, buffer, rrc_eNB_get_next_transaction_identifier(ctxt_pP->module_id),//Transaction_id, - (SRB_ToAddModList_t*)NULL, - (DRB_ToAddModList_t*)NULL, - (DRB_ToReleaseList_t*)NULL, - (struct SPS_Config*)NULL, - (struct PhysicalConfigDedicated*)NULL, - (MeasObjectToAddModList_t*)NULL, - (ReportConfigToAddModList_t*)NULL, - (QuantityConfig_t*)NULL, - (MeasIdToAddModList_t*)NULL, - (MAC_MainConfig_t*)NULL, - (MeasGapConfig_t*)NULL, - (MobilityControlInfo_t*)NULL, - (struct MeasConfig__speedStatePars*)NULL, - (RSRP_Range_t*)NULL, - (C_RNTI_t*)NULL, - (struct RRCConnectionReconfiguration_r8_IEs__dedicatedInfoNASList*)NULL, - (SL_CommConfig_r12_t*)NULL, - (SL_DiscConfig_r12_t*)NULL + (LTE_SRB_ToAddModList_t*)NULL, + (LTE_DRB_ToAddModList_t*)NULL, + (LTE_DRB_ToReleaseList_t*)NULL, + (struct LTE_SPS_Config*)NULL, + (struct LTE_PhysicalConfigDedicated*)NULL, + (LTE_MeasObjectToAddModList_t*)NULL, + (LTE_ReportConfigToAddModList_t*)NULL, + (LTE_QuantityConfig_t*)NULL, + (LTE_MeasIdToAddModList_t*)NULL, + (LTE_MAC_MainConfig_t*)NULL, + (LTE_MeasGapConfig_t*)NULL, + (LTE_MobilityControlInfo_t*)NULL, + (struct LTE_MeasConfig__speedStatePars*)NULL, + (LTE_RSRP_Range_t*)NULL, + (LTE_C_RNTI_t*)NULL, + (struct LTE_RRCConnectionReconfiguration_r8_IEs__dedicatedInfoNASList*)NULL, + (LTE_SL_CommConfig_r12_t*)NULL, + (LTE_SL_DiscConfig_r12_t*)NULL -#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) , ue_context_pP->ue_context.sCell_config #endif ); - LOG_I(RRC,"[eNB %d] Frame %d, Logical Channel DL-DCCH, Generate RRCConnectionReconfiguration (bytes %d, UE id %x)\n", + LOG_I(RRC,"[eNB %d] Frame %d, Logical Channel DL-DCCH, Generate LTE_RRCConnectionReconfiguration (bytes %d, UE id %x)\n", ctxt_pP->module_id,ctxt_pP->frame, size, ue_context_pP->ue_context.rnti); MSC_LOG_TX_MESSAGE( @@ -4087,7 +4086,7 @@ rrc_eNB_generate_RRCConnectionReconfiguration_SCell( MSC_RRC_UE, buffer, size, - MSC_AS_TIME_FMT" rrcConnectionReconfiguration UE %x MUI %d size %u", + MSC_AS_TIME_FMT" LTE_RRCConnectionReconfiguration UE %x MUI %d size %u", MSC_AS_TIME_ARGS(ctxt_pP), ue_context_pP->ue_context.rnti, rrc_eNB_mui, @@ -4110,7 +4109,7 @@ void rrc_eNB_process_MeasurementReport( const protocol_ctxt_t* const ctxt_pP, rrc_eNB_ue_context_t* ue_context_pP, - const MeasResults_t* const measResults2 + const LTE_MeasResults_t* const measResults2 ) //----------------------------------------------------------------------------- { @@ -4125,7 +4124,7 @@ rrc_eNB_process_MeasurementReport( if (measResults2->measId > 0 ){ if (ue_context_pP->ue_context.measResults == NULL) { - ue_context_pP->ue_context.measResults = CALLOC(1, sizeof(MeasResults_t)); + ue_context_pP->ue_context.measResults = CALLOC(1, sizeof(LTE_MeasResults_t)); } ue_context_pP->ue_context.measResults->measId=measResults2->measId; ue_context_pP->ue_context.measResults->measResultPCell.rsrpResult=measResults2->measResultPCell.rsrpResult; @@ -4147,7 +4146,7 @@ rrc_eNB_process_MeasurementReport( for (i=0; i < neighboring_cells; i++){ memcpy (ue_context_pP->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.array[i], measResults2->measResultNeighCells->choice.measResultListEUTRA.list.array[i], - sizeof(MeasResultListEUTRA_t)); + sizeof(LTE_MeasResultListEUTRA_t)); LOG_D(RRC, "Physical Cell Id %d\n", (int)ue_context_pP->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.array[i]->physCellId); @@ -4158,7 +4157,7 @@ rrc_eNB_process_MeasurementReport( } } -// #if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) +// #if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) // #else @@ -4197,7 +4196,7 @@ void rrc_eNB_generate_HandoverPreparationInformation( const protocol_ctxt_t* const ctxt_pP, rrc_eNB_ue_context_t* const ue_context_pP, - PhysCellId_t targetPhyId + LTE_PhysCellId_t targetPhyId ) //----------------------------------------------------------------------------- { @@ -4208,7 +4207,7 @@ rrc_eNB_generate_HandoverPreparationInformation( /* uint8_t buffer[100]; uint8_t size; - struct PhysicalConfigDedicated **physicalConfigDedicated = &RC.rrc[enb_mod_idP]->physicalConfigDedicated[ue_mod_idP]; + struct LTE_PhysicalConfigDedicated **physicalConfigDedicated = &RC.rrc[enb_mod_idP]->physicalConfigDedicated[ue_mod_idP]; RadioResourceConfigDedicated_t *radioResourceConfigDedicated = CALLOC(1,sizeof(RadioResourceConfigDedicated_t)); */ @@ -4219,9 +4218,9 @@ rrc_eNB_generate_HandoverPreparationInformation( handoverInfo->as_config.sourceDl_CarrierFreq = 36090; //Verify! memcpy((void *)&handoverInfo->as_config.sourceMasterInformationBlock, - (void*)&RC.rrc[ctxt_pP->module_id]->carrier[0] /* CROUX TBC */.mib, sizeof(MasterInformationBlock_t)); + (void*)&RC.rrc[ctxt_pP->module_id]->carrier[0] /* CROUX TBC */.mib, sizeof(LTE_MasterInformationBlock_t)); memcpy((void *)&handoverInfo->as_config.sourceMeasConfig, - (void*)ue_context_pP->ue_context.measConfig, sizeof(MeasConfig_t)); + (void*)ue_context_pP->ue_context.measConfig, sizeof(LTE_MeasConfig_t)); // FIXME handoverInfo not used... free( handoverInfo ); @@ -4229,14 +4228,14 @@ rrc_eNB_generate_HandoverPreparationInformation( //to be configured memset((void*)&ue_context_pP->ue_context.handover_info->as_config.sourceSecurityAlgorithmConfig, - 0, sizeof(SecurityAlgorithmConfig_t)); + 0, sizeof(LTE_SecurityAlgorithmConfig_t)); memcpy((void*)&ue_context_pP->ue_context.handover_info->as_config.sourceSystemInformationBlockType1, - (void*)&RC.rrc[ctxt_pP->module_id]->carrier[0] /* CROUX TBC */.SIB1, sizeof(SystemInformationBlockType1_t)); + (void*)&RC.rrc[ctxt_pP->module_id]->carrier[0] /* CROUX TBC */.SIB1, sizeof(LTE_SystemInformationBlockType1_t)); memcpy((void*)&ue_context_pP->ue_context.handover_info->as_config.sourceSystemInformationBlockType2, - (void*)&RC.rrc[ctxt_pP->module_id]->carrier[0] /* CROUX TBC */.SIB23, sizeof(SystemInformationBlockType2_t)); + (void*)&RC.rrc[ctxt_pP->module_id]->carrier[0] /* CROUX TBC */.SIB23, sizeof(LTE_SystemInformationBlockType2_t)); ue_context_pP->ue_context.handover_info->as_context.reestablishmentInfo = - CALLOC(1, sizeof(ReestablishmentInfo_t)); + CALLOC(1, sizeof(LTE_ReestablishmentInfo_t)); ue_context_pP->ue_context.handover_info->as_context.reestablishmentInfo->sourcePhysCellId = RC.rrc[ctxt_pP->module_id]->carrier[0] /* CROUX TBC */.physCellId; ue_context_pP->ue_context.handover_info->as_context.reestablishmentInfo->targetCellShortMAC_I.buf = NULL; // Check values later @@ -4275,10 +4274,10 @@ rrc_eNB_generate_HandoverPreparationInformation( CALLOC(1, sizeof(*(ue_context_target_p->ue_context.handover_info))); memcpy((void*)&ue_context_target_p->ue_context.handover_info->as_context, (void*)&ue_context_pP->ue_context.handover_info->as_context, - sizeof(AS_Context_t)); + sizeof(LTE_AS_Context_t)); memcpy((void*)&ue_context_target_p->ue_context.handover_info->as_config, (void*)&ue_context_pP->ue_context.handover_info->as_config, - sizeof(AS_Config_t)); + sizeof(LTE_AS_Config_t)); ue_context_target_p->ue_context.handover_info->ho_prepare = 0x00;// 0xFF; ue_context_target_p->ue_context.handover_info->ho_complete = 0; ue_context_pP->ue_context.handover_info->modid_t = mod_id_target; @@ -4310,7 +4309,7 @@ rrc_eNB_process_handoverPreparationInformation( LOG_I(RRC, - "[eNB %d] Frame %d : Logical Channel UL-DCCH, processing RRCHandoverPreparationInformation, sending RRCConnectionReconfiguration to UE %d \n", + "[eNB %d] Frame %d : Logical Channel UL-DCCH, processing RRCHandoverPreparationInformation, sending LTE_RRCConnectionReconfiguration to UE %d \n", ctxt_pP->module_id, ctxt_pP->frame, ue_context_pP->ue_context.rnti); rrc_eNB_generate_RRCConnectionReconfiguration_handover( ctxt_pP, @@ -4341,7 +4340,7 @@ check_handovers( ctxt_pP->rnti, ctxt_pP->module_id, ue_context_p->ue_context.handover_info->modid_t); - // source eNB generates rrcconnectionreconfiguration to prepare the HO + // source eNB generates LTE_RRCConnectionreconfiguration to prepare the HO rrc_eNB_process_handoverPreparationInformation( ctxt_pP, ue_context_p); @@ -4365,7 +4364,7 @@ check_handovers( ue_context_p->ue_context.handover_info->size, ue_context_p->ue_context.handover_info->buf, PDCP_TRANSMISSION_MODE_CONTROL -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) ,NULL, NULL #endif ); @@ -4381,7 +4380,7 @@ check_handovers( } } -// 5.3.5.4 RRCConnectionReconfiguration including the mobilityControlInfo to prepare the UE handover +// 5.3.5.4 LTE_RRCConnectionReconfiguration including the mobilityControlInfo to prepare the UE handover //----------------------------------------------------------------------------- void rrc_eNB_generate_RRCConnectionReconfiguration_handover( @@ -4400,58 +4399,58 @@ rrc_eNB_generate_RRCConnectionReconfiguration_handover( int i; uint8_t rv[2]; uint16_t Idx; - // configure SRB1/SRB2, PhysicalConfigDedicated, MAC_MainConfig for UE + // configure SRB1/SRB2, PhysicalConfigDedicated, LTE_MAC_MainConfig for UE eNB_RRC_INST* rrc_inst = RC.rrc[ctxt_pP->module_id]; - struct PhysicalConfigDedicated** physicalConfigDedicated = &ue_context_pP->ue_context.physicalConfigDedicated; + struct LTE_PhysicalConfigDedicated** physicalConfigDedicated = &ue_context_pP->ue_context.physicalConfigDedicated; - 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 = NULL; - SRB_ToAddModList_t* SRB_configList = ue_context_pP->ue_context.SRB_configList; // not used in this context: may be removed - SRB_ToAddModList_t *SRB_configList2; + struct LTE_SRB_ToAddMod *SRB2_config; + struct LTE_SRB_ToAddMod__rlc_Config *SRB2_rlc_config; + struct LTE_SRB_ToAddMod__logicalChannelConfig *SRB2_lchan_config; + struct LTE_LogicalChannelConfig__ul_SpecificParameters *SRB2_ul_SpecificParameters; + LTE_LogicalChannelConfig_t *SRB1_logicalChannelConfig = NULL; + LTE_SRB_ToAddModList_t* SRB_configList = ue_context_pP->ue_context.SRB_configList; // not used in this context: may be removed + LTE_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_configList2; + struct LTE_DRB_ToAddMod *DRB_config; + struct LTE_RLC_Config *DRB_rlc_config; + struct LTE_PDCP_Config *DRB_pdcp_config; + struct LTE_PDCP_Config__rlc_UM *PDCP_rlc_UM; + struct LTE_LogicalChannelConfig *DRB_lchan_config; + struct LTE_LogicalChannelConfig__ul_SpecificParameters *DRB_ul_SpecificParameters; + LTE_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; + LTE_MAC_MainConfig_t *mac_MainConfig; + LTE_MeasObjectToAddModList_t *MeasObj_list; + LTE_MeasObjectToAddMod_t *MeasObj; + LTE_ReportConfigToAddModList_t *ReportConfig_list; + LTE_ReportConfigToAddMod_t *ReportConfig_per, *ReportConfig_A1, + *ReportConfig_A2, *ReportConfig_A3, *ReportConfig_A4, *ReportConfig_A5; + LTE_MeasIdToAddModList_t *MeasId_list; + LTE_MeasIdToAddMod_t *MeasId0, *MeasId1, *MeasId2, *MeasId3, *MeasId4, *MeasId5; + LTE_QuantityConfig_t *quantityConfig; + LTE_MobilityControlInfo_t *mobilityInfo; // HandoverCommand_t handoverCommand; //uint8_t sourceModId = // get_adjacent_cell_mod_id(ue_context_pP->ue_context.handover_info->as_context.reestablishmentInfo->sourcePhysCellId); -#if (RRC_VERSION >= MAKE_VERSION(9, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) 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; + // LTE_RSRP_Range_t *rsrp; + struct LTE_MeasConfig__speedStatePars *Sparams; + LTE_CellsToAddMod_t *CellToAdd; + LTE_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; + struct LTE_SRB_ToAddMod *SRB1_config; + struct LTE_SRB_ToAddMod__rlc_Config *SRB1_rlc_config; + struct LTE_SRB_ToAddMod__logicalChannelConfig *SRB1_lchan_config; + struct LTE_LogicalChannelConfig__ul_SpecificParameters *SRB1_ul_SpecificParameters; // phy config dedicated - PhysicalConfigDedicated_t *physicalConfigDedicated2; - struct RRCConnectionReconfiguration_r8_IEs__dedicatedInfoNASList *dedicatedInfoNASList; + LTE_PhysicalConfigDedicated_t *physicalConfigDedicated2; + struct LTE_RRCConnectionReconfiguration_r8_IEs__dedicatedInfoNASList *dedicatedInfoNASList; protocol_ctxt_t ctxt; LOG_D(RRC, "[eNB %d] Frame %d: handover preparation: get the newSourceUEIdentity (C-RNTI): ", @@ -4471,19 +4470,19 @@ rrc_eNB_generate_RRCConnectionReconfiguration_handover( 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_ms35; - SRB1_rlc_config->choice.explicitValue.choice.am.dl_AM_RLC.t_StatusProhibit = T_StatusProhibit_ms10; + SRB1_rlc_config->present = LTE_SRB_ToAddMod__rlc_Config_PR_explicitValue; + SRB1_rlc_config->choice.explicitValue.present = LTE_RLC_Config_PR_am; + SRB1_rlc_config->choice.explicitValue.choice.am.ul_AM_RLC.t_PollRetransmit = LTE_T_PollRetransmit_ms15; + SRB1_rlc_config->choice.explicitValue.choice.am.ul_AM_RLC.pollPDU = LTE_PollPDU_p8; + SRB1_rlc_config->choice.explicitValue.choice.am.ul_AM_RLC.pollByte = LTE_PollByte_kB1000; + SRB1_rlc_config->choice.explicitValue.choice.am.ul_AM_RLC.maxRetxThreshold = LTE_UL_AM_RLC__maxRetxThreshold_t16; + SRB1_rlc_config->choice.explicitValue.choice.am.dl_AM_RLC.t_Reordering = LTE_T_Reordering_ms35; + SRB1_rlc_config->choice.explicitValue.choice.am.dl_AM_RLC.t_StatusProhibit = LTE_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_lchan_config->present = LTE_SRB_ToAddMod__logicalChannelConfig_PR_explicitValue; SRB1_ul_SpecificParameters = CALLOC(1, sizeof(*SRB1_ul_SpecificParameters)); SRB1_lchan_config->choice.explicitValue.ul_SpecificParameters = SRB1_ul_SpecificParameters; @@ -4492,11 +4491,11 @@ rrc_eNB_generate_RRCConnectionReconfiguration_handover( //assign_enum(&SRB1_ul_SpecificParameters->prioritisedBitRate,LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_infinity); SRB1_ul_SpecificParameters->prioritisedBitRate = - LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_infinity; + LTE_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; + LTE_LogicalChannelConfig__ul_SpecificParameters__bucketSizeDuration_ms50; logicalchannelgroup = CALLOC(1, sizeof(long)); *logicalchannelgroup = 0; @@ -4528,11 +4527,11 @@ rrc_eNB_generate_RRCConnectionReconfiguration_handover( // PDSCH //assign_enum(&physicalConfigDedicated2->pdsch_ConfigDedicated->p_a, // PDSCH_ConfigDedicated__p_a_dB0); - physicalConfigDedicated2->pdsch_ConfigDedicated->p_a = PDSCH_ConfigDedicated__p_a_dB0; + physicalConfigDedicated2->pdsch_ConfigDedicated->p_a = LTE_PDSCH_ConfigDedicated__p_a_dB0; // PUCCH physicalConfigDedicated2->pucch_ConfigDedicated->ackNackRepetition.present = - PUCCH_ConfigDedicated__ackNackRepetition_PR_release; + LTE_PUCCH_ConfigDedicated__ackNackRepetition_PR_release; physicalConfigDedicated2->pucch_ConfigDedicated->ackNackRepetition.choice.release = 0; physicalConfigDedicated2->pucch_ConfigDedicated->tdd_AckNackFeedbackMode = NULL; //PUCCH_ConfigDedicated__tdd_AckNackFeedbackMode_multiplexing; @@ -4546,18 +4545,18 @@ rrc_eNB_generate_RRCConnectionReconfiguration_handover( //assign_enum(&physicalConfigDedicated2->uplinkPowerControlDedicated->deltaMCS_Enabled, // UplinkPowerControlDedicated__deltaMCS_Enabled_en1); physicalConfigDedicated2->uplinkPowerControlDedicated->deltaMCS_Enabled = - UplinkPowerControlDedicated__deltaMCS_Enabled_en1; + LTE_UplinkPowerControlDedicated__deltaMCS_Enabled_en1; physicalConfigDedicated2->uplinkPowerControlDedicated->accumulationEnabled = 1; // should be TRUE in order to have 0dB power offset 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 + *physicalConfigDedicated2->uplinkPowerControlDedicated->filterCoefficient = LTE_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->present = LTE_TPC_PDCCH_Config_PR_setup; + physicalConfigDedicated2->tpc_PDCCH_ConfigPUCCH->choice.setup.tpc_Index.present = LTE_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; @@ -4565,8 +4564,8 @@ rrc_eNB_generate_RRCConnectionReconfiguration_handover( physicalConfigDedicated2->tpc_PDCCH_ConfigPUCCH->choice.setup.tpc_RNTI.buf[1] = 0x34 + ue_context_pP->local_uid; 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->present = LTE_TPC_PDCCH_Config_PR_setup; + physicalConfigDedicated2->tpc_PDCCH_ConfigPUSCH->choice.setup.tpc_Index.present = LTE_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; @@ -4608,34 +4607,34 @@ rrc_eNB_generate_RRCConnectionReconfiguration_handover( //AntennaInfoDedicated physicalConfigDedicated2->antennaInfo = CALLOC(1, sizeof(*physicalConfigDedicated2->antennaInfo)); - physicalConfigDedicated2->antennaInfo->present = PhysicalConfigDedicated__antennaInfo_PR_explicitValue; + physicalConfigDedicated2->antennaInfo->present = LTE_PhysicalConfigDedicated__antennaInfo_PR_explicitValue; //assign_enum(&physicalConfigDedicated2->antennaInfo->choice.explicitValue.transmissionMode, - // AntennaInfoDedicated__transmissionMode_tm2); + // LTE_AntennaInfoDedicated__transmissionMode_tm2); /* switch (transmission_mode){ case 1: - physicalConfigDedicated2->antennaInfo->choice.explicitValue.transmissionMode= AntennaInfoDedicated__transmissionMode_tm1; + physicalConfigDedicated2->antennaInfo->choice.explicitValue.transmissionMode= LTE_AntennaInfoDedicated__transmissionMode_tm1; break; case 2: - physicalConfigDedicated2->antennaInfo->choice.explicitValue.transmissionMode= AntennaInfoDedicated__transmissionMode_tm2; + physicalConfigDedicated2->antennaInfo->choice.explicitValue.transmissionMode= LTE_AntennaInfoDedicated__transmissionMode_tm2; break; case 4: - physicalConfigDedicated2->antennaInfo->choice.explicitValue.transmissionMode= AntennaInfoDedicated__transmissionMode_tm4; + physicalConfigDedicated2->antennaInfo->choice.explicitValue.transmissionMode= LTE_AntennaInfoDedicated__transmissionMode_tm4; break; case 5: - physicalConfigDedicated2->antennaInfo->choice.explicitValue.transmissionMode= AntennaInfoDedicated__transmissionMode_tm5; + physicalConfigDedicated2->antennaInfo->choice.explicitValue.transmissionMode= LTE_AntennaInfoDedicated__transmissionMode_tm5; break; case 6: - physicalConfigDedicated2->antennaInfo->choice.explicitValue.transmissionMode= AntennaInfoDedicated__transmissionMode_tm6; + physicalConfigDedicated2->antennaInfo->choice.explicitValue.transmissionMode= LTE_AntennaInfoDedicated__transmissionMode_tm6; break; } */ physicalConfigDedicated2->antennaInfo->choice.explicitValue.ue_TransmitAntennaSelection.present = - AntennaInfoDedicated__ue_TransmitAntennaSelection_PR_release; + LTE_AntennaInfoDedicated__ue_TransmitAntennaSelection_PR_release; physicalConfigDedicated2->antennaInfo->choice.explicitValue.ue_TransmitAntennaSelection.choice.release = 0; // SchedulingRequestConfig - physicalConfigDedicated2->schedulingRequestConfig->present = SchedulingRequestConfig_PR_setup; + physicalConfigDedicated2->schedulingRequestConfig->present = LTE_SchedulingRequestConfig_PR_setup; physicalConfigDedicated2->schedulingRequestConfig->choice.setup.sr_PUCCH_ResourceIndex = ue_context_pP->local_uid; if (rrc_inst->carrier[0].sib1->tdd_Config==NULL) { // FD @@ -4668,7 +4667,7 @@ rrc_eNB_generate_RRCConnectionReconfiguration_handover( //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; + LTE_SchedulingRequestConfig__setup__dsr_TransMax_n4; LOG_D(RRC, "handover_config [FRAME %05d][RRC_eNB][MOD %02d][][--- MAC_CONFIG_REQ (SRB1 UE %x) --->][MAC_eNB][MOD %02d][]\n", @@ -4677,38 +4676,38 @@ rrc_eNB_generate_RRCConnectionReconfiguration_handover( ctxt_pP->module_id, ue_context_pP->ue_context.primaryCC_id, 0,0,0,0,0, -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) 0, #endif ue_context_pP->ue_context.rnti, - (BCCH_BCH_Message_t *) NULL, - (RadioResourceConfigCommonSIB_t*) NULL, -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - (RadioResourceConfigCommonSIB_t*) NULL, + (LTE_BCCH_BCH_Message_t *) NULL, + (LTE_RadioResourceConfigCommonSIB_t*) NULL, +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + (LTE_RadioResourceConfigCommonSIB_t*) NULL, #endif ue_context_pP->ue_context.physicalConfigDedicated, -#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) - (SCellToAddMod_r10_t *)NULL, - //(struct PhysicalConfigDedicatedSCell_r10 *)NULL, +#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) + (LTE_SCellToAddMod_r10_t *)NULL, + //(struct LTE_PhysicalConfigDedicatedSCell_r10 *)NULL, #endif - (MeasObjectToAddMod_t **) NULL, + (LTE_MeasObjectToAddMod_t **) NULL, ue_context_pP->ue_context.mac_MainConfig, 1, SRB1_logicalChannelConfig, ue_context_pP->ue_context.measGapConfig, - (TDD_Config_t*) NULL, - (MobilityControlInfo_t*) NULL, - (SchedulingInfoList_t*) NULL, + (LTE_TDD_Config_t*) NULL, + (LTE_MobilityControlInfo_t*) NULL, + (LTE_SchedulingInfoList_t*) NULL, 0, NULL, NULL, - (MBSFN_SubframeConfigList_t *) NULL -#if (RRC_VERSION >= MAKE_VERSION(9, 0, 0)) - , 0, (MBSFN_AreaInfoList_r9_t *) NULL, (PMCH_InfoList_r9_t *) NULL + (LTE_MBSFN_SubframeConfigList_t *) NULL +#if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) + , 0, (LTE_MBSFN_AreaInfoList_r9_t *) NULL, (LTE_PMCH_InfoList_r9_t *) NULL #endif -#if (RRC_VERSION >= MAKE_VERSION(13, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(13, 0, 0)) , - (SystemInformationBlockType1_v1310_IEs_t *)NULL + (LTE_SystemInformationBlockType1_v1310_IEs_t *)NULL #endif ); @@ -4722,27 +4721,27 @@ rrc_eNB_generate_RRCConnectionReconfiguration_handover( 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_ms35; - SRB2_rlc_config->choice.explicitValue.choice.am.dl_AM_RLC.t_StatusProhibit = T_StatusProhibit_ms10; + SRB2_rlc_config->present = LTE_SRB_ToAddMod__rlc_Config_PR_explicitValue; + SRB2_rlc_config->choice.explicitValue.present = LTE_RLC_Config_PR_am; + SRB2_rlc_config->choice.explicitValue.choice.am.ul_AM_RLC.t_PollRetransmit = LTE_T_PollRetransmit_ms15; + SRB2_rlc_config->choice.explicitValue.choice.am.ul_AM_RLC.pollPDU = LTE_PollPDU_p8; + SRB2_rlc_config->choice.explicitValue.choice.am.ul_AM_RLC.pollByte = LTE_PollByte_kB1000; + SRB2_rlc_config->choice.explicitValue.choice.am.ul_AM_RLC.maxRetxThreshold = LTE_UL_AM_RLC__maxRetxThreshold_t32; + SRB2_rlc_config->choice.explicitValue.choice.am.dl_AM_RLC.t_Reordering = LTE_T_Reordering_ms35; + SRB2_rlc_config->choice.explicitValue.choice.am.dl_AM_RLC.t_StatusProhibit = LTE_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 = LTE_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; + LTE_LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_infinity; SRB2_ul_SpecificParameters->bucketSizeDuration = - LogicalChannelConfig__ul_SpecificParameters__bucketSizeDuration_ms50; + LTE_LogicalChannelConfig__ul_SpecificParameters__bucketSizeDuration_ms50; // LCG for CCCH and DCCH is 0 as defined in 36331 logicalchannelgroup = CALLOC(1, sizeof(long)); @@ -4758,17 +4757,17 @@ rrc_eNB_generate_RRCConnectionReconfiguration_handover( /// DRB DRB_config = CALLOC(1, sizeof(*DRB_config)); - //DRB_config->drb_Identity = (DRB_Identity_t) 1; //allowed values 1..32 + //DRB_config->drb_Identity = (LTE_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_mod_idP+1); //allowed values 1..32 + DRB_config->drb_Identity = (LTE_DRB_Identity_t) 1; // (ue_mod_idP+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_ms35; + DRB_rlc_config->present = LTE_RLC_Config_PR_um_Bi_Directional; + DRB_rlc_config->choice.um_Bi_Directional.ul_UM_RLC.sn_FieldLength = LTE_SN_FieldLength_size10; + DRB_rlc_config->choice.um_Bi_Directional.dl_UM_RLC.sn_FieldLength = LTE_SN_FieldLength_size10; + DRB_rlc_config->choice.um_Bi_Directional.dl_UM_RLC.t_Reordering = LTE_T_Reordering_ms35; DRB_pdcp_config = CALLOC(1, sizeof(*DRB_pdcp_config)); DRB_config->pdcp_Config = DRB_pdcp_config; @@ -4776,8 +4775,8 @@ rrc_eNB_generate_RRCConnectionReconfiguration_handover( 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; + PDCP_rlc_UM->pdcp_SN_Size = LTE_PDCP_Config__rlc_UM__pdcp_SN_Size_len12bits; + DRB_pdcp_config->headerCompression.present = LTE_PDCP_Config__headerCompression_PR_notUsed; DRB_lchan_config = CALLOC(1, sizeof(*DRB_lchan_config)); DRB_config->logicalChannelConfig = DRB_lchan_config; @@ -4786,9 +4785,9 @@ rrc_eNB_generate_RRCConnectionReconfiguration_handover( DRB_ul_SpecificParameters->priority = 2; // lower priority than srb1, srb2 DRB_ul_SpecificParameters->prioritisedBitRate = - LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_infinity; + LTE_LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_infinity; DRB_ul_SpecificParameters->bucketSizeDuration = - LogicalChannelConfig__ul_SpecificParameters__bucketSizeDuration_ms50; + LTE_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)); @@ -4803,14 +4802,14 @@ rrc_eNB_generate_RRCConnectionReconfiguration_handover( 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; + *maxHARQ_Tx = LTE_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 = PeriodicBSR_Timer_r12_sf64; + *periodicBSR_Timer = LTE_PeriodicBSR_Timer_r12_sf64; mac_MainConfig->ul_SCH_Config->periodicBSR_Timer = periodicBSR_Timer; - mac_MainConfig->ul_SCH_Config->retxBSR_Timer = RetxBSR_Timer_r12_sf320; + mac_MainConfig->ul_SCH_Config->retxBSR_Timer = LTE_RetxBSR_Timer_r12_sf320; mac_MainConfig->ul_SCH_Config->ttiBundling = 0; // FALSE @@ -4818,17 +4817,17 @@ rrc_eNB_generate_RRCConnectionReconfiguration_handover( 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->present = LTE_MAC_MainConfig__phr_Config_PR_setup; + mac_MainConfig->phr_Config->choice.setup.periodicPHR_Timer = LTE_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.prohibitPHR_Timer = LTE_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 + mac_MainConfig->phr_Config->choice.setup.dl_PathlossChange = LTE_MAC_MainConfig__phr_Config__setup__dl_PathlossChange_dB1; // Value dB1 =1 dB, dB3 = 3 dB -#if (RRC_VERSION >= MAKE_VERSION(9, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) 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->ext1 = CALLOC(1, sizeof(struct MAC_MainConfig__ext1)); + mac_MainConfig->ext1 = CALLOC(1, sizeof(struct LTE_MAC_MainConfig__ext1)); mac_MainConfig->ext1->sr_ProhibitTimer_r9 = sr_ProhibitTimer_r9; //sps_RA_ConfigList_rlola = NULL; #endif @@ -4872,7 +4871,7 @@ rrc_eNB_generate_RRCConnectionReconfiguration_handover( MeasId5->reportConfigId = 6; ASN_SEQUENCE_ADD(&MeasId_list->list, MeasId5); - // rrcConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.measConfig->measIdToAddModList = MeasId_list; + // LTE_RRCConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.measConfig->measIdToAddModList = MeasId_list; // Add one EUTRA Measurement Object MeasObj_list = CALLOC(1, sizeof(*MeasObj_list)); @@ -4884,9 +4883,9 @@ rrc_eNB_generate_RRCConnectionReconfiguration_handover( memset((void *)MeasObj, 0, sizeof(*MeasObj)); MeasObj->measObjectId = 1; - MeasObj->measObject.present = MeasObjectToAddMod__measObject_PR_measObjectEUTRA; + MeasObj->measObject.present = LTE_MeasObjectToAddMod__measObject_PR_measObjectEUTRA; MeasObj->measObject.choice.measObjectEUTRA.carrierFreq = 36090; - MeasObj->measObject.choice.measObjectEUTRA.allowedMeasBandwidth = AllowedMeasBandwidth_mbw25; + MeasObj->measObject.choice.measObjectEUTRA.allowedMeasBandwidth = LTE_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; @@ -4895,21 +4894,21 @@ rrc_eNB_generate_RRCConnectionReconfiguration_handover( MeasObj->measObject.choice.measObjectEUTRA.offsetFreq = NULL; // Default is 15 or 0dB MeasObj->measObject.choice.measObjectEUTRA.cellsToAddModList = - (CellsToAddModList_t *) CALLOC(1, sizeof(*CellsToAddModList)); + (LTE_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 = (LTE_CellsToAddMod_t *) CALLOC(1, sizeof(*CellToAdd)); CellToAdd->cellIndex = i + 1; CellToAdd->physCellId = get_adjacent_cell_id(ctxt_pP->module_id, i); - CellToAdd->cellIndividualOffset = Q_OffsetRange_dB0; + CellToAdd->cellIndividualOffset = LTE_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; + // LTE_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)); @@ -4927,126 +4926,126 @@ rrc_eNB_generate_RRCConnectionReconfiguration_handover( ReportConfig_A5 = CALLOC(1, sizeof(*ReportConfig_A5)); ReportConfig_per->reportConfigId = 1; - ReportConfig_per->reportConfig.present = ReportConfigToAddMod__reportConfig_PR_reportConfigEUTRA; + ReportConfig_per->reportConfig.present = LTE_ReportConfigToAddMod__reportConfig_PR_reportConfigEUTRA; ReportConfig_per->reportConfig.choice.reportConfigEUTRA.triggerType.present = - ReportConfigEUTRA__triggerType_PR_periodical; + LTE_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; + LTE_ReportConfigEUTRA__triggerType__periodical__purpose_reportStrongestCells; + ReportConfig_per->reportConfig.choice.reportConfigEUTRA.triggerQuantity = LTE_ReportConfigEUTRA__triggerQuantity_rsrp; + ReportConfig_per->reportConfig.choice.reportConfigEUTRA.reportQuantity = LTE_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 = LTE_ReportInterval_ms120; + ReportConfig_per->reportConfig.choice.reportConfigEUTRA.reportAmount = LTE_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.present = LTE_ReportConfigToAddMod__reportConfig_PR_reportConfigEUTRA; ReportConfig_A1->reportConfig.choice.reportConfigEUTRA.triggerType.present = - ReportConfigEUTRA__triggerType_PR_event; + LTE_ReportConfigEUTRA__triggerType_PR_event; ReportConfig_A1->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.present = - ReportConfigEUTRA__triggerType__event__eventId_PR_eventA1; + LTE_ReportConfigEUTRA__triggerType__event__eventId_PR_eventA1; ReportConfig_A1->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.choice.eventA1. - a1_Threshold.present = ThresholdEUTRA_PR_threshold_RSRP; + a1_Threshold.present = LTE_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.triggerQuantity = LTE_ReportConfigEUTRA__triggerQuantity_rsrp; + ReportConfig_A1->reportConfig.choice.reportConfigEUTRA.reportQuantity = LTE_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 = LTE_ReportInterval_ms120; + ReportConfig_A1->reportConfig.choice.reportConfigEUTRA.reportAmount = LTE_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.present = LTE_ReportConfigToAddMod__reportConfig_PR_reportConfigEUTRA; ReportConfig_A2->reportConfig.choice.reportConfigEUTRA.triggerType.present = - ReportConfigEUTRA__triggerType_PR_event; + LTE_ReportConfigEUTRA__triggerType_PR_event; ReportConfig_A2->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.present = - ReportConfigEUTRA__triggerType__event__eventId_PR_eventA2; + LTE_ReportConfigEUTRA__triggerType__event__eventId_PR_eventA2; ReportConfig_A2->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.choice.eventA2. - a2_Threshold.present = ThresholdEUTRA_PR_threshold_RSRP; + a2_Threshold.present = LTE_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.triggerQuantity = LTE_ReportConfigEUTRA__triggerQuantity_rsrp; + ReportConfig_A2->reportConfig.choice.reportConfigEUTRA.reportQuantity = LTE_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; + ReportConfig_A2->reportConfig.choice.reportConfigEUTRA.reportInterval = LTE_ReportInterval_ms120; + ReportConfig_A2->reportConfig.choice.reportConfigEUTRA.reportAmount = LTE_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.present = LTE_ReportConfigToAddMod__reportConfig_PR_reportConfigEUTRA; ReportConfig_A3->reportConfig.choice.reportConfigEUTRA.triggerType.present = - ReportConfigEUTRA__triggerType_PR_event; + LTE_ReportConfigEUTRA__triggerType_PR_event; ReportConfig_A3->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.present = - ReportConfigEUTRA__triggerType__event__eventId_PR_eventA3; + LTE_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.triggerQuantity = LTE_ReportConfigEUTRA__triggerQuantity_rsrp; + ReportConfig_A3->reportConfig.choice.reportConfigEUTRA.reportQuantity = LTE_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.reportInterval = LTE_ReportInterval_ms120; + ReportConfig_A3->reportConfig.choice.reportConfigEUTRA.reportAmount = LTE_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.present = LTE_ReportConfigToAddMod__reportConfig_PR_reportConfigEUTRA; ReportConfig_A4->reportConfig.choice.reportConfigEUTRA.triggerType.present = - ReportConfigEUTRA__triggerType_PR_event; + LTE_ReportConfigEUTRA__triggerType_PR_event; ReportConfig_A4->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.present = - ReportConfigEUTRA__triggerType__event__eventId_PR_eventA4; + LTE_ReportConfigEUTRA__triggerType__event__eventId_PR_eventA4; ReportConfig_A4->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.choice.eventA4. - a4_Threshold.present = ThresholdEUTRA_PR_threshold_RSRP; + a4_Threshold.present = LTE_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.triggerQuantity = LTE_ReportConfigEUTRA__triggerQuantity_rsrp; + ReportConfig_A4->reportConfig.choice.reportConfigEUTRA.reportQuantity = LTE_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; + ReportConfig_A4->reportConfig.choice.reportConfigEUTRA.reportInterval = LTE_ReportInterval_ms120; + ReportConfig_A4->reportConfig.choice.reportConfigEUTRA.reportAmount = LTE_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.present = LTE_ReportConfigToAddMod__reportConfig_PR_reportConfigEUTRA; ReportConfig_A5->reportConfig.choice.reportConfigEUTRA.triggerType.present = - ReportConfigEUTRA__triggerType_PR_event; + LTE_ReportConfigEUTRA__triggerType_PR_event; ReportConfig_A5->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.present = - ReportConfigEUTRA__triggerType__event__eventId_PR_eventA5; + LTE_ReportConfigEUTRA__triggerType__event__eventId_PR_eventA5; ReportConfig_A5->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.choice. - eventA5.a5_Threshold1.present = ThresholdEUTRA_PR_threshold_RSRP; + eventA5.a5_Threshold1.present = LTE_ThresholdEUTRA_PR_threshold_RSRP; ReportConfig_A5->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.choice. - eventA5.a5_Threshold2.present = ThresholdEUTRA_PR_threshold_RSRP; + eventA5.a5_Threshold2.present = LTE_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.triggerQuantity = LTE_ReportConfigEUTRA__triggerQuantity_rsrp; + ReportConfig_A5->reportConfig.choice.reportConfigEUTRA.reportQuantity = LTE_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; + ReportConfig_A5->reportConfig.choice.reportConfigEUTRA.reportInterval = LTE_ReportInterval_ms120; + ReportConfig_A5->reportConfig.choice.reportConfigEUTRA.reportAmount = LTE_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->present = LTE_MeasConfig__speedStatePars_PR_setup; + Sparams->choice.setup.timeToTrigger_SF.sf_High = LTE_SpeedStateScaleFactors__sf_Medium_oDot75; + Sparams->choice.setup.timeToTrigger_SF.sf_Medium = LTE_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; + Sparams->choice.setup.mobilityStateParameters.t_Evaluation = LTE_MobilityStateParameters__t_Evaluation_s60; + Sparams->choice.setup.mobilityStateParameters.t_HystNormal = LTE_MobilityStateParameters__t_HystNormal_s120; quantityConfig = CALLOC(1, sizeof(*quantityConfig)); memset((void *)quantityConfig, 0, sizeof(*quantityConfig)); @@ -5059,15 +5058,15 @@ rrc_eNB_generate_RRCConnectionReconfiguration_handover( 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; + *quantityConfig->quantityConfigEUTRA->filterCoefficientRSRP = LTE_FilterCoefficient_fc4; + *quantityConfig->quantityConfigEUTRA->filterCoefficientRSRQ = LTE_FilterCoefficient_fc4; /* mobilityinfo */ mobilityInfo = CALLOC(1, sizeof(*mobilityInfo)); memset((void *)mobilityInfo, 0, sizeof(*mobilityInfo)); mobilityInfo->targetPhysCellId = - (PhysCellId_t) two_tier_hexagonal_cellIds[ue_context_pP->ue_context.handover_info->modid_t]; + (LTE_PhysCellId_t) two_tier_hexagonal_cellIds[ue_context_pP->ue_context.handover_info->modid_t]; LOG_D(RRC, "[eNB %d] Frame %d: handover preparation: targetPhysCellId: %ld mod_id: %d ue: %x \n", ctxt_pP->module_id, ctxt_pP->frame, @@ -5078,7 +5077,7 @@ rrc_eNB_generate_RRCConnectionReconfiguration_handover( 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 + mobilityInfo->t304 = LTE_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; @@ -5094,41 +5093,41 @@ rrc_eNB_generate_RRCConnectionReconfiguration_handover( mobilityInfo->radioResourceConfigCommon.rach_ConfigCommon = CALLOC(1, sizeof(*mobilityInfo->radioResourceConfigCommon.rach_ConfigCommon)); memcpy((void *)mobilityInfo->radioResourceConfigCommon.rach_ConfigCommon, - (void *)&rrc_inst->carrier[0] /* CROUX TBC */.sib2->radioResourceConfigCommon.rach_ConfigCommon, sizeof(RACH_ConfigCommon_t)); + (void *)&rrc_inst->carrier[0] /* CROUX TBC */.sib2->radioResourceConfigCommon.rach_ConfigCommon, sizeof(LTE_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->carrier[0] /* CROUX TBC */.sib2->radioResourceConfigCommon.prach_Config.prach_ConfigInfo, - sizeof(PRACH_ConfigInfo_t)); + sizeof(LTE_PRACH_ConfigInfo_t)); mobilityInfo->radioResourceConfigCommon.prach_Config.rootSequenceIndex = rrc_inst->carrier[0] /* CROUX TBC */.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->carrier[0] /* CROUX TBC */.sib2->radioResourceConfigCommon.pdsch_ConfigCommon, sizeof(PDSCH_ConfigCommon_t)); + (void *)&rrc_inst->carrier[0] /* CROUX TBC */.sib2->radioResourceConfigCommon.pdsch_ConfigCommon, sizeof(LTE_PDSCH_ConfigCommon_t)); memcpy((void *)&mobilityInfo->radioResourceConfigCommon.pusch_ConfigCommon, - (void *)&rrc_inst->carrier[0] /* CROUX TBC */.sib2->radioResourceConfigCommon.pusch_ConfigCommon, sizeof(PUSCH_ConfigCommon_t)); + (void *)&rrc_inst->carrier[0] /* CROUX TBC */.sib2->radioResourceConfigCommon.pusch_ConfigCommon, sizeof(LTE_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->carrier[0] /* CROUX TBC */.sib2->radioResourceConfigCommon.pucch_ConfigCommon, sizeof(PUCCH_ConfigCommon_t)); + (void *)&rrc_inst->carrier[0] /* CROUX TBC */.sib2->radioResourceConfigCommon.pucch_ConfigCommon, sizeof(LTE_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->carrier[0] /* CROUX TBC */.sib2->radioResourceConfigCommon.soundingRS_UL_ConfigCommon, - sizeof(SoundingRS_UL_ConfigCommon_t)); + sizeof(LTE_SoundingRS_UL_ConfigCommon_t)); mobilityInfo->radioResourceConfigCommon.uplinkPowerControlCommon = CALLOC(1, sizeof(*mobilityInfo->radioResourceConfigCommon.uplinkPowerControlCommon)); memcpy((void *)mobilityInfo->radioResourceConfigCommon.uplinkPowerControlCommon, (void *)&rrc_inst->carrier[0] /* CROUX TBC */.sib2->radioResourceConfigCommon.uplinkPowerControlCommon, - sizeof(UplinkPowerControlCommon_t)); + sizeof(LTE_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.tdd_Config = NULL; //CALLOC(1,sizeof(LTE_TDD_Config_t)); + //memcpy((void *)mobilityInfo->radioResourceConfigCommon.tdd_Config,(void *)rrc_inst->sib1->tdd_Config,sizeof(LTE_TDD_Config_t)); mobilityInfo->radioResourceConfigCommon.ul_CyclicPrefixLength = rrc_inst->carrier[0] /* CROUX TBC */.sib2->radioResourceConfigCommon.ul_CyclicPrefixLength; //End of configuration of radioResourceConfigCommon @@ -5138,8 +5137,8 @@ rrc_eNB_generate_RRCConnectionReconfiguration_handover( 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)); //CALLOC(1,sizeof(struct LTE_CarrierBandwidthEUTRA)); LTE_AllowedMeasBandwidth_mbw25 + mobilityInfo->carrierBandwidth->dl_Bandwidth = LTE_CarrierBandwidthEUTRA__dl_Bandwidth_n25; mobilityInfo->carrierBandwidth->ul_Bandwidth = NULL; mobilityInfo->rach_ConfigDedicated = NULL; @@ -5147,17 +5146,17 @@ rrc_eNB_generate_RRCConnectionReconfiguration_handover( memcpy(ue_context_pP->ue_context.handover_info->as_config.sourceRadioResourceConfig.srb_ToAddModList, (void*)SRB_configList2, - sizeof(SRB_ToAddModList_t)); + sizeof(LTE_SRB_ToAddModList_t)); memcpy((void*)ue_context_pP->ue_context.handover_info->as_config.sourceRadioResourceConfig.drb_ToAddModList, (void*)DRB_configList2, - sizeof(DRB_ToAddModList_t)); + sizeof(LTE_DRB_ToAddModList_t)); ue_context_pP->ue_context.handover_info->as_config.sourceRadioResourceConfig.drb_ToReleaseList = NULL; memcpy((void*)ue_context_pP->ue_context.handover_info->as_config.sourceRadioResourceConfig.mac_MainConfig, (void*)mac_MainConfig, - sizeof(MAC_MainConfig_t)); + sizeof(LTE_MAC_MainConfig_t)); memcpy((void*)ue_context_pP->ue_context.handover_info->as_config.sourceRadioResourceConfig.physicalConfigDedicated, (void*)ue_context_pP->ue_context.physicalConfigDedicated, - sizeof(PhysicalConfigDedicated_t)); + sizeof(LTE_PhysicalConfigDedicated_t)); /* memcpy((void *)rrc_inst->handover_info[ue_mod_idP]->as_config.sourceRadioResourceConfig.sps_Config, (void *)rrc_inst->sps_Config[ue_mod_idP], sizeof(SPS_Config_t)); @@ -5186,17 +5185,17 @@ rrc_eNB_generate_RRCConnectionReconfiguration_handover( rrc_pdcp_config_asn1_req(&ctxt, ue_context_pP->ue_context.SRB_configList, - (DRB_ToAddModList_t *) NULL, (DRB_ToReleaseList_t *) NULL, 0xff, NULL, NULL, NULL -#if (RRC_VERSION >= MAKE_VERSION(9, 0, 0)) - , (PMCH_InfoList_r9_t *) NULL + (LTE_DRB_ToAddModList_t *) NULL, (LTE_DRB_ToReleaseList_t *) NULL, 0xff, NULL, NULL, NULL +#if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) + , (LTE_PMCH_InfoList_r9_t *) NULL #endif ,NULL); rrc_rlc_config_asn1_req(&ctxt, ue_context_pP->ue_context.SRB_configList, - (DRB_ToAddModList_t *) NULL, (DRB_ToReleaseList_t *) NULL -#if (RRC_VERSION >= MAKE_VERSION(9, 0, 0)) - , (PMCH_InfoList_r9_t *) NULL + (LTE_DRB_ToAddModList_t *) NULL, (LTE_DRB_ToReleaseList_t *) NULL +#if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) + , (LTE_PMCH_InfoList_r9_t *) NULL , 0, 0 #endif ); @@ -5204,7 +5203,7 @@ rrc_eNB_generate_RRCConnectionReconfiguration_handover( /* Initialize NAS list */ dedicatedInfoNASList = NULL; - // rrcConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.measConfig->reportConfigToAddModList = ReportConfig_list; + // LTE_RRCConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.measConfig->reportConfigToAddModList = ReportConfig_list; memset(buffer, 0, RRC_BUF_SIZE); int size=do_RRCConnectionReconfiguration( @@ -5227,23 +5226,23 @@ rrc_eNB_generate_RRCConnectionReconfiguration_handover( NULL, NULL, dedicatedInfoNASList, - (SL_CommConfig_r12_t*)NULL, - (SL_DiscConfig_r12_t*)NULL -#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) + (LTE_SL_CommConfig_r12_t*)NULL, + (LTE_SL_DiscConfig_r12_t*)NULL +#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) , NULL // SCellToAddMod_r10_t #endif ); if (size <= 0) LOG_E(RRC, - "[eNB %d] Frame %d, Logical Channel DL-DCCH, Generate RRCConnectionReconfiguration for handover (bytes %d, UE rnti %x) failed\n", + "[eNB %d] Frame %d, Logical Channel DL-DCCH, Generate LTE_RRCConnectionReconfiguration for handover (bytes %d, UE rnti %x) failed\n", ctxt_pP->module_id, ctxt_pP->frame, size, ue_context_pP->ue_context.rnti); else LOG_I(RRC, - "[eNB %d] Frame %d, Logical Channel DL-DCCH, Generate RRCConnectionReconfiguration for handover (bytes %d, UE rnti %x)\n", + "[eNB %d] Frame %d, Logical Channel DL-DCCH, Generate LTE_RRCConnectionReconfiguration for handover (bytes %d, UE rnti %x)\n", ctxt_pP->module_id, ctxt_pP->frame, size, ue_context_pP->ue_context.rnti); // to be updated if needed /*if (RC.rrc[ctxt_pP->module_id]->SRB1_config[ue_mod_idP]->logicalChannelConfig) { - if (RC.rrc[ctxt_pP->module_id]->SRB1_config[ue_mod_idP]->logicalChannelConfig->present == SRB_ToAddMod__logicalChannelConfig_PR_explicitValue) { + if (RC.rrc[ctxt_pP->module_id]->SRB1_config[ue_mod_idP]->logicalChannelConfig->present == LTE_SRB_ToAddMod__logicalChannelConfig_PR_explicitValue) { SRB1_logicalChannelConfig = &RC.rrc[ctxt_pP->module_id]->SRB1_config[ue_mod_idP]->logicalChannelConfig->choice.explicitValue; } else { @@ -5265,34 +5264,34 @@ rrc_eNB_generate_RRCConnectionReconfiguration_handover( ctxt_pP->module_id, ue_context_pP->ue_context.primaryCC_id, 0,0,0,0,0, -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) 0, #endif ue_context_pP->ue_context.rnti, - (BCCH_BCH_Message_t *) NULL, - (RadioResourceConfigCommonSIB_t *) NULL, -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - (RadioResourceConfigCommonSIB_t *) NULL, + (LTE_BCCH_BCH_Message_t *) NULL, + (LTE_RadioResourceConfigCommonSIB_t *) NULL, +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + (LTE_RadioResourceConfigCommonSIB_t *) NULL, #endif ue_context_pP->ue_context.physicalConfigDedicated, -#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) - (SCellToAddMod_r10_t *)NULL, - //(struct PhysicalConfigDedicatedSCell_r10 *)NULL, +#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) + (LTE_SCellToAddMod_r10_t *)NULL, + //(struct LTE_PhysicalConfigDedicatedSCell_r10 *)NULL, #endif - (MeasObjectToAddMod_t **) NULL, + (LTE_MeasObjectToAddMod_t **) NULL, ue_context_pP->ue_context.mac_MainConfig, 1, SRB1_logicalChannelConfig, ue_context_pP->ue_context.measGapConfig, - (TDD_Config_t *) NULL, - (MobilityControlInfo_t *) mobilityInfo, - (SchedulingInfoList_t *) NULL, 0, NULL, NULL, (MBSFN_SubframeConfigList_t *) NULL -#if (RRC_VERSION >= MAKE_VERSION(9, 0, 0)) - , 0, (MBSFN_AreaInfoList_r9_t *) NULL, (PMCH_InfoList_r9_t *) NULL + (LTE_TDD_Config_t *) NULL, + (LTE_MobilityControlInfo_t *) mobilityInfo, + (LTE_SchedulingInfoList_t *) NULL, 0, NULL, NULL, (LTE_MBSFN_SubframeConfigList_t *) NULL +#if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) + , 0, (LTE_MBSFN_AreaInfoList_r9_t *) NULL, (LTE_PMCH_InfoList_r9_t *) NULL #endif -#if (RRC_VERSION >= MAKE_VERSION(13, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(13, 0, 0)) , - (SystemInformationBlockType1_v1310_IEs_t *)NULL + (LTE_SystemInformationBlockType1_v1310_IEs_t *)NULL #endif ); @@ -5329,15 +5328,15 @@ rrc_eNB_generate_RRCConnectionReconfiguration_handover( /* void ue_rrc_process_rrcConnectionReconfiguration(uint8_t enb_mod_idP,frame_t frameP, - RRCConnectionReconfiguration_t *rrcConnectionReconfiguration, + LTE_RRCConnectionReconfiguration_t *rrcConnectionReconfiguration, uint8_t CH_index) { - if (rrcConnectionReconfiguration->criticalExtensions.present == RRCConnectionReconfiguration__criticalExtensions_PR_c1) - if (rrcConnectionReconfiguration->criticalExtensions.choice.c1.present == RRCConnectionReconfiguration__criticalExtensions__c1_PR_rrcConnectionReconfiguration_r8) { + if (rrcConnectionReconfiguration->criticalExtensions.present == LTE_RRCConnectionReconfiguration__criticalExtensions_PR_c1) + if (rrcConnectionReconfiguration->criticalExtensions.choice.c1.present == LTE_RRCConnectionReconfiguration__criticalExtensions__c1_PR_rrcConnectionReconfiguration_r8) { if (rrcConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.radioResourceConfigDedicated) { rrc_ue_process_radioResourceConfigDedicated(enb_mod_idP,frameP,CH_index, - rrcConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.radioResourceConfigDedicated); + LTE_RRCConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.radioResourceConfigDedicated); } @@ -5369,10 +5368,10 @@ rrc_eNB_process_RRCConnectionReconfigurationComplete( uint8_t *kUPenc = NULL; ue_context_pP->ue_context.ue_reestablishment_timer = 0; - DRB_ToAddModList_t* DRB_configList = ue_context_pP->ue_context.DRB_configList2[xid]; - SRB_ToAddModList_t* SRB_configList = ue_context_pP->ue_context.SRB_configList2[xid]; - DRB_ToReleaseList_t* DRB_Release_configList2 = ue_context_pP->ue_context.DRB_Release_configList2[xid]; - DRB_Identity_t* drb_id_p = NULL; + LTE_DRB_ToAddModList_t* DRB_configList = ue_context_pP->ue_context.DRB_configList2[xid]; + LTE_SRB_ToAddModList_t* SRB_configList = ue_context_pP->ue_context.SRB_configList2[xid]; + LTE_DRB_ToReleaseList_t* DRB_Release_configList2 = ue_context_pP->ue_context.DRB_Release_configList2[xid]; + LTE_DRB_Identity_t* drb_id_p = NULL; T(T_ENB_RRC_CONNECTION_RECONFIGURATION_COMPLETE, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame), T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti)); @@ -5406,7 +5405,7 @@ rrc_eNB_process_RRCConnectionReconfigurationComplete( ctxt_pP, SRB_configList, //NULL, //LG-RK 14/05/2014 SRB_configList, DRB_configList, -// (DRB_ToReleaseList_t *) NULL, +// (LTE_DRB_ToReleaseList_t *) NULL, DRB_Release_configList2, /*RC.rrc[ctxt_pP->module_id]->ciphering_algorithm[ue_mod_idP] | (RC.rrc[ctxt_pP->module_id]->integrity_algorithm[ue_mod_idP] << 4), @@ -5415,8 +5414,8 @@ rrc_eNB_process_RRCConnectionReconfigurationComplete( kRRCenc, kRRCint, kUPenc -#if (RRC_VERSION >= MAKE_VERSION(9, 0, 0)) - , (PMCH_InfoList_r9_t *) NULL +#if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) + , (LTE_PMCH_InfoList_r9_t *) NULL #endif ,NULL); // Refresh SRBs/DRBs @@ -5424,10 +5423,10 @@ rrc_eNB_process_RRCConnectionReconfigurationComplete( ctxt_pP, SRB_configList, // NULL, //LG-RK 14/05/2014 SRB_configList, DRB_configList, -// (DRB_ToReleaseList_t *) NULL +// (LTE_DRB_ToReleaseList_t *) NULL DRB_Release_configList2 -#if (RRC_VERSION >= MAKE_VERSION(9, 0, 0)) - , (PMCH_InfoList_r9_t *) NULL +#if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) + , (LTE_PMCH_InfoList_r9_t *) NULL , 0, 0 #endif ); @@ -5464,7 +5463,7 @@ rrc_eNB_process_RRCConnectionReconfigurationComplete( if (DRB_configList->list.array[i]) { drb_id = (int)DRB_configList->list.array[i]->drb_Identity; LOG_I(RRC, - "[eNB %d] Frame %d : Logical Channel UL-DCCH, Received RRCConnectionReconfigurationComplete from UE rnti %x, reconfiguring DRB %d/LCID %d\n", + "[eNB %d] Frame %d : Logical Channel UL-DCCH, Received LTE_RRCConnectionReconfigurationComplete from UE rnti %x, reconfiguring DRB %d/LCID %d\n", ctxt_pP->module_id, ctxt_pP->frame, ctxt_pP->rnti, @@ -5472,7 +5471,7 @@ rrc_eNB_process_RRCConnectionReconfigurationComplete( (int)*DRB_configList->list.array[i]->logicalChannelIdentity); // for pre-ci tests LOG_I(RRC, - "[eNB %d] Frame %d : Logical Channel UL-DCCH, Received RRCConnectionReconfigurationComplete from UE %u, reconfiguring DRB %d/LCID %d\n", + "[eNB %d] Frame %d : Logical Channel UL-DCCH, Received LTE_RRCConnectionReconfigurationComplete from UE %u, reconfiguring DRB %d/LCID %d\n", ctxt_pP->module_id, ctxt_pP->frame, oai_emulation.info.eNB_ue_local_uid_to_ue_module_id[ctxt_pP->module_id][ue_context_pP->local_uid], @@ -5500,7 +5499,7 @@ rrc_eNB_process_RRCConnectionReconfigurationComplete( ctxt_pP->module_id); oip_ifup = nas_config( ctxt_pP->module_id, // interface index - ctxt_pP->module_id + 1, // thrid octet + ctxtReportConfigToAddMod__reportConfig_PR_reportConfigEUTRA_pP->module_id + 1, // thrid octet ctxt_pP->module_id + 1); // fourth octet if (oip_ifup == 0) { // interface is up --> send a config the DRB @@ -5537,35 +5536,35 @@ rrc_eNB_process_RRCConnectionReconfigurationComplete( ctxt_pP->module_id, ue_context_pP->ue_context.primaryCC_id, 0,0,0,0,0, -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) 0, #endif ue_context_pP->ue_context.rnti, - (BCCH_BCH_Message_t *) NULL, - (RadioResourceConfigCommonSIB_t *) NULL, -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - (RadioResourceConfigCommonSIB_t *) NULL, + (LTE_BCCH_BCH_Message_t *) NULL, + (LTE_RadioResourceConfigCommonSIB_t *) NULL, +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + (LTE_RadioResourceConfigCommonSIB_t *) NULL, #endif ue_context_pP->ue_context.physicalConfigDedicated, -#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) - (SCellToAddMod_r10_t *)NULL, - //(struct PhysicalConfigDedicatedSCell_r10 *)NULL, +#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) + (LTE_SCellToAddMod_r10_t *)NULL, + //(struct LTE_PhysicalConfigDedicatedSCell_r10 *)NULL, #endif - (MeasObjectToAddMod_t **) NULL, + (LTE_MeasObjectToAddMod_t **) NULL, ue_context_pP->ue_context.mac_MainConfig, DRB2LCHAN[i], DRB_configList->list.array[i]->logicalChannelConfig, ue_context_pP->ue_context.measGapConfig, - (TDD_Config_t *) NULL, + (LTE_TDD_Config_t *) NULL, NULL, - (SchedulingInfoList_t *) NULL, - 0, NULL, NULL, (MBSFN_SubframeConfigList_t *) NULL -#if (RRC_VERSION >= MAKE_VERSION(9, 0, 0)) - , 0, (MBSFN_AreaInfoList_r9_t *) NULL, (PMCH_InfoList_r9_t *) NULL + (LTE_SchedulingInfoList_t *) NULL, + 0, NULL, NULL, (LTE_MBSFN_SubframeConfigList_t *) NULL +#if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) + , 0, (LTE_MBSFN_AreaInfoList_r9_t *) NULL, (LTE_PMCH_InfoList_r9_t *) NULL #endif -#if (RRC_VERSION >= MAKE_VERSION(13, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(13, 0, 0)) , - (SystemInformationBlockType1_v1310_IEs_t *)NULL + (LTE_SystemInformationBlockType1_v1310_IEs_t *)NULL #endif ); @@ -5592,35 +5591,35 @@ rrc_eNB_process_RRCConnectionReconfigurationComplete( rrc_mac_config_req_eNB(ctxt_pP->module_id, ue_context_pP->ue_context.primaryCC_id, 0,0,0,0,0, -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) 0, #endif ue_context_pP->ue_context.rnti, - (BCCH_BCH_Message_t *) NULL, - (RadioResourceConfigCommonSIB_t *) NULL, -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - (RadioResourceConfigCommonSIB_t *) NULL, + (LTE_BCCH_BCH_Message_t *) NULL, + (LTE_RadioResourceConfigCommonSIB_t *) NULL, +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + (LTE_RadioResourceConfigCommonSIB_t *) NULL, #endif ue_context_pP->ue_context.physicalConfigDedicated, -#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) - (SCellToAddMod_r10_t *)NULL, - //(struct PhysicalConfigDedicatedSCell_r10 *)NULL, +#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) + (LTE_SCellToAddMod_r10_t *)NULL, + //(struct LTE_PhysicalConfigDedicatedSCell_r10 *)NULL, #endif - (MeasObjectToAddMod_t **) NULL, + (LTE_MeasObjectToAddMod_t **) NULL, ue_context_pP->ue_context.mac_MainConfig, DRB2LCHAN[i], - (LogicalChannelConfig_t *) NULL, - (MeasGapConfig_t *) NULL, - (TDD_Config_t *) NULL, + (LTE_LogicalChannelConfig_t *) NULL, + (LTE_MeasGapConfig_t *) NULL, + (LTE_TDD_Config_t *) NULL, NULL, - (SchedulingInfoList_t *) NULL, + (LTE_SchedulingInfoList_t *) NULL, 0, NULL, NULL, NULL -#if (RRC_VERSION >= MAKE_VERSION(9, 0, 0)) - , 0, (MBSFN_AreaInfoList_r9_t *) NULL, (PMCH_InfoList_r9_t *) NULL +#if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) + , 0, (LTE_MBSFN_AreaInfoList_r9_t *) NULL, (LTE_PMCH_InfoList_r9_t *) NULL #endif -#if (RRC_VERSION >= MAKE_VERSION(13, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(13, 0, 0)) , - (SystemInformationBlockType1_v1310_IEs_t *)NULL + (LTE_SystemInformationBlockType1_v1310_IEs_t *)NULL #endif ); } @@ -5655,9 +5654,9 @@ rrc_eNB_generate_RRCConnectionSetup( //----------------------------------------------------------------------------- { - LogicalChannelConfig_t *SRB1_logicalChannelConfig; //,*SRB2_logicalChannelConfig; - SRB_ToAddModList_t **SRB_configList; - SRB_ToAddMod_t *SRB1_config; + LTE_LogicalChannelConfig_t *SRB1_logicalChannelConfig; //,*SRB2_logicalChannelConfig; + LTE_SRB_ToAddModList_t **SRB_configList; + LTE_SRB_ToAddMod_t *SRB1_config; int cnt; T(T_ENB_RRC_CONNECTION_SETUP, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame), @@ -5679,7 +5678,7 @@ rrc_eNB_generate_RRCConnectionSetup( RC.rrc[ctxt_pP->module_id]->carrier[CC_id].Srb0.Tx_buffer.payload_size, "[MSG] RRC Connection Setup\n"); - // configure SRB1/SRB2, PhysicalConfigDedicated, MAC_MainConfig for UE + // configure SRB1/SRB2, PhysicalConfigDedicated, LTE_MAC_MainConfig for UE if (*SRB_configList != NULL) { for (cnt = 0; cnt < (*SRB_configList)->list.count; cnt++) { @@ -5688,7 +5687,7 @@ rrc_eNB_generate_RRCConnectionSetup( if (SRB1_config->logicalChannelConfig) { if (SRB1_config->logicalChannelConfig->present == - SRB_ToAddMod__logicalChannelConfig_PR_explicitValue) { + LTE_SRB_ToAddMod__logicalChannelConfig_PR_explicitValue) { SRB1_logicalChannelConfig = &SRB1_config->logicalChannelConfig->choice.explicitValue; } else { SRB1_logicalChannelConfig = &SRB1_logicalChannelConfig_defaultValue; @@ -5704,35 +5703,35 @@ rrc_eNB_generate_RRCConnectionSetup( ctxt_pP->module_id, ue_context_pP->ue_context.primaryCC_id, 0,0,0,0,0, -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) 0, #endif ue_context_pP->ue_context.rnti, - (BCCH_BCH_Message_t *) NULL, - (RadioResourceConfigCommonSIB_t *) NULL, -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - (RadioResourceConfigCommonSIB_t *) NULL, + (LTE_BCCH_BCH_Message_t *) NULL, + (LTE_RadioResourceConfigCommonSIB_t *) NULL, +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + (LTE_RadioResourceConfigCommonSIB_t *) NULL, #endif ue_context_pP->ue_context.physicalConfigDedicated, -#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) - (SCellToAddMod_r10_t *)NULL, - //(struct PhysicalConfigDedicatedSCell_r10 *)NULL, +#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) + (LTE_SCellToAddMod_r10_t *)NULL, + //(struct LTE_PhysicalConfigDedicatedSCell_r10 *)NULL, #endif - (MeasObjectToAddMod_t **) NULL, + (LTE_MeasObjectToAddMod_t **) NULL, ue_context_pP->ue_context.mac_MainConfig, 1, SRB1_logicalChannelConfig, ue_context_pP->ue_context.measGapConfig, - (TDD_Config_t *) NULL, + (LTE_TDD_Config_t *) NULL, NULL, - (SchedulingInfoList_t *) NULL, - 0, NULL, NULL, (MBSFN_SubframeConfigList_t *) NULL -#if (RRC_VERSION >= MAKE_VERSION(9, 0, 0)) - , 0, (MBSFN_AreaInfoList_r9_t *) NULL, (PMCH_InfoList_r9_t *) NULL + (LTE_SchedulingInfoList_t *) NULL, + 0, NULL, NULL, (LTE_MBSFN_SubframeConfigList_t *) NULL +#if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) + , 0, (LTE_MBSFN_AreaInfoList_r9_t *) NULL, (LTE_PMCH_InfoList_r9_t *) NULL #endif -#if (RRC_VERSION >= MAKE_VERSION(13, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(13, 0, 0)) , - (SystemInformationBlockType1_v1310_IEs_t *)NULL + (LTE_SystemInformationBlockType1_v1310_IEs_t *)NULL #endif ); break; @@ -5745,21 +5744,21 @@ rrc_eNB_generate_RRCConnectionSetup( MSC_RRC_UE, RC.rrc[ctxt_pP->module_id]->carrier[CC_id].Srb0.Tx_buffer.Header, // LG WARNING RC.rrc[ctxt_pP->module_id]->carrier[CC_id].Srb0.Tx_buffer.payload_size, - MSC_AS_TIME_FMT" RRCConnectionSetup UE %x size %u", + MSC_AS_TIME_FMT" LTE_RRCConnectionSetup UE %x size %u", MSC_AS_TIME_ARGS(ctxt_pP), ue_context_pP->ue_context.rnti, RC.rrc[ctxt_pP->module_id]->carrier[CC_id].Srb0.Tx_buffer.payload_size); LOG_I(RRC, - PROTOCOL_RRC_CTXT_UE_FMT" [RAPROC] Logical Channel DL-CCCH, Generating RRCConnectionSetup (bytes %d)\n", + PROTOCOL_RRC_CTXT_UE_FMT" [RAPROC] Logical Channel DL-CCCH, Generating LTE_RRCConnectionSetup (bytes %d)\n", PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP), RC.rrc[ctxt_pP->module_id]->carrier[CC_id].Srb0.Tx_buffer.payload_size); //ue_context_pP->ue_context.ue_release_timer_thres=100; // activate release timer, if RRCSetupComplete not received after 100 frames, remove UE ue_context_pP->ue_context.ue_release_timer=1; - // remove UE after 10 frames after RRCConnectionRelease is triggered + // remove UE after 10 frames after LTE_RRCConnectionRelease is triggered ue_context_pP->ue_context.ue_release_timer_thres=1000; } @@ -5835,14 +5834,14 @@ openair_rrc_eNB_init( LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" Checking release \n", PROTOCOL_RRC_CTXT_ARGS(&ctxt)); -#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) // can clear it at runtime RC.rrc[ctxt.module_id]->carrier[0].MBMS_flag = 0; // This has to come from some top-level configuration // only CC_id 0 is logged -#if (RRC_VERSION < MAKE_VERSION(10, 0, 0)) +#if (LTE_RRC_VERSION < MAKE_VERSION(10, 0, 0)) LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" Rel10 RRC detected, MBMS flag %d\n", #else LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" Rel14 RRC detected, MBMS flag %d\n", @@ -5892,7 +5891,7 @@ openair_rrc_eNB_init( rrc_init_global_param(); for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { -#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) switch (RC.rrc[ctxt.module_id]->carrier[CC_id].MBMS_flag) { case 1: case 2: @@ -5937,11 +5936,11 @@ rrc_eNB_decode_ccch( ) //----------------------------------------------------------------------------- { - module_id_t Idx; - asn_dec_rval_t dec_rval; - UL_CCCH_Message_t *ul_ccch_msg = NULL; - RRCConnectionRequest_r8_IEs_t* rrcConnectionRequest = NULL; - RRCConnectionReestablishmentRequest_r8_IEs_t* rrcConnectionReestablishmentRequest = NULL; + module_id_t Idx; + asn_dec_rval_t dec_rval; + LTE_UL_CCCH_Message_t *ul_ccch_msg = NULL; + LTE_RRCConnectionRequest_r8_IEs_t* rrcConnectionRequest = NULL; + LTE_RRCConnectionReestablishmentRequest_r8_IEs_t* rrcConnectionReestablishmentRequest = NULL; int i, rval; struct rrc_eNB_ue_context_s* ue_context_p = NULL; uint64_t random_value = 0; @@ -5962,7 +5961,7 @@ rrc_eNB_decode_ccch( ((uint8_t *) Srb_info->Rx_buffer.Payload)[5], (uint8_t *) Srb_info->Rx_buffer.Payload); dec_rval = uper_decode( NULL, - &asn_DEF_UL_CCCH_Message, + &asn_DEF_LTE_UL_CCCH_Message, (void**)&ul_ccch_msg, (uint8_t*) Srb_info->Rx_buffer.Payload, 100, @@ -5986,7 +5985,7 @@ rrc_eNB_decode_ccch( size_t message_string_size; if ((message_string_size = - xer_sprint(message_string, sizeof(message_string), &asn_DEF_UL_CCCH_Message, (void *)ul_ccch_msg)) > 0) { + xer_sprint(message_string, sizeof(message_string), &asn_DEF_LTE_UL_CCCH_Message, (void *)ul_ccch_msg)) > 0) { MessageDef *msg_p; msg_p = itti_alloc_new_message_sized(TASK_RRC_ENB, RRC_UL_CCCH, message_string_size + sizeof(IttiMsgText)); @@ -6011,17 +6010,17 @@ rrc_eNB_decode_ccch( return -1; } - if (ul_ccch_msg->message.present == UL_CCCH_MessageType_PR_c1) { + if (ul_ccch_msg->message.present == LTE_UL_CCCH_MessageType_PR_c1) { switch (ul_ccch_msg->message.choice.c1.present) { - case UL_CCCH_MessageType__c1_PR_NOTHING: + case LTE_UL_CCCH_MessageType__c1_PR_NOTHING: LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" Received PR_NOTHING on UL-CCCH-Message\n", PROTOCOL_RRC_CTXT_ARGS(ctxt_pP)); break; - case UL_CCCH_MessageType__c1_PR_rrcConnectionReestablishmentRequest: + case LTE_UL_CCCH_MessageType__c1_PR_rrcConnectionReestablishmentRequest: T(T_ENB_RRC_CONNECTION_REESTABLISHMENT_REQUEST, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame), T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti)); @@ -6035,10 +6034,10 @@ rrc_eNB_decode_ccch( rrcConnectionReestablishmentRequest = &ul_ccch_msg->message.choice.c1.choice.rrcConnectionReestablishmentRequest.criticalExtensions.choice.rrcConnectionReestablishmentRequest_r8; LOG_I(RRC, - PROTOCOL_RRC_CTXT_UE_FMT" RRCConnectionReestablishmentRequest cause %s\n", + PROTOCOL_RRC_CTXT_UE_FMT" LTE_RRCConnectionReestablishmentRequest cause %s\n", PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP), - ((rrcConnectionReestablishmentRequest->reestablishmentCause == ReestablishmentCause_otherFailure) ? "Other Failure" : - (rrcConnectionReestablishmentRequest->reestablishmentCause == ReestablishmentCause_handoverFailure) ? "Handover Failure" : + ((rrcConnectionReestablishmentRequest->reestablishmentCause == LTE_ReestablishmentCause_otherFailure) ? "Other Failure" : + (rrcConnectionReestablishmentRequest->reestablishmentCause == LTE_ReestablishmentCause_handoverFailure) ? "Handover Failure" : "reconfigurationFailure")); /*{ uint64_t c_rnti = 0; @@ -6064,7 +6063,7 @@ rrc_eNB_decode_ccch( if (rrcConnectionReestablishmentRequest->ue_Identity.physCellId != RC.rrc[ctxt_pP->module_id]->carrier[CC_id].physCellId) { LOG_E(RRC, - PROTOCOL_RRC_CTXT_UE_FMT" RRCConnectionReestablishmentRequest ue_Identity.physCellId(%ld) is not equal to current physCellId(%d), let's reject the UE\n", + PROTOCOL_RRC_CTXT_UE_FMT" LTE_RRCConnectionReestablishmentRequest ue_Identity.physCellId(%ld) is not equal to current physCellId(%d), let's reject the UE\n", PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP), rrcConnectionReestablishmentRequest->ue_Identity.physCellId, RC.rrc[ctxt_pP->module_id]->carrier[CC_id].physCellId); @@ -6081,7 +6080,7 @@ rrc_eNB_decode_ccch( if (rrcConnectionReestablishmentRequest->ue_Identity.c_RNTI.size == 0 || rrcConnectionReestablishmentRequest->ue_Identity.c_RNTI.size > 2) { LOG_E(RRC, - PROTOCOL_RRC_CTXT_UE_FMT" RRCConnectionReestablishmentRequest c_RNTI range error, let's reject the UE\n", + PROTOCOL_RRC_CTXT_UE_FMT" LTE_RRCConnectionReestablishmentRequest c_RNTI range error, let's reject the UE\n", PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP)); rrc_eNB_generate_RRCConnectionReestablishmentReject(ctxt_pP, ue_context_p, CC_id); break; @@ -6094,7 +6093,7 @@ rrc_eNB_decode_ccch( ue_context_p = rrc_eNB_get_ue_context(RC.rrc[ctxt_pP->module_id], c_rnti); if (ue_context_p == NULL) { LOG_E(RRC, - PROTOCOL_RRC_CTXT_UE_FMT" RRCConnectionReestablishmentRequest without UE context, let's reject the UE\n", + PROTOCOL_RRC_CTXT_UE_FMT" LTE_RRCConnectionReestablishmentRequest without UE context, let's reject the UE\n", PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP)); rrc_eNB_generate_RRCConnectionReestablishmentReject(ctxt_pP, ue_context_p, CC_id); break; @@ -6102,7 +6101,7 @@ rrc_eNB_decode_ccch( int UE_id = find_UE_id(ctxt_pP->module_id, c_rnti); if(UE_id == -1){ LOG_E(RRC, - PROTOCOL_RRC_CTXT_UE_FMT" RRCConnectionReestablishmentRequest without UE_id(MAC) rnti %x, let's reject the UE\n", + PROTOCOL_RRC_CTXT_UE_FMT" LTE_RRCConnectionReestablishmentRequest without UE_id(MAC) rnti %x, let's reject the UE\n", PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP),c_rnti); rrc_eNB_generate_RRCConnectionReestablishmentReject(ctxt_pP, ue_context_p, CC_id); break; @@ -6217,23 +6216,23 @@ rrc_eNB_decode_ccch( rrc_pdcp_config_asn1_req(ctxt_pP, ue_context_p->ue_context.SRB_configList, - (DRB_ToAddModList_t *) NULL, - (DRB_ToReleaseList_t*) NULL, + (LTE_DRB_ToAddModList_t *) NULL, + (LTE_DRB_ToReleaseList_t*) NULL, 0xff, NULL, NULL, NULL -#if (RRC_VERSION >= MAKE_VERSION(9, 0, 0)) - , (PMCH_InfoList_r9_t *) NULL +#if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) + , (LTE_PMCH_InfoList_r9_t *) NULL #endif ,NULL); rrc_rlc_config_asn1_req(ctxt_pP, ue_context_p->ue_context.SRB_configList, - (DRB_ToAddModList_t*) NULL, - (DRB_ToReleaseList_t*) NULL -#if (RRC_VERSION >= MAKE_VERSION(9, 0, 0)) - , (PMCH_InfoList_r9_t *) NULL, + (LTE_DRB_ToAddModList_t*) NULL, + (LTE_DRB_ToReleaseList_t*) NULL +#if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) + , (LTE_PMCH_InfoList_r9_t *) NULL, 0,0 # endif ); @@ -6241,7 +6240,7 @@ rrc_eNB_decode_ccch( } break; - case UL_CCCH_MessageType__c1_PR_rrcConnectionRequest: + case LTE_UL_CCCH_MessageType__c1_PR_rrcConnectionRequest: T(T_ENB_RRC_CONNECTION_REQUEST, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame), T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti)); @@ -6265,14 +6264,14 @@ rrc_eNB_decode_ccch( MSC_RRC_UE, Srb_info->Rx_buffer.Payload, dec_rval.consumed, - MSC_AS_TIME_FMT" RRCConnectionRequest UE %x size %u (UE already in context)", + MSC_AS_TIME_FMT" LTE_RRCConnectionRequest UE %x size %u (UE already in context)", MSC_AS_TIME_ARGS(ctxt_pP), ue_context_p->ue_context.rnti, dec_rval.consumed); } else { rrcConnectionRequest = &ul_ccch_msg->message.choice.c1.choice.rrcConnectionRequest.criticalExtensions.choice.rrcConnectionRequest_r8; { - if (InitialUE_Identity_PR_randomValue == rrcConnectionRequest->ue_Identity.present) { + if (LTE_InitialUE_Identity_PR_randomValue == rrcConnectionRequest->ue_Identity.present) { if(rrcConnectionRequest->ue_Identity.choice.randomValue.size != 5) { LOG_I(RRC, "wrong InitialUE-Identity randomValue size, expected 5, provided %lu", @@ -6291,9 +6290,9 @@ rrc_eNB_decode_ccch( ue_context_p->ue_context.ul_failure_timer = 20000; } ue_context_p = rrc_eNB_get_next_free_ue_context(ctxt_pP, random_value); - } else if (InitialUE_Identity_PR_s_TMSI == rrcConnectionRequest->ue_Identity.present) { + } else if (LTE_InitialUE_Identity_PR_s_TMSI == rrcConnectionRequest->ue_Identity.present) { /* Save s-TMSI */ - S_TMSI_t s_TMSI = rrcConnectionRequest->ue_Identity.choice.s_TMSI; + LTE_S_TMSI_t s_TMSI = rrcConnectionRequest->ue_Identity.choice.s_TMSI; mme_code_t mme_code = BIT_STRING_to_uint8(&s_TMSI.mmec); m_tmsi_t m_tmsi = BIT_STRING_to_uint32(&s_TMSI.m_TMSI); random_value = (((uint64_t)mme_code) << 32) | m_tmsi; @@ -6361,10 +6360,9 @@ rrc_eNB_decode_ccch( if (ue_context_p != NULL) { - #if defined(ENABLE_ITTI) ue_context_p->ue_context.establishment_cause = rrcConnectionRequest->establishmentCause; - ue_context_p->ue_context.reestablishment_cause = ReestablishmentCause_spare1; + ue_context_p->ue_context.reestablishment_cause = LTE_ReestablishmentCause_spare1; if (stmsi_received==0) LOG_I(RRC, PROTOCOL_RRC_CTXT_UE_FMT" Accept new connection from UE random UE identity (0x%" PRIx64 ") MME code %u TMSI %u cause %ld\n", PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP), @@ -6445,23 +6443,23 @@ rrc_eNB_decode_ccch( rrc_pdcp_config_asn1_req(ctxt_pP, ue_context_p->ue_context.SRB_configList, - (DRB_ToAddModList_t *) NULL, - (DRB_ToReleaseList_t*) NULL, + (LTE_DRB_ToAddModList_t *) NULL, + (LTE_DRB_ToReleaseList_t*) NULL, 0xff, NULL, NULL, NULL -#if (RRC_VERSION >= MAKE_VERSION(9, 0, 0)) - , (PMCH_InfoList_r9_t *) NULL +#if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) + , (LTE_PMCH_InfoList_r9_t *) NULL #endif ,NULL); rrc_rlc_config_asn1_req(ctxt_pP, ue_context_p->ue_context.SRB_configList, - (DRB_ToAddModList_t*) NULL, - (DRB_ToReleaseList_t*) NULL -#if (RRC_VERSION >= MAKE_VERSION(9, 0, 0)) - , (PMCH_InfoList_r9_t *) NULL + (LTE_DRB_ToAddModList_t*) NULL, + (LTE_DRB_ToReleaseList_t*) NULL +#if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) + , (LTE_PMCH_InfoList_r9_t *) NULL , 0, 0 #endif ); @@ -6499,7 +6497,7 @@ rrc_eNB_decode_dcch( asn_dec_rval_t dec_rval; //UL_DCCH_Message_t uldcchmsg; - UL_DCCH_Message_t *ul_dcch_msg = NULL; //&uldcchmsg; + LTE_UL_DCCH_Message_t *ul_dcch_msg = NULL; //&uldcchmsg; int i; struct rrc_eNB_ue_context_s* ue_context_p = NULL; #if defined(ENABLE_ITTI) @@ -6529,7 +6527,7 @@ rrc_eNB_decode_dcch( PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP)); dec_rval = uper_decode( NULL, - &asn_DEF_UL_DCCH_Message, + &asn_DEF_LTE_UL_DCCH_Message, (void**)&ul_dcch_msg, Rx_sdu, sdu_sizeP, @@ -6555,16 +6553,16 @@ rrc_eNB_decode_dcch( RC.rrc[ctxt_pP->module_id], ctxt_pP->rnti); - if (ul_dcch_msg->message.present == UL_DCCH_MessageType_PR_c1) { + if (ul_dcch_msg->message.present == LTE_UL_DCCH_MessageType_PR_c1) { switch (ul_dcch_msg->message.choice.c1.present) { - case UL_DCCH_MessageType__c1_PR_NOTHING: /* No components present */ + case LTE_UL_DCCH_MessageType__c1_PR_NOTHING: /* No components present */ break; - case UL_DCCH_MessageType__c1_PR_csfbParametersRequestCDMA2000: + case LTE_UL_DCCH_MessageType__c1_PR_csfbParametersRequestCDMA2000: break; - case UL_DCCH_MessageType__c1_PR_measurementReport: + case LTE_UL_DCCH_MessageType__c1_PR_measurementReport: // to avoid segmentation fault if(!ue_context_p){ LOG_I(RRC, "Processing measurementReport UE %x, ue_context_p is NULL\n", ctxt_pP->rnti); @@ -6583,10 +6581,10 @@ rrc_eNB_decode_dcch( criticalExtensions.choice.c1.choice.measurementReport_r8.measResults); break; - case UL_DCCH_MessageType__c1_PR_rrcConnectionReconfigurationComplete: + case LTE_UL_DCCH_MessageType__c1_PR_rrcConnectionReconfigurationComplete: // to avoid segmentation fault if(!ue_context_p){ - LOG_I(RRC, "Processing RRCConnectionReconfigurationComplete UE %x, ue_context_p is NULL\n", ctxt_pP->rnti); + LOG_I(RRC, "Processing LTE_RRCConnectionReconfigurationComplete UE %x, ue_context_p is NULL\n", ctxt_pP->rnti); break; } LOG_DUMPMSG(RRC,DEBUG_RRC,(char *)(Rx_sdu),sdu_sizeP, @@ -6597,7 +6595,7 @@ rrc_eNB_decode_dcch( MSC_RRC_UE, Rx_sdu, sdu_sizeP, - MSC_AS_TIME_FMT" RRCConnectionReconfigurationComplete UE %x size %u", + MSC_AS_TIME_FMT" LTE_RRCConnectionReconfigurationComplete UE %x size %u", MSC_AS_TIME_ARGS(ctxt_pP), ue_context_p->ue_context.rnti, sdu_sizeP); @@ -6611,7 +6609,7 @@ rrc_eNB_decode_dcch( if (ul_dcch_msg->message.choice.c1.choice.rrcConnectionReconfigurationComplete.criticalExtensions. present == - RRCConnectionReconfigurationComplete__criticalExtensions_PR_rrcConnectionReconfigurationComplete_r8) { + LTE_RRCConnectionReconfigurationComplete__criticalExtensions_PR_rrcConnectionReconfigurationComplete_r8) { /*NN: revise the condition */ /*FK: left the condition as is for the case MME is used (S1 mode) but setting dedicated_DRB = 1 otherwise (noS1 mode) so that no second RRCReconfiguration message activationg more DRB is sent as this causes problems with the nasmesh driver.*/ if (EPC_MODE_ENABLED) { @@ -6707,11 +6705,11 @@ if (ue_context_p->ue_context.nb_of_modify_e_rabs > 0) { ul_dcch_msg->message.choice.c1.choice.rrcConnectionReconfigurationComplete.rrc_TransactionIdentifier); } }else if(dedicated_DRB == 0){ - if(ue_context_p->ue_context.reestablishment_cause == ReestablishmentCause_spare1){ + if(ue_context_p->ue_context.reestablishment_cause == LTE_ReestablishmentCause_spare1){ rrc_eNB_send_S1AP_INITIAL_CONTEXT_SETUP_RESP(ctxt_pP, ue_context_p); } else { - ue_context_p->ue_context.reestablishment_cause = ReestablishmentCause_spare1; + ue_context_p->ue_context.reestablishment_cause = LTE_ReestablishmentCause_spare1; for (uint8_t e_rab = 0; e_rab < ue_context_p->ue_context.nb_of_e_rabs; e_rab++) { if (ue_context_p->ue_context.e_rab[e_rab].status == E_RAB_STATUS_DONE) { ue_context_p->ue_context.e_rab[e_rab].status = E_RAB_STATUS_ESTABLISHED; @@ -6738,7 +6736,7 @@ if (ue_context_p->ue_context.nb_of_modify_e_rabs > 0) { #endif break; - case UL_DCCH_MessageType__c1_PR_rrcConnectionReestablishmentComplete: + case LTE_UL_DCCH_MessageType__c1_PR_rrcConnectionReestablishmentComplete: T(T_ENB_RRC_CONNECTION_REESTABLISHMENT_COMPLETE, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame), T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti)); @@ -6750,7 +6748,7 @@ if (ue_context_p->ue_context.nb_of_modify_e_rabs > 0) { MSC_RRC_UE, Rx_sdu, sdu_sizeP, - MSC_AS_TIME_FMT" rrcConnectionReestablishmentComplete UE %x size %u", + MSC_AS_TIME_FMT" LTE_RRCConnectionReestablishmentComplete UE %x size %u", MSC_AS_TIME_ARGS(ctxt_pP), ue_context_p->ue_context.rnti, sdu_sizeP); @@ -6781,7 +6779,7 @@ if (ue_context_p->ue_context.nb_of_modify_e_rabs > 0) { if (!ue_context_p) { LOG_E(RRC, - PROTOCOL_RRC_CTXT_UE_FMT" RRCConnectionReestablishmentComplete without UE context, falt\n", + PROTOCOL_RRC_CTXT_UE_FMT" LTE_RRCConnectionReestablishmentComplete without UE context, falt\n", PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP)); break; } @@ -6789,7 +6787,7 @@ if (ue_context_p->ue_context.nb_of_modify_e_rabs > 0) { int UE_id = find_UE_id(ctxt_pP->module_id, ctxt_pP->rnti); if(UE_id == -1){ LOG_E(RRC, - PROTOCOL_RRC_CTXT_UE_FMT" RRCConnectionReestablishmentComplete without UE_id(MAC) rnti %x, fault\n", + PROTOCOL_RRC_CTXT_UE_FMT" LTE_RRCConnectionReestablishmentComplete without UE_id(MAC) rnti %x, fault\n", PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP),ctxt_pP->rnti); break; } @@ -6797,7 +6795,7 @@ if (ue_context_p->ue_context.nb_of_modify_e_rabs > 0) { ue_context_p->ue_context.ue_reestablishment_timer = 0; if (ul_dcch_msg->message.choice.c1.choice.rrcConnectionReestablishmentComplete.criticalExtensions.present == - RRCConnectionReestablishmentComplete__criticalExtensions_PR_rrcConnectionReestablishmentComplete_r8) { + LTE_RRCConnectionReestablishmentComplete__criticalExtensions_PR_rrcConnectionReestablishmentComplete_r8) { rrc_eNB_process_RRCConnectionReestablishmentComplete(ctxt_pP, reestablish_rnti, ue_context_p, ul_dcch_msg->message.choice.c1.choice.rrcConnectionReestablishmentComplete.rrc_TransactionIdentifier, &ul_dcch_msg->message.choice.c1.choice.rrcConnectionReestablishmentComplete.criticalExtensions.choice.rrcConnectionReestablishmentComplete_r8); @@ -6811,15 +6809,15 @@ if (ue_context_p->ue_context.nb_of_modify_e_rabs > 0) { } //ue_context_p->ue_context.ue_release_timer = 0; ue_context_p->ue_context.ue_reestablishment_timer = 1; - // remove UE after 100 frames after RRCConnectionReestablishmentRelease is triggered + // remove UE after 100 frames after LTE_RRCConnectionReestablishmentRelease is triggered ue_context_p->ue_context.ue_reestablishment_timer_thres = 1000; } break; - case UL_DCCH_MessageType__c1_PR_rrcConnectionSetupComplete: + case LTE_UL_DCCH_MessageType__c1_PR_rrcConnectionSetupComplete: // to avoid segmentation fault if(!ue_context_p){ - LOG_I(RRC, "Processing RRCConnectionSetupComplete UE %x, ue_context_p is NULL\n", ctxt_pP->rnti); + LOG_I(RRC, "Processing LTE_RRCConnectionSetupComplete UE %x, ue_context_p is NULL\n", ctxt_pP->rnti); break; } LOG_DUMPMSG(RRC,DEBUG_RRC,(char *)Rx_sdu,sdu_sizeP, @@ -6830,7 +6828,7 @@ if (ue_context_p->ue_context.nb_of_modify_e_rabs > 0) { MSC_RRC_UE, Rx_sdu, sdu_sizeP, - MSC_AS_TIME_FMT" RRCConnectionSetupComplete UE %x size %u", + MSC_AS_TIME_FMT" LTE_RRCConnectionSetupComplete UE %x size %u", MSC_AS_TIME_ARGS(ctxt_pP), ue_context_p->ue_context.rnti, sdu_sizeP); @@ -6843,10 +6841,10 @@ if (ue_context_p->ue_context.nb_of_modify_e_rabs > 0) { sdu_sizeP); if (ul_dcch_msg->message.choice.c1.choice.rrcConnectionSetupComplete.criticalExtensions.present == - RRCConnectionSetupComplete__criticalExtensions_PR_c1) { + LTE_RRCConnectionSetupComplete__criticalExtensions_PR_c1) { if (ul_dcch_msg->message.choice.c1.choice.rrcConnectionSetupComplete.criticalExtensions.choice.c1. present == - RRCConnectionSetupComplete__criticalExtensions__c1_PR_rrcConnectionSetupComplete_r8) { + LTE_RRCConnectionSetupComplete__criticalExtensions__c1_PR_rrcConnectionSetupComplete_r8) { rrc_eNB_process_RRCConnectionSetupComplete( ctxt_pP, ue_context_p, @@ -6867,7 +6865,7 @@ if (ue_context_p->ue_context.nb_of_modify_e_rabs > 0) { ue_context_p->ue_context.ue_release_timer=0; break; - case UL_DCCH_MessageType__c1_PR_securityModeComplete: + case LTE_UL_DCCH_MessageType__c1_PR_securityModeComplete: T(T_ENB_RRC_SECURITY_MODE_COMPLETE, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame), T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti)); // to avoid segmentation fault @@ -6900,7 +6898,7 @@ if (ue_context_p->ue_context.nb_of_modify_e_rabs > 0) { DCCH, sdu_sizeP); if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) { - xer_fprint(stdout, &asn_DEF_UL_DCCH_Message, (void *)ul_dcch_msg); + xer_fprint(stdout, &asn_DEF_LTE_UL_DCCH_Message, (void *)ul_dcch_msg); } // confirm with PDCP about the security mode for DCCH //rrc_pdcp_config_req (enb_mod_idP, frameP, 1,CONFIG_ACTION_SET_SECURITY_MODE, (ue_mod_idP * NB_RB_MAX) + DCCH, 0x77); @@ -6910,7 +6908,7 @@ if (ue_context_p->ue_context.nb_of_modify_e_rabs > 0) { ue_context_p); break; - case UL_DCCH_MessageType__c1_PR_securityModeFailure: + case LTE_UL_DCCH_MessageType__c1_PR_securityModeFailure: T(T_ENB_RRC_SECURITY_MODE_FAILURE, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame), T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti)); @@ -6934,7 +6932,7 @@ if (ue_context_p->ue_context.nb_of_modify_e_rabs > 0) { DCCH, sdu_sizeP); if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) { - xer_fprint(stdout, &asn_DEF_UL_DCCH_Message, (void *)ul_dcch_msg); + xer_fprint(stdout, &asn_DEF_LTE_UL_DCCH_Message, (void *)ul_dcch_msg); } // cancel the security mode in PDCP @@ -6943,7 +6941,7 @@ if (ue_context_p->ue_context.nb_of_modify_e_rabs > 0) { rrc_eNB_generate_UECapabilityEnquiry(ctxt_pP, ue_context_p); break; - case UL_DCCH_MessageType__c1_PR_ueCapabilityInformation: + case LTE_UL_DCCH_MessageType__c1_PR_ueCapabilityInformation: T(T_ENB_RRC_UE_CAPABILITY_INFORMATION, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame), T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti)); // to avoid segmentation fault @@ -6976,17 +6974,17 @@ if (ue_context_p->ue_context.nb_of_modify_e_rabs > 0) { DCCH, sdu_sizeP); if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) { - xer_fprint(stdout, &asn_DEF_UL_DCCH_Message, (void *)ul_dcch_msg); + xer_fprint(stdout, &asn_DEF_LTE_UL_DCCH_Message, (void *)ul_dcch_msg); } LOG_I(RRC, "got UE capabilities for UE %x\n", ctxt_pP->rnti); if (ue_context_p->ue_context.UE_Capability) { LOG_I(RRC, "freeing old UE capabilities for UE %x\n", ctxt_pP->rnti); - ASN_STRUCT_FREE(asn_DEF_UE_EUTRA_Capability, + ASN_STRUCT_FREE(asn_DEF_LTE_UE_EUTRA_Capability, ue_context_p->ue_context.UE_Capability); ue_context_p->ue_context.UE_Capability = 0; } dec_rval = uper_decode(NULL, - &asn_DEF_UE_EUTRA_Capability, + &asn_DEF_LTE_UE_EUTRA_Capability, (void **)&ue_context_p->ue_context.UE_Capability, ul_dcch_msg->message.choice.c1.choice.ueCapabilityInformation.criticalExtensions. choice.c1.choice.ueCapabilityInformation_r8.ue_CapabilityRAT_ContainerList.list. @@ -6995,14 +6993,14 @@ if (ue_context_p->ue_context.nb_of_modify_e_rabs > 0) { choice.c1.choice.ueCapabilityInformation_r8.ue_CapabilityRAT_ContainerList.list. array[0]->ueCapabilityRAT_Container.size, 0, 0); if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) { - xer_fprint(stdout, &asn_DEF_UE_EUTRA_Capability, ue_context_p->ue_context.UE_Capability); + xer_fprint(stdout, &asn_DEF_LTE_UE_EUTRA_Capability, ue_context_p->ue_context.UE_Capability); } if ((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)) { LOG_E(RRC, PROTOCOL_RRC_CTXT_UE_FMT" Failed to decode UE capabilities (%zu bytes)\n", PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP), dec_rval.consumed); - ASN_STRUCT_FREE(asn_DEF_UE_EUTRA_Capability, + ASN_STRUCT_FREE(asn_DEF_LTE_UE_EUTRA_Capability, ue_context_p->ue_context.UE_Capability); ue_context_p->ue_context.UE_Capability = 0; } @@ -7029,13 +7027,13 @@ if (ue_context_p->ue_context.nb_of_modify_e_rabs > 0) { RC.rrc[ctxt_pP->module_id]->HO_flag); break; - case UL_DCCH_MessageType__c1_PR_ulHandoverPreparationTransfer: + case LTE_UL_DCCH_MessageType__c1_PR_ulHandoverPreparationTransfer: T(T_ENB_RRC_UL_HANDOVER_PREPARATION_TRANSFER, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame), T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti)); break; - case UL_DCCH_MessageType__c1_PR_ulInformationTransfer: + case LTE_UL_DCCH_MessageType__c1_PR_ulInformationTransfer: T(T_ENB_RRC_UL_INFORMATION_TRANSFER, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame), T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti)); // to avoid segmentation fault @@ -7065,41 +7063,41 @@ if (ue_context_p->ue_context.nb_of_modify_e_rabs > 0) { } break; - case UL_DCCH_MessageType__c1_PR_counterCheckResponse: + case LTE_UL_DCCH_MessageType__c1_PR_counterCheckResponse: T(T_ENB_RRC_COUNTER_CHECK_RESPONSE, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame), T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti)); break; -#if (RRC_VERSION >= MAKE_VERSION(9, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) - case UL_DCCH_MessageType__c1_PR_ueInformationResponse_r9: + case LTE_UL_DCCH_MessageType__c1_PR_ueInformationResponse_r9: T(T_ENB_RRC_UE_INFORMATION_RESPONSE_R9, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame), T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti)); break; - case UL_DCCH_MessageType__c1_PR_proximityIndication_r9: + case LTE_UL_DCCH_MessageType__c1_PR_proximityIndication_r9: T(T_ENB_RRC_PROXIMITY_INDICATION_R9, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame), T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti)); break; #endif -#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) - case UL_DCCH_MessageType__c1_PR_rnReconfigurationComplete_r10: +#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) + case LTE_UL_DCCH_MessageType__c1_PR_rnReconfigurationComplete_r10: T(T_ENB_RRC_RECONFIGURATION_COMPLETE_R10, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame), T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti)); break; - case UL_DCCH_MessageType__c1_PR_mbmsCountingResponse_r10: + case LTE_UL_DCCH_MessageType__c1_PR_mbmsCountingResponse_r10: T(T_ENB_RRC_MBMS_COUNTING_RESPONSE_R10, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame), T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti)); break; - case UL_DCCH_MessageType__c1_PR_interFreqRSTDMeasurementIndication_r10: + case LTE_UL_DCCH_MessageType__c1_PR_interFreqRSTDMeasurementIndication_r10: T(T_ENB_RRC_INTER_FREQ_RSTD_MEASUREMENT_INDICATION, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame), T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti)); @@ -7118,13 +7116,13 @@ if (ue_context_p->ue_context.nb_of_modify_e_rabs > 0) { return 0; //TTN for D2D - } else if (ul_dcch_msg->message.present == UL_DCCH_MessageType_PR_messageClassExtension){ + } else if (ul_dcch_msg->message.present == LTE_UL_DCCH_MessageType_PR_messageClassExtension){ LOG_I(RRC, "THINH [UL_DCCH_MessageType_PR_messageClassExtension]\n"); switch (ul_dcch_msg->message.choice.messageClassExtension.present) { - case UL_DCCH_MessageType__messageClassExtension_PR_NOTHING: /* No components present */ + case LTE_UL_DCCH_MessageType__messageClassExtension_PR_NOTHING: /* No components present */ break; - case UL_DCCH_MessageType__messageClassExtension_PR_c2: //SidelinkUEInformation + case LTE_UL_DCCH_MessageType__messageClassExtension_PR_c2: //SidelinkUEInformation //case UL_DCCH_MessageType__messageClassExtension__c2_PR_sidelinkUEInformation_r12: //SidelinkUEInformation LOG_I(RRC,"THINH [UL_DCCH_MessageType__messageClassExtension_PR_c2]\n"); @@ -7405,7 +7403,7 @@ openair_rrc_top_init_eNB(int eMBMS_active,uint8_t HO_active) RC.rrc[module_id]->HO_flag = (uint8_t)HO_active; } -#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) LOG_I(RRC,"[eNB] eMBMS active state is %d \n", eMBMS_active); for (module_id=0; module_idcriticalExtensions.present == SidelinkUEInformation_r12__criticalExtensions_PR_c1){ - if (sidelinkUEInformation->criticalExtensions.choice.c1.present == SidelinkUEInformation_r12__criticalExtensions__c1_PR_sidelinkUEInformation_r12){ + if (sidelinkUEInformation->criticalExtensions.present == LTE_SidelinkUEInformation_r12__criticalExtensions_PR_c1){ + if (sidelinkUEInformation->criticalExtensions.choice.c1.present == LTE_SidelinkUEInformation_r12__criticalExtensions__c1_PR_sidelinkUEInformation_r12){ // express its interest to receive SL communication if (sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.commRxInterestedFreq_r12 != NULL){ @@ -7471,7 +7469,7 @@ rrc_eNB_process_SidelinkUEInformation( // express its interest to transmit non-relay one-to-many SL communication if ((sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.commTxResourceReq_r12 != NULL) && (sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.commTxResourceReq_r12->carrierFreq_r12 != NULL)){ n_destinations = sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.commTxResourceReq_r12->destinationInfoList_r12.list.count; - destinationInfoList = CALLOC(1, sizeof(SL_DestinationInfoList_r12_t)); + destinationInfoList = CALLOC(1, sizeof(LTE_SL_DestinationInfoList_r12_t)); for (int i=0; i< n_destinations; i++ ){ //sl_DestinationIdentityList[i] = *(sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.commTxResourceReq_r12->destinationInfoList_r12.list.array[i]); ASN_SEQUENCE_ADD(&destinationInfoList->list, sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.commTxResourceReq_r12->destinationInfoList_r12.list.array[i]); @@ -7486,7 +7484,7 @@ rrc_eNB_process_SidelinkUEInformation( if ((sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.nonCriticalExtension != NULL) && (sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.nonCriticalExtension->commTxResourceReqUC_r13 != NULL)) { if (sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.nonCriticalExtension->commTxResourceReqUC_r13->carrierFreq_r12 != NULL){ n_destinations = sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.nonCriticalExtension->commTxResourceReqUC_r13->destinationInfoList_r12.list.count; - destinationInfoList = CALLOC(1, sizeof(SL_DestinationInfoList_r12_t)); + destinationInfoList = CALLOC(1, sizeof(LTE_SL_DestinationInfoList_r12_t)); for (int i=0; i< n_destinations; i++ ){ //sl_DestinationIdentityList[i] = *(sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.nonCriticalExtension->commTxResourceReqUC_r13->destinationInfoList_r12.list.array[i]); ASN_SEQUENCE_ADD(&destinationInfoList->list,sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.nonCriticalExtension->commTxResourceReqUC_r13->destinationInfoList_r12.list.array[i]); @@ -7501,7 +7499,7 @@ rrc_eNB_process_SidelinkUEInformation( if ((sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.nonCriticalExtension != NULL) &&(sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.nonCriticalExtension->commTxResourceInfoReqRelay_r13->commTxResourceReqRelayUC_r13 != NULL)) { if (sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.nonCriticalExtension->commTxResourceInfoReqRelay_r13->commTxResourceReqRelayUC_r13->destinationInfoList_r12.list.count > 0) { n_destinations = sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.nonCriticalExtension->commTxResourceInfoReqRelay_r13->commTxResourceReqRelayUC_r13->destinationInfoList_r12.list.count; - destinationInfoList = CALLOC(1, sizeof(SL_DestinationInfoList_r12_t)); + destinationInfoList = CALLOC(1, sizeof(LTE_SL_DestinationInfoList_r12_t)); for (int i=0; i< n_destinations; i++ ){ //sl_DestinationIdentityList[i] = *(sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.nonCriticalExtension->commTxResourceInfoReqRelay_r13->commTxResourceReqRelayUC_r13->destinationInfoList_r12.list.array[i]); ASN_SEQUENCE_ADD(&destinationInfoList->list, sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.nonCriticalExtension->commTxResourceInfoReqRelay_r13->commTxResourceReqRelayUC_r13->destinationInfoList_r12.list.array[i]); @@ -7516,7 +7514,7 @@ rrc_eNB_process_SidelinkUEInformation( if ((sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.nonCriticalExtension != NULL) && (sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.nonCriticalExtension->commTxResourceInfoReqRelay_r13 != NULL)) { if (sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.nonCriticalExtension->commTxResourceInfoReqRelay_r13->commTxResourceReqRelay_r13->destinationInfoList_r12.list.count > 0){ n_destinations = sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.nonCriticalExtension->commTxResourceInfoReqRelay_r13->commTxResourceReqRelay_r13->destinationInfoList_r12.list.count; - destinationInfoList = CALLOC(1, sizeof(SL_DestinationInfoList_r12_t)); + destinationInfoList = CALLOC(1, sizeof(LTE_SL_DestinationInfoList_r12_t)); for (int i=0; i< n_destinations; i++ ){ //sl_DestinationIdentityList[i] = *(sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.nonCriticalExtension->commTxResourceInfoReqRelay_r13->commTxResourceReqRelay_r13->destinationInfoList_r12.list.array[i]); ASN_SEQUENCE_ADD(&destinationInfoList->list,sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.nonCriticalExtension->commTxResourceInfoReqRelay_r13->commTxResourceReqRelay_r13->destinationInfoList_r12.list.array[i]); @@ -7555,7 +7553,7 @@ int rrc_eNB_generate_RRCConnectionReconfiguration_Sidelink( const protocol_ctxt_t* const ctxt_pP, rrc_eNB_ue_context_t* const ue_context_pP, - SL_DestinationInfoList_r12_t *destinationInfoList, + LTE_SL_DestinationInfoList_r12_t *destinationInfoList, int n_discoveryMessages ) //----------------------------------------------------------------------------- @@ -7569,55 +7567,55 @@ rrc_eNB_generate_RRCConnectionReconfiguration_Sidelink( //populate dedicated resources for SL communication (sl-CommConfig) if ((destinationInfoList != NULL) && (destinationInfoList->list.count > 0)) { - LOG_I(RRC,"[eNB %d] Frame %d, Generate RRCConnectionReconfiguration_Sidelink (bytes %d, UE id %x), number of destinations %d\n", + LOG_I(RRC,"[eNB %d] Frame %d, Generate LTE_RRCConnectionReconfiguration_Sidelink (bytes %d, UE id %x), number of destinations %d\n", ctxt_pP->module_id,ctxt_pP->frame, size, ue_context_pP->ue_context.rnti,destinationInfoList->list.count ); //get dedicated resources from available pool and assign to the UE - SL_CommConfig_r12_t sl_CommConfig[destinationInfoList->list.count]; + LTE_SL_CommConfig_r12_t sl_CommConfig[destinationInfoList->list.count]; //get a RP from the available RPs sl_CommConfig[0] = rrc_eNB_get_sidelink_commTXPool(ctxt_pP, ue_context_pP, destinationInfoList); size = do_RRCConnectionReconfiguration(ctxt_pP, buffer, rrc_eNB_get_next_transaction_identifier(ctxt_pP->module_id), //Transaction_id - (SRB_ToAddModList_t*)NULL, - (DRB_ToAddModList_t*)NULL, - (DRB_ToReleaseList_t*)NULL, // DRB2_list, - (struct SPS_Config*)NULL, // *sps_Config, + (LTE_SRB_ToAddModList_t*)NULL, + (LTE_DRB_ToAddModList_t*)NULL, + (LTE_DRB_ToReleaseList_t*)NULL, // DRB2_list, + (struct LTE_SPS_Config*)NULL, // *sps_Config, NULL, NULL, NULL, NULL,NULL, NULL, NULL, NULL, NULL, NULL, NULL, - (struct RRCConnectionReconfiguration_r8_IEs__dedicatedInfoNASList*)NULL, - (SL_CommConfig_r12_t*)&sl_CommConfig, - (SL_DiscConfig_r12_t*)NULL - #if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) - , (SCellToAddMod_r10_t*)NULL + (struct LTE_RRCConnectionReconfiguration_r8_IEs__dedicatedInfoNASList*)NULL, + (LTE_SL_CommConfig_r12_t*)&sl_CommConfig, + (LTE_SL_DiscConfig_r12_t*)NULL + #if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) + , (LTE_SCellToAddMod_r10_t*)NULL #endif ); // } //populate dedicated resources for SL discovery (sl-DiscConfig) if (n_discoveryMessages > 0) { - SL_DiscConfig_r12_t sl_DiscConfig[n_discoveryMessages]; + LTE_SL_DiscConfig_r12_t sl_DiscConfig[n_discoveryMessages]; //get a RP from the available RPs sl_DiscConfig[0] = rrc_eNB_get_sidelink_discTXPool(ctxt_pP, ue_context_pP, n_discoveryMessages ); size = do_RRCConnectionReconfiguration(ctxt_pP, buffer, rrc_eNB_get_next_transaction_identifier(ctxt_pP->module_id), //Transaction_id - (SRB_ToAddModList_t*)NULL, - (DRB_ToAddModList_t*)NULL, - (DRB_ToReleaseList_t*)NULL, // DRB2_list, - (struct SPS_Config*)NULL, // *sps_Config, + (LTE_SRB_ToAddModList_t*)NULL, + (LTE_DRB_ToAddModList_t*)NULL, + (LTE_DRB_ToReleaseList_t*)NULL, // DRB2_list, + (struct LTE_SPS_Config*)NULL, // *sps_Config, NULL, NULL, NULL, NULL,NULL, NULL, NULL, NULL, NULL, NULL, NULL, - (struct RRCConnectionReconfiguration_r8_IEs__dedicatedInfoNASList*)NULL, - (SL_CommConfig_r12_t*)NULL, - (SL_DiscConfig_r12_t*)&sl_DiscConfig - #if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) - , (SCellToAddMod_r10_t*)NULL + (struct LTE_RRCConnectionReconfiguration_r8_IEs__dedicatedInfoNASList*)NULL, + (LTE_SL_CommConfig_r12_t*)NULL, + (LTE_SL_DiscConfig_r12_t*)&sl_DiscConfig + #if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) + , (LTE_SCellToAddMod_r10_t*)NULL #endif ); } - LOG_I(RRC,"[eNB %d] Frame %d, Logical Channel DL-DCCH, Generate RRCConnectionReconfiguration_Sidelink (bytes %d, UE id %x)\n", + LOG_I(RRC,"[eNB %d] Frame %d, Logical Channel DL-DCCH, Generate LTE_RRCConnectionReconfiguration_Sidelink (bytes %d, UE id %x)\n", ctxt_pP->module_id,ctxt_pP->frame, size, ue_context_pP->ue_context.rnti); rrc_data_req( @@ -7634,16 +7632,16 @@ rrc_eNB_generate_RRCConnectionReconfiguration_Sidelink( return size; } -SL_CommConfig_r12_t rrc_eNB_get_sidelink_commTXPool( const protocol_ctxt_t* const ctxt_pP, rrc_eNB_ue_context_t* const ue_context_pP, SL_DestinationInfoList_r12_t *destinationInfoList ){ +LTE_SL_CommConfig_r12_t rrc_eNB_get_sidelink_commTXPool( const protocol_ctxt_t* const ctxt_pP, rrc_eNB_ue_context_t* const ue_context_pP, LTE_SL_DestinationInfoList_r12_t *destinationInfoList ){ // for the moment, use scheduled resource allocation - SL_CommConfig_r12_t *sl_CommConfig; - SL_CommResourcePool_r12_t *sc_CommTxConfig; + LTE_SL_CommConfig_r12_t *sl_CommConfig; + LTE_SL_CommResourcePool_r12_t *sc_CommTxConfig; - sl_CommConfig = CALLOC(1, sizeof(struct SL_CommConfig_r12)); + sl_CommConfig = CALLOC(1, sizeof(struct LTE_SL_CommConfig_r12)); sl_CommConfig->commTxResources_r12 = CALLOC(1, sizeof(*sl_CommConfig->commTxResources_r12)); - sl_CommConfig->commTxResources_r12->present = SL_CommConfig_r12__commTxResources_r12_PR_setup; + sl_CommConfig->commTxResources_r12->present = LTE_SL_CommConfig_r12__commTxResources_r12_PR_setup; - sl_CommConfig->commTxResources_r12->choice.setup.present = SL_CommConfig_r12__commTxResources_r12__setup_PR_scheduled_r12; + sl_CommConfig->commTxResources_r12->choice.setup.present = LTE_SL_CommConfig_r12__commTxResources_r12__setup_PR_scheduled_r12; sl_CommConfig->commTxResources_r12->choice.setup.choice.scheduled_r12.sl_RNTI_r12.size = 2; sl_CommConfig->commTxResources_r12->choice.setup.choice.scheduled_r12.sl_RNTI_r12.buf = CALLOC(1,2); sl_CommConfig->commTxResources_r12->choice.setup.choice.scheduled_r12.sl_RNTI_r12.buf[0] = 0x00; @@ -7651,37 +7649,37 @@ SL_CommConfig_r12_t rrc_eNB_get_sidelink_commTXPool( const protocol_ctxt_t* cons sl_CommConfig->commTxResources_r12->choice.setup.choice.scheduled_r12.sl_RNTI_r12.bits_unused = 0; sl_CommConfig->commTxResources_r12->choice.setup.choice.scheduled_r12.mcs_r12 = CALLOC(1,sizeof(*sl_CommConfig->commTxResources_r12->choice.setup.choice.scheduled_r12.mcs_r12)); //*sl_CommConfig_test->commTxResources_r12->choice.setup.choice.scheduled_r12.mcs_r12 = 12; //Msc - sl_CommConfig->commTxResources_r12->choice.setup.choice.scheduled_r12.mac_MainConfig_r12.retx_BSR_TimerSL = RetxBSR_Timer_r12_sf320; //MacConfig, for testing only + sl_CommConfig->commTxResources_r12->choice.setup.choice.scheduled_r12.mac_MainConfig_r12.retx_BSR_TimerSL = LTE_RetxBSR_Timer_r12_sf320; //MacConfig, for testing only //sl_CommConfig_test->commTxResources_r12->choice.setup.choice.scheduled_r12.sc_CommTxConfig_r12; sc_CommTxConfig = & sl_CommConfig->commTxResources_r12->choice.setup.choice.scheduled_r12.sc_CommTxConfig_r12; - sc_CommTxConfig->sc_CP_Len_r12 = SL_CP_Len_r12_normal; - sc_CommTxConfig->sc_Period_r12 = SL_PeriodComm_r12_sf40; - sc_CommTxConfig->data_CP_Len_r12 = SL_CP_Len_r12_normal; + sc_CommTxConfig->sc_CP_Len_r12 = LTE_SL_CP_Len_r12_normal; + sc_CommTxConfig->sc_Period_r12 = LTE_SL_PeriodComm_r12_sf40; + sc_CommTxConfig->data_CP_Len_r12 = LTE_SL_CP_Len_r12_normal; //sc_TF_ResourceConfig_r12 sc_CommTxConfig->sc_TF_ResourceConfig_r12.prb_Num_r12 = 20; sc_CommTxConfig->sc_TF_ResourceConfig_r12.prb_Start_r12 = 5; sc_CommTxConfig->sc_TF_ResourceConfig_r12.prb_End_r12 = 44; - sc_CommTxConfig->sc_TF_ResourceConfig_r12.offsetIndicator_r12.present = SL_OffsetIndicator_r12_PR_small_r12; + sc_CommTxConfig->sc_TF_ResourceConfig_r12.offsetIndicator_r12.present = LTE_SL_OffsetIndicator_r12_PR_small_r12; sc_CommTxConfig->sc_TF_ResourceConfig_r12.offsetIndicator_r12.choice.small_r12 = 0; - sc_CommTxConfig->sc_TF_ResourceConfig_r12.subframeBitmap_r12.present = SubframeBitmapSL_r12_PR_bs40_r12; + sc_CommTxConfig->sc_TF_ResourceConfig_r12.subframeBitmap_r12.present = LTE_SubframeBitmapSL_r12_PR_bs40_r12; sc_CommTxConfig->sc_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs40_r12.size = 5; sc_CommTxConfig->sc_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs40_r12.buf = CALLOC(1,5); sc_CommTxConfig->sc_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs40_r12.bits_unused = 0; //dataHoppingConfig_r12 sc_CommTxConfig->dataHoppingConfig_r12.hoppingParameter_r12 = 0; - sc_CommTxConfig->dataHoppingConfig_r12.numSubbands_r12 = SL_HoppingConfigComm_r12__numSubbands_r12_ns1; + sc_CommTxConfig->dataHoppingConfig_r12.numSubbands_r12 = LTE_SL_HoppingConfigComm_r12__numSubbands_r12_ns1; sc_CommTxConfig->dataHoppingConfig_r12.rb_Offset_r12 = 0; //ue_SelectedResourceConfig_r12 sc_CommTxConfig->ue_SelectedResourceConfig_r12 = CALLOC (1, sizeof (*sc_CommTxConfig->ue_SelectedResourceConfig_r12)); sc_CommTxConfig->ue_SelectedResourceConfig_r12->data_TF_ResourceConfig_r12.prb_Num_r12 = 20; sc_CommTxConfig->ue_SelectedResourceConfig_r12->data_TF_ResourceConfig_r12.prb_Start_r12 = 5; sc_CommTxConfig->ue_SelectedResourceConfig_r12->data_TF_ResourceConfig_r12.prb_End_r12 = 44; - sc_CommTxConfig->ue_SelectedResourceConfig_r12->data_TF_ResourceConfig_r12.offsetIndicator_r12.present = SL_OffsetIndicator_r12_PR_small_r12; + sc_CommTxConfig->ue_SelectedResourceConfig_r12->data_TF_ResourceConfig_r12.offsetIndicator_r12.present = LTE_SL_OffsetIndicator_r12_PR_small_r12; sc_CommTxConfig->ue_SelectedResourceConfig_r12->data_TF_ResourceConfig_r12.offsetIndicator_r12.choice.small_r12 = 0 ; - sc_CommTxConfig->ue_SelectedResourceConfig_r12->data_TF_ResourceConfig_r12.subframeBitmap_r12.present = SubframeBitmapSL_r12_PR_bs40_r12; + sc_CommTxConfig->ue_SelectedResourceConfig_r12->data_TF_ResourceConfig_r12.subframeBitmap_r12.present = LTE_SubframeBitmapSL_r12_PR_bs40_r12; sc_CommTxConfig->ue_SelectedResourceConfig_r12->data_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs4_r12.size = 5; sc_CommTxConfig->ue_SelectedResourceConfig_r12->data_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs4_r12.buf = CALLOC(1,5); sc_CommTxConfig->ue_SelectedResourceConfig_r12->data_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs4_r12.bits_unused = 0; @@ -7698,7 +7696,7 @@ SL_CommConfig_r12_t rrc_eNB_get_sidelink_commTXPool( const protocol_ctxt_t* cons sc_CommTxConfig->rxParametersNCell_r12->syncConfigIndex_r12 = 0; //txParameters_r12 sc_CommTxConfig->txParameters_r12 = CALLOC (1, sizeof (*sc_CommTxConfig->txParameters_r12)); - sc_CommTxConfig->txParameters_r12->sc_TxParameters_r12.alpha_r12 = Alpha_r12_al0; + sc_CommTxConfig->txParameters_r12->sc_TxParameters_r12.alpha_r12 = LTE_Alpha_r12_al0; sc_CommTxConfig->txParameters_r12->sc_TxParameters_r12.p0_r12 = 0; sc_CommTxConfig->ext1 = NULL ; @@ -7706,12 +7704,12 @@ SL_CommConfig_r12_t rrc_eNB_get_sidelink_commTXPool( const protocol_ctxt_t* cons } -SL_DiscConfig_r12_t rrc_eNB_get_sidelink_discTXPool( const protocol_ctxt_t* const ctxt_pP, rrc_eNB_ue_context_t* const ue_context_pP, int n_discoveryMessages ){ +LTE_SL_DiscConfig_r12_t rrc_eNB_get_sidelink_discTXPool( const protocol_ctxt_t* const ctxt_pP, rrc_eNB_ue_context_t* const ue_context_pP, int n_discoveryMessages ){ //TODO - SL_DiscConfig_r12_t sl_DiscConfig; + LTE_SL_DiscConfig_r12_t sl_DiscConfig; sl_DiscConfig.discTxResources_r12 = CALLOC(1,sizeof(*sl_DiscConfig.discTxResources_r12)); - sl_DiscConfig.discTxResources_r12->present = SL_DiscConfig_r12__discTxResources_r12_PR_setup; - sl_DiscConfig.discTxResources_r12->choice.setup.present = SL_DiscConfig_r12__discTxResources_r12__setup_PR_scheduled_r12; + sl_DiscConfig.discTxResources_r12->present = LTE_SL_DiscConfig_r12__discTxResources_r12_PR_setup; + sl_DiscConfig.discTxResources_r12->choice.setup.present = LTE_SL_DiscConfig_r12__discTxResources_r12__setup_PR_scheduled_r12; //sl_DiscConfig.discTxResources_r12->choice.setup.choice.scheduled_r12.discHoppingConfig_r12; //sl_DiscConfig.discTxResources_r12->choice.setup.choice.scheduled_r12.discTF_IndexList_r12; //sl_DiscConfig.discTxResources_r12->choice.setup.choice.scheduled_r12.discTxConfig_r12; diff --git a/openair2/RRC/LTE/rrc_eNB_S1AP.c b/openair2/RRC/LTE/rrc_eNB_S1AP.c index d225b6eae0..83ae4fff40 100644 --- a/openair2/RRC/LTE/rrc_eNB_S1AP.c +++ b/openair2/RRC/LTE/rrc_eNB_S1AP.c @@ -52,7 +52,7 @@ #endif #include "msc.h" -#include "UERadioAccessCapabilityInformation.h" +#include "LTE_UERadioAccessCapabilityInformation.h" #include "gtpv1u_eNB_task.h" #include "RRC/LTE/rrc_eNB_GTPV1U.h" @@ -74,13 +74,13 @@ static const uint16_t S1AP_ENCRYPTION_EEA2_MASK = 0x4000; static const uint16_t S1AP_INTEGRITY_EIA1_MASK = 0x8000; static const uint16_t S1AP_INTEGRITY_EIA2_MASK = 0x4000; -#if (RRC_VERSION >= MAKE_VERSION(9, 2, 0)) -# define INTEGRITY_ALGORITHM_NONE SecurityAlgorithmConfig__integrityProtAlgorithm_eia0_v920 +#if (LTE_RRC_VERSION >= MAKE_VERSION(9, 2, 0)) +# define INTEGRITY_ALGORITHM_NONE LTE_SecurityAlgorithmConfig__integrityProtAlgorithm_eia0_v920 #else #ifdef EXMIMO_IOT -# define INTEGRITY_ALGORITHM_NONE SecurityAlgorithmConfig__integrityProtAlgorithm_eia2 +# define INTEGRITY_ALGORITHM_NONE LTE_SecurityAlgorithmConfig__integrityProtAlgorithm_eia2 #else -# define INTEGRITY_ALGORITHM_NONE SecurityAlgorithmConfig__integrityProtAlgorithm_reserved +# define INTEGRITY_ALGORITHM_NONE LTE_SecurityAlgorithmConfig__integrityProtAlgorithm_reserved #endif #endif @@ -305,21 +305,21 @@ rrc_eNB_get_ue_context_from_s1ap_ids( *\param algorithms The bit mask of available algorithms received from S1AP. *\return the selected algorithm. */ -static CipheringAlgorithm_r12_t rrc_eNB_select_ciphering(uint16_t algorithms) +static LTE_CipheringAlgorithm_r12_t rrc_eNB_select_ciphering(uint16_t algorithms) { //#warning "Forced return SecurityAlgorithmConfig__cipheringAlgorithm_eea0, to be deleted in future" - return CipheringAlgorithm_r12_eea0; + return LTE_CipheringAlgorithm_r12_eea0; if (algorithms & S1AP_ENCRYPTION_EEA2_MASK) { - return CipheringAlgorithm_r12_eea2; + return LTE_CipheringAlgorithm_r12_eea2; } if (algorithms & S1AP_ENCRYPTION_EEA1_MASK) { - return CipheringAlgorithm_r12_eea1; + return LTE_CipheringAlgorithm_r12_eea1; } - return CipheringAlgorithm_r12_eea0; + return LTE_CipheringAlgorithm_r12_eea0; } /*! \fn e_SecurityAlgorithmConfig__integrityProtAlgorithm rrc_eNB_select_integrity(uint16_t algorithms) @@ -327,15 +327,15 @@ static CipheringAlgorithm_r12_t rrc_eNB_select_ciphering(uint16_t algorithms) *\param algorithms The bit mask of available algorithms received from S1AP. *\return the selected algorithm. */ -static e_SecurityAlgorithmConfig__integrityProtAlgorithm rrc_eNB_select_integrity(uint16_t algorithms) +static e_LTE_SecurityAlgorithmConfig__integrityProtAlgorithm rrc_eNB_select_integrity(uint16_t algorithms) { if (algorithms & S1AP_INTEGRITY_EIA2_MASK) { - return SecurityAlgorithmConfig__integrityProtAlgorithm_eia2; + return LTE_SecurityAlgorithmConfig__integrityProtAlgorithm_eia2; } if (algorithms & S1AP_INTEGRITY_EIA1_MASK) { - return SecurityAlgorithmConfig__integrityProtAlgorithm_eia1; + return LTE_SecurityAlgorithmConfig__integrityProtAlgorithm_eia1; } return INTEGRITY_ALGORITHM_NONE; @@ -355,9 +355,9 @@ rrc_eNB_process_security( security_capabilities_t* security_capabilities_pP ) { - boolean_t changed = FALSE; - CipheringAlgorithm_r12_t cipheringAlgorithm; - e_SecurityAlgorithmConfig__integrityProtAlgorithm integrityProtAlgorithm; + boolean_t changed = FALSE; + LTE_CipheringAlgorithm_r12_t cipheringAlgorithm; + e_LTE_SecurityAlgorithmConfig__integrityProtAlgorithm integrityProtAlgorithm; /* Save security parameters */ ue_context_pP->ue_context.security_capabilities = *security_capabilities_pP; @@ -443,7 +443,7 @@ rrc_pdcp_config_security( #if defined(ENABLE_SECURITY) - SRB_ToAddModList_t* SRB_configList = ue_context_pP->ue_context.SRB_configList; + LTE_SRB_ToAddModList_t* SRB_configList = ue_context_pP->ue_context.SRB_configList; uint8_t *kRRCenc = NULL; uint8_t *kRRCint = NULL; uint8_t *kUPenc = NULL; @@ -565,21 +565,21 @@ void rrc_eNB_send_S1AP_UPLINK_NAS( const protocol_ctxt_t* const ctxt_pP, rrc_eNB_ue_context_t* const ue_context_pP, - UL_DCCH_Message_t* const ul_dcch_msg + LTE_UL_DCCH_Message_t* const ul_dcch_msg ) //------------------------------------------------------------------------------ { #if defined(ENABLE_ITTI) { - ULInformationTransfer_t *ulInformationTransfer = &ul_dcch_msg->message.choice.c1.choice.ulInformationTransfer; + LTE_ULInformationTransfer_t *ulInformationTransfer = &ul_dcch_msg->message.choice.c1.choice.ulInformationTransfer; - if ((ulInformationTransfer->criticalExtensions.present == ULInformationTransfer__criticalExtensions_PR_c1) + if ((ulInformationTransfer->criticalExtensions.present == LTE_ULInformationTransfer__criticalExtensions_PR_c1) && (ulInformationTransfer->criticalExtensions.choice.c1.present - == ULInformationTransfer__criticalExtensions__c1_PR_ulInformationTransfer_r8) + == LTE_ULInformationTransfer__criticalExtensions__c1_PR_ulInformationTransfer_r8) && (ulInformationTransfer->criticalExtensions.choice.c1.choice.ulInformationTransfer_r8.dedicatedInfoType.present - == ULInformationTransfer_r8_IEs__dedicatedInfoType_PR_dedicatedInfoNAS)) { + == LTE_ULInformationTransfer_r8_IEs__dedicatedInfoType_PR_dedicatedInfoNAS)) { /* This message hold a dedicated info NAS payload, forward it to NAS */ - struct ULInformationTransfer_r8_IEs__dedicatedInfoType *dedicatedInfoType = + struct LTE_ULInformationTransfer_r8_IEs__dedicatedInfoType *dedicatedInfoType = &ulInformationTransfer->criticalExtensions.choice.c1.choice.ulInformationTransfer_r8.dedicatedInfoType; uint32_t pdu_length; uint8_t *pdu_buffer; @@ -602,15 +602,15 @@ rrc_eNB_send_S1AP_UPLINK_NAS( } #else { - ULInformationTransfer_t *ulInformationTransfer; + LTE_ULInformationTransfer_t *ulInformationTransfer; ulInformationTransfer = &ul_dcch_msg->message.choice.c1.choice. ulInformationTransfer; if (ulInformationTransfer->criticalExtensions.present == - ULInformationTransfer__criticalExtensions_PR_c1) { + LTE_ULInformationTransfer__criticalExtensions_PR_c1) { if (ulInformationTransfer->criticalExtensions.choice.c1.present == - ULInformationTransfer__criticalExtensions__c1_PR_ulInformationTransfer_r8) { + LTE_ULInformationTransfer__criticalExtensions__c1_PR_ulInformationTransfer_r8) { ULInformationTransfer_r8_IEs_t *ulInformationTransferR8; @@ -619,7 +619,7 @@ rrc_eNB_send_S1AP_UPLINK_NAS( c1.choice.ulInformationTransfer_r8; if (ulInformationTransferR8->dedicatedInfoType.present == - ULInformationTransfer_r8_IEs__dedicatedInfoType_PR_dedicatedInfoNAS) { + LTE_ULInformationTransfer_r8_IEs__dedicatedInfoType_PR_dedicatedInfoNAS) { extract_imsi(ulInformationTransferR8->dedicatedInfoType.choice.dedicatedInfoNAS.buf, ulInformationTransferR8->dedicatedInfoType.choice.dedicatedInfoNAS.size, @@ -639,30 +639,30 @@ rrc_eNB_send_S1AP_UPLINK_NAS( void rrc_eNB_send_S1AP_UE_CAPABILITIES_IND( const protocol_ctxt_t* const ctxt_pP, rrc_eNB_ue_context_t* const ue_context_pP, - UL_DCCH_Message_t* ul_dcch_msg + LTE_UL_DCCH_Message_t* ul_dcch_msg ) //------------------------------------------------------------------------------ { - UECapabilityInformation_t *ueCapabilityInformation = &ul_dcch_msg->message.choice.c1.choice.ueCapabilityInformation; + LTE_UECapabilityInformation_t *ueCapabilityInformation = &ul_dcch_msg->message.choice.c1.choice.ueCapabilityInformation; /* 4096 is arbitrary, should be big enough */ unsigned char buf[4096]; unsigned char *buf2; - UERadioAccessCapabilityInformation_t rac; + LTE_UERadioAccessCapabilityInformation_t rac; - if (ueCapabilityInformation->criticalExtensions.present != UECapabilityInformation__criticalExtensions_PR_c1 - || ueCapabilityInformation->criticalExtensions.choice.c1.present != UECapabilityInformation__criticalExtensions__c1_PR_ueCapabilityInformation_r8) { + if (ueCapabilityInformation->criticalExtensions.present != LTE_UECapabilityInformation__criticalExtensions_PR_c1 + || ueCapabilityInformation->criticalExtensions.choice.c1.present != LTE_UECapabilityInformation__criticalExtensions__c1_PR_ueCapabilityInformation_r8) { LOG_E(RRC, "[eNB %d][UE %x] bad UE capabilities\n", ctxt_pP->module_id, ue_context_pP->ue_context.rnti); return; } - asn_enc_rval_t ret = uper_encode_to_buffer(&asn_DEF_UECapabilityInformation, NULL, ueCapabilityInformation, buf, 4096); + asn_enc_rval_t ret = uper_encode_to_buffer(&asn_DEF_LTE_UECapabilityInformation, NULL, ueCapabilityInformation, buf, 4096); if (ret.encoded == -1) abort(); - memset(&rac, 0, sizeof(UERadioAccessCapabilityInformation_t)); + memset(&rac, 0, sizeof(LTE_UERadioAccessCapabilityInformation_t)); - rac.criticalExtensions.present = UERadioAccessCapabilityInformation__criticalExtensions_PR_c1; - rac.criticalExtensions.choice.c1.present = UERadioAccessCapabilityInformation__criticalExtensions__c1_PR_ueRadioAccessCapabilityInformation_r8; + rac.criticalExtensions.present = LTE_UERadioAccessCapabilityInformation__criticalExtensions_PR_c1; + rac.criticalExtensions.choice.c1.present = LTE_UERadioAccessCapabilityInformation__criticalExtensions__c1_PR_ueRadioAccessCapabilityInformation_r8; rac.criticalExtensions.choice.c1.choice.ueRadioAccessCapabilityInformation_r8.ue_RadioAccessCapabilityInfo.buf = buf; rac.criticalExtensions.choice.c1.choice.ueRadioAccessCapabilityInformation_r8.ue_RadioAccessCapabilityInfo.size = (ret.encoded+7)/8; rac.criticalExtensions.choice.c1.choice.ueRadioAccessCapabilityInformation_r8.nonCriticalExtension = NULL; @@ -671,7 +671,7 @@ void rrc_eNB_send_S1AP_UE_CAPABILITIES_IND( buf2 = malloc16(8192); if (buf2 == NULL) abort(); - ret = uper_encode_to_buffer(&asn_DEF_UERadioAccessCapabilityInformation, NULL, &rac, buf2, 8192); + ret = uper_encode_to_buffer(&asn_DEF_LTE_UERadioAccessCapabilityInformation, NULL, &rac, buf2, 8192); if (ret.encoded == -1) abort(); @@ -690,7 +690,7 @@ void rrc_eNB_send_S1AP_NAS_FIRST_REQ( const protocol_ctxt_t* const ctxt_pP, rrc_eNB_ue_context_t* const ue_context_pP, - RRCConnectionSetupComplete_r8_IEs_t* rrcConnectionSetupComplete + LTE_RRCConnectionSetupComplete_r8_IEs_t* rrcConnectionSetupComplete ) //------------------------------------------------------------------------------ @@ -761,7 +761,7 @@ rrc_eNB_send_S1AP_NAS_FIRST_REQ( if (rrcConnectionSetupComplete->registeredMME != NULL) { /* Fill GUMMEI */ - struct RegisteredMME *r_mme = rrcConnectionSetupComplete->registeredMME; + struct LTE_RegisteredMME *r_mme = rrcConnectionSetupComplete->registeredMME; S1AP_NAS_FIRST_REQ (message_p).ue_identity.presenceMask |= UE_IDENTITIES_gummei; @@ -1858,7 +1858,7 @@ int rrc_eNB_process_PAGING_IND(MessageDef *msg_p, const char *msg_name, instance /* get nB from configuration */ /* get default DRX cycle from configuration */ Tc = (uint8_t)RC.rrc[instance]->configuration.pcch_defaultPagingCycle[CC_id]; - if (Tc < PCCH_Config__defaultPagingCycle_rf32 || Tc > PCCH_Config__defaultPagingCycle_rf256) { + if (Tc < LTE_PCCH_Config__defaultPagingCycle_rf32 || Tc > LTE_PCCH_Config__defaultPagingCycle_rf256) { continue; } Tue = (uint8_t)S1AP_PAGING_IND(msg_p).paging_drx; @@ -1867,10 +1867,10 @@ int rrc_eNB_process_PAGING_IND(MessageDef *msg_p, const char *msg_name, instance /* set pcch_nB = PCCH-Config->nB */ pcch_nB = (uint32_t)RC.rrc[instance]->configuration.pcch_nB[CC_id]; switch (pcch_nB) { - case PCCH_Config__nB_fourT: + case LTE_PCCH_Config__nB_fourT: Ns = 4; break; - case PCCH_Config__nB_twoT: + case LTE_PCCH_Config__nB_twoT: Ns = 2; break; default: @@ -1878,21 +1878,21 @@ int rrc_eNB_process_PAGING_IND(MessageDef *msg_p, const char *msg_name, instance break; } /* set N = min(T,nB) */ - if (pcch_nB > PCCH_Config__nB_oneT) { + if (pcch_nB > LTE_PCCH_Config__nB_oneT) { switch (pcch_nB) { - case PCCH_Config__nB_halfT: + case LTE_PCCH_Config__nB_halfT: N = T/2; break; - case PCCH_Config__nB_quarterT: + case LTE_PCCH_Config__nB_quarterT: N = T/4; break; - case PCCH_Config__nB_oneEighthT: + case LTE_PCCH_Config__nB_oneEighthT: N = T/8; break; - case PCCH_Config__nB_oneSixteenthT: + case LTE_PCCH_Config__nB_oneSixteenthT: N = T/16; break; - case PCCH_Config__nB_oneThirtySecondT: + case LTE_PCCH_Config__nB_oneThirtySecondT: N = T/32; break; default: diff --git a/openair2/RRC/LTE/rrc_eNB_S1AP.h b/openair2/RRC/LTE/rrc_eNB_S1AP.h index a924caf254..eb427bc7bd 100644 --- a/openair2/RRC/LTE/rrc_eNB_S1AP.h +++ b/openair2/RRC/LTE/rrc_eNB_S1AP.h @@ -33,7 +33,7 @@ # if defined(ENABLE_USE_MME) -#include "UL-DCCH-Message.h" +#include "LTE_UL-DCCH-Message.h" /* Up link procedures */ @@ -106,7 +106,7 @@ void rrc_eNB_send_S1AP_UPLINK_NAS( const protocol_ctxt_t* const ctxt_pP, rrc_eNB_ue_context_t* const ue_context_pP, - UL_DCCH_Message_t* const ul_dcch_msg + LTE_UL_DCCH_Message_t* const ul_dcch_msg ); /*! \fn void rrc_eNB_send_S1AP_UE_CAPABILITIES_IND(const protocol_ctxt_t * const ctxt_pP, eNB_RRC_UE_t * const ue_context_pP, UL_DCCH_Message_t *ul_dcch_msg) @@ -118,7 +118,7 @@ rrc_eNB_send_S1AP_UPLINK_NAS( void rrc_eNB_send_S1AP_UE_CAPABILITIES_IND( const protocol_ctxt_t* const ctxt_pP, rrc_eNB_ue_context_t* const ue_context_pP, - UL_DCCH_Message_t* ul_dcch_msg + LTE_UL_DCCH_Message_t* ul_dcch_msg ); /*! \fn rrc_eNB_send_S1AP_NAS_FIRST_REQ(const protocol_ctxt_t* const ctxt_pP,eNB_RRC_UE_t *const ue_context_pP, RRCConnectionSetupComplete_r8_IEs_t *rrcConnectionSetupComplete) @@ -132,7 +132,7 @@ void rrc_eNB_send_S1AP_NAS_FIRST_REQ( const protocol_ctxt_t* const ctxt_pP, rrc_eNB_ue_context_t* const ue_context_pP, - RRCConnectionSetupComplete_r8_IEs_t* rrcConnectionSetupComplete + LTE_RRCConnectionSetupComplete_r8_IEs_t* rrcConnectionSetupComplete ); diff --git a/openair2/RRC/LTE/rrc_extern.h b/openair2/RRC/LTE/rrc_extern.h index 59200fb9cc..90017dc80c 100644 --- a/openair2/RRC/LTE/rrc_extern.h +++ b/openair2/RRC/LTE/rrc_extern.h @@ -40,8 +40,8 @@ extern UE_RRC_INST *UE_rrc_inst; extern uint8_t DRB2LCHAN[8]; -extern LogicalChannelConfig_t SRB1_logicalChannelConfig_defaultValue; -extern LogicalChannelConfig_t SRB2_logicalChannelConfig_defaultValue; +extern LTE_LogicalChannelConfig_t SRB1_logicalChannelConfig_defaultValue; +extern LTE_LogicalChannelConfig_t SRB2_logicalChannelConfig_defaultValue; #ifndef PHY_EMUL diff --git a/openair2/RRC/LTE/rrc_proto.h b/openair2/RRC/LTE/rrc_proto.h index de16f45c2a..0aeb67dfba 100644 --- a/openair2/RRC/LTE/rrc_proto.h +++ b/openair2/RRC/LTE/rrc_proto.h @@ -106,7 +106,7 @@ rrc_ue_decode_dcch( const uint8_t eNB_indexP ); -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) int decode_SL_Discovery_Message( const protocol_ctxt_t* const ctxt_pP, const uint8_t eNB_index, @@ -130,7 +130,7 @@ rrc_ue_generate_RRCConnectionRequest( void rrc_ue_process_rrcConnectionReconfiguration( const protocol_ctxt_t* const ctxt_pP, - RRCConnectionReconfiguration_t* rrcConnectionReconfiguration, + LTE_RRCConnectionReconfiguration_t* rrcConnectionReconfiguration, uint8_t eNB_index ); @@ -140,7 +140,7 @@ rrc_ue_process_rrcConnectionReconfiguration( \param eNB_index Index of corresponding eNB/CH \param SRB_config Pointer to SRB_ToAddMod IE from configuration @returns 0 on success*/ -int32_t rrc_ue_establish_srb1(module_id_t module_idP,frame_t frameP,uint8_t eNB_index,struct SRB_ToAddMod *SRB_config); +int32_t rrc_ue_establish_srb1(module_id_t module_idP,frame_t frameP,uint8_t eNB_index,struct LTE_SRB_ToAddMod *SRB_config); /** \brief Establish SRB2 based on configuration in SRB_ToAddMod structure. Configures RLC/PDCP accordingly \param module_idP Instance ID of UE @@ -148,14 +148,14 @@ int32_t rrc_ue_establish_srb1(module_id_t module_idP,frame_t frameP,uint8_t eNB \param eNB_index Index of corresponding eNB/CH \param SRB_config Pointer to SRB_ToAddMod IE from configuration @returns 0 on success*/ -int32_t rrc_ue_establish_srb2(module_id_t module_idP,frame_t frameP, uint8_t eNB_index,struct SRB_ToAddMod *SRB_config); +int32_t rrc_ue_establish_srb2(module_id_t module_idP,frame_t frameP, uint8_t eNB_index,struct LTE_SRB_ToAddMod *SRB_config); /** \brief Establish a DRB according to DRB_ToAddMod structure \param module_idP Instance ID of UE \param eNB_index Index of corresponding CH/eNB \param DRB_config Pointer to DRB_ToAddMod IE from configuration @returns 0 on success */ -int32_t rrc_ue_establish_drb(module_id_t module_idP,frame_t frameP,uint8_t eNB_index,struct DRB_ToAddMod *DRB_config); +int32_t rrc_ue_establish_drb(module_id_t module_idP,frame_t frameP,uint8_t eNB_index,struct LTE_DRB_ToAddMod *DRB_config); /** \brief Process MobilityControlInfo Message to proceed with handover and configure PHY/MAC \param ctxt_pP Running context @@ -166,7 +166,7 @@ void rrc_ue_process_mobilityControlInfo( const protocol_ctxt_t* const ctxt_pP, const uint8_t eNB_index, - struct MobilityControlInfo* const mobilityControlInfo + struct LTE_MobilityControlInfo* const mobilityControlInfo ); /** \brief Process a measConfig Message and configure PHY/MAC @@ -177,7 +177,7 @@ void rrc_ue_process_measConfig( const protocol_ctxt_t* const ctxt_pP, const uint8_t eNB_index, - MeasConfig_t* const measConfig + LTE_MeasConfig_t* const measConfig ); /** \brief Process a RadioResourceConfigDedicated Message and configure PHY/MAC @@ -187,7 +187,7 @@ rrc_ue_process_measConfig( void rrc_ue_process_radioResourceConfigDedicated( const protocol_ctxt_t* const ctxt_pP, uint8_t eNB_index, - RadioResourceConfigDedicated_t *radioResourceConfigDedicated); + LTE_RadioResourceConfigDedicated_t *radioResourceConfigDedicated); /** \brief Process a RadioResourceConfig and configure PHY/MAC for SL communication/discovery @@ -200,10 +200,10 @@ void rrc_ue_process_radioResourceConfigDedicated( void rrc_ue_process_sidelink_radioResourceConfig( module_id_t Mod_idP, uint8_t eNB_index, - SystemInformationBlockType18_r12_t *sib18, - SystemInformationBlockType19_r12_t *sib19, - SL_CommConfig_r12_t* sl_CommConfig, - SL_DiscConfig_r12_t* sl_DiscConfig); + LTE_SystemInformationBlockType18_r12_t *sib18, + LTE_SystemInformationBlockType19_r12_t *sib19, + LTE_SL_CommConfig_r12_t* sl_CommConfig, + LTE_SL_DiscConfig_r12_t* sl_DiscConfig); /** \brief Init control socket to listen to incoming packets from ProSe App * @@ -269,7 +269,7 @@ void rrc_eNB_process_RRCConnectionSetupComplete( const protocol_ctxt_t* const ctxt_pP, rrc_eNB_ue_context_t* ue_context_pP, - RRCConnectionSetupComplete_r8_IEs_t* rrcConnectionSetupComplete + LTE_RRCConnectionSetupComplete_r8_IEs_t* rrcConnectionSetupComplete ); /**\brief Process the RRCConnectionReconfigurationComplete based on information coming from UE @@ -370,7 +370,7 @@ int rrc_eNB_generate_RRCConnectionReconfiguration_Sidelink( const protocol_ctxt_t* const ctxt_pP, rrc_eNB_ue_context_t* const ue_context_pP, - SL_DestinationInfoList_r12_t *destinationInfoList, + LTE_SL_DestinationInfoList_r12_t *destinationInfoList, int n_discoveryMessages ); @@ -381,24 +381,24 @@ uint8_t rrc_eNB_process_SidelinkUEInformation( const protocol_ctxt_t* const ctxt_pP, rrc_eNB_ue_context_t* ue_context_pP, - SidelinkUEInformation_r12_t* sidelinkUEInformation + LTE_SidelinkUEInformation_r12_t* sidelinkUEInformation ); /** \brief Get a Resource Pool to transmit SL communication \param ctxt_pP Running context \param ue_context_pP UE context \param destinationInfoList Pointer to the list of SL destinations*/ -SL_CommConfig_r12_t rrc_eNB_get_sidelink_commTXPool( +LTE_SL_CommConfig_r12_t rrc_eNB_get_sidelink_commTXPool( const protocol_ctxt_t* const ctxt_pP, rrc_eNB_ue_context_t* const ue_context_pP, - SL_DestinationInfoList_r12_t *destinationInfoList + LTE_SL_DestinationInfoList_r12_t *destinationInfoList ); /** \brief Get a Resource Pool for Discovery \param ctxt_pP Running context \param ue_context_pP UE context \param n_discoveryMessages Number of discovery messages*/ -SL_DiscConfig_r12_t rrc_eNB_get_sidelink_discTXPool( +LTE_SL_DiscConfig_r12_t rrc_eNB_get_sidelink_discTXPool( const protocol_ctxt_t* const ctxt_pP, rrc_eNB_ue_context_t* const ue_context_pP, int n_discoveryMessages @@ -572,14 +572,14 @@ void rrc_eNB_process_MeasurementReport( const protocol_ctxt_t* const ctxt_pP, rrc_eNB_ue_context_t* ue_context_pP, - const MeasResults_t* const measResults2 + const LTE_MeasResults_t* const measResults2 ); void rrc_eNB_generate_HandoverPreparationInformation( const protocol_ctxt_t* const ctxt_pP, rrc_eNB_ue_context_t* const ue_context_pP, - PhysCellId_t targetPhyId + LTE_PhysCellId_t targetPhyId ); void diff --git a/openair2/RRC/LTE/rrc_vars.h b/openair2/RRC/LTE/rrc_vars.h index 028a59f7d9..e328ce1359 100644 --- a/openair2/RRC/LTE/rrc_vars.h +++ b/openair2/RRC/LTE/rrc_vars.h @@ -47,34 +47,34 @@ uint8_t DRB2LCHAN[8]; long logicalChannelGroup0 = 0; long logicalChannelSR_Mask_r9=0; -struct LogicalChannelConfig__ul_SpecificParameters LCSRB1 = {1, - LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_infinity, +struct LTE_LogicalChannelConfig__ul_SpecificParameters LCSRB1 = {1, + LTE_LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_infinity, 0, &logicalChannelGroup0 }; -struct LogicalChannelConfig__ul_SpecificParameters LCSRB2 = {3, - LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_infinity, +struct LTE_LogicalChannelConfig__ul_SpecificParameters LCSRB2 = {3, + LTE_LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_infinity, 0, &logicalChannelGroup0 }; -#if (RRC_VERSION >= MAKE_VERSION(9, 0, 0)) -struct LogicalChannelConfig__ext1 logicalChannelSR_Mask_r9_ext1 = { +#if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) +struct LTE_LogicalChannelConfig__ext1 logicalChannelSR_Mask_r9_ext1 = { logicalChannelSR_Mask_r9: &logicalChannelSR_Mask_r9 }; #endif // These are the default SRB configurations from 36.331 (Chapter 9, p. 176-179 in v8.6) -LogicalChannelConfig_t SRB1_logicalChannelConfig_defaultValue = {ul_SpecificParameters: &LCSRB1 -#if (RRC_VERSION >= MAKE_VERSION(9, 0, 0)) +LTE_LogicalChannelConfig_t SRB1_logicalChannelConfig_defaultValue = {ul_SpecificParameters: &LCSRB1 +#if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) , ext1: &logicalChannelSR_Mask_r9_ext1 #endif }; -LogicalChannelConfig_t SRB2_logicalChannelConfig_defaultValue = {ul_SpecificParameters: &LCSRB2 -#if (RRC_VERSION >= MAKE_VERSION(9, 0, 0)) +LTE_LogicalChannelConfig_t SRB2_logicalChannelConfig_defaultValue = {ul_SpecificParameters: &LCSRB2 +#if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) , ext1: &logicalChannelSR_Mask_r9_ext1 #endif diff --git a/openair3/GTPV1-U/gtpv1u_eNB.c b/openair3/GTPV1-U/gtpv1u_eNB.c index 1e2cd85710..c8bfd1255c 100644 --- a/openair3/GTPV1-U/gtpv1u_eNB.c +++ b/openair3/GTPV1-U/gtpv1u_eNB.c @@ -263,7 +263,7 @@ NwGtpv1uRcT gtpv1u_eNB_process_stack_req( buffer_len, buffer, PDCP_TRANSMISSION_MODE_DATA -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) ,NULL, NULL #endif ); @@ -1052,7 +1052,7 @@ void *gtpv1u_eNB_process_itti_msg(void *notUsed) { if (hash_rc == HASH_TABLE_KEY_NOT_EXISTS) { LOG_E(GTPU, "nwGtpv1uProcessUlpReq failed: while getting ue rnti %x in hashtable ue_mapping\n", data_req_p->rnti); } else { - if ((data_req_p->rab_id >= GTPV1U_BEARER_OFFSET) && (data_req_p->rab_id <= max_val_DRB_Identity)) { + if ((data_req_p->rab_id >= GTPV1U_BEARER_OFFSET) && (data_req_p->rab_id <= max_val_LTE_DRB_Identity)) { enb_s1u_teid = gtpv1u_ue_data_p->bearers[data_req_p->rab_id - GTPV1U_BEARER_OFFSET].teid_eNB; sgw_s1u_teid = gtpv1u_ue_data_p->bearers[data_req_p->rab_id - GTPV1U_BEARER_OFFSET].teid_sgw; stack_req.apiType = NW_GTPV1U_ULP_API_SEND_TPDU; diff --git a/openair3/GTPV1-U/gtpv1u_eNB_defs.h b/openair3/GTPV1-U/gtpv1u_eNB_defs.h index db928c4438..978a3c58bc 100644 --- a/openair3/GTPV1-U/gtpv1u_eNB_defs.h +++ b/openair3/GTPV1-U/gtpv1u_eNB_defs.h @@ -28,7 +28,7 @@ */ #include "hashtable.h" -#include "asn_constant.h" +#include "LTE_asn_constant.h" #ifndef GTPV1U_ENB_DEFS_H_ #define GTPV1U_ENB_DEFS_H_ @@ -38,7 +38,7 @@ #define GTPV1U_UDP_PORT (2152) #define GTPV1U_BEARER_OFFSET 3 -#define GTPV1U_MAX_BEARERS_ID (max_val_DRB_Identity - GTPV1U_BEARER_OFFSET) +#define GTPV1U_MAX_BEARERS_ID (max_val_LTE_DRB_Identity - GTPV1U_BEARER_OFFSET) typedef enum { BEARER_DOWN = 0, diff --git a/targets/RT/USER/lte-enb.c b/targets/RT/USER/lte-enb.c index e2415e1156..20d2e87f75 100644 --- a/targets/RT/USER/lte-enb.c +++ b/targets/RT/USER/lte-enb.c @@ -146,7 +146,7 @@ void stop_eNB(int nb_inst); int wakeup_tx(PHY_VARS_eNB *eNB,RU_proc_t *ru_proc); int wakeup_txfh(eNB_rxtx_proc_t *proc,RU_proc_t *ru_proc); void wakeup_prach_eNB(PHY_VARS_eNB *eNB,RU_t *ru,int frame,int subframe); -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) void wakeup_prach_eNB_br(PHY_VARS_eNB *eNB,RU_t *ru,int frame,int subframe); #endif extern PARALLEL_CONF_t get_thread_parallel_conf(void); @@ -209,7 +209,7 @@ static inline int rxtx(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc, char *thread_nam // if this is IF5 or 3GPP_eNB if (eNB && eNB->RU_list && eNB->RU_list[0] && eNB->RU_list[0]->function < NGFI_RAU_IF4p5) { wakeup_prach_eNB(eNB,NULL,proc->frame_rx,proc->subframe_rx); -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) wakeup_prach_eNB_br(eNB,NULL,proc->frame_rx,proc->subframe_rx); #endif } @@ -697,7 +697,7 @@ void wakeup_prach_eNB(PHY_VARS_eNB *eNB,RU_t *ru,int frame,int subframe) { } -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) void wakeup_prach_eNB_br(PHY_VARS_eNB *eNB,RU_t *ru,int frame,int subframe) { eNB_proc_t *proc = &eNB->proc; @@ -787,7 +787,7 @@ static void* eNB_thread_prach( void* param ) { LOG_D(PHY,"Running eNB prach procedures\n"); prach_procedures(eNB -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) ,0 #endif ); @@ -801,7 +801,7 @@ static void* eNB_thread_prach( void* param ) { return &eNB_thread_prach_status; } -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) /*! * \brief The prach receive thread of eNB for BL/CE UEs. * \param param is a \ref eNB_proc_t structure which contains the info what to process. @@ -886,7 +886,7 @@ void init_eNB_proc(int inst) { eNB_proc_t *proc; eNB_rxtx_proc_t *proc_rxtx; pthread_attr_t *attr0=NULL,*attr1=NULL,*attr_prach=NULL; -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) pthread_attr_t *attr_prach_br=NULL; #endif @@ -932,7 +932,7 @@ void init_eNB_proc(int inst) { pthread_attr_init( &proc->attr_asynch_rxtx); pthread_attr_init( &proc_rxtx[0].attr_rxtx); pthread_attr_init( &proc_rxtx[1].attr_rxtx); -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) proc->instance_cnt_prach_br = -1; proc->RU_mask_prach_br=0; pthread_mutex_init( &proc->mutex_prach_br, NULL); @@ -944,7 +944,7 @@ void init_eNB_proc(int inst) { attr0 = &proc_rxtx[0].attr_rxtx; attr1 = &proc_rxtx[1].attr_rxtx; attr_prach = &proc->attr_prach; -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) attr_prach_br = &proc->attr_prach_br; #endif @@ -966,7 +966,7 @@ void init_eNB_proc(int inst) { pthread_create( &proc_rxtx[1].pthread_rxtx, attr1, tx_thread, proc); } pthread_create( &proc->pthread_prach, attr_prach, eNB_thread_prach, eNB ); -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) pthread_create( &proc->pthread_prach_br, attr_prach_br, eNB_thread_prach_br, eNB ); #endif /*char name[16]; @@ -1054,7 +1054,7 @@ void kill_eNB_proc(int inst) { LOG_I(PHY, "Destroying prach mutex/cond\n"); pthread_mutex_destroy( &proc->mutex_prach ); pthread_cond_destroy( &proc->cond_prach ); -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) proc->instance_cnt_prach_br = 0; pthread_cond_signal( &proc->cond_prach_br ); pthread_join( proc->pthread_prach_br, (void**)&status ); @@ -1075,7 +1075,7 @@ void kill_eNB_proc(int inst) { pthread_attr_destroy(&proc->attr_asynch_rxtx); pthread_attr_destroy(&proc_rxtx[0].attr_rxtx); pthread_attr_destroy(&proc_rxtx[1].attr_rxtx); -#ifdef Rel14 +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) pthread_mutex_destroy(&proc->mutex_RU_PRACH_br); pthread_attr_destroy(&proc->attr_prach_br); #endif @@ -1214,7 +1214,7 @@ void init_eNB_afterRU(void) { LOG_I(PHY,"Overwriting eNB->prach_vars.rxsigF[0]:%p\n", eNB->prach_vars.rxsigF[0]); eNB->prach_vars.rxsigF[0] = (int16_t**)malloc16(64*sizeof(int16_t*)); -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) for (int ce_level=0;ce_level<4;ce_level++) { LOG_I(PHY,"Overwriting eNB->prach_vars_br.rxsigF.rxsigF[0]:%p\n", eNB->prach_vars_br.rxsigF[ce_level]); eNB->prach_vars_br.rxsigF[ce_level] = (int16_t**)malloc16(64*sizeof(int16_t*)); @@ -1237,7 +1237,7 @@ void init_eNB_afterRU(void) { for (i=0;iRU_list[ru_id]->nb_rx;aa++,i++) { LOG_I(PHY,"Attaching RU %d antenna %d to eNB antenna %d\n",eNB->RU_list[ru_id]->idx,i,aa); eNB->prach_vars.rxsigF[0][aa] = eNB->RU_list[ru_id]->prach_rxsigF[i]; -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) for (int ce_level=0;ce_level<4;ce_level++) eNB->prach_vars_br.rxsigF[ce_level][aa] = eNB->RU_list[ru_id]->prach_rxsigF_br[ce_level][i]; #endif @@ -1290,7 +1290,7 @@ void init_eNB_afterRU(void) { RC.ru[ru_id]->wakeup_rxtx = wakeup_rxtx; RC.ru[ru_id]->wakeup_prach_eNB = wakeup_prach_eNB; -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) RC.ru[ru_id]->wakeup_prach_eNB_br = wakeup_prach_eNB_br; #endif RC.ru[ru_id]->eNB_top = eNB_top; diff --git a/targets/RT/USER/lte-ru.c b/targets/RT/USER/lte-ru.c index 7002bc4ebd..4a0d2d5266 100644 --- a/targets/RT/USER/lte-ru.c +++ b/targets/RT/USER/lte-ru.c @@ -526,7 +526,7 @@ void fh_if4p5_south_asynch_in(RU_t *ru,int *frame,int *subframe) { } if (packet_type == IF4p5_PULFFT) symbol_mask &= (~(1<= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) else if (packet_type == IF4p5_PRACH_BR_CE0) prach_rx &= (~0x2); else if (packet_type == IF4p5_PRACH_BR_CE1) prach_rx &= (~0x4); else if (packet_type == IF4p5_PRACH_BR_CE2) prach_rx &= (~0x8); @@ -1086,7 +1086,7 @@ static void* ru_thread_prach( void* param ) { if (ru->eNB_list[0]){ prach_procedures( ru->eNB_list[0] -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) ,0 #endif ); @@ -1099,7 +1099,7 @@ static void* ru_thread_prach( void* param ) { NULL, proc->frame_prach, 0 -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) ,0 #endif ); @@ -1114,7 +1114,7 @@ static void* ru_thread_prach( void* param ) { return &ru_thread_prach_status; } -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) static void* ru_thread_prach_br( void* param ) { static int ru_thread_prach_status; @@ -1315,7 +1315,7 @@ static inline int wakeup_prach_ru(RU_t *ru) { return(0); } -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) static inline int wakeup_prach_ru_br(RU_t *ru) { struct timespec wait; @@ -1739,7 +1739,7 @@ static void* ru_thread( void* param ) { if ((ru->do_prach>0) && (is_prach_subframe(fp, proc->frame_rx, proc->subframe_rx)==1)) { wakeup_prach_ru(ru); } -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) else if ((ru->do_prach>0) && (is_prach_subframe(fp, proc->frame_rx, proc->subframe_rx)>1)) { wakeup_prach_ru_br(ru); } @@ -2101,7 +2101,7 @@ void init_RU_proc(RU_t *ru) { RU_proc_t *proc; pthread_attr_t *attr_FH=NULL,*attr_FH1=NULL,*attr_prach=NULL,*attr_asynch=NULL,*attr_synch=NULL,*attr_emulateRF=NULL; //pthread_attr_t *attr_fep=NULL; -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) pthread_attr_t *attr_prach_br=NULL; #endif char name[100]; @@ -2154,7 +2154,7 @@ void init_RU_proc(RU_t *ru) { pthread_attr_init( &proc->attr_asynch_rxtx); pthread_attr_init( &proc->attr_fep); -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) proc->instance_cnt_prach_br = -1; pthread_mutex_init( &proc->mutex_prach_br, NULL); pthread_cond_init( &proc->cond_prach_br, NULL); @@ -2177,7 +2177,7 @@ void init_RU_proc(RU_t *ru) { attr_synch = &proc->attr_synch; attr_asynch = &proc->attr_asynch_rxtx; attr_emulateRF = &proc->attr_emulateRF; -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) attr_prach_br = &proc->attr_prach_br; #endif #endif @@ -2206,7 +2206,7 @@ void init_RU_proc(RU_t *ru) { if (ru->function == NGFI_RRU_IF4p5) { pthread_create( &proc->pthread_prach, attr_prach, ru_thread_prach, (void*)ru ); -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) pthread_create( &proc->pthread_prach_br, attr_prach_br, ru_thread_prach_br, (void*)ru ); #endif if (ru->is_slave == 1) pthread_create( &proc->pthread_synch, attr_synch, ru_thread_synch, (void*)ru); @@ -2288,7 +2288,7 @@ void kill_RU_proc(RU_t *ru) pthread_cond_signal(&proc->cond_prach); pthread_mutex_unlock(&proc->mutex_prach); -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) pthread_mutex_lock(&proc->mutex_prach_br); proc->instance_cnt_prach_br = 0; pthread_cond_signal(&proc->cond_prach_br); @@ -2322,7 +2322,7 @@ void kill_RU_proc(RU_t *ru) if (ru->function == NGFI_RRU_IF4p5) { LOG_D(PHY, "Joining pthread_prach\n"); pthread_join(proc->pthread_prach, NULL); -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) LOG_D(PHY, "Joining pthread_prach_br\n"); pthread_join(proc->pthread_prach_br, NULL); #endif @@ -2364,7 +2364,7 @@ void kill_RU_proc(RU_t *ru) pthread_attr_destroy(&proc->attr_asynch_rxtx); pthread_attr_destroy(&proc->attr_fep); -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) pthread_mutex_destroy(&proc->mutex_prach_br); pthread_cond_destroy(&proc->cond_prach_br); pthread_attr_destroy(&proc->attr_prach_br); @@ -2460,7 +2460,7 @@ void configure_ru(int idx, LOG_I(PHY,"REMOTE_IF4p5: prach_FrequOffset %d, prach_ConfigIndex %d\n", config->prach_FreqOffset[0],config->prach_ConfigIndex[0]); -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) int i; for (i=0;i<4;i++) { config->emtc_prach_CElevel_enable[0][i] = ru->frame_parms.prach_emtc_config_common.prach_ConfigInfo.prach_CElevel_enable[i]; @@ -2504,7 +2504,7 @@ void configure_rru(int idx, config->prach_FreqOffset[0],config->prach_ConfigIndex[0],ru->att_tx,ru->att_rx); ru->frame_parms.prach_config_common.prach_ConfigInfo.prach_FreqOffset = config->prach_FreqOffset[0]; ru->frame_parms.prach_config_common.prach_ConfigInfo.prach_ConfigIndex = config->prach_ConfigIndex[0]; -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) for (int i=0;i<4;i++) { ru->frame_parms.prach_emtc_config_common.prach_ConfigInfo.prach_CElevel_enable[i] = config->emtc_prach_CElevel_enable[0][i]; ru->frame_parms.prach_emtc_config_common.prach_ConfigInfo.prach_FreqOffset[i] = config->emtc_prach_FreqOffset[0][i]; diff --git a/targets/RT/USER/lte-ue.c b/targets/RT/USER/lte-ue.c index c49a54b98a..fa67165693 100644 --- a/targets/RT/USER/lte-ue.c +++ b/targets/RT/USER/lte-ue.c @@ -1862,7 +1862,7 @@ void init_UE_threads_stub(int inst) { #ifdef OPENAIR2 void fill_ue_band_info(void) { - UE_EUTRA_Capability_t *UE_EUTRA_Capability = UE_rrc_inst[0].UECap->UE_EUTRA_Capability; + LTE_UE_EUTRA_Capability_t *UE_EUTRA_Capability = UE_rrc_inst[0].UECap->UE_EUTRA_Capability; int i,j; bands_to_scan.nbands = UE_EUTRA_Capability->rf_Parameters.supportedBandListEUTRA.list.count; diff --git a/targets/RT/USER/lte-uesoftmodem.c b/targets/RT/USER/lte-uesoftmodem.c index 69556b19f2..3071544133 100644 --- a/targets/RT/USER/lte-uesoftmodem.c +++ b/targets/RT/USER/lte-uesoftmodem.c @@ -914,7 +914,7 @@ printf("~~~~~~~~~~~~~~~~~~~~successfully get the parallel config[%d], worker con #endif //TTN for D2D -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) printf ("RRC control socket\n"); rrc_control_socket_init(); printf ("PDCP PC5S socket\n"); From 075a713de9ae1a09245facb0d7274ed499c33f86 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Thu, 18 Oct 2018 16:42:32 +0200 Subject: [PATCH 018/233] hotfix: fix a problem with multiple UEs The symptom: when two UEs do uplink traffic at the same time, the eNB fails to decode data sometimes. This has been seen with FDD and 50 RBs. This generates a cascade of other problems leading to disconnection/reconnection events seen in the log. The problem: there are probably many, but one obvious bug was found while analyzing some logs. Scheduling in the same TTI one UE's uplink traffic and random access (msg3) was done in the same RB. This commit fixes this simple case. It is probably not the end of the story. This is a hotfix, that does not change the code much. We need to use vrb_map_UL properly all over the places. Today is not used, but this is the way to go (most probably). --- openair2/LAYER2/MAC/eNB_scheduler_ulsch.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c b/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c index 31c11e2c0a..c521837142 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c @@ -1029,7 +1029,8 @@ schedule_ulsch(module_id_t module_idP, frame_t frameP, for (i = 0; i < NB_RA_PROC_MAX; i++) { if ((cc->ra[i].state == WAITMSG3) && (cc->ra[i].Msg3_subframe == sched_subframe)) { - first_rb[CC_id]++; + if (first_rb[CC_id] < cc->ra[i].msg3_first_rb + cc->ra[i].msg3_nb_rb) + first_rb[CC_id] = cc->ra[i].msg3_first_rb + cc->ra[i].msg3_nb_rb; // cc->ray[i].Msg3_subframe = -1; break; } From 506edcaec26869922c0da3d2cb36743648c3a0b7 Mon Sep 17 00:00:00 2001 From: Raymond Knopp Date: Sat, 20 Oct 2018 09:16:24 +0200 Subject: [PATCH 019/233] lowered debug level for RF simulator --- targets/PROJECTS/GENERIC-LTE-EPC/CONF/rru.oaisim.conf | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rru.oaisim.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rru.oaisim.conf index ba2e7f1ada..750936cfea 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rru.oaisim.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rru.oaisim.conf @@ -31,9 +31,9 @@ log_config = { global_log_verbosity ="medium"; hw_log_level ="info"; hw_log_verbosity ="medium"; - phy_log_level ="debug"; + phy_log_level ="info"; phy_log_verbosity ="medium"; - mac_log_level ="debug"; + mac_log_level ="info"; mac_log_verbosity ="high"; rlc_log_level ="info"; rlc_log_verbosity ="medium"; From d27a0cbb231638cec8f57e154bf5f5cbb4361e69 Mon Sep 17 00:00:00 2001 From: Y_Tomita Date: Mon, 22 Oct 2018 13:26:51 +0900 Subject: [PATCH 020/233] Move initialization of ru pointer before it's accessed. --- targets/RT/USER/lte-softmodem.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/targets/RT/USER/lte-softmodem.c b/targets/RT/USER/lte-softmodem.c index 101f8fa0a8..d3f1b9736a 100755 --- a/targets/RT/USER/lte-softmodem.c +++ b/targets/RT/USER/lte-softmodem.c @@ -1034,8 +1034,14 @@ int main( int argc, char **argv ) } printf("NFAPI MODE:%s\n", nfapi_mode_str); - if (nfapi_mode==2) // VNF + +if (nfapi_mode==2) {// VNF +#if defined(PRE_SCD_THREAD) + init_ru_vnf(); // ru pointer is necessary for pre_scd. +#endif wait_nfapi_init("main?"); + } + printf("START MAIN THREADS\n"); @@ -1064,12 +1070,6 @@ int main( int argc, char **argv ) } -#if defined(PRE_SCD_THREAD) - if (nfapi_mode==2) { // ru pointer is necessary for pre_scd. - init_ru_vnf(); - } -#endif - config_sync_var=0; if (nfapi_mode==1) { // PNF From 7a755d8df6e4646231928ac1ee0ba86a5d43eb9e Mon Sep 17 00:00:00 2001 From: Y_Tomita Date: Mon, 22 Oct 2018 13:30:09 +0900 Subject: [PATCH 021/233] Modify not to use initializations of usual test in L2 FAPI simulator. --- targets/RT/USER/lte-softmodem.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/targets/RT/USER/lte-softmodem.c b/targets/RT/USER/lte-softmodem.c index d3f1b9736a..87c43fbf55 100755 --- a/targets/RT/USER/lte-softmodem.c +++ b/targets/RT/USER/lte-softmodem.c @@ -1049,7 +1049,7 @@ if (nfapi_mode==2) {// VNF number_of_cards = 1; printf("RC.nb_L1_inst:%d\n", RC.nb_L1_inst); - if (RC.nb_L1_inst > 0) { + if (RC.nb_L1_inst > 0 && nfapi_mode != 2) { printf("Initializing eNB threads single_thread_flag:%d wait_for_sync:%d\n", single_thread_flag,wait_for_sync); init_eNB(single_thread_flag,wait_for_sync); // for (inst=0;inst0) { + if (RC.nb_RU >0 && nfapi_mode != 2) { printf("Initializing RU threads\n"); init_RU(rf_config_file); for (ru_id=0;ru_id Date: Mon, 22 Oct 2018 13:33:24 +0900 Subject: [PATCH 022/233] Modify to use Mod_id = 0 in L2 FAPI simulator's eNB to avoid Segmentation Fault --- targets/RT/USER/lte-enb.c | 9 +++++++-- targets/RT/USER/lte-ru.c | 9 +++++++-- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/targets/RT/USER/lte-enb.c b/targets/RT/USER/lte-enb.c index a93a52a1a9..17d3cd63d4 100755 --- a/targets/RT/USER/lte-enb.c +++ b/targets/RT/USER/lte-enb.c @@ -236,8 +236,13 @@ static inline int rxtx(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc, char *thread_nam if (nfapi_mode == 2){ new_dlsch_ue_select_tbl_in_use = dlsch_ue_select_tbl_in_use; dlsch_ue_select_tbl_in_use = !dlsch_ue_select_tbl_in_use; - memcpy(&pre_scd_eNB_UE_stats,&RC.mac[ru->eNB_list[0]->Mod_id]->UE_list.eNB_UE_stats, sizeof(eNB_UE_STATS)*MAX_NUM_CCs*NUMBER_OF_UE_MAX); - memcpy(&pre_scd_activeUE, &RC.mac[ru->eNB_list[0]->Mod_id]->UE_list.active, sizeof(boolean_t)*NUMBER_OF_UE_MAX); + +// L2-emulator can work only one eNB. +// memcpy(&pre_scd_eNB_UE_stats,&RC.mac[ru->eNB_list[0]->Mod_id]->UE_list.eNB_UE_stats, sizeof(eNB_UE_STATS)*MAX_NUM_CCs*NUMBER_OF_UE_MAX); +// memcpy(&pre_scd_activeUE, &RC.mac[ru->eNB_list[0]->Mod_id]->UE_list.active, sizeof(boolean_t)*NUMBER_OF_UE_MAX); + memcpy(&pre_scd_eNB_UE_stats,&RC.mac[0]->UE_list.eNB_UE_stats, sizeof(eNB_UE_STATS)*MAX_NUM_CCs*NUMBER_OF_UE_MAX); + memcpy(&pre_scd_activeUE, &RC.mac[0]->UE_list.active, sizeof(boolean_t)*NUMBER_OF_UE_MAX); + if (pthread_mutex_lock(&ru->proc.mutex_pre_scd)!= 0) { LOG_E( PHY, "[eNB] error locking proc mutex for eNB pre scd\n"); exit_fun("error locking mutex_time"); diff --git a/targets/RT/USER/lte-ru.c b/targets/RT/USER/lte-ru.c index 750d8239da..502d406d0e 100755 --- a/targets/RT/USER/lte-ru.c +++ b/targets/RT/USER/lte-ru.c @@ -121,7 +121,7 @@ extern int emulate_rf; extern int numerology; extern clock_source_t clock_source; extern uint8_t dlsch_ue_select_tbl_in_use; - +extern uint8_t nfapi_mode; extern PARALLEL_CONF_t get_thread_parallel_conf(void); extern WORKER_CONF_t get_thread_worker_conf(void); extern void phy_init_RU(RU_t*); @@ -1923,7 +1923,12 @@ void* pre_scd_thread( void* param ){ int CC_id; int Mod_id; RU_t *ru = (RU_t*)param; - Mod_id = ru->eNB_list[0]->Mod_id; + + // L2-emulator can work only one eNB + if( nfapi_mode == 2) + Mod_id = 0; + else + Mod_id = ru->eNB_list[0]->Mod_id; frame = 0; subframe = 4; From 50df0f683f9ed8e2cf45ecb12173567f30659a7d Mon Sep 17 00:00:00 2001 From: Y_Tomita Date: Mon, 22 Oct 2018 13:42:43 +0900 Subject: [PATCH 023/233] Temporary Fix: disabling FAPI log to avoid Segmentation Fault. --- nfapi/open-nFAPI/pnf/src/pnf.c | 2 +- nfapi/open-nFAPI/pnf/src/pnf_p7.c | 2 +- nfapi/open-nFAPI/vnf/src/vnf_p7.c | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) mode change 100644 => 100755 nfapi/open-nFAPI/pnf/src/pnf.c mode change 100644 => 100755 nfapi/open-nFAPI/pnf/src/pnf_p7.c mode change 100644 => 100755 nfapi/open-nFAPI/vnf/src/vnf_p7.c diff --git a/nfapi/open-nFAPI/pnf/src/pnf.c b/nfapi/open-nFAPI/pnf/src/pnf.c old mode 100644 new mode 100755 index d0a7fa6fd1..362162cd9d --- a/nfapi/open-nFAPI/pnf/src/pnf.c +++ b/nfapi/open-nFAPI/pnf/src/pnf.c @@ -1260,7 +1260,7 @@ int pnf_connect(pnf_t* pnf) address = inet_ntoa(addr->sin_addr); } - NFAPI_TRACE(NFAPI_TRACE_NOTE, "Host address info %d Family:%s Address:%s\n", i++, family, address); +// NFAPI_TRACE(NFAPI_TRACE_NOTE, "Host address info %d Family:%s Address:%s\n", i++, family, address); if (pnf->sctp) { diff --git a/nfapi/open-nFAPI/pnf/src/pnf_p7.c b/nfapi/open-nFAPI/pnf/src/pnf_p7.c old mode 100644 new mode 100755 index 8d94c23476..f7152cc077 --- a/nfapi/open-nFAPI/pnf/src/pnf_p7.c +++ b/nfapi/open-nFAPI/pnf/src/pnf_p7.c @@ -379,7 +379,7 @@ static uint32_t get_sf_time(uint32_t now_hr, uint32_t sf_start_hr) { if(now_hr < sf_start_hr) { - NFAPI_TRACE(NFAPI_TRACE_INFO, "now is earlier than start of subframe now_hr:%u sf_start_hr:%u\n", now_hr, sf_start_hr); +// NFAPI_TRACE(NFAPI_TRACE_INFO, "now is earlier than start of subframe now_hr:%u sf_start_hr:%u\n", now_hr, sf_start_hr); return 0; } else diff --git a/nfapi/open-nFAPI/vnf/src/vnf_p7.c b/nfapi/open-nFAPI/vnf/src/vnf_p7.c old mode 100644 new mode 100755 index cea259c35b..6c17fb2a99 --- a/nfapi/open-nFAPI/vnf/src/vnf_p7.c +++ b/nfapi/open-nFAPI/vnf/src/vnf_p7.c @@ -1203,13 +1203,13 @@ void vnf_handle_ul_node_sync(void *pRecvMsg, int recvMsgLen, vnf_p7_t* vnf_p7) if(phy->in_sync == 0) { - NFAPI_TRACE(NFAPI_TRACE_NOTE, "***** Adjusting VNF phy_id:%d SFN/SF (%s) from %d to %d (%d) mode:%s zeroCount:%u sync:%s\n", +/* NFAPI_TRACE(NFAPI_TRACE_NOTE, "***** Adjusting VNF phy_id:%d SFN/SF (%s) from %d to %d (%d) mode:%s zeroCount:%u sync:%s\n", ind.header.phy_id, (phy->in_sync ? "via sfn" : "now"), NFAPI_SFNSF2DEC(curr_sfn_sf), NFAPI_SFNSF2DEC(new_sfn_sf), phy->adjustment, phy->filtered_adjust ? "FILTERED" : "ABSOLUTE", phy->zero_count, phy->in_sync ? "IN_SYNC" : "OUT_OF_SYNC"); - +*/ phy->sfn_sf = new_sfn_sf; } } From 2151da7b333232ba57f363b3520ae8994e29921f Mon Sep 17 00:00:00 2001 From: Y_Tomita Date: Mon, 22 Oct 2018 13:47:05 +0900 Subject: [PATCH 024/233] Fix to set message_id in VNF. --- nfapi/oai_integration/nfapi_vnf.c | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 nfapi/oai_integration/nfapi_vnf.c diff --git a/nfapi/oai_integration/nfapi_vnf.c b/nfapi/oai_integration/nfapi_vnf.c old mode 100644 new mode 100755 From ac0d6cc1f3c8fb85b6b1f53c3a1238e2889a06c7 Mon Sep 17 00:00:00 2001 From: Y_Tomita Date: Mon, 22 Oct 2018 14:00:47 +0900 Subject: [PATCH 025/233] Add NAS initialization in L2 FAPI simulator. --- targets/RT/USER/lte-ue.c | 7 +++++++ 1 file changed, 7 insertions(+) mode change 100644 => 100755 targets/RT/USER/lte-ue.c diff --git a/targets/RT/USER/lte-ue.c b/targets/RT/USER/lte-ue.c old mode 100644 new mode 100755 index c49a54b98a..ada4144a4f --- a/targets/RT/USER/lte-ue.c +++ b/targets/RT/USER/lte-ue.c @@ -1771,6 +1771,13 @@ void init_UE_single_thread_stub(int nb_inst) { AssertFatal(PHY_vars_UE_g!=NULL,"PHY_vars_UE_g is NULL\n"); AssertFatal(PHY_vars_UE_g[i]!=NULL,"PHY_vars_UE_g[inst] is NULL\n"); AssertFatal(PHY_vars_UE_g[i][0]!=NULL,"PHY_vars_UE_g[inst][0] is NULL\n"); + if(nfapi_mode == 3){ +#ifdef NAS_UE + MessageDef *message_p; + message_p = itti_alloc_new_message(TASK_NAS_UE, INITIALIZE_MESSAGE); + itti_send_msg_to_task (TASK_NAS_UE, i + NB_eNB_INST, message_p); +#endif + } } UE = PHY_vars_UE_g[0][0]; From f4aa4ee9187d20fc848761ebb5b8987389bba800 Mon Sep 17 00:00:00 2001 From: Y_Tomita Date: Mon, 22 Oct 2018 14:06:01 +0900 Subject: [PATCH 026/233] Fix for setting of harq_information->harq_information_rel10.tl.tag --- openair2/LAYER2/MAC/eNB_scheduler_primitives.c | 1 + 1 file changed, 1 insertion(+) mode change 100644 => 100755 openair2/LAYER2/MAC/eNB_scheduler_primitives.c diff --git a/openair2/LAYER2/MAC/eNB_scheduler_primitives.c b/openair2/LAYER2/MAC/eNB_scheduler_primitives.c old mode 100644 new mode 100755 index c9d3d9dbac..bb4e7a0f38 --- a/openair2/LAYER2/MAC/eNB_scheduler_primitives.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_primitives.c @@ -1286,6 +1286,7 @@ fill_nfapi_ulsch_harq_information(module_id_t module_ */ #endif harq_information->harq_information_rel10.delta_offset_harq = puschConfigDedicated->betaOffset_ACK_Index; + harq_information->harq_information_rel10.tl.tag = NFAPI_UL_CONFIG_REQUEST_ULSCH_HARQ_INFORMATION_REL10_TAG; AssertFatal(UE_list->UE_template[CC_idP][UE_id].physicalConfigDedicated->pucch_ConfigDedicated != NULL, "pucch_ConfigDedicated is null!\n"); if ((UE_list->UE_template[CC_idP][UE_id].physicalConfigDedicated->pucch_ConfigDedicated->tdd_AckNackFeedbackMode != NULL) From d43dd64b94460c6ead834045a87068a17c8323c7 Mon Sep 17 00:00:00 2001 From: Y_Tomita Date: Mon, 22 Oct 2018 14:12:41 +0900 Subject: [PATCH 027/233] Change not to watch timing in MSG2 and MSG4 procedure in L2 FAPI simulator because it's possible to differ timing(frame, subframe) between eNB and UE. --- openair2/LAYER2/MAC/eNB_scheduler_RA.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) mode change 100644 => 100755 openair2/LAYER2/MAC/eNB_scheduler_RA.c diff --git a/openair2/LAYER2/MAC/eNB_scheduler_RA.c b/openair2/LAYER2/MAC/eNB_scheduler_RA.c old mode 100644 new mode 100755 index b637a92a96..98a500a23d --- a/openair2/LAYER2/MAC/eNB_scheduler_RA.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_RA.c @@ -501,7 +501,9 @@ generate_Msg2(module_id_t module_idP, int CC_idP, frame_t frameP, #endif { - if ((ra->Msg2_frame == frameP) && (ra->Msg2_subframe == subframeP)) { + // In case of nFAPI, sometimes timing of eNB and UE become different. + // So if nfapi_mode == 2(VNF) , this function don't check timing to avoid Attach failure. + if (((ra->Msg2_frame == frameP) && (ra->Msg2_subframe == subframeP)) || (nfapi_mode == 2)) { LOG_D(MAC, "[eNB %d] CC_id %d Frame %d, subframeP %d: Generating RAR DCI, state %d\n", module_idP, CC_idP, frameP, subframeP, ra->state); @@ -1010,7 +1012,9 @@ generate_Msg4(module_id_t module_idP, int CC_idP, frame_t frameP, { // This is normal LTE case LOG_D(MAC, "generate_Msg4 1 ra->Msg4_frame SFN/SF: %d.%d, frameP SFN/SF: %d.%d FOR eNB_Mod: %d \n", ra->Msg4_frame, ra->Msg4_subframe, frameP, subframeP, module_idP); - if ((ra->Msg4_frame == frameP) && (ra->Msg4_subframe == subframeP)) { + // In case of nFAPI, sometimes timing of eNB and UE become different. + // So if nfapi_mode == 2(VNF) , this function don't check timing to avoid Attach failure. + if (((ra->Msg4_frame == frameP) && (ra->Msg4_subframe == subframeP))||((nfapi_mode == 2)&&(cc->tdd_Config == NULL))) { // Get RRCConnectionSetup for Piggyback /*rrc_sdu_length = mac_rrc_data_req(module_idP, CC_idP, frameP, CCCH, 1, // 1 transport block @@ -1421,7 +1425,9 @@ schedule_RA(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP) if (ra->state == MSG2) generate_Msg2(module_idP, CC_id, frameP, subframeP, ra); - else if (ra->state == MSG4 && ra->Msg4_frame == frameP && ra->Msg4_subframe == subframeP ) + // In case of nFAPI, sometimes timing of eNB and UE become different. + // So if nfapi_mode == 2(VNF) , this function don't check timing to avoid Attach failure. + else if ((ra->state == MSG4 && ra->Msg4_frame == frameP && ra->Msg4_subframe == subframeP ) || (nfapi_mode == 2)) generate_Msg4(module_idP, CC_id, frameP, subframeP, ra); else if (ra->state == WAITMSG4ACK) check_Msg4_retransmission(module_idP, CC_id, frameP, From d9d204a5d3a64ac8a7b8e6356f10858772e23ae1 Mon Sep 17 00:00:00 2001 From: Y_Tomita Date: Mon, 22 Oct 2018 14:20:51 +0900 Subject: [PATCH 028/233] Modify RRC SDU length is not enough when UE received it. --- openair2/LAYER2/MAC/eNB_scheduler_RA.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openair2/LAYER2/MAC/eNB_scheduler_RA.c b/openair2/LAYER2/MAC/eNB_scheduler_RA.c index 98a500a23d..d8c5683f61 100755 --- a/openair2/LAYER2/MAC/eNB_scheduler_RA.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_RA.c @@ -1172,7 +1172,7 @@ generate_Msg4(module_id_t module_idP, int CC_idP, frame_t frameP, mac->TX_req[CC_idP].sfn_sf = fill_nfapi_tx_req(&mac->TX_req[CC_idP].tx_request_body, (frameP * 10) + subframeP, - rrc_sdu_length, + rrc_sdu_length + offset, mac->pdu_index[CC_idP], mac->UE_list. DLSCH_pdu[CC_idP][0][(unsigned char)UE_id].payload[0]); From 564f2cbfd4db81e3ca0286cab92573c08de78d19 Mon Sep 17 00:00:00 2001 From: Y_Tomita Date: Mon, 22 Oct 2018 14:43:22 +0900 Subject: [PATCH 029/233] Modify not to assert a part in L2 FAPI simulator because it's possible to differ timing(frame, subframe) between eNB and UE. --- openair2/LAYER2/MAC/eNB_scheduler_primitives.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/openair2/LAYER2/MAC/eNB_scheduler_primitives.c b/openair2/LAYER2/MAC/eNB_scheduler_primitives.c index bb4e7a0f38..599dff678e 100755 --- a/openair2/LAYER2/MAC/eNB_scheduler_primitives.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_primitives.c @@ -61,6 +61,7 @@ extern uint16_t frame_cnt; #include "SCHED/sched_common.h" extern RAN_CONTEXT_t RC; +extern uint8_t nfapi_mode; int choose(int n, int k) { @@ -3631,9 +3632,19 @@ extract_harq(module_id_t mod_idP, int CC_idP, int UE_id, AssertFatal(num_ack_nak == 1, "num_ack_nak %d > 1 for 1 CC and single-layer transmission frame:%d subframe:%d\n", num_ack_nak,frameP,subframeP); - AssertFatal(sched_ctl->round[CC_idP][harq_pid] < 8, - "Got ACK/NAK for inactive harq_pid %d for UE %d/%x\n", - harq_pid, UE_id, rnti); + + // In case of nFAPI, sometimes timing of eNB and UE become different. + // So if nfapi_mode == 2(VNF) , this function don't check assertion to avoid process exit. + if (nfapi_mode != 2){ + AssertFatal(sched_ctl->round[CC_idP][harq_pid] < 8, + "Got ACK/NAK for inactive harq_pid %d for UE %d/%x\n", + harq_pid, UE_id, rnti); + } else { + if(sched_ctl->round[CC_idP][harq_pid] == 8){ + LOG_E(MAC,"Got ACK/NAK for inactive harq_pid %d for UE %d/%x\n",harq_pid, UE_id, rnti); + return; + } + } AssertFatal(pdu[0] == 1 || pdu[0] == 2 || pdu[0] == 4, "Received ACK/NAK %d which is not 1 or 2 for harq_pid %d from UE %d/%x\n", From 0e0a04fbc17ae9e772079d4c574e3bceacf05d8b Mon Sep 17 00:00:00 2001 From: Y_Tomita Date: Mon, 22 Oct 2018 15:35:34 +0900 Subject: [PATCH 030/233] Fix for 256UEs. --- openair2/LAYER2/PDCP_v10.1.0/pdcp.c | 4 ++-- openair2/LAYER2/RLC/rlc.c | 4 ++-- openair3/NAS/UE/nas_ue_task.c | 2 +- targets/RT/USER/lte-softmodem.h | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) mode change 100644 => 100755 openair2/LAYER2/RLC/rlc.c mode change 100644 => 100755 openair3/NAS/UE/nas_ue_task.c diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp.c b/openair2/LAYER2/PDCP_v10.1.0/pdcp.c index 15b970b319..3d6650a96f 100755 --- a/openair2/LAYER2/PDCP_v10.1.0/pdcp.c +++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp.c @@ -49,7 +49,7 @@ #include "platform_constants.h" #include "common/utils/LOG/vcd_signal_dumper.h" #include "msc.h" - +#include "targets/COMMON/openairinterface5g_limits.h" #if defined(ENABLE_SECURITY) # include "UTIL/OSA/osa_defs.h" #endif @@ -2015,7 +2015,7 @@ void pdcp_layer_init(void) * Initialize SDU list */ list_init(&pdcp_sdu_list, NULL); - pdcp_coll_p = hashtable_create ((maxDRB + 2) * 16, NULL, pdcp_free); + pdcp_coll_p = hashtable_create ((maxDRB + 2) * NUMBER_OF_UE_MAX, NULL, pdcp_free); AssertFatal(pdcp_coll_p != NULL, "UNRECOVERABLE error, PDCP hashtable_create failed"); for (instance = 0; instance < MAX_MOBILES_PER_ENB; instance++) { diff --git a/openair2/LAYER2/RLC/rlc.c b/openair2/LAYER2/RLC/rlc.c old mode 100644 new mode 100755 index 846d406319..1b705c1328 --- a/openair2/LAYER2/RLC/rlc.c +++ b/openair2/LAYER2/RLC/rlc.c @@ -34,7 +34,7 @@ #include "common/utils/LOG/log.h" #include "UTIL/OCG/OCG_vars.h" #include "common/utils/LOG/vcd_signal_dumper.h" - +#include "targets/COMMON/openairinterface5g_limits.h" #include "assertions.h" extern boolean_t pdcp_data_ind( @@ -649,7 +649,7 @@ rlc_module_init (void) rlc_rrc_data_ind = NULL; rlc_rrc_data_conf = NULL; - rlc_coll_p = hashtable_create ((maxDRB + 2) * 16, NULL, rb_free_rlc_union); + rlc_coll_p = hashtable_create ((maxDRB + 2) * NUMBER_OF_UE_MAX, NULL, rb_free_rlc_union); //AssertFatal(rlc_coll_p != NULL, "UNRECOVERABLE error, RLC hashtable_create failed"); if(rlc_coll_p == NULL) { LOG_E(RLC, "UNRECOVERABLE error, RLC hashtable_create failed\n"); diff --git a/openair3/NAS/UE/nas_ue_task.c b/openair3/NAS/UE/nas_ue_task.c old mode 100644 new mode 100755 index 529ac5e602..6df6666638 --- a/openair3/NAS/UE/nas_ue_task.c +++ b/openair3/NAS/UE/nas_ue_task.c @@ -40,7 +40,7 @@ // FIXME review these externs extern unsigned char NB_eNB_INST; -extern unsigned char NB_UE_INST; +extern uint16_t NB_UE_INST; char *make_port_str_from_ueid(const char *base_port_str, int ueid); diff --git a/targets/RT/USER/lte-softmodem.h b/targets/RT/USER/lte-softmodem.h index bd71e0877f..9682bb0a56 100755 --- a/targets/RT/USER/lte-softmodem.h +++ b/targets/RT/USER/lte-softmodem.h @@ -147,7 +147,7 @@ {"ue-max-power", NULL, 0, iptr:&(tx_max_power[0]), defintval:23, TYPE_INT, 0}, \ {"emul-iface", CONFIG_HLP_EMULIFACE, 0, strptr:&emul_iface, defstrval:"lo", TYPE_STRING, 100}, \ {"L2-emul", NULL, 0, u8ptr:&nfapi_mode, defuintval:3, TYPE_UINT8, 0}, \ -{"num-ues", NULL, 0, u8ptr:&(NB_UE_INST), defuintval:1, TYPE_UINT8, 0}, \ +{"num-ues", NULL, 0, u16ptr:&(NB_UE_INST), defuintval:1, TYPE_UINT16, 0}, \ {"r" , CONFIG_HLP_PRB, 0, u8ptr:&(frame_parms[0]->N_RB_DL), defintval:25, TYPE_UINT8, 0}, \ {"dlsch-demod-shift", CONFIG_HLP_DLSHIFT, 0, iptr:(int32_t *)&dlsch_demod_shift, defintval:0, TYPE_INT, 0}, \ {"usrp-args", CONFIG_HLP_USRP_ARGS, 0, strptr:(char **)&usrp_args, defstrval:"type=b200", TYPE_STRING, 0}, \ From 2b0097a8d4f4709abfe285f4976e84bab9b8b925 Mon Sep 17 00:00:00 2001 From: Y_Tomita Date: Mon, 22 Oct 2018 16:01:15 +0900 Subject: [PATCH 031/233] Add UE's thread ID for L2 FAPI simulator. --- openair1/PHY/defs_UE.h | 1 + targets/RT/USER/lte-softmodem.h | 1 + targets/RT/USER/lte-uesoftmodem.c | 14 ++++++++++++-- 3 files changed, 14 insertions(+), 2 deletions(-) mode change 100644 => 100755 openair1/PHY/defs_UE.h diff --git a/openair1/PHY/defs_UE.h b/openair1/PHY/defs_UE.h old mode 100644 new mode 100755 index 55f8c9639a..0a4bd36731 --- a/openair1/PHY/defs_UE.h +++ b/openair1/PHY/defs_UE.h @@ -889,6 +889,7 @@ typedef struct { struct rx_tx_thread_data { PHY_VARS_UE *UE; UE_rxtx_proc_t *proc; + uint16_t ue_thread_id; }; diff --git a/targets/RT/USER/lte-softmodem.h b/targets/RT/USER/lte-softmodem.h index 9682bb0a56..56598a6c14 100755 --- a/targets/RT/USER/lte-softmodem.h +++ b/targets/RT/USER/lte-softmodem.h @@ -148,6 +148,7 @@ {"emul-iface", CONFIG_HLP_EMULIFACE, 0, strptr:&emul_iface, defstrval:"lo", TYPE_STRING, 100}, \ {"L2-emul", NULL, 0, u8ptr:&nfapi_mode, defuintval:3, TYPE_UINT8, 0}, \ {"num-ues", NULL, 0, u16ptr:&(NB_UE_INST), defuintval:1, TYPE_UINT16, 0}, \ +{"nums_ue_thread" , NULL, 0, u16ptr:&(NB_THREAD_INST), defuintval:1, TYPE_UINT16, 0}, \ {"r" , CONFIG_HLP_PRB, 0, u8ptr:&(frame_parms[0]->N_RB_DL), defintval:25, TYPE_UINT8, 0}, \ {"dlsch-demod-shift", CONFIG_HLP_DLSHIFT, 0, iptr:(int32_t *)&dlsch_demod_shift, defintval:0, TYPE_INT, 0}, \ {"usrp-args", CONFIG_HLP_USRP_ARGS, 0, strptr:(char **)&usrp_args, defstrval:"type=b200", TYPE_STRING, 0}, \ diff --git a/targets/RT/USER/lte-uesoftmodem.c b/targets/RT/USER/lte-uesoftmodem.c index 0081e7be8b..2a2c874a91 100755 --- a/targets/RT/USER/lte-uesoftmodem.c +++ b/targets/RT/USER/lte-uesoftmodem.c @@ -823,7 +823,7 @@ int main( int argc, char **argv ) // Default value for the number of UEs. It will hold, // if not changed from the command line option --num-ues NB_UE_INST=1; - + NB_THREAD_INST=1; #if defined (XFORMS) int ret; #endif @@ -859,6 +859,16 @@ printf("~~~~~~~~~~~~~~~~~~~~successfully get the parallel config[%d], worker con printf("NFAPI_MODE value: %d \n", nfapi_mode); + // Checking option of nums_ue_thread. + if(NB_THREAD_INST < 1){ + printf("Running with 0 UE rxtx thread, exiting.\n"); + abort(); + } + // Checking option's relation between nums_ue_thread and num-ues + if(NB_UE_INST Date: Mon, 22 Oct 2018 16:09:34 +0900 Subject: [PATCH 032/233] Add definition about mutex for multiple UE's L2 FAPI simulator. --- openair1/PHY/defs_UE.h | 6 ++++++ openair2/PHY_INTERFACE/IF_Module.h | 11 +++++++++++ openair2/PHY_INTERFACE/phy_stub_UE.h | 3 +++ 3 files changed, 20 insertions(+) mode change 100644 => 100755 openair2/PHY_INTERFACE/IF_Module.h mode change 100644 => 100755 openair2/PHY_INTERFACE/phy_stub_UE.h diff --git a/openair1/PHY/defs_UE.h b/openair1/PHY/defs_UE.h index 0a4bd36731..d6da512e9a 100755 --- a/openair1/PHY/defs_UE.h +++ b/openair1/PHY/defs_UE.h @@ -204,6 +204,12 @@ typedef struct { /// condition variable for timer_thread; pthread_cond_t cond_ticking; //time_stats_t timer_stats; + + // below 3 members is used for waiting each UE threads(multiple UEs test) in L2 FAPI simulator. + // This used in UE_phy_stub_single_thread_rxn_txnp4 + pthread_mutex_t mutex_single_thread; + pthread_cond_t cond_single_thread; + int num_single_thread[NUMBER_OF_UE_MAX]; } SF_ticking; typedef struct { diff --git a/openair2/PHY_INTERFACE/IF_Module.h b/openair2/PHY_INTERFACE/IF_Module.h old mode 100644 new mode 100755 index 0390a90551..f89fcda568 --- a/openair2/PHY_INTERFACE/IF_Module.h +++ b/openair2/PHY_INTERFACE/IF_Module.h @@ -128,6 +128,17 @@ typedef struct IF_Module_s{ pthread_mutex_t if_mutex; }IF_Module_t; +// These mutex is used for multiple UEs L2 FAPI simulator. +// Each UEs set these value in UL and UL_INFO is shared in all UE's thread. +typedef struct { + pthread_mutex_t rx_mutex; + pthread_mutex_t crc_mutex; + pthread_mutex_t sr_mutex; + pthread_mutex_t harq_mutex; + pthread_mutex_t cqi_mutex; + pthread_mutex_t rach_mutex; +}FILL_UL_INFO_MUTEX_t; + /*Initial */ IF_Module_t *IF_Module_init(int Mod_id); void IF_Module_kill(int Mod_id); diff --git a/openair2/PHY_INTERFACE/phy_stub_UE.h b/openair2/PHY_INTERFACE/phy_stub_UE.h old mode 100644 new mode 100755 index 9060951b26..1afb82add3 --- a/openair2/PHY_INTERFACE/phy_stub_UE.h +++ b/openair2/PHY_INTERFACE/phy_stub_UE.h @@ -17,6 +17,9 @@ //#include "openair1/PHY/defs.h" //#include "openair1/PHY/LTE_TRANSPORT/defs.h" +// this mutex is used to set multiple UE's UL value in L2 FAPI simulator. +FILL_UL_INFO_MUTEX_t fill_ul_mutex; + UL_IND_t *UL_INFO; nfapi_tx_request_pdu_t* tx_request_pdu_list; From da3e4ced9d076a67dee57a5a8cd40be58018e7a8 Mon Sep 17 00:00:00 2001 From: Y_Tomita Date: Mon, 22 Oct 2018 16:15:24 +0900 Subject: [PATCH 033/233] Fix for TDD's ULSCH HARQ in L2 FAPI simulator. --- openair2/PHY_INTERFACE/phy_stub_UE.c | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) mode change 100644 => 100755 openair2/PHY_INTERFACE/phy_stub_UE.c diff --git a/openair2/PHY_INTERFACE/phy_stub_UE.c b/openair2/PHY_INTERFACE/phy_stub_UE.c old mode 100644 new mode 100755 index 166616c368..bda6f156c5 --- a/openair2/PHY_INTERFACE/phy_stub_UE.c +++ b/openair2/PHY_INTERFACE/phy_stub_UE.c @@ -311,6 +311,7 @@ void fill_uci_harq_indication_UE_MAC(int Mod_id, else if (SNRtimes10 > 635) pdu->ul_cqi_information.ul_cqi=255; else pdu->ul_cqi_information.ul_cqi=(640+SNRtimes10)/5; pdu->ul_cqi_information.channel = 0; + if(harq_information->harq_information_rel9_fdd.tl.tag == NFAPI_UL_CONFIG_REQUEST_HARQ_INFORMATION_REL9_FDD_TAG){ if ((harq_information->harq_information_rel9_fdd.ack_nack_mode == 0) && (harq_information->harq_information_rel9_fdd.harq_size == 1)) { @@ -332,7 +333,24 @@ void fill_uci_harq_indication_UE_MAC(int Mod_id, pdu->harq_indication_fdd_rel13.harq_tb_n[1] = 1; // Assuming always an ACK (No NACK or DTX) } - else AssertFatal(1==0,"only format 1a/b for now, received \n"); + }else if(harq_information->harq_information_rel10_tdd.tl.tag == NFAPI_UL_CONFIG_REQUEST_HARQ_INFORMATION_REL10_TDD_TAG ){ + if ((harq_information->harq_information_rel10_tdd.ack_nack_mode == 0) && + (harq_information->harq_information_rel10_tdd.harq_size == 1)) { + pdu->harq_indication_tdd_rel13.tl.tag = NFAPI_HARQ_INDICATION_TDD_REL13_TAG; + pdu->harq_indication_tdd_rel13.mode = 0; + pdu->harq_indication_tdd_rel13.number_of_ack_nack = 1; + pdu->harq_indication_tdd_rel13.harq_data[0].bundling.value_0 = 1; + + } else if ((harq_information->harq_information_rel10_tdd.ack_nack_mode == 1) && + (harq_information->harq_information_rel10_tdd.harq_size == 2)) { + pdu->harq_indication_tdd_rel13.tl.tag = NFAPI_HARQ_INDICATION_TDD_REL13_TAG; + pdu->harq_indication_tdd_rel13.mode = 0; + pdu->harq_indication_tdd_rel13.number_of_ack_nack = 1; + pdu->harq_indication_tdd_rel13.harq_data[0].bundling.value_0 = 1; + pdu->harq_indication_tdd_rel13.harq_data[1].bundling.value_0 = 1; + + } + } else AssertFatal(1==0,"only format 1a/b for now, received \n"); UL_INFO->harq_ind.harq_indication_body.number_of_harqs++; From 04691fb04ca3110cd3f3beeb4a5cb25618d4280f Mon Sep 17 00:00:00 2001 From: Y_Tomita Date: Mon, 22 Oct 2018 16:39:44 +0900 Subject: [PATCH 034/233] Add checking pdu_index is enough in function of dl_config_req_UE_MAC. --- openair2/PHY_INTERFACE/phy_stub_UE.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/openair2/PHY_INTERFACE/phy_stub_UE.c b/openair2/PHY_INTERFACE/phy_stub_UE.c index bda6f156c5..b1269d92c6 100755 --- a/openair2/PHY_INTERFACE/phy_stub_UE.c +++ b/openair2/PHY_INTERFACE/phy_stub_UE.c @@ -640,7 +640,8 @@ int dl_config_req_UE_MAC(nfapi_dl_config_request_t* req, module_id_t Mod_id) //, //if(tx_request_pdu_list[dl_config_pdu_tmp->dlsch_pdu.dlsch_pdu_rel8.pdu_index].segments[0].segment_data!= NULL && tx_request_pdu_list[dl_config_pdu_tmp->dlsch_pdu.dlsch_pdu_rel8.pdu_index].segments[0].segment_length >0){ */ - if(dl_config_pdu_tmp->dlsch_pdu.dlsch_pdu_rel8.pdu_index <= tx_req_num_elems -1){ + // to avoid unexpected error , add check pdu_index is more than 0. + if((dl_config_pdu_tmp->dlsch_pdu.dlsch_pdu_rel8.pdu_index >= 0) &&(dl_config_pdu_tmp->dlsch_pdu.dlsch_pdu_rel8.pdu_index <= tx_req_num_elems -1)){ //if(tx_request_pdu_list + dl_config_pdu_tmp->dlsch_pdu.dlsch_pdu_rel8.pdu_index!= NULL){ LOG_E(MAC, "dl_config_req_UE_MAC 2 Received data: sfn/sf:%d PDU[%d] size:%d, TX_PDU index: %d, tx_req_num_elems: %d \n", NFAPI_SFNSF2DEC(req->sfn_sf), i, dl_config_pdu_list[i].pdu_size, dl_config_pdu_tmp->dlsch_pdu.dlsch_pdu_rel8.pdu_index, tx_req_num_elems); From bf8706d2c0e1698203e4dd1257cc8764e3f1b9f1 Mon Sep 17 00:00:00 2001 From: Y_Tomita Date: Mon, 22 Oct 2018 16:48:31 +0900 Subject: [PATCH 035/233] Modify to keep ulsch_buffer's value. --- openair2/PHY_INTERFACE/phy_stub_UE.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/openair2/PHY_INTERFACE/phy_stub_UE.c b/openair2/PHY_INTERFACE/phy_stub_UE.c index b1269d92c6..6ff14c61e9 100755 --- a/openair2/PHY_INTERFACE/phy_stub_UE.c +++ b/openair2/PHY_INTERFACE/phy_stub_UE.c @@ -65,7 +65,11 @@ void fill_rx_indication_UE_MAC(module_id_t Mod_id,int frame,int subframe, UL_IND //pdu->rx_indication_rel8.length = eNB->ulsch[UE_id]->harq_processes[harq_pid]->TBS>>3; pdu->rx_indication_rel8.length = buflen; pdu->rx_indication_rel8.offset = 1; // DJP - I dont understand - but broken unless 1 ???? 0; // filled in at the end of the UL_INFO formation - pdu->data = ulsch_buffer; + + // ulsch_buffer is necessary to keep its value. + //pdu->data = ulsch_buffer; + pdu->data = malloc(buflen); + memcpy(pdu->data,ulsch_buffer,buflen); // estimate timing advance for MAC //sync_pos = lte_est_timing_advance_pusch(eNB,UE_id); timing_advance_update = 0; // Don't know what to put here From eb0ebc588fda0983482587aa1a5a7c9585031747 Mon Sep 17 00:00:00 2001 From: Y_Tomita Date: Mon, 22 Oct 2018 16:56:51 +0900 Subject: [PATCH 036/233] Add some valuables initialization to avoid unexpected exit. --- openair2/PHY_INTERFACE/phy_stub_UE.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/openair2/PHY_INTERFACE/phy_stub_UE.c b/openair2/PHY_INTERFACE/phy_stub_UE.c index 6ff14c61e9..bf542b00d3 100755 --- a/openair2/PHY_INTERFACE/phy_stub_UE.c +++ b/openair2/PHY_INTERFACE/phy_stub_UE.c @@ -25,7 +25,11 @@ extern int oai_nfapi_rach_ind(nfapi_rach_indication_t *rach_ind); void configure_nfapi_pnf(char *vnf_ip_addr, int vnf_p5_port, char *pnf_ip_addr, int pnf_p7_port, int vnf_p7_port); - +UL_IND_t *UL_INFO = NULL; +nfapi_tx_request_pdu_t* tx_request_pdu_list = NULL; +nfapi_dl_config_request_t* dl_config_req = NULL; +nfapi_ul_config_request_t* ul_config_req = NULL; +nfapi_hi_dci0_request_t* hi_dci0_req = NULL; //extern uint8_t nfapi_pnf; //UL_IND_t *UL_INFO; From 20a2e83c39dd96ee76bd914065b9270ce727cbec Mon Sep 17 00:00:00 2001 From: Y_Tomita Date: Mon, 22 Oct 2018 17:21:30 +0900 Subject: [PATCH 037/233] Add multiple UE's L2 FAPI simulator's function. --- openair2/LAYER2/MAC/mac_extern.h | 1 + openair2/LAYER2/MAC/main_ue.c | 9 +- openair2/LAYER2/MAC/ue_procedures.c | 54 ++++---- openair2/PHY_INTERFACE/phy_stub_UE.c | 69 +++++++--- targets/RT/USER/lte-ue.c | 182 ++++++++++++++++++++------- 5 files changed, 223 insertions(+), 92 deletions(-) mode change 100644 => 100755 openair2/LAYER2/MAC/main_ue.c mode change 100644 => 100755 openair2/LAYER2/MAC/ue_procedures.c diff --git a/openair2/LAYER2/MAC/mac_extern.h b/openair2/LAYER2/MAC/mac_extern.h index 10822465f1..fd9ffb6a87 100755 --- a/openair2/LAYER2/MAC/mac_extern.h +++ b/openair2/LAYER2/MAC/mac_extern.h @@ -65,6 +65,7 @@ extern unsigned char NB_INST; #endif extern unsigned char NB_eNB_INST; extern uint16_t NB_UE_INST; +extern uint16_t NB_THREAD_INST; extern unsigned char NB_RN_INST; extern unsigned short NODE_ID[1]; diff --git a/openair2/LAYER2/MAC/main_ue.c b/openair2/LAYER2/MAC/main_ue.c old mode 100644 new mode 100755 index 95f25c7ff5..dd76df76dd --- a/openair2/LAYER2/MAC/main_ue.c +++ b/openair2/LAYER2/MAC/main_ue.c @@ -43,7 +43,7 @@ #include "common/ran_context.h" - +extern FILL_UL_INFO_MUTEX_t fill_ul_mutex; extern void openair_rrc_top_init_ue( int eMBMS_active, char* uecap_xer, uint8_t cba_group_active, uint8_t HO_active); void dl_phy_sync_success(module_id_t module_idP, frame_t frameP, unsigned char eNB_index, uint8_t first_sync) //init as MR @@ -103,6 +103,13 @@ mac_top_init_ue(int eMBMS_active, char *uecap_xer, UE_mac_inst = NULL; } + // mutex below are used for multiple UE's L2 FAPI simulation. + pthread_mutex_init(&fill_ul_mutex.rx_mutex,NULL); + pthread_mutex_init(&fill_ul_mutex.crc_mutex,NULL); + pthread_mutex_init(&fill_ul_mutex.sr_mutex,NULL); + pthread_mutex_init(&fill_ul_mutex.harq_mutex,NULL); + pthread_mutex_init(&fill_ul_mutex.cqi_mutex,NULL); + pthread_mutex_init(&fill_ul_mutex.rach_mutex,NULL); LOG_I(MAC, "[MAIN] calling RRC\n"); openair_rrc_top_init_ue(eMBMS_active, uecap_xer, cba_group_active, diff --git a/openair2/LAYER2/MAC/ue_procedures.c b/openair2/LAYER2/MAC/ue_procedures.c old mode 100644 new mode 100755 index 2c99b79ce8..12fbef7d80 --- a/openair2/LAYER2/MAC/ue_procedures.c +++ b/openair2/LAYER2/MAC/ue_procedures.c @@ -70,6 +70,8 @@ extern uint8_t usim_test; extern UL_IND_t *UL_INFO; extern uint8_t nfapi_mode; +extern int next_ra_frame; +extern module_id_t next_Mod_id; /* * @@ -2524,44 +2526,46 @@ ue_scheduler(const module_id_t module_idP, UE_mac_inst[module_idP].crnti, txFrameP, txSubframeP, eNB_indexP); #if defined(ENABLE_ITTI) + if(module_idP == 0){ + do { + // Checks if a message has been sent to MAC sub-task + itti_poll_msg(TASK_MAC_UE, &msg_p); - do { - // Checks if a message has been sent to MAC sub-task - itti_poll_msg(TASK_MAC_UE, &msg_p); + if (msg_p != NULL) { - if (msg_p != NULL) { + switch (ITTI_MSG_ID(msg_p)) { + case RRC_MAC_CCCH_DATA_REQ: + LOG_I(MAC, + "Received %s from %s: instance %d, frameP %d, eNB_index %d\n", + ITTI_MSG_NAME(msg_p), ITTI_MSG_ORIGIN_NAME(msg_p), ITTI_MSG_INSTANCE(msg_p), + RRC_MAC_CCCH_DATA_REQ(msg_p).frame, + RRC_MAC_CCCH_DATA_REQ(msg_p).enb_index); - switch (ITTI_MSG_ID(msg_p)) { - case RRC_MAC_CCCH_DATA_REQ: - LOG_I(MAC, - "Received %s from %s: instance %d, frameP %d, eNB_index %d\n", - ITTI_MSG_NAME(msg_p), ITTI_MSG_ORIGIN_NAME(msg_p), ITTI_MSG_INSTANCE(msg_p), - RRC_MAC_CCCH_DATA_REQ(msg_p).frame, - RRC_MAC_CCCH_DATA_REQ(msg_p).enb_index); - - // TODO process CCCH data req. - break; + // TODO process CCCH data req. + break; - default: - LOG_E(MAC, "Received unexpected message %s\n", ITTI_MSG_NAME(msg_p)); - break; + default: + LOG_E(MAC, "Received unexpected message %s\n", ITTI_MSG_NAME(msg_p)); + break; + } + + result = itti_free(ITTI_MSG_ORIGIN_ID(msg_p), msg_p); + AssertFatal(result == EXIT_SUCCESS, + "Failed to free memory (%d)!\n", result); } - - result = itti_free(ITTI_MSG_ORIGIN_ID(msg_p), msg_p); - AssertFatal(result == EXIT_SUCCESS, - "Failed to free memory (%d)!\n", result); - } - } + } while (msg_p != NULL); - + } #endif //Mac_rlc_xface->frameP=frameP; //Rrc_xface->Frame_index=Mac_rlc_xface->frameP; //if (subframe%5 == 0) //LG#ifdef EXMIMO - pdcp_run(&ctxt); + if(module_idP == 0){ + pdcp_run(&ctxt); + } //#endif UE_mac_inst[module_idP].txFrame = txFrameP; UE_mac_inst[module_idP].txSubframe = txSubframeP; diff --git a/openair2/PHY_INTERFACE/phy_stub_UE.c b/openair2/PHY_INTERFACE/phy_stub_UE.c index bf542b00d3..a1340e5e2e 100755 --- a/openair2/PHY_INTERFACE/phy_stub_UE.c +++ b/openair2/PHY_INTERFACE/phy_stub_UE.c @@ -51,7 +51,9 @@ void fill_rx_indication_UE_MAC(module_id_t Mod_id,int frame,int subframe, UL_IND int timing_advance_update; - pthread_mutex_lock(&UE_mac_inst[Mod_id].UL_INFO_mutex); + // pthread_mutex_lock(&UE_mac_inst[Mod_id].UL_INFO_mutex); + // change for mutiple UE's simulation. + pthread_mutex_lock(&fill_ul_mutex.rx_mutex); UL_INFO->rx_ind.sfn_sf = frame<<4| subframe; @@ -88,7 +90,9 @@ void fill_rx_indication_UE_MAC(module_id_t Mod_id,int frame,int subframe, UL_IND UL_INFO->rx_ind.rx_indication_body.number_of_pdus++; UL_INFO->rx_ind.sfn_sf = frame<<4 | subframe; - pthread_mutex_unlock(&UE_mac_inst[Mod_id].UL_INFO_mutex); + // pthread_mutex_unlock(&UE_mac_inst[Mod_id].UL_INFO_mutex); + // change for mutiple UE's simulation. + pthread_mutex_unlock(&fill_ul_mutex.rx_mutex); } @@ -96,7 +100,9 @@ void fill_rx_indication_UE_MAC(module_id_t Mod_id,int frame,int subframe, UL_IND void fill_sr_indication_UE_MAC(int Mod_id,int frame,int subframe, UL_IND_t *UL_INFO, uint16_t rnti) { - pthread_mutex_lock(&UE_mac_inst[Mod_id].UL_INFO_mutex); + // change for mutiple UE's simulation. + //pthread_mutex_lock(&UE_mac_inst[Mod_id].UL_INFO_mutex); + pthread_mutex_lock(&fill_ul_mutex.sr_mutex); nfapi_sr_indication_t *sr_ind = &UL_INFO->sr_ind; nfapi_sr_indication_body_t *sr_ind_body = &sr_ind->sr_indication_body; @@ -130,13 +136,17 @@ void fill_sr_indication_UE_MAC(int Mod_id,int frame,int subframe, UL_IND_t *UL_I //UL_INFO->rx_ind.rx_indication_body.number_of_pdus++; sr_ind_body->number_of_srs++; - pthread_mutex_unlock(&UE_mac_inst[Mod_id].UL_INFO_mutex); + // change for mutiple UE's simulation. + // pthread_mutex_unlock(&UE_mac_inst[Mod_id].UL_INFO_mutex); + pthread_mutex_unlock(&fill_ul_mutex.sr_mutex); } void fill_crc_indication_UE_MAC(int Mod_id,int frame,int subframe, UL_IND_t *UL_INFO, uint8_t crc_flag, int index, uint16_t rnti) { - pthread_mutex_lock(&UE_mac_inst[Mod_id].UL_INFO_mutex); + // change for mutiple UE's simulation. + //pthread_mutex_lock(&UE_mac_inst[Mod_id].UL_INFO_mutex); + pthread_mutex_lock(&fill_ul_mutex.crc_mutex); // REMEMBER HAVE EXCHANGED THE FOLLOWING TWO LINES HERE! nfapi_crc_indication_pdu_t *pdu = &UL_INFO->crc_ind.crc_indication_body.crc_pdu_list[UL_INFO->crc_ind.crc_indication_body.number_of_crcs]; @@ -159,14 +169,21 @@ void fill_crc_indication_UE_MAC(int Mod_id,int frame,int subframe, UL_IND_t *UL_ LOG_D(PHY, "%s() rnti:%04x pdus:%d\n", __FUNCTION__, pdu->rx_ue_information.rnti, UL_INFO->crc_ind.crc_indication_body.number_of_crcs); - pthread_mutex_unlock(&UE_mac_inst[Mod_id].UL_INFO_mutex); + // change for mutiple UE's simulation. + // pthread_mutex_unlock(&UE_mac_inst[Mod_id].UL_INFO_mutex); + pthread_mutex_unlock(&fill_ul_mutex.crc_mutex); } void fill_rach_indication_UE_MAC(int Mod_id,int frame,int subframe, UL_IND_t *UL_INFO, uint8_t ra_PreambleIndex, uint16_t ra_RNTI) { LOG_D(MAC, "fill_rach_indication_UE_MAC 1 \n"); - pthread_mutex_lock(&UE_mac_inst[Mod_id].UL_INFO_mutex); - UL_INFO = (UL_IND_t*)malloc(sizeof(UL_IND_t)); + + // change for mutiple UE's simulation. + // pthread_mutex_lock(&UE_mac_inst[Mod_id].UL_INFO_mutex); + pthread_mutex_lock(&fill_ul_mutex.rach_mutex); + + // memory allocation and free memory of UL_INFO are done in UE_phy_stub_single_thread_rxn_txnp4. + // UL_INFO = (UL_IND_t*)malloc(sizeof(UL_IND_t)); UL_INFO->rach_ind.rach_indication_body.number_of_preambles = 1; @@ -203,16 +220,22 @@ void fill_rach_indication_UE_MAC(int Mod_id,int frame,int subframe, UL_IND_t *UL // with that branch. oai_nfapi_rach_ind(&UL_INFO->rach_ind); free(UL_INFO->rach_ind.rach_indication_body.preamble_list); - free(UL_INFO); + + // memory allocation and free memory of UL_INFO are done in UE_phy_stub_single_thread_rxn_txnp4. + //free(UL_INFO); //} - pthread_mutex_unlock(&UE_mac_inst[Mod_id].UL_INFO_mutex); + // change for mutiple UE's simulation. + // pthread_mutex_unlock(&UE_mac_inst[Mod_id].UL_INFO_mutex); + pthread_mutex_unlock(&fill_ul_mutex.rach_mutex); } void fill_ulsch_cqi_indication_UE_MAC(int Mod_id, uint16_t frame,uint8_t subframe, UL_IND_t *UL_INFO, uint16_t rnti) { - pthread_mutex_lock(&UE_mac_inst[Mod_id].UL_INFO_mutex); + // change for mutiple UE's simulation. + //pthread_mutex_lock(&UE_mac_inst[Mod_id].UL_INFO_mutex); + pthread_mutex_lock(&fill_ul_mutex.cqi_mutex); nfapi_cqi_indication_pdu_t *pdu = &UL_INFO->cqi_ind.cqi_pdu_list[UL_INFO->cqi_ind.number_of_cqis]; nfapi_cqi_indication_raw_pdu_t *raw_pdu = &UL_INFO->cqi_ind.cqi_raw_pdu_list[UL_INFO->cqi_ind.number_of_cqis]; @@ -241,14 +264,18 @@ void fill_ulsch_cqi_indication_UE_MAC(int Mod_id, uint16_t frame,uint8_t subfram UL_INFO->cqi_ind.number_of_cqis++; - pthread_mutex_unlock(&UE_mac_inst[Mod_id].UL_INFO_mutex); - + // change for mutiple UE's simulation. + //pthread_mutex_unlock(&UE_mac_inst[Mod_id].UL_INFO_mutex); + pthread_mutex_unlock(&fill_ul_mutex.cqi_mutex); } void fill_ulsch_harq_indication_UE_MAC(int Mod_id, int frame,int subframe, UL_IND_t *UL_INFO, nfapi_ul_config_ulsch_harq_information *harq_information, uint16_t rnti) { - pthread_mutex_lock(&UE_mac_inst[Mod_id].UL_INFO_mutex); + // change for mutiple UE's simulation. + //pthread_mutex_lock(&UE_mac_inst[Mod_id].UL_INFO_mutex); + pthread_mutex_lock(&fill_ul_mutex.harq_mutex); + nfapi_harq_indication_pdu_t *pdu = &UL_INFO->harq_ind.harq_indication_body.harq_pdu_list[UL_INFO->harq_ind.harq_indication_body.number_of_harqs]; int i; @@ -279,8 +306,9 @@ void fill_ulsch_harq_indication_UE_MAC(int Mod_id, int frame,int subframe, UL_IN } UL_INFO->harq_ind.harq_indication_body.number_of_harqs++; - pthread_mutex_unlock(&UE_mac_inst[Mod_id].UL_INFO_mutex); -} + // change for mutiple UE's simulation. + //pthread_mutex_unlock(&UE_mac_inst[Mod_id].UL_INFO_mutex); + pthread_mutex_unlock(&fill_ul_mutex.harq_mutex);} void fill_uci_harq_indication_UE_MAC(int Mod_id, @@ -293,7 +321,10 @@ void fill_uci_harq_indication_UE_MAC(int Mod_id, uint16_t tdd_multiplexing_mask*/) { - pthread_mutex_lock(&UE_mac_inst[Mod_id].UL_INFO_mutex); + // change for mutiple UE's simulation. + //pthread_mutex_lock(&UE_mac_inst[Mod_id].UL_INFO_mutex); + pthread_mutex_lock(&fill_ul_mutex.harq_mutex); + nfapi_harq_indication_t *ind = &UL_INFO->harq_ind; nfapi_harq_indication_body_t *body = &ind->harq_indication_body; nfapi_harq_indication_pdu_t *pdu = &body->harq_pdu_list[UL_INFO->harq_ind.harq_indication_body.number_of_harqs]; @@ -363,7 +394,9 @@ void fill_uci_harq_indication_UE_MAC(int Mod_id, UL_INFO->harq_ind.harq_indication_body.number_of_harqs++; LOG_D(PHY,"Incremented eNB->UL_INFO.harq_ind.number_of_harqs:%d\n", UL_INFO->harq_ind.harq_indication_body.number_of_harqs); - pthread_mutex_unlock(&UE_mac_inst[Mod_id].UL_INFO_mutex); + // change for mutiple UE's simulation. + //pthread_mutex_unlock(&UE_mac_inst[Mod_id].UL_INFO_mutex); + pthread_mutex_unlock(&fill_ul_mutex.harq_mutex); } diff --git a/targets/RT/USER/lte-ue.c b/targets/RT/USER/lte-ue.c index ada4144a4f..39e6179d65 100755 --- a/targets/RT/USER/lte-ue.c +++ b/targets/RT/USER/lte-ue.c @@ -102,9 +102,11 @@ void ue_stub_rx_handler(unsigned int, char *); int32_t **rxdata; int32_t **txdata; -int timer_subframe; -int timer_frame; -SF_ticking *phy_stub_ticking; +int timer_subframe = 0; +int timer_frame = 0; +SF_ticking *phy_stub_ticking = NULL; +int next_ra_frame = 0; +module_id_t next_Mod_id = 0; #define KHz (1000UL) #define MHz (1000*KHz) @@ -954,31 +956,53 @@ static void *UE_phy_stub_single_thread_rxn_txnp4(void *arg) { thread_top_init("UE_phy_stub_thread_rxn_txnp4",1,870000L,1000000L,1000000L); - module_id_t Mod_id = 0; + // for multipule UE's L2-emulator + //module_id_t Mod_id = 0; + //int init_ra_UE = -1; // This counter is used to initiate the RA of each UE in different SFrames static __thread int UE_thread_rxtx_retval; struct rx_tx_thread_data *rtd = arg; UE_rxtx_proc_t *proc = rtd->proc; - // Initializations for nfapi-L2-emulator mode - dl_config_req = NULL; - ul_config_req = NULL; - hi_dci0_req = NULL; - tx_request_pdu_list = NULL; - + // settings for nfapi-L2-emulator mode + module_id_t ue_thread_id = rtd->ue_thread_id; + uint16_t ue_index = 0; + uint16_t ue_num = NB_UE_INST/NB_THREAD_INST+((NB_UE_INST%NB_THREAD_INST > ue_thread_id) ? 1 :0); + module_id_t ue_Mod_id; PHY_VARS_UE *UE; //= rtd->UE; int ret; + uint8_t end_flag; + proc = &PHY_vars_UE_g[0][0]->proc.proc_rxtx[0]; + phy_stub_ticking->num_single_thread[ue_thread_id] = -1; + if(ue_thread_id == 0){ + phy_stub_ticking->ticking_var = -1; + proc->subframe_rx=proc->sub_frame_start; + // Initializations for nfapi-L2-emulator mode + dl_config_req = NULL; + ul_config_req = NULL; + hi_dci0_req = NULL; + tx_request_pdu_list = NULL; - phy_stub_ticking->ticking_var = -1; - proc->subframe_rx=proc->sub_frame_start; + // waiting for all UE's threads set phy_stub_ticking->num_single_thread[ue_thread_id] = -1. + do{ + end_flag = 1; + for(uint16_t i = 0;i< NB_THREAD_INST;i++){ + if(phy_stub_ticking->num_single_thread[i] == 0){ + end_flag = 0; + } + } + }while(end_flag == 0); + + sync_var=0; + } //PANOS: CAREFUL HERE! wait_sync("UE_phy_stub_single_thread_rxn_txnp4"); while (!oai_exit) { - + if(ue_thread_id == 0){ if (pthread_mutex_lock(&phy_stub_ticking->mutex_ticking) != 0) { LOG_E( MAC, "[SCHED][UE] error locking mutex for UE RXTX\n" ); exit_fun("nothing to add"); @@ -1026,14 +1050,46 @@ static void *UE_phy_stub_single_thread_rxn_txnp4(void *arg) { UL_INFO->harq_ind.harq_indication_body.number_of_harqs = 0; UL_INFO->sr_ind.sr_indication_body.sr_pdu_list = (nfapi_sr_indication_pdu_t*)malloc(NB_UE_INST*sizeof(nfapi_sr_indication_pdu_t)); - UL_INFO->sr_ind.sr_indication_body.number_of_srs = 0; + UL_INFO->sr_ind.sr_indication_body.sr_pdu_list = (nfapi_sr_indication_pdu_t*)malloc(NB_UE_INST*sizeof(nfapi_sr_indication_pdu_t)); + UL_INFO->sr_ind.sr_indication_body.number_of_srs = 0; + UL_INFO->cqi_ind.cqi_pdu_list = (nfapi_cqi_indication_pdu_t*)malloc(NB_UE_INST*sizeof(nfapi_cqi_indication_pdu_t)); + UL_INFO->cqi_ind.cqi_raw_pdu_list = (nfapi_cqi_indication_raw_pdu_t*)malloc(NB_UE_INST*sizeof(nfapi_cqi_indication_raw_pdu_t)); + UL_INFO->cqi_ind.number_of_cqis = 0; + if (pthread_mutex_lock(&phy_stub_ticking->mutex_single_thread) != 0) { + LOG_E( MAC, "[SCHED][UE] error locking mutex for ue_thread_id %d (mutex_single_thread)\n",ue_thread_id); + exit_fun("nothing to add"); + } + memset(&phy_stub_ticking->num_single_thread[0],0,sizeof(int)*NB_THREAD_INST); + pthread_cond_broadcast(&phy_stub_ticking->cond_single_thread); + if (pthread_mutex_unlock(&phy_stub_ticking->mutex_single_thread) != 0) { + LOG_E( MAC, "[SCHED][UE] error unlocking mutex for ue_thread_id %d (mutex_single_thread)\n",ue_thread_id); + exit_fun("nothing to add"); + } + }else{ + if (pthread_mutex_lock(&phy_stub_ticking->mutex_single_thread) != 0) { + LOG_E( MAC, "[SCHED][UE] error locking mutex for ue_thread_id %d (mutex_single_thread)\n",ue_thread_id); + exit_fun("nothing to add"); + } + while (phy_stub_ticking->num_single_thread[ue_thread_id] < 0) { + // most of the time, the thread is waiting here + LOG_D(MAC,"Waiting for single_thread (ue_thread_id %d)\n",ue_thread_id); + pthread_cond_wait( &phy_stub_ticking->cond_single_thread, &phy_stub_ticking->mutex_single_thread); + } + if (pthread_mutex_unlock(&phy_stub_ticking->mutex_single_thread) != 0) { + LOG_E( MAC, "[SCHED][UE] error unlocking mutex for ue_thread_id %d (mutex_single_thread)\n",ue_thread_id); + exit_fun("nothing to add"); + } + } - for (Mod_id=0; Mod_idframe_parms, proc->subframe_rx); if ((sf_type == SF_DL) || (UE->frame_parms.frame_type == FDD) || @@ -1059,12 +1115,12 @@ static void *UE_phy_stub_single_thread_rxn_txnp4(void *arg) { if (dl_config_req!=NULL && tx_request_pdu_list!=NULL){ //if(dl_config_req!= NULL) { - dl_config_req_UE_MAC(dl_config_req, Mod_id); + dl_config_req_UE_MAC(dl_config_req, ue_Mod_id); } if (hi_dci0_req!=NULL && hi_dci0_req->hi_dci0_request_body.hi_dci0_pdu_list!=NULL){ - hi_dci0_req_UE_MAC(hi_dci0_req, Mod_id); + hi_dci0_req_UE_MAC(hi_dci0_req, ue_Mod_id); } if(nfapi_mode!=3) @@ -1078,7 +1134,7 @@ static void *UE_phy_stub_single_thread_rxn_txnp4(void *arg) { if (UE->mac_enabled==1) { - ret = ue_scheduler(UE->Mod_id, + ret = ue_scheduler(ue_Mod_id, proc->frame_rx, proc->subframe_rx, proc->frame_tx, @@ -1104,34 +1160,37 @@ static void *UE_phy_stub_single_thread_rxn_txnp4(void *arg) { // We make the start of RA between consecutive UEs differ by 20 frames //if ((UE_mac_inst[Mod_id].UE_mode[0] == PRACH && Mod_id == 0) || (UE_mac_inst[Mod_id].UE_mode[0] == PRACH && Mod_id>0 && proc->frame_rx >= UE_mac_inst[Mod_id-1].ra_frame + 20) ) { - if (UE_mac_inst[Mod_id].UE_mode[0] == PRACH && Mod_id == next_Mod_id && proc->frame_rx >= next_ra_frame) { - + if (UE_mac_inst[ue_Mod_id].UE_mode[0] == PRACH && ue_Mod_id == next_Mod_id) { + next_ra_frame++; + if(next_ra_frame > 200){ // check if we have PRACH opportunity - if (is_prach_subframe(&UE->frame_parms,proc->frame_tx, proc->subframe_tx) && UE_mac_inst[Mod_id].SI_Decoded == 1) { + if (is_prach_subframe(&UE->frame_parms,proc->frame_tx, proc->subframe_tx) && UE_mac_inst[ue_Mod_id].SI_Decoded == 1) { // The one working strangely... //if (is_prach_subframe(&UE->frame_parms,proc->frame_tx, proc->subframe_tx && Mod_id == (module_id_t) init_ra_UE) ) { - PRACH_RESOURCES_t *prach_resources = ue_get_rach(Mod_id, 0, proc->frame_tx, 0, proc->subframe_tx); + PRACH_RESOURCES_t *prach_resources = ue_get_rach(ue_Mod_id, 0, proc->frame_tx, 0, proc->subframe_tx); if(prach_resources!=NULL ) { - UE_mac_inst[Mod_id].ra_frame = proc->frame_rx; - LOG_D(MAC, "UE_phy_stub_thread_rxn_txnp4 before RACH, Mod_id: %d \n", Mod_id ); - fill_rach_indication_UE_MAC(Mod_id, proc->frame_tx ,proc->subframe_tx, UL_INFO, prach_resources->ra_PreambleIndex, prach_resources->ra_RNTI); - Msg1_transmitted(Mod_id, 0, proc->frame_tx, 0); - UE_mac_inst[Mod_id].UE_mode[0] = RA_RESPONSE; - next_Mod_id = Mod_id + 1; - next_ra_frame = (proc->frame_rx + 20)%1000; + UE_mac_inst[ue_Mod_id].ra_frame = proc->frame_rx; + LOG_D(MAC, "UE_phy_stub_thread_rxn_txnp4 before RACH, Mod_id: %d frame %d subframe %d\n", ue_Mod_id ,proc->frame_tx, proc->subframe_tx); + fill_rach_indication_UE_MAC(ue_Mod_id, proc->frame_tx ,proc->subframe_tx, UL_INFO, prach_resources->ra_PreambleIndex, prach_resources->ra_RNTI); + Msg1_transmitted(ue_Mod_id, 0, proc->frame_tx, 0); + UE_mac_inst[ue_Mod_id].UE_mode[0] = RA_RESPONSE; + next_Mod_id = ue_Mod_id + 1; + //next_ra_frame = (proc->frame_rx + 20)%1000; + next_ra_frame = 0; } //ue_prach_procedures(ue,proc,eNB_id,abstraction_flag,mode); } + } } // mode is PRACH // Substitute call to phy_procedures Tx with call to phy_stub functions in order to trigger // UE Tx procedures directly at the MAC layer, based on the received ul_config requests from the vnf (eNB). // Generate UL_indications which correspond to UL traffic. if(ul_config_req!=NULL){ //&& UE_mac_inst[Mod_id].ul_config_req->ul_config_request_body.ul_config_pdu_list != NULL){ - ul_config_req_UE_MAC(ul_config_req, timer_frame, timer_subframe, Mod_id); + ul_config_req_UE_MAC(ul_config_req, timer_frame, timer_subframe, ue_Mod_id); } } @@ -1140,6 +1199,19 @@ static void *UE_phy_stub_single_thread_rxn_txnp4(void *arg) { } //for (Mod_id=0; Mod_idnum_single_thread[ue_thread_id] = -1; + + // waiting for all UE's threads set phy_stub_ticking->num_single_thread[ue_thread_id] = -1. + if(ue_thread_id == 0){ + do{ + end_flag = 1; + for(uint16_t i = 0;i< NB_THREAD_INST;i++){ + if(phy_stub_ticking->num_single_thread[i] == 0){ + end_flag = 0; + } + } + }while(end_flag == 0); + if (UL_INFO->crc_ind.crc_indication_body.number_of_crcs>0) { @@ -1154,6 +1226,9 @@ static void *UE_phy_stub_single_thread_rxn_txnp4(void *arg) { //LOG_D(PHY,"UL_info->rx_ind.number_of_pdus:%d RX_IND:SFN/SF:%d\n", UL_info->rx_ind.rx_indication_body.number_of_pdus, NFAPI_SFNSF2DEC(UL_info->rx_ind.sfn_sf)); //LOG_I(MAC, "ul_config_req_UE_MAC 2.3, SFN/SF of PNF counter:%d.%d, number_of_pdus: %d \n", timer_frame, timer_subframe, UL_INFO->rx_ind.rx_indication_body.number_of_pdus); oai_nfapi_rx_ind(&UL_INFO->rx_ind); + for(uint8_t num_pdu = 0;num_pdu < UL_INFO->rx_ind.rx_indication_body.number_of_pdus;num_pdu++){ + free(UL_INFO->rx_ind.rx_indication_body.rx_pdu_list[num_pdu].data); + } //LOG_I(MAC, "ul_config_req_UE_MAC 2.31 \n"); UL_INFO->rx_ind.rx_indication_body.number_of_pdus = 0; } @@ -1190,14 +1265,19 @@ static void *UE_phy_stub_single_thread_rxn_txnp4(void *arg) { free(UL_INFO->sr_ind.sr_indication_body.sr_pdu_list); UL_INFO->sr_ind.sr_indication_body.sr_pdu_list = NULL; //} - + free(UL_INFO->cqi_ind.cqi_pdu_list); + UL_INFO->cqi_ind.cqi_pdu_list = NULL; + free(UL_INFO->cqi_ind.cqi_raw_pdu_list); + UL_INFO->cqi_ind.cqi_raw_pdu_list = NULL; free(UL_INFO); UL_INFO = NULL; // De-allocate memory of nfapi requests copies before next subframe round if(dl_config_req!=NULL){ - if(dl_config_req->vendor_extension) - free(dl_config_req->vendor_extension); + if(dl_config_req->vendor_extension!=NULL){ + free(dl_config_req->vendor_extension); + dl_config_req->vendor_extension = NULL; + } if(dl_config_req->dl_config_request_body.dl_config_pdu_list!=NULL){ free(dl_config_req->dl_config_request_body.dl_config_pdu_list); dl_config_req->dl_config_request_body.dl_config_pdu_list = NULL; @@ -1227,7 +1307,7 @@ static void *UE_phy_stub_single_thread_rxn_txnp4(void *arg) { hi_dci0_req = NULL; } - + } } // thread finished @@ -1792,19 +1872,22 @@ void init_UE_single_thread_stub(int nb_inst) { // In phy_stub_UE mode due to less heavy processing operations we don't need two threads //int nb_threads=RX_NB_TH; int nb_threads=1; - for (int i=0; iUE = UE; - rtd->proc = &UE->proc.proc_rxtx[i]; - - pthread_mutex_init(&UE->proc.proc_rxtx[i].mutex_rxtx,NULL); - pthread_cond_init(&UE->proc.proc_rxtx[i].cond_rxtx,NULL); - UE->proc.proc_rxtx[i].sub_frame_start=i; - UE->proc.proc_rxtx[i].sub_frame_step=nb_threads; - printf("Init_UE_threads rtd %d proc %d nb_threads %d i %d\n",rtd->proc->sub_frame_start, UE->proc.proc_rxtx[i].sub_frame_start,nb_threads, i); - pthread_create(&UE->proc.proc_rxtx[i].pthread_rxtx, NULL, UE_phy_stub_single_thread_rxn_txnp4, rtd); + for(uint16_t ue_thread_id = 0;ue_thread_id < NB_THREAD_INST;ue_thread_id++){ + UE = PHY_vars_UE_g[ue_thread_id][0]; + for (int i=0; iUE = UE; + rtd->proc = &UE->proc.proc_rxtx[i]; + rtd->ue_thread_id = ue_thread_id; + pthread_mutex_init(&UE->proc.proc_rxtx[i].mutex_rxtx,NULL); + pthread_cond_init(&UE->proc.proc_rxtx[i].cond_rxtx,NULL); + UE->proc.proc_rxtx[i].sub_frame_start=i; + UE->proc.proc_rxtx[i].sub_frame_step=nb_threads; + printf("Init_UE_threads rtd %d proc %d nb_threads %d i %d\n",rtd->proc->sub_frame_start, UE->proc.proc_rxtx[i].sub_frame_start,nb_threads, i); + pthread_create(&UE->proc.proc_rxtx[i].pthread_rxtx, NULL, UE_phy_stub_single_thread_rxn_txnp4, rtd); + } } // Remove thread for UE_sync in phy_stub_UE mode. //pthread_create(&UE->proc.pthread_synch,NULL,UE_thread_synch,(void*)UE); @@ -2074,8 +2157,11 @@ int init_timer_thread(void) { pthread_mutex_init(&UE->timer_mutex,NULL); pthread_cond_init(&UE->timer_cond,NULL); UE->instance_cnt_timer = -1; + memset(&phy_stub_ticking->num_single_thread[0],0,sizeof(int)*NB_THREAD_INST); pthread_mutex_init(&phy_stub_ticking->mutex_ticking,NULL); pthread_cond_init(&phy_stub_ticking->cond_ticking,NULL); + pthread_mutex_init(&phy_stub_ticking->mutex_single_thread,NULL); + pthread_cond_init(&phy_stub_ticking->cond_single_thread,NULL); pthread_create(&phy_stub_ticking->pthread_timer, NULL, &timer_thread, NULL); return 0; } From 05fb6c9192ea78a242ab96e75478b6152e1da520 Mon Sep 17 00:00:00 2001 From: Y_Tomita Date: Mon, 22 Oct 2018 17:59:24 +0900 Subject: [PATCH 038/233] bugfix about MSG4 in L2 FAPI simulator. --- openair2/LAYER2/MAC/eNB_scheduler_RA.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openair2/LAYER2/MAC/eNB_scheduler_RA.c b/openair2/LAYER2/MAC/eNB_scheduler_RA.c index d8c5683f61..4010d892e9 100755 --- a/openair2/LAYER2/MAC/eNB_scheduler_RA.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_RA.c @@ -1427,7 +1427,7 @@ schedule_RA(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP) generate_Msg2(module_idP, CC_id, frameP, subframeP, ra); // In case of nFAPI, sometimes timing of eNB and UE become different. // So if nfapi_mode == 2(VNF) , this function don't check timing to avoid Attach failure. - else if ((ra->state == MSG4 && ra->Msg4_frame == frameP && ra->Msg4_subframe == subframeP ) || (nfapi_mode == 2)) + else if ((ra->state == MSG4 && ra->Msg4_frame == frameP && ra->Msg4_subframe == subframeP ) || (nfapi_mode == 2 && ra->state == MSG4)) generate_Msg4(module_idP, CC_id, frameP, subframeP, ra); else if (ra->state == WAITMSG4ACK) check_Msg4_retransmission(module_idP, CC_id, frameP, From 7b264ac923acddb89709801d81bb476b5858bc96 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Mon, 22 Oct 2018 17:23:53 +0200 Subject: [PATCH 039/233] T: macpdu2wireshark: add MIB logging The tracer macpdu2wireshark can send MIBs to wireshark. This can be disabled by passing the new -no-mib option. openair1/SCHED/phy_procedures_lte_eNb.c has been modified to have a new T trace with the MIB. --- common/utils/T/T_messages.txt | 4 ++ common/utils/T/tracer/macpdu2wireshark.c | 82 ++++++++++++++++++++---- openair1/SCHED/phy_procedures_lte_eNb.c | 2 + 3 files changed, 75 insertions(+), 13 deletions(-) diff --git a/common/utils/T/T_messages.txt b/common/utils/T/T_messages.txt index 2bce891ac9..a3d75aff27 100644 --- a/common/utils/T/T_messages.txt +++ b/common/utils/T/T_messages.txt @@ -77,6 +77,10 @@ ID = ENB_PHY_INITIATE_RA_PROCEDURE DESC = eNodeB initiates a random access procedure after detecting enough energy for one of the preambles GROUP = ALL:PHY:ENB FORMAT = int,eNB_ID : int,frame : int,subframe : int,preamble : int,energy : int,delay +ID = ENB_PHY_MIB + DESC = MIB data + GROUP = ALL:PHY:ENB + FORMAT = int,eNB_ID : int,frame : int,subframe : buffer,data #MAC logs ID = ENB_MAC_UE_DL_SDU diff --git a/common/utils/T/tracer/macpdu2wireshark.c b/common/utils/T/tracer/macpdu2wireshark.c index 954f668aa4..4ab7606c6c 100644 --- a/common/utils/T/tracer/macpdu2wireshark.c +++ b/common/utils/T/tracer/macpdu2wireshark.c @@ -28,6 +28,10 @@ typedef struct { int dl_frame; int dl_subframe; int dl_data; + /* mib */ + int mib_frame; + int mib_subframe; + int mib_data; } ev_data; void ul(void *_d, event e) @@ -100,20 +104,55 @@ void dl(void *_d, event e) if (ret != d->buf.osize) abort(); } -void setup_data(ev_data *d, void *database, int ul_id, int dl_id) +void mib(void *_d, event e) +{ + ev_data *d = _d; + ssize_t ret; + int fsf; + int i; + + d->buf.osize = 0; + + PUTS(&d->buf, MAC_LTE_START_STRING); + PUTC(&d->buf, FDD_RADIO); + PUTC(&d->buf, DIRECTION_DOWNLINK); + PUTC(&d->buf, NO_RNTI); + + /* for newer version of wireshark? */ + fsf = (e.e[d->mib_frame].i << 4) + e.e[d->mib_subframe].i; + /* for older version? */ + //fsf = e.e[d->mib_subframe].i; + PUTC(&d->buf, MAC_LTE_FRAME_SUBFRAME_TAG); + PUTC(&d->buf, (fsf>>8) & 255); + PUTC(&d->buf, fsf & 255); + + PUTC(&d->buf, MAC_LTE_PAYLOAD_TAG); + for (i = 0; i < e.e[d->mib_data].bsize; i++) + PUTC(&d->buf, ((char*)e.e[d->mib_data].b)[i]); + + ret = sendto(d->socket, d->buf.obuf, d->buf.osize, 0, + (struct sockaddr *)&d->to, sizeof(struct sockaddr_in)); + if (ret != d->buf.osize) abort(); +} + +void setup_data(ev_data *d, void *database, int ul_id, int dl_id, int mib_id) { database_event_format f; int i; - d->ul_rnti = -1; - d->ul_frame = -1; - d->ul_subframe = -1; - d->ul_data = -1; + d->ul_rnti = -1; + d->ul_frame = -1; + d->ul_subframe = -1; + d->ul_data = -1; - d->dl_rnti = -1; - d->dl_frame = -1; - d->dl_subframe = -1; - d->dl_data = -1; + d->dl_rnti = -1; + d->dl_frame = -1; + d->dl_subframe = -1; + d->dl_data = -1; + + d->mib_frame = -1; + d->mib_subframe = -1; + d->mib_data = -1; #define G(var_name, var_type, var) \ if (!strcmp(f.name[i], var_name)) { \ @@ -144,6 +183,18 @@ void setup_data(ev_data *d, void *database, int ul_id, int dl_id) if (d->dl_rnti == -1 || d->dl_frame == -1 || d->dl_subframe == -1 || d->dl_data == -1) goto error; + if (mib_id != -1) { + /* MIB: frame, subframe, data */ + f = get_format(database, mib_id); + for (i = 0; i < f.count; i++) { + G("frame", "int", d->mib_frame); + G("subframe", "int", d->mib_subframe); + G("data", "buffer", d->mib_data); + } + if (d->mib_frame == -1 || d->mib_subframe == -1 || d->mib_data == -1) + goto error; + } + #undef G return; @@ -179,7 +230,8 @@ void usage(void) " -d this option is mandatory\n" " -i read events from this dump file\n" " -ip send packets to this IP address (default %s)\n" -" -p send packets to this port (default %d)\n", +" -p send packets to this port (default %d)\n" +" -no-mib do not report MIB\n", DEFAULT_IP, DEFAULT_PORT ); @@ -194,10 +246,11 @@ int main(int n, char **v) event_handler *h; int in; int i; - int ul_id, dl_id; + int ul_id, dl_id, mib_id = -1; ev_data d; char *ip = DEFAULT_IP; int port = DEFAULT_PORT; + int do_mib = 1; memset(&d, 0, sizeof(ev_data)); @@ -209,6 +262,7 @@ int main(int n, char **v) { if (i > n-2) usage(); input_filename = v[++i]; continue; } if (!strcmp(v[i], "-ip")) { if (i > n-2) usage(); ip = v[++i]; continue; } if (!strcmp(v[i], "-p")) {if(i>n-2)usage(); port=atoi(v[++i]); continue; } + if (!strcmp(v[i], "-no-mib")) { do_mib = 0; continue; } usage(); } @@ -232,10 +286,12 @@ int main(int n, char **v) ul_id = event_id_from_name(database, "ENB_MAC_UE_UL_PDU_WITH_DATA"); dl_id = event_id_from_name(database, "ENB_MAC_UE_DL_PDU_WITH_DATA"); - setup_data(&d, database, ul_id, dl_id); + if (do_mib) mib_id = event_id_from_name(database, "ENB_PHY_MIB"); + setup_data(&d, database, ul_id, dl_id, mib_id); register_handler_function(h, ul_id, ul, &d); register_handler_function(h, dl_id, dl, &d); + if (do_mib) register_handler_function(h, mib_id, mib, &d); d.socket = socket(AF_INET, SOCK_DGRAM, 0); if (d.socket == -1) { perror("socket"); exit(1); } @@ -253,7 +309,7 @@ int main(int n, char **v) event e; e = get_event(in, &ebuf, database); if (e.type == -1) break; - if (!(e.type == ul_id || e.type == dl_id)) continue; + if (!(e.type == ul_id || e.type == dl_id || e.type == mib_id)) continue; handle_event(h, e); } diff --git a/openair1/SCHED/phy_procedures_lte_eNb.c b/openair1/SCHED/phy_procedures_lte_eNb.c index 276006ec3b..7015df2d2a 100644 --- a/openair1/SCHED/phy_procedures_lte_eNb.c +++ b/openair1/SCHED/phy_procedures_lte_eNb.c @@ -254,6 +254,8 @@ void common_signal_procedures (PHY_VARS_eNB *eNB,int frame, int subframe) { if (eNB->pbch_configured!=1) return; eNB->pbch_configured=0; } + T(T_ENB_PHY_MIB, T_INT(eNB->Mod_id), T_INT(frame), T_INT(subframe), + T_BUFFER(pbch_pdu, 3)); generate_pbch(&eNB->pbch, txdataF, AMP, From ff312b1b97533660a21c26b24b8ff176a9ab5e59 Mon Sep 17 00:00:00 2001 From: Y_Tomita Date: Tue, 23 Oct 2018 12:56:56 +0900 Subject: [PATCH 040/233] Fix to set message_id in VNF.(Failed to commit 2151da7b.) --- nfapi/oai_integration/nfapi_vnf.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/nfapi/oai_integration/nfapi_vnf.c b/nfapi/oai_integration/nfapi_vnf.c index 8022bc53f4..765dc266b9 100755 --- a/nfapi/oai_integration/nfapi_vnf.c +++ b/nfapi/oai_integration/nfapi_vnf.c @@ -1112,7 +1112,7 @@ int oai_nfapi_dl_config_req(nfapi_dl_config_request_t *dl_config_req) nfapi_vnf_p7_config_t *p7_config = vnf.p7_vnfs[0].config; dl_config_req->header.phy_id = 1; // DJP HACK TODO FIXME - need to pass this around!!!! - + dl_config_req->header.message_id = NFAPI_DL_CONFIG_REQUEST; int retval = nfapi_vnf_p7_dl_config_req(p7_config, dl_config_req); dl_config_req->dl_config_request_body.number_pdcch_ofdm_symbols = 1; @@ -1131,7 +1131,7 @@ int oai_nfapi_tx_req(nfapi_tx_request_t *tx_req) nfapi_vnf_p7_config_t *p7_config = vnf.p7_vnfs[0].config; tx_req->header.phy_id = 1; // DJP HACK TODO FIXME - need to pass this around!!!! - + tx_req->header.message_id = NFAPI_TX_REQUEST; //LOG_D(PHY, "[VNF] %s() TX_REQ sfn_sf:%d number_of_pdus:%d\n", __FUNCTION__, NFAPI_SFNSF2DEC(tx_req->sfn_sf), tx_req->tx_request_body.number_of_pdus); int retval = nfapi_vnf_p7_tx_req(p7_config, tx_req); @@ -1149,7 +1149,7 @@ int oai_nfapi_hi_dci0_req(nfapi_hi_dci0_request_t *hi_dci0_req) { nfapi_vnf_p7_config_t *p7_config = vnf.p7_vnfs[0].config; hi_dci0_req->header.phy_id = 1; // DJP HACK TODO FIXME - need to pass this around!!!! - + hi_dci0_req->header.message_id = NFAPI_HI_DCI0_REQUEST; //LOG_D(PHY, "[VNF] %s() HI_DCI0_REQ sfn_sf:%d dci:%d hi:%d\n", __FUNCTION__, NFAPI_SFNSF2DEC(hi_dci0_req->sfn_sf), hi_dci0_req->hi_dci0_request_body.number_of_dci, hi_dci0_req->hi_dci0_request_body.number_of_hi); int retval = nfapi_vnf_p7_hi_dci0_req(p7_config, hi_dci0_req); @@ -1168,7 +1168,7 @@ int oai_nfapi_ul_config_req(nfapi_ul_config_request_t *ul_config_req) { nfapi_vnf_p7_config_t *p7_config = vnf.p7_vnfs[0].config; ul_config_req->header.phy_id = 1; // DJP HACK TODO FIXME - need to pass this around!!!! - + ul_config_req->header.message_id = NFAPI_UL_CONFIG_REQUEST; //LOG_D(PHY, "[VNF] %s() header message_id:%02x\n", __FUNCTION__, ul_config_req->header.message_id); //LOG_D(PHY, "[VNF] %s() UL_CONFIG sfn_sf:%d PDUs:%d rach_prach_frequency_resources:%d srs_present:%d\n", __FUNCTION__, NFAPI_SFNSF2DEC(ul_config_req->sfn_sf), ul_config_req->ul_config_request_body.number_of_pdus, ul_config_req->ul_config_request_body.rach_prach_frequency_resources, ul_config_req->ul_config_request_body.srs_present); From 2ed0722544fd6fe9662187b06bc093a7f995d1fc Mon Sep 17 00:00:00 2001 From: Y_Tomita Date: Tue, 23 Oct 2018 13:15:09 +0900 Subject: [PATCH 041/233] Changed difinition of some valuables to add initialization. --- openair2/PHY_INTERFACE/phy_stub_UE.h | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/openair2/PHY_INTERFACE/phy_stub_UE.h b/openair2/PHY_INTERFACE/phy_stub_UE.h index 1afb82add3..21fb8518fa 100755 --- a/openair2/PHY_INTERFACE/phy_stub_UE.h +++ b/openair2/PHY_INTERFACE/phy_stub_UE.h @@ -19,20 +19,21 @@ // this mutex is used to set multiple UE's UL value in L2 FAPI simulator. FILL_UL_INFO_MUTEX_t fill_ul_mutex; - -UL_IND_t *UL_INFO; - -nfapi_tx_request_pdu_t* tx_request_pdu_list; +//below 2 difinitions move to phy_stub_UE.c to add initialization when difinition. +extern UL_IND_t *UL_INFO; +extern nfapi_tx_request_pdu_t* tx_request_pdu_list; // New /// Pointers to config_request types. Used from nfapi callback functions. -nfapi_dl_config_request_t* dl_config_req; -nfapi_ul_config_request_t* ul_config_req; -nfapi_hi_dci0_request_t* hi_dci0_req; +//below 3 difinitions move to phy_stub_UE.c to add initialization when difinition. +extern nfapi_dl_config_request_t* dl_config_req; +extern nfapi_ul_config_request_t* ul_config_req; +extern nfapi_hi_dci0_request_t* hi_dci0_req; int tx_req_num_elems; -int next_ra_frame; -module_id_t next_Mod_id; +//below 2 difinitions move to lte-ue.c to add initialization when difinition. +//int next_ra_frame; +//module_id_t next_Mod_id; eth_params_t stub_eth_params; From 6404eddfc12d05ee950ce97080447813d72409bd Mon Sep 17 00:00:00 2001 From: Y_Tomita Date: Tue, 23 Oct 2018 13:19:33 +0900 Subject: [PATCH 042/233] Fix easy mistatke. --- targets/RT/USER/lte-ue.c | 1 - 1 file changed, 1 deletion(-) diff --git a/targets/RT/USER/lte-ue.c b/targets/RT/USER/lte-ue.c index 39e6179d65..4c52b0b792 100755 --- a/targets/RT/USER/lte-ue.c +++ b/targets/RT/USER/lte-ue.c @@ -1049,7 +1049,6 @@ static void *UE_phy_stub_single_thread_rxn_txnp4(void *arg) { UL_INFO->harq_ind.harq_indication_body.harq_pdu_list = (nfapi_harq_indication_pdu_t*)malloc(NB_UE_INST*sizeof(nfapi_harq_indication_pdu_t)); UL_INFO->harq_ind.harq_indication_body.number_of_harqs = 0; - UL_INFO->sr_ind.sr_indication_body.sr_pdu_list = (nfapi_sr_indication_pdu_t*)malloc(NB_UE_INST*sizeof(nfapi_sr_indication_pdu_t)); UL_INFO->sr_ind.sr_indication_body.sr_pdu_list = (nfapi_sr_indication_pdu_t*)malloc(NB_UE_INST*sizeof(nfapi_sr_indication_pdu_t)); UL_INFO->sr_ind.sr_indication_body.number_of_srs = 0; From 31d6783d60dea25f90253e563904d2f9f71db675 Mon Sep 17 00:00:00 2001 From: Y_Tomita Date: Tue, 23 Oct 2018 15:23:11 +0900 Subject: [PATCH 043/233] Modify setting of new_sdu_p->data->inst to avoid unexpected setting in case of UE. --- openair2/LAYER2/PDCP_v10.1.0/pdcp.c | 4 +++- openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c | 6 +++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp.c b/openair2/LAYER2/PDCP_v10.1.0/pdcp.c index 3d6650a96f..b16b7ad062 100755 --- a/openair2/LAYER2/PDCP_v10.1.0/pdcp.c +++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp.c @@ -800,8 +800,10 @@ pdcp_data_ind( #endif } else { ((pdcp_data_ind_header_t*) new_sdu_p->data)->rb_id = rb_id + (ctxt_pP->module_id * maxDRB); + ((pdcp_data_ind_header_t*) new_sdu_p->data)->inst = ctxt_pP->module_id; } - ((pdcp_data_ind_header_t*) new_sdu_p->data)->inst = ctxt_pP->module_id; + // new_sdu_p->data->inst is set again in UE case so move to above. + //((pdcp_data_ind_header_t*) new_sdu_p->data)->inst = ctxt_pP->module_id; #ifdef DEBUG_PDCP_FIFO_FLUSH_SDU static uint32_t pdcp_inst = 0; diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c b/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c index 96a0ad26ce..3b0283525e 100755 --- a/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c +++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c @@ -168,7 +168,11 @@ int pdcp_fifo_flush_sdus(const protocol_ctxt_t* const ctxt_pP) ((pdcp_data_ind_header_t*) sdu_p->data)->inst, ((pdcp_data_ind_header_t *) sdu_p->data)->data_size); #else - ((pdcp_data_ind_header_t *)(sdu_p->data))->inst = 0; + // value of sdu_p->data->inst is set in pdcp_data_ind + // it's necessary to set 1 in case of UE with S1. + if (ctxt_pP->enb_flag){ + ((pdcp_data_ind_header_t *)(sdu_p->data))->inst = 0; + } #endif #if defined(LINK_ENB_PDCP_TO_GTPV1U) From 35e81d8a66bf49ddb7fa2d102c455f4c366a19ab Mon Sep 17 00:00:00 2001 From: Y_Tomita Date: Tue, 23 Oct 2018 15:28:04 +0900 Subject: [PATCH 044/233] Add virtual NIC setting for L2 FAPI simulator. --- openair3/NAS/UE/ESM/esm_ebr_context.c | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) mode change 100644 => 100755 openair3/NAS/UE/ESM/esm_ebr_context.c diff --git a/openair3/NAS/UE/ESM/esm_ebr_context.c b/openair3/NAS/UE/ESM/esm_ebr_context.c old mode 100644 new mode 100755 index e2a327f488..865be3ea8c --- a/openair3/NAS/UE/ESM/esm_ebr_context.c +++ b/openair3/NAS/UE/ESM/esm_ebr_context.c @@ -58,6 +58,7 @@ Description Defines functions used to handle EPS bearer contexts. #include #include +extern uint8_t nfapi_mode; /****************************************************************************/ /**************** E X T E R N A L D E F I N I T I O N S ****************/ @@ -272,7 +273,21 @@ int esm_ebr_context_create( strcpy(broadcast, ipv4_addr); } - res = sprintf(command_line, + if(nfapi_mode ==3){ + // this is for L2 FAPI simulator. + // change for multiple UE's like 256UEs. + // if it's made too many tables , OS may crush so we use one table. + res = sprintf(command_line, + "ifconfig oip%d %s netmask %s broadcast %s up && " + "ip rule add from %s/24 table %d && " + "ip rule add to %s/24 table %d && " + "ip route add default dev oip%d table %d && " + ueid+1, ipv4_addr, netmask, broadcast, + ipv4_addr, 201, + ipv4_addr, 201, + ueid+1, 201, ueid+1); + } else { + res = sprintf(command_line, "ifconfig oip%d %s netmask %s broadcast %s up && " "ip rule add from %s/32 table %d && " "ip rule add to %s/32 table %d && " @@ -281,6 +296,7 @@ int esm_ebr_context_create( ipv4_addr, ueid + 201, ipv4_addr, ueid + 201, ueid + 1, ueid + 201); + } if ( res<0 ) { LOG_TRACE(WARNING, "ESM-PROC - Failed to system command string"); } From 6d97a7358bd6a7784caf017e95f9e6d6ad322915 Mon Sep 17 00:00:00 2001 From: Y_Tomita Date: Tue, 23 Oct 2018 15:31:13 +0900 Subject: [PATCH 045/233] Add sudo to enable init_nas_S1. --- cmake_targets/tools/init_nas_s1 | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/cmake_targets/tools/init_nas_s1 b/cmake_targets/tools/init_nas_s1 index cab4ad047b..b78ab34ff9 100755 --- a/cmake_targets/tools/init_nas_s1 +++ b/cmake_targets/tools/init_nas_s1 @@ -52,20 +52,20 @@ load_module ../../targets/bin/ue_ip.ko if [ "$1" = "UE" ]; then echo "bring up $LTEIF interface for UE" - ifconfig $LTEIF up + sudo ifconfig $LTEIF up fi -ip route flush cache +sudo ip route flush cache sleep 1 -sysctl -w net.ipv4.conf.all.log_martians=1 +sudo sysctl -w net.ipv4.conf.all.log_martians=1 echo "Disabling reverse path filtering" -sysctl -w net.ipv4.conf.all.rp_filter=0 -ip route flush cache +sudo sysctl -w net.ipv4.conf.all.rp_filter=0 +sudo ip route flush cache # Check table 200 lte in /etc/iproute2/rt_tables fgrep lte /etc/iproute2/rt_tables > /dev/null if [ $? -ne 0 ]; then echo "200 lte " >> /etc/iproute2/rt_tables fi -ip rule add fwmark 1 table lte -ip route add default dev $LTEIF table lte +sudo ip rule add fwmark 1 table lte +sudo ip route add default dev $LTEIF table lte From fdb16fae7d0540cccf5a036c65620dc668143e3f Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Tue, 23 Oct 2018 10:19:51 +0200 Subject: [PATCH 046/233] T: macpdu2wireshark: add SIBs tracing Only schedule_SI is done, not schedule_SIB1_BR and not schedule_SI_BR. --- common/utils/T/tracer/macpdu2wireshark.c | 22 ++++++++++++++++------ openair2/LAYER2/MAC/eNB_scheduler_bch.c | 3 +++ 2 files changed, 19 insertions(+), 6 deletions(-) diff --git a/common/utils/T/tracer/macpdu2wireshark.c b/common/utils/T/tracer/macpdu2wireshark.c index 4ab7606c6c..81fd44c443 100644 --- a/common/utils/T/tracer/macpdu2wireshark.c +++ b/common/utils/T/tracer/macpdu2wireshark.c @@ -14,6 +14,8 @@ #define DEFAULT_IP "127.0.0.1" #define DEFAULT_PORT 9999 +int no_sib = 0; + typedef struct { int socket; struct sockaddr_in to; @@ -76,21 +78,27 @@ void dl(void *_d, event e) int fsf; int i; + if (e.e[d->dl_rnti].i == 0xffff && no_sib) return; + d->buf.osize = 0; PUTS(&d->buf, MAC_LTE_START_STRING); PUTC(&d->buf, FDD_RADIO); PUTC(&d->buf, DIRECTION_DOWNLINK); - PUTC(&d->buf, C_RNTI); + if (e.e[d->dl_rnti].i != 0xffff) { + PUTC(&d->buf, C_RNTI); - PUTC(&d->buf, MAC_LTE_RNTI_TAG); - PUTC(&d->buf, (e.e[d->dl_rnti].i>>8) & 255); - PUTC(&d->buf, e.e[d->dl_rnti].i & 255); + PUTC(&d->buf, MAC_LTE_RNTI_TAG); + PUTC(&d->buf, (e.e[d->dl_rnti].i>>8) & 255); + PUTC(&d->buf, e.e[d->dl_rnti].i & 255); + } else { + PUTC(&d->buf, SI_RNTI); + } /* for newer version of wireshark? */ fsf = (e.e[d->dl_frame].i << 4) + e.e[d->dl_subframe].i; /* for older version? */ - fsf = e.e[d->dl_subframe].i; + //fsf = e.e[d->dl_subframe].i; PUTC(&d->buf, MAC_LTE_FRAME_SUBFRAME_TAG); PUTC(&d->buf, (fsf>>8) & 255); PUTC(&d->buf, fsf & 255); @@ -231,7 +239,8 @@ void usage(void) " -i read events from this dump file\n" " -ip send packets to this IP address (default %s)\n" " -p send packets to this port (default %d)\n" -" -no-mib do not report MIB\n", +" -no-mib do not report MIB\n" +" -no-sib do not report SIBs\n", DEFAULT_IP, DEFAULT_PORT ); @@ -263,6 +272,7 @@ int main(int n, char **v) if (!strcmp(v[i], "-ip")) { if (i > n-2) usage(); ip = v[++i]; continue; } if (!strcmp(v[i], "-p")) {if(i>n-2)usage(); port=atoi(v[++i]); continue; } if (!strcmp(v[i], "-no-mib")) { do_mib = 0; continue; } + if (!strcmp(v[i], "-no-sib")) { no_sib = 1; continue; } usage(); } diff --git a/openair2/LAYER2/MAC/eNB_scheduler_bch.c b/openair2/LAYER2/MAC/eNB_scheduler_bch.c index b2b59691f8..7a2b5846fd 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_bch.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_bch.c @@ -758,6 +758,9 @@ schedule_SI(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP) module_idP, CC_id, frameP, subframeP); } + T(T_ENB_MAC_UE_DL_PDU_WITH_DATA, T_INT(module_idP), T_INT(CC_id), T_INT(0xffff), + T_INT(frameP), T_INT(subframeP), T_INT(0), T_BUFFER(cc->BCCH_pdu.payload, bcch_sdu_length)); + if (opt_enabled == 1) { trace_pdu(DIRECTION_DOWNLINK, &cc->BCCH_pdu.payload[0], From f39f321d3bc0e774167838c314028e04e679bf62 Mon Sep 17 00:00:00 2001 From: Y_Tomita Date: Tue, 23 Oct 2018 18:50:46 +0900 Subject: [PATCH 047/233] Compiling error fix. --- openair3/NAS/UE/ESM/esm_ebr_context.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openair3/NAS/UE/ESM/esm_ebr_context.c b/openair3/NAS/UE/ESM/esm_ebr_context.c index 865be3ea8c..25d3bea6ea 100755 --- a/openair3/NAS/UE/ESM/esm_ebr_context.c +++ b/openair3/NAS/UE/ESM/esm_ebr_context.c @@ -281,11 +281,11 @@ int esm_ebr_context_create( "ifconfig oip%d %s netmask %s broadcast %s up && " "ip rule add from %s/24 table %d && " "ip rule add to %s/24 table %d && " - "ip route add default dev oip%d table %d && " + "ip route add default dev oip%d table %d", ueid+1, ipv4_addr, netmask, broadcast, ipv4_addr, 201, ipv4_addr, 201, - ueid+1, 201, ueid+1); + ueid+1, 201); } else { res = sprintf(command_line, "ifconfig oip%d %s netmask %s broadcast %s up && " From 35a7e3a180f25da09a1dd13332b588f1d12a3e34 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Tue, 23 Oct 2018 16:08:29 +0200 Subject: [PATCH 048/233] T: macpdu2wireshark: add RA preamble and RAR tracing --- common/utils/T/T_messages.txt | 4 + common/utils/T/tracer/macpdu2wireshark.c | 146 ++++++++++++++++++++--- openair2/LAYER2/MAC/eNB_scheduler_RA.c | 5 + 3 files changed, 140 insertions(+), 15 deletions(-) diff --git a/common/utils/T/T_messages.txt b/common/utils/T/T_messages.txt index a3d75aff27..c8320c60d8 100644 --- a/common/utils/T/T_messages.txt +++ b/common/utils/T/T_messages.txt @@ -123,6 +123,10 @@ ID = ENB_MAC_SCHEDULING_REQUEST DESC = MAC scheduling request detected for an UE GROUP = ALL:MAC:ENB FORMAT = int,eNB_ID : int,CC_id : int,frame : int,subframe : int,rnti +ID = ENB_MAC_UE_DL_RAR_PDU_WITH_DATA + DESC = MAC downlink PDU for an UE + GROUP = ALL:MAC:ENB + FORMAT = int,eNB_ID : int,CC_id : int,rnti : int,frame : int,subframe : int,harq_pid : buffer,data #RLC logs ID = ENB_RLC_DL diff --git a/common/utils/T/tracer/macpdu2wireshark.c b/common/utils/T/tracer/macpdu2wireshark.c index 81fd44c443..34678c774e 100644 --- a/common/utils/T/tracer/macpdu2wireshark.c +++ b/common/utils/T/tracer/macpdu2wireshark.c @@ -34,6 +34,15 @@ typedef struct { int mib_frame; int mib_subframe; int mib_data; + /* RA preamble */ + int preamble_frame; + int preamble_subframe; + int preamble_preamble; + /* RAR */ + int rar_rnti; + int rar_frame; + int rar_subframe; + int rar_data; } ev_data; void ul(void *_d, event e) @@ -143,24 +152,105 @@ void mib(void *_d, event e) if (ret != d->buf.osize) abort(); } -void setup_data(ev_data *d, void *database, int ul_id, int dl_id, int mib_id) +void preamble(void *_d, event e) +{ + ev_data *d = _d; + ssize_t ret; + int fsf; + + d->buf.osize = 0; + + PUTS(&d->buf, MAC_LTE_START_STRING); + PUTC(&d->buf, FDD_RADIO); + PUTC(&d->buf, DIRECTION_UPLINK); + + PUTC(&d->buf, NO_RNTI); + + /* for newer version of wireshark? */ + fsf = (e.e[d->preamble_frame].i << 4) + e.e[d->preamble_subframe].i; + /* for older version? */ + //fsf = e.e[d->preamble_subframe].i; + PUTC(&d->buf, MAC_LTE_FRAME_SUBFRAME_TAG); + PUTC(&d->buf, (fsf>>8) & 255); + PUTC(&d->buf, fsf & 255); + + PUTC(&d->buf, MAC_LTE_SEND_PREAMBLE_TAG); + PUTC(&d->buf, e.e[d->preamble_preamble].i); + PUTC(&d->buf, 0); /* rach attempt - always 0 for us (not sure of this) */ + + /* if we don't put this (even with no data) wireshark (2.4.5) is not happy */ + PUTC(&d->buf, MAC_LTE_PAYLOAD_TAG); + + ret = sendto(d->socket, d->buf.obuf, d->buf.osize, 0, + (struct sockaddr *)&d->to, sizeof(struct sockaddr_in)); + if (ret != d->buf.osize) abort(); +} + +void rar(void *_d, event e) +{ + ev_data *d = _d; + ssize_t ret; + int fsf; + int i; + + if (e.e[d->rar_rnti].i == 0xffff && no_sib) return; + + d->buf.osize = 0; + + PUTS(&d->buf, MAC_LTE_START_STRING); + PUTC(&d->buf, FDD_RADIO); + PUTC(&d->buf, DIRECTION_DOWNLINK); + PUTC(&d->buf, RA_RNTI); + + PUTC(&d->buf, MAC_LTE_RNTI_TAG); + PUTC(&d->buf, (e.e[d->rar_rnti].i>>8) & 255); + PUTC(&d->buf, e.e[d->rar_rnti].i & 255); + + /* for newer version of wireshark? */ + fsf = (e.e[d->rar_frame].i << 4) + e.e[d->rar_subframe].i; + /* for older version? */ + //fsf = e.e[d->rar_subframe].i; + PUTC(&d->buf, MAC_LTE_FRAME_SUBFRAME_TAG); + PUTC(&d->buf, (fsf>>8) & 255); + PUTC(&d->buf, fsf & 255); + + PUTC(&d->buf, MAC_LTE_PAYLOAD_TAG); + for (i = 0; i < e.e[d->rar_data].bsize; i++) + PUTC(&d->buf, ((char*)e.e[d->rar_data].b)[i]); + + ret = sendto(d->socket, d->buf.obuf, d->buf.osize, 0, + (struct sockaddr *)&d->to, sizeof(struct sockaddr_in)); + if (ret != d->buf.osize) abort(); +} + +void setup_data(ev_data *d, void *database, int ul_id, int dl_id, int mib_id, + int preamble_id, int rar_id) { database_event_format f; int i; - d->ul_rnti = -1; - d->ul_frame = -1; - d->ul_subframe = -1; - d->ul_data = -1; + d->ul_rnti = -1; + d->ul_frame = -1; + d->ul_subframe = -1; + d->ul_data = -1; - d->dl_rnti = -1; - d->dl_frame = -1; - d->dl_subframe = -1; - d->dl_data = -1; + d->dl_rnti = -1; + d->dl_frame = -1; + d->dl_subframe = -1; + d->dl_data = -1; - d->mib_frame = -1; - d->mib_subframe = -1; - d->mib_data = -1; + d->mib_frame = -1; + d->mib_subframe = -1; + d->mib_data = -1; + + d->preamble_frame = -1; + d->preamble_subframe = -1; + d->preamble_preamble = -1; + + d->rar_rnti = -1; + d->rar_frame = -1; + d->rar_subframe = -1; + d->rar_data = -1; #define G(var_name, var_type, var) \ if (!strcmp(f.name[i], var_name)) { \ @@ -203,6 +293,27 @@ void setup_data(ev_data *d, void *database, int ul_id, int dl_id, int mib_id) goto error; } + /* preamble: frame, subframe, preamble */ + f = get_format(database, preamble_id); + for (i = 0; i < f.count; i++) { + G("frame", "int", d->preamble_frame); + G("subframe", "int", d->preamble_subframe); + G("preamble", "int", d->preamble_preamble); + } + if (d->preamble_frame == -1 || d->preamble_subframe == -1 || + d->preamble_preamble == -1) goto error; + + /* rar: rnti, frame, subframe, data */ + f = get_format(database, rar_id); + for (i = 0; i < f.count; i++) { + G("rnti", "int", d->rar_rnti); + G("frame", "int", d->rar_frame); + G("subframe", "int", d->rar_subframe); + G("data", "buffer", d->rar_data); + } + if (d->rar_rnti == -1 || d->rar_frame == -1 || d->rar_subframe == -1 || + d->rar_data == -1) goto error; + #undef G return; @@ -255,7 +366,7 @@ int main(int n, char **v) event_handler *h; int in; int i; - int ul_id, dl_id, mib_id = -1; + int ul_id, dl_id, mib_id = -1, preamble_id, rar_id; ev_data d; char *ip = DEFAULT_IP; int port = DEFAULT_PORT; @@ -297,11 +408,15 @@ int main(int n, char **v) ul_id = event_id_from_name(database, "ENB_MAC_UE_UL_PDU_WITH_DATA"); dl_id = event_id_from_name(database, "ENB_MAC_UE_DL_PDU_WITH_DATA"); if (do_mib) mib_id = event_id_from_name(database, "ENB_PHY_MIB"); - setup_data(&d, database, ul_id, dl_id, mib_id); + preamble_id=event_id_from_name(database, "ENB_PHY_INITIATE_RA_PROCEDURE"); + rar_id = event_id_from_name(database, "ENB_MAC_UE_DL_RAR_PDU_WITH_DATA"); + setup_data(&d, database, ul_id, dl_id, mib_id, preamble_id, rar_id); register_handler_function(h, ul_id, ul, &d); register_handler_function(h, dl_id, dl, &d); if (do_mib) register_handler_function(h, mib_id, mib, &d); + register_handler_function(h, preamble_id, preamble, &d); + register_handler_function(h, rar_id, rar, &d); d.socket = socket(AF_INET, SOCK_DGRAM, 0); if (d.socket == -1) { perror("socket"); exit(1); } @@ -319,7 +434,8 @@ int main(int n, char **v) event e; e = get_event(in, &ebuf, database); if (e.type == -1) break; - if (!(e.type == ul_id || e.type == dl_id || e.type == mib_id)) continue; + if (!(e.type == ul_id || e.type == dl_id || e.type == mib_id || + e.type == preamble_id || e.type == rar_id)) continue; handle_event(h, e); } diff --git a/openair2/LAYER2/MAC/eNB_scheduler_RA.c b/openair2/LAYER2/MAC/eNB_scheduler_RA.c index b637a92a96..f0b75f95d3 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_RA.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_RA.c @@ -584,6 +584,11 @@ generate_Msg2(module_id_t module_idP, int CC_idP, frame_t frameP, ra->state = WAITMSG3; LOG_D(MAC,"[eNB %d][RAPROC] Frame %d, Subframe %d: state:WAITMSG3\n", module_idP, frameP, subframeP); + T(T_ENB_MAC_UE_DL_RAR_PDU_WITH_DATA, T_INT(module_idP), + T_INT(CC_idP), T_INT(ra->RA_rnti), T_INT(frameP), + T_INT(subframeP), T_INT(0 /*harq_pid always 0? */ ), + T_BUFFER(cc[CC_idP].RAR_pdu.payload, 7)); + // DL request mac->TX_req[CC_idP].sfn_sf = (frameP << 4) + subframeP; TX_req = From 2e5ae1eac65ee07935501d9c8da18b150c698b2f Mon Sep 17 00:00:00 2001 From: Louis Adrien Dufrene Date: Tue, 23 Oct 2018 16:20:14 +0200 Subject: [PATCH 049/233] Format of function rrc_rx_tx() --- openair2/RRC/LTE/rrc_eNB.c | 322 +++++++++++++++++++++---------------- 1 file changed, 181 insertions(+), 141 deletions(-) diff --git a/openair2/RRC/LTE/rrc_eNB.c b/openair2/RRC/LTE/rrc_eNB.c index 00f814b8b1..6bce1c21f0 100644 --- a/openair2/RRC/LTE/rrc_eNB.c +++ b/openair2/RRC/LTE/rrc_eNB.c @@ -7705,7 +7705,6 @@ SL_CommConfig_r12_t rrc_eNB_get_sidelink_commTXPool( const protocol_ctxt_t* cons return *sl_CommConfig; } - SL_DiscConfig_r12_t rrc_eNB_get_sidelink_discTXPool( const protocol_ctxt_t* const ctxt_pP, rrc_eNB_ue_context_t* const ue_context_pP, int n_discoveryMessages ){ //TODO SL_DiscConfig_r12_t sl_DiscConfig; @@ -7717,178 +7716,213 @@ SL_DiscConfig_r12_t rrc_eNB_get_sidelink_discTXPool( const protocol_ctxt_t* cons //sl_DiscConfig.discTxResources_r12->choice.setup.choice.scheduled_r12.discTxConfig_r12; return sl_DiscConfig; } + RRC_status_t rrc_rx_tx( protocol_ctxt_t* const ctxt_pP, - const int CC_id + const int CC_id ) //----------------------------------------------------------------------------- { - //uint8_t UE_id; - int32_t current_timestamp_ms, ref_timestamp_ms; + int32_t current_timestamp_ms = 0; + int32_t ref_timestamp_ms = 0; struct timeval ts; - struct rrc_eNB_ue_context_s *ue_context_p = NULL,*ue_to_be_removed = NULL; + struct rrc_eNB_ue_context_s *ue_context_p = NULL; + struct rrc_eNB_ue_context_s *ue_to_be_removed = NULL; #ifdef LOCALIZATION - double estimated_distance; - protocol_ctxt_t ctxt; + + double estimated_distance = 0; + protocol_ctxt_t ctxt; + #endif - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RRC_RX_TX,VCD_FUNCTION_IN); - check_handovers(ctxt_pP); - // counetr, and get the value and aggregate + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RRC_RX_TX, VCD_FUNCTION_IN); - // check for UL failure + check_handovers(ctxt_pP); // counter, get the value and aggregate + + // check for UL failure or for UE to be released RB_FOREACH(ue_context_p, rrc_ue_tree_s, &(RC.rrc[ctxt_pP->module_id]->rrc_ue_head)) { ctxt_pP->rnti = ue_context_p->ue_id_rnti; - if ((ctxt_pP->frame == 0) && (ctxt_pP->subframe==0)) { - if (ue_context_p->ue_context.Initialue_identity_s_TMSI.presence == TRUE) { - LOG_I(RRC,"UE rnti %x:S-TMSI %x failure timer %d/8\n", - ue_context_p->ue_context.rnti, - ue_context_p->ue_context.Initialue_identity_s_TMSI.m_tmsi, - ue_context_p->ue_context.ul_failure_timer); - } - else { - LOG_I(RRC,"UE rnti %x failure timer %d/8\n", - ue_context_p->ue_context.rnti, - ue_context_p->ue_context.ul_failure_timer); - } + + if ((ctxt_pP->frame == 0) && (ctxt_pP->subframe == 0)) { + if (ue_context_p->ue_context.Initialue_identity_s_TMSI.presence == TRUE) { + LOG_I(RRC, "UE rnti %x: S-TMSI %x failure timer %d/8\n", + ue_context_p->ue_context.rnti, + ue_context_p->ue_context.Initialue_identity_s_TMSI.m_tmsi, + ue_context_p->ue_context.ul_failure_timer); + } else { + LOG_I(RRC, "UE rnti %x failure timer %d/8\n", + ue_context_p->ue_context.rnti, + ue_context_p->ue_context.ul_failure_timer); + } } - if (ue_context_p->ue_context.ul_failure_timer>0) { - ue_context_p->ue_context.ul_failure_timer++; - if (ue_context_p->ue_context.ul_failure_timer >= 20000) { - // remove UE after 20 seconds after MAC has indicated UL failure - LOG_I(RRC,"Removing UE %x instance\n",ue_context_p->ue_context.rnti); - ue_to_be_removed = ue_context_p; - break; - } + + if (ue_context_p->ue_context.ul_failure_timer > 0) { + ue_context_p->ue_context.ul_failure_timer++; + + if (ue_context_p->ue_context.ul_failure_timer >= 20000) { + // remove UE after 20 seconds after MAC (or else) has indicated UL failure + LOG_I(RRC, "Removing UE %x instance, because of uplink failure timer timeout\n", + ue_context_p->ue_context.rnti); + + ue_to_be_removed = ue_context_p; + break; // break RB_FOREACH + } } - if (ue_context_p->ue_context.ue_release_timer_s1>0) { + + if (ue_context_p->ue_context.ue_release_timer_s1 > 0) { ue_context_p->ue_context.ue_release_timer_s1++; - if (ue_context_p->ue_context.ue_release_timer_s1 >= - ue_context_p->ue_context.ue_release_timer_thres_s1) { - LOG_I(RRC,"Removing UE %x instance Because of UE_CONTEXT_RELEASE_COMMAND not received after %d ms from sending request\n", - ue_context_p->ue_context.rnti, ue_context_p->ue_context.ue_release_timer_thres_s1); -// ue_context_p->ue_context.ue_release_timer_s1 = 0; + + if (ue_context_p->ue_context.ue_release_timer_s1 >= ue_context_p->ue_context.ue_release_timer_thres_s1) { + LOG_I(RRC, "Removing UE %x instance, because of UE_CONTEXT_RELEASE_COMMAND not received after %d ms from sending request\n", + ue_context_p->ue_context.rnti, + ue_context_p->ue_context.ue_release_timer_thres_s1); + #if defined(ENABLE_USE_MME) #if defined(ENABLE_ITTI) + rrc_eNB_generate_RRCConnectionRelease(ctxt_pP, ue_context_p); + #endif #else + ue_to_be_removed = ue_context_p; + #endif ue_context_p->ue_context.ue_release_timer_s1 = 0; - break; + break; // break RB_FOREACH + } // end if timer_s1 timeout + } // end if timer_s1 > 0 (S1 UE_CONTEXT_RELEASE_REQ ongoing) + + if (ue_context_p->ue_context.ue_release_timer_rrc > 0) { + ue_context_p->ue_context.ue_release_timer_rrc++; + + if (ue_context_p->ue_context.ue_release_timer_rrc >= ue_context_p->ue_context.ue_release_timer_thres_rrc) { + LOG_I(RRC, "Removing UE %x instance after UE_CONTEXT_RELEASE_Complete (ue_release_timer_rrc timeout)\n", + ue_context_p->ue_context.rnti); + + ue_context_p->ue_context.ue_release_timer_rrc = 0; + ue_to_be_removed = ue_context_p; + break; // break RB_FOREACH } } - if (ue_context_p->ue_context.ue_release_timer_rrc>0) { - ue_context_p->ue_context.ue_release_timer_rrc++; - if (ue_context_p->ue_context.ue_release_timer_rrc >= - ue_context_p->ue_context.ue_release_timer_thres_rrc) { - LOG_I(RRC,"Removing UE %x instance After UE_CONTEXT_RELEASE_Complete\n", ue_context_p->ue_context.rnti); - ue_context_p->ue_context.ue_release_timer_rrc = 0; - ue_to_be_removed = ue_context_p; - ue_context_p->ue_context.ue_release_timer_rrc = 0; - break; - } - } - pthread_mutex_lock(&rrc_release_freelist); - if(rrc_release_info.num_UEs > 0){ + pthread_mutex_lock(&rrc_release_freelist); + if (rrc_release_info.num_UEs > 0) { uint16_t release_total = 0; - for(uint16_t release_num = 0;release_num < NUMBER_OF_UE_MAX;release_num++){ - if(rrc_release_info.RRC_release_ctrl[release_num].flag > 0){ + + for (uint16_t release_num = 0; release_num < NUMBER_OF_UE_MAX; release_num++) { + if (rrc_release_info.RRC_release_ctrl[release_num].flag > 0) { release_total++; } - if( (rrc_release_info.RRC_release_ctrl[release_num].flag > 2) && - (rrc_release_info.RRC_release_ctrl[release_num].rnti == ue_context_p->ue_context.rnti)){ - ue_context_p->ue_context.ue_release_timer_rrc = 1; - ue_context_p->ue_context.ue_release_timer_thres_rrc = 100; + + if ((rrc_release_info.RRC_release_ctrl[release_num].flag > 2) && + (rrc_release_info.RRC_release_ctrl[release_num].rnti == ue_context_p->ue_context.rnti)) { + + ue_context_p->ue_context.ue_release_timer_rrc = 1; + ue_context_p->ue_context.ue_release_timer_thres_rrc = 100; + #if defined(ENABLE_USE_MME) #if defined(ENABLE_ITTI) - int e_rab; - MessageDef *msg_complete_p = NULL; - MessageDef *msg_delete_tunnels_p = NULL; - uint32_t eNB_ue_s1ap_id = ue_context_p->ue_context.eNB_ue_s1ap_id; - if(rrc_release_info.RRC_release_ctrl[release_num].flag == 4){ - MSC_LOG_TX_MESSAGE( - MSC_RRC_ENB, - MSC_S1AP_ENB, - NULL,0, - "0 S1AP_UE_CONTEXT_RELEASE_COMPLETE eNB_ue_s1ap_id 0x%06"PRIX32" ", - eNB_ue_s1ap_id); - msg_complete_p = itti_alloc_new_message(TASK_RRC_ENB, S1AP_UE_CONTEXT_RELEASE_COMPLETE); - S1AP_UE_CONTEXT_RELEASE_COMPLETE(msg_complete_p).eNB_ue_s1ap_id = eNB_ue_s1ap_id; - itti_send_msg_to_task(TASK_S1AP, ctxt_pP->module_id, msg_complete_p); - } - MSC_LOG_TX_MESSAGE(MSC_RRC_ENB, MSC_GTPU_ENB, NULL,0, "0 GTPV1U_ENB_DELETE_TUNNEL_REQ rnti %x ", eNB_ue_s1ap_id); - msg_delete_tunnels_p = itti_alloc_new_message(TASK_RRC_ENB, GTPV1U_ENB_DELETE_TUNNEL_REQ); - memset(>PV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p), 0, sizeof(GTPV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p))); - // do not wait response - GTPV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p).rnti = ue_context_p->ue_context.rnti; - for (e_rab = 0; e_rab < ue_context_p->ue_context.nb_of_e_rabs; e_rab++) { - GTPV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p).eps_bearer_id[GTPV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p).num_erab++] = - ue_context_p->ue_context.enb_gtp_ebi[e_rab]; - // erase data - ue_context_p->ue_context.enb_gtp_teid[e_rab] = 0; - memset(&ue_context_p->ue_context.enb_gtp_addrs[e_rab], 0, sizeof(ue_context_p->ue_context.enb_gtp_addrs[e_rab])); - ue_context_p->ue_context.enb_gtp_ebi[e_rab] = 0; - } - itti_send_msg_to_task(TASK_GTPV1_U, ctxt_pP->module_id, msg_delete_tunnels_p); - struct rrc_ue_s1ap_ids_s *rrc_ue_s1ap_ids = NULL; - rrc_ue_s1ap_ids = rrc_eNB_S1AP_get_ue_ids( - RC.rrc[ctxt_pP->module_id], - 0, - eNB_ue_s1ap_id); - if (NULL != rrc_ue_s1ap_ids) { - rrc_eNB_S1AP_remove_ue_ids( - RC.rrc[ctxt_pP->module_id], - rrc_ue_s1ap_ids); - } -#endif -#endif - rrc_release_info.RRC_release_ctrl[release_num].flag = 0; - rrc_release_info.num_UEs--; - break; - } - if(release_total >= rrc_release_info.num_UEs) - break; - } - } - pthread_mutex_unlock(&rrc_release_freelist); - if (ue_context_p->ue_context.ue_reestablishment_timer>0) { + int e_rab = 0; + MessageDef *msg_complete_p = NULL; + MessageDef *msg_delete_tunnels_p = NULL; + uint32_t eNB_ue_s1ap_id = ue_context_p->ue_context.eNB_ue_s1ap_id; + + if (rrc_release_info.RRC_release_ctrl[release_num].flag == 4) { // if timer_s1 == 0 + MSC_LOG_TX_MESSAGE(MSC_RRC_ENB, MSC_S1AP_ENB, NULL, 0, + "0 S1AP_UE_CONTEXT_RELEASE_COMPLETE eNB_ue_s1ap_id 0x%06"PRIX32" ", + eNB_ue_s1ap_id); + + msg_complete_p = itti_alloc_new_message(TASK_RRC_ENB, S1AP_UE_CONTEXT_RELEASE_COMPLETE); + S1AP_UE_CONTEXT_RELEASE_COMPLETE(msg_complete_p).eNB_ue_s1ap_id = eNB_ue_s1ap_id; + itti_send_msg_to_task(TASK_S1AP, ctxt_pP->module_id, msg_complete_p); + } + + MSC_LOG_TX_MESSAGE(MSC_RRC_ENB, MSC_GTPU_ENB, NULL,0, "0 GTPV1U_ENB_DELETE_TUNNEL_REQ rnti %x ", eNB_ue_s1ap_id); + + msg_delete_tunnels_p = itti_alloc_new_message(TASK_RRC_ENB, GTPV1U_ENB_DELETE_TUNNEL_REQ); + memset(>PV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p), 0, sizeof(GTPV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p))); + + // do not wait response + GTPV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p).rnti = ue_context_p->ue_context.rnti; + + for (e_rab = 0; e_rab < ue_context_p->ue_context.nb_of_e_rabs; e_rab++) { + GTPV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p).eps_bearer_id[GTPV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p).num_erab++] = + ue_context_p->ue_context.enb_gtp_ebi[e_rab]; + + // erase data + ue_context_p->ue_context.enb_gtp_teid[e_rab] = 0; + memset(&ue_context_p->ue_context.enb_gtp_addrs[e_rab], 0, sizeof(ue_context_p->ue_context.enb_gtp_addrs[e_rab])); + ue_context_p->ue_context.enb_gtp_ebi[e_rab] = 0; + } + + itti_send_msg_to_task(TASK_GTPV1_U, ctxt_pP->module_id, msg_delete_tunnels_p); + + struct rrc_ue_s1ap_ids_s *rrc_ue_s1ap_ids = NULL; + + rrc_ue_s1ap_ids = rrc_eNB_S1AP_get_ue_ids(RC.rrc[ctxt_pP->module_id], 0, eNB_ue_s1ap_id); + + if (rrc_ue_s1ap_ids != NULL) { + rrc_eNB_S1AP_remove_ue_ids(RC.rrc[ctxt_pP->module_id], rrc_ue_s1ap_ids); + } + +#endif +#endif + + rrc_release_info.RRC_release_ctrl[release_num].flag = 0; + rrc_release_info.num_UEs--; + break; // break for (release_num) + } // end if ((rrc_release_info.RRC_release_ctrl[release_num].flag > 2) && ... + + if (release_total >= rrc_release_info.num_UEs) { + break; // break for (release_num) + } + } // end for (release_num) + } // end if (rrc_release_info.num_UEs > 0) + pthread_mutex_unlock(&rrc_release_freelist); + + if (ue_context_p->ue_context.ue_reestablishment_timer > 0) { ue_context_p->ue_context.ue_reestablishment_timer++; - if (ue_context_p->ue_context.ue_reestablishment_timer >= - ue_context_p->ue_context.ue_reestablishment_timer_thres) { - LOG_I(RRC,"UE %d reestablishment_timer max\n",ue_context_p->ue_context.rnti); - ue_context_p->ue_context.ul_failure_timer = 20000; + + if (ue_context_p->ue_context.ue_reestablishment_timer >= ue_context_p->ue_context.ue_reestablishment_timer_thres) { + LOG_I(RRC, "Removing UE %x instance because of reestablishment_timer timeout\n", + ue_context_p->ue_context.rnti); + + ue_context_p->ue_context.ul_failure_timer = 20000; // lead to send S1 UE_CONTEXT_RELEASE_REQ ue_to_be_removed = ue_context_p; ue_context_p->ue_context.ue_reestablishment_timer = 0; - break; + break; // break RB_FOREACH } } - if (ue_context_p->ue_context.ue_release_timer>0) { - ue_context_p->ue_context.ue_release_timer++; - if (ue_context_p->ue_context.ue_release_timer >= - ue_context_p->ue_context.ue_release_timer_thres) { - LOG_I(RRC,"Removing UE %x instance\n",ue_context_p->ue_context.rnti); - ue_to_be_removed = ue_context_p; + if (ue_context_p->ue_context.ue_release_timer > 0) { + ue_context_p->ue_context.ue_release_timer++; + + if (ue_context_p->ue_context.ue_release_timer >= ue_context_p->ue_context.ue_release_timer_thres) { + LOG_I(RRC, "Removing UE %x instance because of RRC Connection Setup timer timeout\n", + ue_context_p->ue_context.rnti); + + ue_to_be_removed = ue_context_p; ue_context_p->ue_context.ue_release_timer = 0; - break; - } + break; // break RB_FOREACH + } } - } + } // end RB_FOREACH + if (ue_to_be_removed) { - if(ue_to_be_removed->ue_context.ul_failure_timer >= 20000) { - ue_to_be_removed->ue_context.ue_release_timer_s1 = 1; - ue_to_be_removed->ue_context.ue_release_timer_thres_s1 = 100; - ue_to_be_removed->ue_context.ue_release_timer = 0; - ue_to_be_removed->ue_context.ue_reestablishment_timer = 0; + if (ue_to_be_removed->ue_context.ul_failure_timer >= 20000) { + ue_to_be_removed->ue_context.ue_release_timer_s1 = 1; + ue_to_be_removed->ue_context.ue_release_timer_thres_s1 = 100; + ue_to_be_removed->ue_context.ue_release_timer = 0; + ue_to_be_removed->ue_context.ue_reestablishment_timer = 0; } - rrc_eNB_free_UE(ctxt_pP->module_id,ue_to_be_removed); - if(ue_to_be_removed->ue_context.ul_failure_timer >= 20000){ + + rrc_eNB_free_UE(ctxt_pP->module_id, ue_to_be_removed); + + if (ue_to_be_removed->ue_context.ul_failure_timer >= 20000) { ue_to_be_removed->ue_context.ul_failure_timer = 0; } } @@ -7897,37 +7931,43 @@ rrc_rx_tx( /* for the localization, only primary CC_id might be relevant*/ gettimeofday(&ts, NULL); + current_timestamp_ms = ts.tv_sec * 1000 + ts.tv_usec / 1000; ref_timestamp_ms = RC.rrc[ctxt_pP->module_id]->reference_timestamp_ms; + RB_FOREACH(ue_context_p, rrc_ue_tree_s, &(RC.rrc[ctxt_pP->module_id]->rrc_ue_head)) { ctxt = *ctxt_pP; ctxt.rnti = ue_context_p->ue_context.rnti; - estimated_distance = rrc_get_estimated_ue_distance( - &ctxt, - CC_id, - RC.rrc[ctxt_pP->module_id]->loc_type); + + estimated_distance = rrc_get_estimated_ue_distance(&ctxt, CC_id, RC.rrc[ctxt_pP->module_id]->loc_type); if ((current_timestamp_ms - ref_timestamp_ms > RC.rrc[ctxt_pP->module_id]->aggregation_period_ms) && estimated_distance != -1) { - LOG_D(LOCALIZE, " RRC [UE/id %d -> eNB/id %d] timestamp %d frame %d estimated r = %f\n", + + LOG_D(LOCALIZE, "RRC [UE/id %d -> eNB/id %d] timestamp %d frame %d estimated r = %f\n", ctxt.rnti, ctxt_pP->module_id, current_timestamp_ms, ctxt_pP->frame, estimated_distance); - LOG_D(LOCALIZE, " RRC status %d\n", ue_context_p->ue_context.Status); - push_front(&RC.rrc[ctxt_pP->module_id]->loc_list, - estimated_distance); + + LOG_D(LOCALIZE, "RRC status %d\n", + ue_context_p->ue_context.Status); + + push_front(&RC.rrc[ctxt_pP->module_id]->loc_list, estimated_distance); + RC.rrc[ctxt_pP->module_id]->reference_timestamp_ms = current_timestamp_ms; - } - } + } // end if + } // end RB_FOREACH #endif + (void)ts; /* remove gcc warning "unused variable" */ (void)ref_timestamp_ms; /* remove gcc warning "unused variable" */ (void)current_timestamp_ms; /* remove gcc warning "unused variable" */ - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RRC_RX_TX,VCD_FUNCTION_OUT); - return (RRC_OK); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RRC_RX_TX, VCD_FUNCTION_OUT); + + return RRC_OK; } From 9a6d30d71611448e496b082e7da8edfddfaed913 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Tue, 23 Oct 2018 16:39:04 +0200 Subject: [PATCH 050/233] T: macpdu2wireshark: cleanup - factorize - harmonize - simplify --- common/utils/T/tracer/macpdu2wireshark.c | 205 +++++++---------------- 1 file changed, 61 insertions(+), 144 deletions(-) diff --git a/common/utils/T/tracer/macpdu2wireshark.c b/common/utils/T/tracer/macpdu2wireshark.c index 34678c774e..f65fdf34c3 100644 --- a/common/utils/T/tracer/macpdu2wireshark.c +++ b/common/utils/T/tracer/macpdu2wireshark.c @@ -14,7 +14,10 @@ #define DEFAULT_IP "127.0.0.1" #define DEFAULT_PORT 9999 +#define NO_PREAMBLE -1 + int no_sib = 0; +int no_mib = 0; typedef struct { int socket; @@ -45,9 +48,9 @@ typedef struct { int rar_data; } ev_data; -void ul(void *_d, event e) +void trace(ev_data *d, int direction, int rnti_type, int rnti, + int frame, int subframe, void *buf, int bufsize, int preamble) { - ev_data *d = _d; ssize_t ret; int fsf; int i; @@ -56,171 +59,88 @@ void ul(void *_d, event e) PUTS(&d->buf, MAC_LTE_START_STRING); PUTC(&d->buf, FDD_RADIO); - PUTC(&d->buf, DIRECTION_UPLINK); - PUTC(&d->buf, C_RNTI); + PUTC(&d->buf, direction); + PUTC(&d->buf, rnti_type); - PUTC(&d->buf, MAC_LTE_RNTI_TAG); - PUTC(&d->buf, (e.e[d->ul_rnti].i>>8) & 255); - PUTC(&d->buf, e.e[d->ul_rnti].i & 255); + if (rnti_type == C_RNTI || rnti_type == RA_RNTI) { + PUTC(&d->buf, MAC_LTE_RNTI_TAG); + PUTC(&d->buf, (rnti>>8) & 255); + PUTC(&d->buf, rnti & 255); + } /* for newer version of wireshark? */ - fsf = (e.e[d->ul_frame].i << 4) + e.e[d->ul_subframe].i; + fsf = (frame << 4) + subframe; /* for older version? */ - fsf = e.e[d->ul_subframe].i; + //fsf = subframe; PUTC(&d->buf, MAC_LTE_FRAME_SUBFRAME_TAG); PUTC(&d->buf, (fsf>>8) & 255); PUTC(&d->buf, fsf & 255); + if (preamble != NO_PREAMBLE) { + PUTC(&d->buf, MAC_LTE_SEND_PREAMBLE_TAG); + PUTC(&d->buf, preamble); + PUTC(&d->buf, 0); /* rach attempt - always 0 for us (not sure of this) */ + } + PUTC(&d->buf, MAC_LTE_PAYLOAD_TAG); - for (i = 0; i < e.e[d->ul_data].bsize; i++) - PUTC(&d->buf, ((char*)e.e[d->ul_data].b)[i]); + for (i = 0; i < bufsize; i++) + PUTC(&d->buf, ((char*)buf)[i]); ret = sendto(d->socket, d->buf.obuf, d->buf.osize, 0, (struct sockaddr *)&d->to, sizeof(struct sockaddr_in)); if (ret != d->buf.osize) abort(); } +void ul(void *_d, event e) +{ + ev_data *d = _d; + trace(d, DIRECTION_UPLINK, C_RNTI, e.e[d->ul_rnti].i, + e.e[d->ul_frame].i, e.e[d->ul_subframe].i, + e.e[d->ul_data].b, e.e[d->ul_data].bsize, + NO_PREAMBLE); +} + void dl(void *_d, event e) { ev_data *d = _d; - ssize_t ret; - int fsf; - int i; if (e.e[d->dl_rnti].i == 0xffff && no_sib) return; - d->buf.osize = 0; - - PUTS(&d->buf, MAC_LTE_START_STRING); - PUTC(&d->buf, FDD_RADIO); - PUTC(&d->buf, DIRECTION_DOWNLINK); - if (e.e[d->dl_rnti].i != 0xffff) { - PUTC(&d->buf, C_RNTI); - - PUTC(&d->buf, MAC_LTE_RNTI_TAG); - PUTC(&d->buf, (e.e[d->dl_rnti].i>>8) & 255); - PUTC(&d->buf, e.e[d->dl_rnti].i & 255); - } else { - PUTC(&d->buf, SI_RNTI); - } - - /* for newer version of wireshark? */ - fsf = (e.e[d->dl_frame].i << 4) + e.e[d->dl_subframe].i; - /* for older version? */ - //fsf = e.e[d->dl_subframe].i; - PUTC(&d->buf, MAC_LTE_FRAME_SUBFRAME_TAG); - PUTC(&d->buf, (fsf>>8) & 255); - PUTC(&d->buf, fsf & 255); - - PUTC(&d->buf, MAC_LTE_PAYLOAD_TAG); - for (i = 0; i < e.e[d->dl_data].bsize; i++) - PUTC(&d->buf, ((char*)e.e[d->dl_data].b)[i]); - - ret = sendto(d->socket, d->buf.obuf, d->buf.osize, 0, - (struct sockaddr *)&d->to, sizeof(struct sockaddr_in)); - if (ret != d->buf.osize) abort(); + trace(d, DIRECTION_DOWNLINK, + e.e[d->dl_rnti].i != 0xffff ? C_RNTI : SI_RNTI, e.e[d->dl_rnti].i, + e.e[d->dl_frame].i, e.e[d->dl_subframe].i, + e.e[d->dl_data].b, e.e[d->dl_data].bsize, + NO_PREAMBLE); } void mib(void *_d, event e) { ev_data *d = _d; - ssize_t ret; - int fsf; - int i; - d->buf.osize = 0; + if (no_mib) return; - PUTS(&d->buf, MAC_LTE_START_STRING); - PUTC(&d->buf, FDD_RADIO); - PUTC(&d->buf, DIRECTION_DOWNLINK); - PUTC(&d->buf, NO_RNTI); - - /* for newer version of wireshark? */ - fsf = (e.e[d->mib_frame].i << 4) + e.e[d->mib_subframe].i; - /* for older version? */ - //fsf = e.e[d->mib_subframe].i; - PUTC(&d->buf, MAC_LTE_FRAME_SUBFRAME_TAG); - PUTC(&d->buf, (fsf>>8) & 255); - PUTC(&d->buf, fsf & 255); - - PUTC(&d->buf, MAC_LTE_PAYLOAD_TAG); - for (i = 0; i < e.e[d->mib_data].bsize; i++) - PUTC(&d->buf, ((char*)e.e[d->mib_data].b)[i]); - - ret = sendto(d->socket, d->buf.obuf, d->buf.osize, 0, - (struct sockaddr *)&d->to, sizeof(struct sockaddr_in)); - if (ret != d->buf.osize) abort(); + trace(d, DIRECTION_DOWNLINK, NO_RNTI, 0, + e.e[d->mib_frame].i, e.e[d->mib_subframe].i, + e.e[d->mib_data].b, e.e[d->mib_data].bsize, + NO_PREAMBLE); } void preamble(void *_d, event e) { ev_data *d = _d; - ssize_t ret; - int fsf; - - d->buf.osize = 0; - - PUTS(&d->buf, MAC_LTE_START_STRING); - PUTC(&d->buf, FDD_RADIO); - PUTC(&d->buf, DIRECTION_UPLINK); - - PUTC(&d->buf, NO_RNTI); - - /* for newer version of wireshark? */ - fsf = (e.e[d->preamble_frame].i << 4) + e.e[d->preamble_subframe].i; - /* for older version? */ - //fsf = e.e[d->preamble_subframe].i; - PUTC(&d->buf, MAC_LTE_FRAME_SUBFRAME_TAG); - PUTC(&d->buf, (fsf>>8) & 255); - PUTC(&d->buf, fsf & 255); - - PUTC(&d->buf, MAC_LTE_SEND_PREAMBLE_TAG); - PUTC(&d->buf, e.e[d->preamble_preamble].i); - PUTC(&d->buf, 0); /* rach attempt - always 0 for us (not sure of this) */ - - /* if we don't put this (even with no data) wireshark (2.4.5) is not happy */ - PUTC(&d->buf, MAC_LTE_PAYLOAD_TAG); - - ret = sendto(d->socket, d->buf.obuf, d->buf.osize, 0, - (struct sockaddr *)&d->to, sizeof(struct sockaddr_in)); - if (ret != d->buf.osize) abort(); + trace(d, DIRECTION_UPLINK, NO_RNTI, 0, + e.e[d->preamble_frame].i, e.e[d->preamble_subframe].i, + NULL, 0, + e.e[d->preamble_preamble].i); } void rar(void *_d, event e) { ev_data *d = _d; - ssize_t ret; - int fsf; - int i; - - if (e.e[d->rar_rnti].i == 0xffff && no_sib) return; - - d->buf.osize = 0; - - PUTS(&d->buf, MAC_LTE_START_STRING); - PUTC(&d->buf, FDD_RADIO); - PUTC(&d->buf, DIRECTION_DOWNLINK); - PUTC(&d->buf, RA_RNTI); - - PUTC(&d->buf, MAC_LTE_RNTI_TAG); - PUTC(&d->buf, (e.e[d->rar_rnti].i>>8) & 255); - PUTC(&d->buf, e.e[d->rar_rnti].i & 255); - - /* for newer version of wireshark? */ - fsf = (e.e[d->rar_frame].i << 4) + e.e[d->rar_subframe].i; - /* for older version? */ - //fsf = e.e[d->rar_subframe].i; - PUTC(&d->buf, MAC_LTE_FRAME_SUBFRAME_TAG); - PUTC(&d->buf, (fsf>>8) & 255); - PUTC(&d->buf, fsf & 255); - - PUTC(&d->buf, MAC_LTE_PAYLOAD_TAG); - for (i = 0; i < e.e[d->rar_data].bsize; i++) - PUTC(&d->buf, ((char*)e.e[d->rar_data].b)[i]); - - ret = sendto(d->socket, d->buf.obuf, d->buf.osize, 0, - (struct sockaddr *)&d->to, sizeof(struct sockaddr_in)); - if (ret != d->buf.osize) abort(); + trace(d, DIRECTION_DOWNLINK, RA_RNTI, e.e[d->rar_rnti].i, + e.e[d->rar_frame].i, e.e[d->rar_subframe].i, + e.e[d->rar_data].b, e.e[d->rar_data].bsize, + NO_PREAMBLE); } void setup_data(ev_data *d, void *database, int ul_id, int dl_id, int mib_id, @@ -281,17 +201,15 @@ void setup_data(ev_data *d, void *database, int ul_id, int dl_id, int mib_id, if (d->dl_rnti == -1 || d->dl_frame == -1 || d->dl_subframe == -1 || d->dl_data == -1) goto error; - if (mib_id != -1) { - /* MIB: frame, subframe, data */ - f = get_format(database, mib_id); - for (i = 0; i < f.count; i++) { - G("frame", "int", d->mib_frame); - G("subframe", "int", d->mib_subframe); - G("data", "buffer", d->mib_data); - } - if (d->mib_frame == -1 || d->mib_subframe == -1 || d->mib_data == -1) - goto error; + /* MIB: frame, subframe, data */ + f = get_format(database, mib_id); + for (i = 0; i < f.count; i++) { + G("frame", "int", d->mib_frame); + G("subframe", "int", d->mib_subframe); + G("data", "buffer", d->mib_data); } + if (d->mib_frame == -1 || d->mib_subframe == -1 || d->mib_data == -1) + goto error; /* preamble: frame, subframe, preamble */ f = get_format(database, preamble_id); @@ -370,7 +288,6 @@ int main(int n, char **v) ev_data d; char *ip = DEFAULT_IP; int port = DEFAULT_PORT; - int do_mib = 1; memset(&d, 0, sizeof(ev_data)); @@ -382,7 +299,7 @@ int main(int n, char **v) { if (i > n-2) usage(); input_filename = v[++i]; continue; } if (!strcmp(v[i], "-ip")) { if (i > n-2) usage(); ip = v[++i]; continue; } if (!strcmp(v[i], "-p")) {if(i>n-2)usage(); port=atoi(v[++i]); continue; } - if (!strcmp(v[i], "-no-mib")) { do_mib = 0; continue; } + if (!strcmp(v[i], "-no-mib")) { no_mib = 1; continue; } if (!strcmp(v[i], "-no-sib")) { no_sib = 1; continue; } usage(); } @@ -407,14 +324,14 @@ int main(int n, char **v) ul_id = event_id_from_name(database, "ENB_MAC_UE_UL_PDU_WITH_DATA"); dl_id = event_id_from_name(database, "ENB_MAC_UE_DL_PDU_WITH_DATA"); - if (do_mib) mib_id = event_id_from_name(database, "ENB_PHY_MIB"); - preamble_id=event_id_from_name(database, "ENB_PHY_INITIATE_RA_PROCEDURE"); + mib_id = event_id_from_name(database, "ENB_PHY_MIB"); + preamble_id = event_id_from_name(database, "ENB_PHY_INITIATE_RA_PROCEDURE"); rar_id = event_id_from_name(database, "ENB_MAC_UE_DL_RAR_PDU_WITH_DATA"); setup_data(&d, database, ul_id, dl_id, mib_id, preamble_id, rar_id); register_handler_function(h, ul_id, ul, &d); register_handler_function(h, dl_id, dl, &d); - if (do_mib) register_handler_function(h, mib_id, mib, &d); + register_handler_function(h, mib_id, mib, &d); register_handler_function(h, preamble_id, preamble, &d); register_handler_function(h, rar_id, rar, &d); From 57a383e77c096f57deed32ad9f669b74ebc69c54 Mon Sep 17 00:00:00 2001 From: Louis Adrien Dufrene Date: Tue, 23 Oct 2018 16:51:55 +0200 Subject: [PATCH 051/233] Format rrc_eNB_process_S1AP_UE_CONTEXT_RELEASE_COMMAND() and rrc_eNB_free_UE() --- openair2/RRC/LTE/rrc_eNB.c | 148 ++++++++++++++++++-------------- openair2/RRC/LTE/rrc_eNB_S1AP.c | 66 +++++++------- 2 files changed, 117 insertions(+), 97 deletions(-) diff --git a/openair2/RRC/LTE/rrc_eNB.c b/openair2/RRC/LTE/rrc_eNB.c index 6bce1c21f0..a3deeec800 100644 --- a/openair2/RRC/LTE/rrc_eNB.c +++ b/openair2/RRC/LTE/rrc_eNB.c @@ -832,45 +832,58 @@ rrc_eNB_free_mem_UE_context( } //----------------------------------------------------------------------------- -// should be called when UE is lost by eNB +/* +* Should be called when UE context in eNB should be released +* or when S1 command UE_CONTEXT_RELEASE_REQ should be sent +*/ void -rrc_eNB_free_UE(const module_id_t enb_mod_idP,const struct rrc_eNB_ue_context_s* const ue_context_pP) +rrc_eNB_free_UE( + const module_id_t enb_mod_idP, + const struct rrc_eNB_ue_context_s *const ue_context_pP) //----------------------------------------------------------------------------- { - - - protocol_ctxt_t ctxt; + protocol_ctxt_t ctxt; rnti_t rnti = ue_context_pP->ue_context.rnti; + if (enb_mod_idP >= NB_eNB_INST) { - LOG_I(RRC, "eNB inst invalid (%d/%d) for UE %x!\n",enb_mod_idP, NB_eNB_INST,rnti); - return; + LOG_I(RRC, "eNB instance invalid (%d/%d) for UE %x!\n", + enb_mod_idP, + NB_eNB_INST, + rnti); + + return; } - /* ue_context_p = rrc_eNB_get_ue_context( - &RC.rrc[enb_mod_idP], - rntiP - ); - */ + if (NULL != ue_context_pP) { - PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, enb_mod_idP, ENB_FLAG_YES, rnti, 0, 0,enb_mod_idP); - LOG_W(RRC, "[eNB %d] Removing UE RNTI %x\n", enb_mod_idP, rnti); + PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, enb_mod_idP, ENB_FLAG_YES, rnti, 0, 0, enb_mod_idP); - if(EPC_MODE_ENABLED) { + LOG_W(RRC, "[eNB %d] Removing UE RNTI %x\n", + enb_mod_idP, + rnti); - if((ue_context_pP->ue_context.ul_failure_timer >= 20000) && - (mac_eNB_get_rrc_status(enb_mod_idP,rnti) >= RRC_CONNECTED)) { - LOG_I(RRC, "[eNB %d] S1AP_UE_CONTEXT_RELEASE_REQ RNTI %x\n", enb_mod_idP, rnti); - rrc_eNB_send_S1AP_UE_CONTEXT_RELEASE_REQ(enb_mod_idP, ue_context_pP, S1AP_CAUSE_RADIO_NETWORK, 21); // send cause 21: connection with ue lost - /* From 3GPP 36300v10 p129 : 19.2.2.2.2 S1 UE Context Release Request (eNB triggered) - * If the E-UTRAN internal reason is a radio link failure detected in the eNB, the eNB shall wait a sufficient time before - * triggering the S1 UE Context Release Request procedure - * in order to allow the UE to perform the NAS recovery - * procedure, see TS 23.401 [17]. - */ - return; + if (EPC_MODE_ENABLED) { + if((ue_context_pP->ue_context.ul_failure_timer >= 20000) && (mac_eNB_get_rrc_status(enb_mod_idP,rnti) >= RRC_CONNECTED)) { + LOG_I(RRC, "[eNB %d] S1AP_UE_CONTEXT_RELEASE_REQ sent for RNTI %x\n", + enb_mod_idP, + rnti); + + rrc_eNB_send_S1AP_UE_CONTEXT_RELEASE_REQ(enb_mod_idP, ue_context_pP, S1AP_CAUSE_RADIO_NETWORK, 21); + // send cause 21: connection with ue lost + /* From 3GPP 36300v10 p129 : 19.2.2.2.2 S1 UE Context Release Request (eNB triggered) + * If the E-UTRAN internal reason is a radio link failure detected in the eNB, the eNB shall wait a sufficient time before + * triggering the S1 UE Context Release Request procedure in order to allow the UE to perform the NAS recovery + * procedure, see TS 23.401 [17]. + */ + + return; + } + // TODO : add here cause ul inactivity } - } + // add UE info to freeList - LOG_I(RRC, "put UE %x into freeList\n", rnti); + LOG_I(RRC, "Put UE %x into freeList\n", + rnti); + put_UE_in_freelist(enb_mod_idP, rnti, 1); } } @@ -1980,44 +1993,40 @@ rrc_eNB_generate_RRCConnectionReestablishmentReject( } //----------------------------------------------------------------------------- +/* +* Generate the RRC Connection Release to UE. +* If received, UE should switch to RRC_IDLE mode. +*/ void rrc_eNB_generate_RRCConnectionRelease( const protocol_ctxt_t* const ctxt_pP, - rrc_eNB_ue_context_t* const ue_context_pP + rrc_eNB_ue_context_t* const ue_context_pP ) //----------------------------------------------------------------------------- { - - uint8_t buffer[RRC_BUF_SIZE]; - uint16_t size; + uint8_t buffer[RRC_BUF_SIZE] = 0; + uint16_t size = 0; T(T_ENB_RRC_CONNECTION_RELEASE, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame), T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti)); memset(buffer, 0, RRC_BUF_SIZE); size = do_RRCConnectionRelease(ctxt_pP->module_id, buffer,rrc_eNB_get_next_transaction_identifier(ctxt_pP->module_id)); - // set release timer - //ue_context_pP->ue_context.ue_release_timer=1; - // remove UE after 10 frames after RRCConnectionRelease is triggered - //ue_context_pP->ue_context.ue_release_timer_thres=100; - // set release timer -// ue_context_pP->ue_context.ue_release_timer_rrc = 1; - // remove UE after 10 frames after RRCConnectionRelease is triggered -// ue_context_pP->ue_context.ue_release_timer_thres_rrc = 100; + ue_context_pP->ue_context.ue_reestablishment_timer = 0; ue_context_pP->ue_context.ue_release_timer = 0; - //ue_context_pP->ue_context.ue_release_timer_s1 = 0; + LOG_I(RRC, - PROTOCOL_RRC_CTXT_UE_FMT" Logical Channel DL-DCCH, Generate RRCConnectionRelease (bytes %d)\n", - PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP), - size); + PROTOCOL_RRC_CTXT_UE_FMT" Logical Channel DL-DCCH, Generate RRCConnectionRelease (bytes %d)\n", + PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP), + size); LOG_D(RRC, - PROTOCOL_RRC_CTXT_UE_FMT" --- PDCP_DATA_REQ/%d Bytes (rrcConnectionRelease MUI %d) --->[PDCP][RB %u]\n", - PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP), - size, - rrc_eNB_mui, - DCCH); + PROTOCOL_RRC_CTXT_UE_FMT" --- PDCP_DATA_REQ/%d Bytes (rrcConnectionRelease MUI %d) --->[PDCP][RB %u]\n", + PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP), + size, + rrc_eNB_mui, + DCCH); MSC_LOG_TX_MESSAGE( MSC_RRC_ENB, @@ -2029,31 +2038,39 @@ rrc_eNB_generate_RRCConnectionRelease( ue_context_pP->ue_context.rnti, rrc_eNB_mui, size); + pthread_mutex_lock(&rrc_release_freelist); - for(uint16_t release_num = 0;release_num < NUMBER_OF_UE_MAX;release_num++){ - if(rrc_release_info.RRC_release_ctrl[release_num].flag == 0){ - if(ue_context_pP->ue_context.ue_release_timer_s1 > 0){ + for (uint16_t release_num = 0; release_num < NUMBER_OF_UE_MAX; release_num++) { + if (rrc_release_info.RRC_release_ctrl[release_num].flag == 0) { + + if (ue_context_pP->ue_context.ue_release_timer_s1 > 0) { rrc_release_info.RRC_release_ctrl[release_num].flag = 1; - }else{ + } else { rrc_release_info.RRC_release_ctrl[release_num].flag = 2; } + rrc_release_info.RRC_release_ctrl[release_num].rnti = ctxt_pP->rnti; rrc_release_info.RRC_release_ctrl[release_num].rrc_eNB_mui = rrc_eNB_mui; rrc_release_info.num_UEs++; - LOG_D(RRC,"Generate DLSCH Release send: index %d rnti %x mui %d flag %d \n",release_num, - ctxt_pP->rnti, rrc_eNB_mui,rrc_release_info.RRC_release_ctrl[release_num].flag); + + LOG_D(RRC, "Generate DLSCH Release send: index %d rnti %x mui %d flag %d \n", + release_num, + ctxt_pP->rnti, + rrc_eNB_mui, + rrc_release_info.RRC_release_ctrl[release_num].flag); + break; } } pthread_mutex_unlock(&rrc_release_freelist); - rrc_data_req( - ctxt_pP, - DCCH, - rrc_eNB_mui++, - SDU_CONFIRM_NO, - size, - buffer, - PDCP_TRANSMISSION_MODE_CONTROL); + + rrc_data_req(ctxt_pP, + DCCH, + rrc_eNB_mui++, + SDU_CONFIRM_NO, + size, + buffer, + PDCP_TRANSMISSION_MODE_CONTROL); } uint8_t qci_to_priority[9]={2,4,3,5,1,6,7,8,9}; @@ -7904,6 +7921,11 @@ rrc_rx_tx( if (ue_context_p->ue_context.ue_release_timer >= ue_context_p->ue_context.ue_release_timer_thres) { LOG_I(RRC, "Removing UE %x instance because of RRC Connection Setup timer timeout\n", ue_context_p->ue_context.rnti); + /* + * TODO: Naming problem here: ue_release_timer seems to have been used when RRC Connection Release was sent. + * It is no more the case. + * The timer should be renamed. + */ ue_to_be_removed = ue_context_p; ue_context_p->ue_context.ue_release_timer = 0; diff --git a/openair2/RRC/LTE/rrc_eNB_S1AP.c b/openair2/RRC/LTE/rrc_eNB_S1AP.c index d225b6eae0..0bec59f647 100644 --- a/openair2/RRC/LTE/rrc_eNB_S1AP.c +++ b/openair2/RRC/LTE/rrc_eNB_S1AP.c @@ -1201,66 +1201,64 @@ void rrc_eNB_send_S1AP_UE_CONTEXT_RELEASE_REQ ( } -/*------------------------------------------------------------------------------*/ -int rrc_eNB_process_S1AP_UE_CONTEXT_RELEASE_COMMAND (MessageDef *msg_p, const char *msg_name, instance_t instance) +//----------------------------------------------------------------------------- +/* +* Process the S1 command UE_CONTEXT_RELEASE_COMMAND, sent by MME. +* The eNB should remove all e-rab, S1 context, and other context of the UE. +*/ +int +rrc_eNB_process_S1AP_UE_CONTEXT_RELEASE_COMMAND ( + MessageDef *msg_p, + const char *msg_name, + instance_t instance) { +//----------------------------------------------------------------------------- uint32_t eNB_ue_s1ap_id; - protocol_ctxt_t ctxt; + protocol_ctxt_t ctxt; struct rrc_eNB_ue_context_s *ue_context_p = NULL; - struct rrc_ue_s1ap_ids_s *rrc_ue_s1ap_ids = NULL; + struct rrc_ue_s1ap_ids_s *rrc_ue_s1ap_ids = NULL; eNB_ue_s1ap_id = S1AP_UE_CONTEXT_RELEASE_COMMAND(msg_p).eNB_ue_s1ap_id; - - ue_context_p = rrc_eNB_get_ue_context_from_s1ap_ids(instance, UE_INITIAL_ID_INVALID, eNB_ue_s1ap_id); + ue_context_p = rrc_eNB_get_ue_context_from_s1ap_ids(instance, UE_INITIAL_ID_INVALID, eNB_ue_s1ap_id); if (ue_context_p == NULL) { /* Can not associate this message to an UE index */ - MessageDef *msg_complete_p; + MessageDef *msg_complete_p = NULL; - LOG_W(RRC, - "[eNB %d] In S1AP_UE_CONTEXT_RELEASE_COMMAND: unknown UE from eNB_ue_s1ap_id (%d)\n", - instance, - eNB_ue_s1ap_id); + LOG_W(RRC, "[eNB %d] In S1AP_UE_CONTEXT_RELEASE_COMMAND: unknown UE from eNB_ue_s1ap_id (%d)\n", + instance, + eNB_ue_s1ap_id); - MSC_LOG_EVENT( - MSC_RRC_ENB, - "0 S1AP_UE_CONTEXT_RELEASE_COMPLETE eNB_ue_s1ap_id 0x%06"PRIX32" context not found", + MSC_LOG_EVENT(MSC_RRC_ENB, "0 S1AP_UE_CONTEXT_RELEASE_COMPLETE eNB_ue_s1ap_id 0x%06"PRIX32" context not found", eNB_ue_s1ap_id); - MSC_LOG_TX_MESSAGE( - MSC_RRC_ENB, - MSC_S1AP_ENB, - NULL,0, - "0 S1AP_UE_CONTEXT_RELEASE_COMPLETE eNB_ue_s1ap_id 0x%06"PRIX32" ", + MSC_LOG_TX_MESSAGE(MSC_RRC_ENB, + MSC_S1AP_ENB, + NULL, + 0, + "0 S1AP_UE_CONTEXT_RELEASE_COMPLETE eNB_ue_s1ap_id 0x%06"PRIX32" ", eNB_ue_s1ap_id); msg_complete_p = itti_alloc_new_message(TASK_RRC_ENB, S1AP_UE_CONTEXT_RELEASE_COMPLETE); S1AP_UE_CONTEXT_RELEASE_COMPLETE(msg_complete_p).eNB_ue_s1ap_id = eNB_ue_s1ap_id; itti_send_msg_to_task(TASK_S1AP, instance, msg_complete_p); - rrc_ue_s1ap_ids = rrc_eNB_S1AP_get_ue_ids( - RC.rrc[instance], - UE_INITIAL_ID_INVALID, - eNB_ue_s1ap_id); + rrc_ue_s1ap_ids = rrc_eNB_S1AP_get_ue_ids(RC.rrc[instance], UE_INITIAL_ID_INVALID, eNB_ue_s1ap_id); if (NULL != rrc_ue_s1ap_ids) { - rrc_eNB_S1AP_remove_ue_ids( - RC.rrc[instance], - rrc_ue_s1ap_ids); + rrc_eNB_S1AP_remove_ue_ids(RC.rrc[instance], rrc_ue_s1ap_ids); } - return (-1); + + return -1; } else { ue_context_p->ue_context.ue_release_timer_s1 = 0; + PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt, instance, ENB_FLAG_YES, ue_context_p->ue_context.rnti, 0, 0); + rrc_eNB_generate_RRCConnectionRelease(&ctxt, ue_context_p); - /* - LOG_W(RRC, - "[eNB %d] In S1AP_UE_CONTEXT_RELEASE_COMMAND: TODO call rrc_eNB_connection_release for eNB %d\n", - instance, - eNB_ue_s1ap_id); - */ - return (0); + + return 0; } } From 2966cdf1c0f5df5aaadb61c1857ecf26ae6406cb Mon Sep 17 00:00:00 2001 From: Louis Adrien Dufrene Date: Tue, 23 Oct 2018 17:12:45 +0200 Subject: [PATCH 052/233] Format rrc_eNB_send_S1AP_UE_CONTEXT_RELEASE_REQ() --- openair2/RRC/LTE/rrc_eNB.c | 2 +- openair2/RRC/LTE/rrc_eNB_S1AP.c | 36 ++++++++++++++++++--------------- 2 files changed, 21 insertions(+), 17 deletions(-) diff --git a/openair2/RRC/LTE/rrc_eNB.c b/openair2/RRC/LTE/rrc_eNB.c index a3deeec800..56d68117c4 100644 --- a/openair2/RRC/LTE/rrc_eNB.c +++ b/openair2/RRC/LTE/rrc_eNB.c @@ -7890,7 +7890,7 @@ rrc_rx_tx( #endif rrc_release_info.RRC_release_ctrl[release_num].flag = 0; - rrc_release_info.num_UEs--; + rrc_release_info.num_UEs--; break; // break for (release_num) } // end if ((rrc_release_info.RRC_release_ctrl[release_num].flag > 2) && ... diff --git a/openair2/RRC/LTE/rrc_eNB_S1AP.c b/openair2/RRC/LTE/rrc_eNB_S1AP.c index 0bec59f647..6aa4f9485e 100644 --- a/openair2/RRC/LTE/rrc_eNB_S1AP.c +++ b/openair2/RRC/LTE/rrc_eNB_S1AP.c @@ -1172,30 +1172,34 @@ int rrc_eNB_process_S1AP_UE_CONTEXT_RELEASE_REQ (MessageDef *msg_p, const char * } //------------------------------------------------------------------------------ -void rrc_eNB_send_S1AP_UE_CONTEXT_RELEASE_REQ ( - const module_id_t enb_mod_idP, - const rrc_eNB_ue_context_t* const ue_context_pP, - const s1ap_Cause_t causeP, - const long cause_valueP -) +/* +* Send the S1 command UE_CONTEXT_RELEASE_REQUEST to the MME. +*/ +void +rrc_eNB_send_S1AP_UE_CONTEXT_RELEASE_REQ( + const module_id_t enb_mod_idP, + const rrc_eNB_ue_context_t *const ue_context_pP, + const s1ap_Cause_t causeP, + const long cause_valueP) //------------------------------------------------------------------------------ { if (ue_context_pP == NULL) { - LOG_W(RRC, - "[eNB] In S1AP_UE_CONTEXT_RELEASE_COMMAND: invalid UE\n"); + LOG_W(RRC, "[eNB] In S1AP_UE_CONTEXT_RELEASE_REQ: invalid UE\n"); } else { - MSC_LOG_TX_MESSAGE( - MSC_RRC_ENB, - MSC_S1AP_ENB, - NULL,0, - "0 S1AP_UE_CONTEXT_RELEASE_REQ eNB_ue_s1ap_id 0x%06"PRIX32" ", - ue_context_pP->ue_context.eNB_ue_s1ap_id); + MSC_LOG_TX_MESSAGE(MSC_RRC_ENB, + MSC_S1AP_ENB, + NULL, + 0, + "0 S1AP_UE_CONTEXT_RELEASE_REQ eNB_ue_s1ap_id 0x%06"PRIX32" ", + ue_context_pP->ue_context.eNB_ue_s1ap_id); MessageDef *msg_context_release_req_p = NULL; msg_context_release_req_p = itti_alloc_new_message(TASK_RRC_ENB, S1AP_UE_CONTEXT_RELEASE_REQ); + S1AP_UE_CONTEXT_RELEASE_REQ(msg_context_release_req_p).eNB_ue_s1ap_id = ue_context_pP->ue_context.eNB_ue_s1ap_id; S1AP_UE_CONTEXT_RELEASE_REQ(msg_context_release_req_p).cause = causeP; S1AP_UE_CONTEXT_RELEASE_REQ(msg_context_release_req_p).cause_value = cause_valueP; + itti_send_msg_to_task(TASK_S1AP, ENB_MODULE_ID_TO_INSTANCE(enb_mod_idP), msg_context_release_req_p); } } @@ -1207,13 +1211,13 @@ void rrc_eNB_send_S1AP_UE_CONTEXT_RELEASE_REQ ( * The eNB should remove all e-rab, S1 context, and other context of the UE. */ int -rrc_eNB_process_S1AP_UE_CONTEXT_RELEASE_COMMAND ( +rrc_eNB_process_S1AP_UE_CONTEXT_RELEASE_COMMAND( MessageDef *msg_p, const char *msg_name, instance_t instance) { //----------------------------------------------------------------------------- - uint32_t eNB_ue_s1ap_id; + uint32_t eNB_ue_s1ap_id = 0; protocol_ctxt_t ctxt; struct rrc_eNB_ue_context_s *ue_context_p = NULL; struct rrc_ue_s1ap_ids_s *rrc_ue_s1ap_ids = NULL; From bbacffa7fd8d0052ed84d26fb2f7f850c5b51f1a Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Tue, 23 Oct 2018 17:32:36 +0200 Subject: [PATCH 053/233] T: T_messages.txt: create a new group 'WIRESHARK' It is to ease the life of people wanting to record traces to be consumed later on by wireshark. You just run: ./record -d ../T_messages.txt -o /tmp/record.raw -on WIRESHARK and you're good. --- common/utils/T/T_messages.txt | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/common/utils/T/T_messages.txt b/common/utils/T/T_messages.txt index c8320c60d8..9d1bd0bbd0 100644 --- a/common/utils/T/T_messages.txt +++ b/common/utils/T/T_messages.txt @@ -75,11 +75,11 @@ ID = ENB_PHY_MSG3_ALLOCATION FORMAT = int,eNB_ID : int,frame : int,subframe : int,rnti : int,first_transmission : int,Msg3_frame : int,Msg3_subframe ID = ENB_PHY_INITIATE_RA_PROCEDURE DESC = eNodeB initiates a random access procedure after detecting enough energy for one of the preambles - GROUP = ALL:PHY:ENB + GROUP = ALL:PHY:ENB:WIRESHARK FORMAT = int,eNB_ID : int,frame : int,subframe : int,preamble : int,energy : int,delay ID = ENB_PHY_MIB DESC = MIB data - GROUP = ALL:PHY:ENB + GROUP = ALL:PHY:ENB:WIRESHARK FORMAT = int,eNB_ID : int,frame : int,subframe : buffer,data #MAC logs @@ -101,7 +101,7 @@ ID = ENB_MAC_UE_UL_PDU FORMAT = int,eNB_ID : int,CC_id : int,rnti : int,frame : int,subframe : int,harq_pid : int,sdu_length : int,num_ce : int,num_sdu ID = ENB_MAC_UE_UL_PDU_WITH_DATA DESC = MAC uplink UE received PDU - GROUP = ALL:MAC:ENB + GROUP = ALL:MAC:ENB:WIRESHARK FORMAT = int,eNB_ID : int,CC_id : int,rnti : int,frame : int,subframe : int,harq_pid : int,sdu_length : int,num_ce : int,num_sdu : buffer,data ID = ENB_MAC_UE_UL_SDU DESC = MAC uplink UE received SDU @@ -117,7 +117,7 @@ ID = ENB_MAC_UE_UL_CE FORMAT = int,eNB_ID : int,CC_id : int,rnti : int,frame : int,subframe : int,ce ID = ENB_MAC_UE_DL_PDU_WITH_DATA DESC = MAC downlink PDU for an UE - GROUP = ALL:MAC:ENB + GROUP = ALL:MAC:ENB:WIRESHARK FORMAT = int,eNB_ID : int,CC_id : int,rnti : int,frame : int,subframe : int,harq_pid : buffer,data ID = ENB_MAC_SCHEDULING_REQUEST DESC = MAC scheduling request detected for an UE @@ -125,7 +125,7 @@ ID = ENB_MAC_SCHEDULING_REQUEST FORMAT = int,eNB_ID : int,CC_id : int,frame : int,subframe : int,rnti ID = ENB_MAC_UE_DL_RAR_PDU_WITH_DATA DESC = MAC downlink PDU for an UE - GROUP = ALL:MAC:ENB + GROUP = ALL:MAC:ENB:WIRESHARK FORMAT = int,eNB_ID : int,CC_id : int,rnti : int,frame : int,subframe : int,harq_pid : buffer,data #RLC logs From 387b4ff21562f6db6740d482b7f416982a1c703d Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Tue, 23 Oct 2018 18:03:22 +0200 Subject: [PATCH 054/233] T: fix compilation of tracers If you run 'make' in common/utils/T/tracer just after a clone of the repository then the compilation will fail because the file ../T_IDs.h was not generated. Let's add a simple dependency to fix this. --- common/utils/T/tracer/Makefile | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/common/utils/T/tracer/Makefile b/common/utils/T/tracer/Makefile index 3da4aa13a1..792c2a407c 100644 --- a/common/utils/T/tracer/Makefile +++ b/common/utils/T/tracer/Makefile @@ -60,6 +60,11 @@ macpdu2wireshark: macpdu2wireshark.o database.o utils.o handler.o event.o \ multi: multi.o utils.o database.o config.o $(CC) $(CFLAGS) -o multi $^ $(LIBS) +multi.o: ../T_IDs.h + +../T_IDs.h: + cd .. && $(MAKE) + .PHONY: all gui/gui.a view/view.a logger/logger.a filter/filter.a gui/gui.a: From f6f6570d6e9545371373f5fd109bcce74533f3ae Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Tue, 23 Oct 2018 18:05:40 +0200 Subject: [PATCH 055/233] T: minor: don't abort() in textlog.c This leads to some logs missing in some situations. Plus it's not user-friendly. --- common/utils/T/tracer/textlog.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/utils/T/tracer/textlog.c b/common/utils/T/tracer/textlog.c index bb773b4215..dba9d55483 100644 --- a/common/utils/T/tracer/textlog.c +++ b/common/utils/T/tracer/textlog.c @@ -187,7 +187,7 @@ int main(int n, char **v) while (1) { event e; e = get_event(textlog_data.socket, &ebuf, database); - if (e.type == -1) abort(); + if (e.type == -1) break; handle_event(h, e); } From f7bf5905a0ce81e1d35576c6d168aa605635295e Mon Sep 17 00:00:00 2001 From: Y_Tomita Date: Wed, 24 Oct 2018 09:48:09 +0900 Subject: [PATCH 056/233] Refactoring for L2 FAPI simulator. --- openair2/LAYER2/MAC/main_ue.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/openair2/LAYER2/MAC/main_ue.c b/openair2/LAYER2/MAC/main_ue.c index dd76df76dd..1168ed265a 100755 --- a/openair2/LAYER2/MAC/main_ue.c +++ b/openair2/LAYER2/MAC/main_ue.c @@ -44,6 +44,7 @@ #include "common/ran_context.h" extern FILL_UL_INFO_MUTEX_t fill_ul_mutex; +extern uint8_t nfapi_mode; extern void openair_rrc_top_init_ue( int eMBMS_active, char* uecap_xer, uint8_t cba_group_active, uint8_t HO_active); void dl_phy_sync_success(module_id_t module_idP, frame_t frameP, unsigned char eNB_index, uint8_t first_sync) //init as MR @@ -103,13 +104,15 @@ mac_top_init_ue(int eMBMS_active, char *uecap_xer, UE_mac_inst = NULL; } - // mutex below are used for multiple UE's L2 FAPI simulation. - pthread_mutex_init(&fill_ul_mutex.rx_mutex,NULL); - pthread_mutex_init(&fill_ul_mutex.crc_mutex,NULL); - pthread_mutex_init(&fill_ul_mutex.sr_mutex,NULL); - pthread_mutex_init(&fill_ul_mutex.harq_mutex,NULL); - pthread_mutex_init(&fill_ul_mutex.cqi_mutex,NULL); - pthread_mutex_init(&fill_ul_mutex.rach_mutex,NULL); + // mutex below are used for multiple UE's L2 FAPI simulation. + if (nfapi_mode == 3){ + pthread_mutex_init(&fill_ul_mutex.rx_mutex,NULL); + pthread_mutex_init(&fill_ul_mutex.crc_mutex,NULL); + pthread_mutex_init(&fill_ul_mutex.sr_mutex,NULL); + pthread_mutex_init(&fill_ul_mutex.harq_mutex,NULL); + pthread_mutex_init(&fill_ul_mutex.cqi_mutex,NULL); + pthread_mutex_init(&fill_ul_mutex.rach_mutex,NULL); + } LOG_I(MAC, "[MAIN] calling RRC\n"); openair_rrc_top_init_ue(eMBMS_active, uecap_xer, cba_group_active, From 58c6520218dfd707e814766e153456044132086a Mon Sep 17 00:00:00 2001 From: Y_Tomita Date: Wed, 24 Oct 2018 10:00:33 +0900 Subject: [PATCH 057/233] Remove a change about MSG2 and MSG4 because this is used not only in L2 FAPI simulator but also in real eNB. --- openair2/LAYER2/MAC/eNB_scheduler_RA.c | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/openair2/LAYER2/MAC/eNB_scheduler_RA.c b/openair2/LAYER2/MAC/eNB_scheduler_RA.c index 4010d892e9..b6fdaab8a9 100755 --- a/openair2/LAYER2/MAC/eNB_scheduler_RA.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_RA.c @@ -501,9 +501,7 @@ generate_Msg2(module_id_t module_idP, int CC_idP, frame_t frameP, #endif { - // In case of nFAPI, sometimes timing of eNB and UE become different. - // So if nfapi_mode == 2(VNF) , this function don't check timing to avoid Attach failure. - if (((ra->Msg2_frame == frameP) && (ra->Msg2_subframe == subframeP)) || (nfapi_mode == 2)) { + if ((ra->Msg2_frame == frameP) && (ra->Msg2_subframe == subframeP)) { LOG_D(MAC, "[eNB %d] CC_id %d Frame %d, subframeP %d: Generating RAR DCI, state %d\n", module_idP, CC_idP, frameP, subframeP, ra->state); @@ -1012,9 +1010,7 @@ generate_Msg4(module_id_t module_idP, int CC_idP, frame_t frameP, { // This is normal LTE case LOG_D(MAC, "generate_Msg4 1 ra->Msg4_frame SFN/SF: %d.%d, frameP SFN/SF: %d.%d FOR eNB_Mod: %d \n", ra->Msg4_frame, ra->Msg4_subframe, frameP, subframeP, module_idP); - // In case of nFAPI, sometimes timing of eNB and UE become different. - // So if nfapi_mode == 2(VNF) , this function don't check timing to avoid Attach failure. - if (((ra->Msg4_frame == frameP) && (ra->Msg4_subframe == subframeP))||((nfapi_mode == 2)&&(cc->tdd_Config == NULL))) { + if ((ra->Msg4_frame == frameP) && (ra->Msg4_subframe == subframeP)) { // Get RRCConnectionSetup for Piggyback /*rrc_sdu_length = mac_rrc_data_req(module_idP, CC_idP, frameP, CCCH, 1, // 1 transport block @@ -1425,9 +1421,7 @@ schedule_RA(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP) if (ra->state == MSG2) generate_Msg2(module_idP, CC_id, frameP, subframeP, ra); - // In case of nFAPI, sometimes timing of eNB and UE become different. - // So if nfapi_mode == 2(VNF) , this function don't check timing to avoid Attach failure. - else if ((ra->state == MSG4 && ra->Msg4_frame == frameP && ra->Msg4_subframe == subframeP ) || (nfapi_mode == 2 && ra->state == MSG4)) + else if (ra->state == MSG4 && ra->Msg4_frame == frameP && ra->Msg4_subframe == subframeP ) generate_Msg4(module_idP, CC_id, frameP, subframeP, ra); else if (ra->state == WAITMSG4ACK) check_Msg4_retransmission(module_idP, CC_id, frameP, From 66dad294a51e7a39528f059c75061a0661f471a8 Mon Sep 17 00:00:00 2001 From: Y_Tomita Date: Wed, 24 Oct 2018 18:26:24 +0900 Subject: [PATCH 058/233] Change define NUMBER_OF_UE_MAX to avoid unexpected access. --- targets/COMMON/openairinterface5g_limits.h | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) mode change 100644 => 100755 targets/COMMON/openairinterface5g_limits.h diff --git a/targets/COMMON/openairinterface5g_limits.h b/targets/COMMON/openairinterface5g_limits.h old mode 100644 new mode 100755 index 1c27f65585..82a9f7df02 --- a/targets/COMMON/openairinterface5g_limits.h +++ b/targets/COMMON/openairinterface5g_limits.h @@ -15,7 +15,12 @@ # define NUMBER_OF_eNB_MAX 7 # define NUMBER_OF_RU_MAX 32 # ifndef UE_EXPANSION -# define NUMBER_OF_UE_MAX 20 +/* if the value of MAX_MOBILES_PER_ENB and NUMBER_OF_UE_MAX is different, +eNB process will exit because unexpected access happens. +Now some parts are using NUMBER_OF_UE_MAX +and the other are using MAX_MOBILES_PER_ENB in for-loop. +*/ +# define NUMBER_OF_UE_MAX 16 # define NUMBER_OF_CONNECTED_eNB_MAX 3 # else # define NUMBER_OF_UE_MAX 256 From 0b55ecab3769b6c4951d3b0d7ec7564bf67071c4 Mon Sep 17 00:00:00 2001 From: Y_Tomita Date: Wed, 24 Oct 2018 18:44:18 +0900 Subject: [PATCH 059/233] Fix lack of initialize a valuable. --- openair2/LAYER2/MAC/eNB_scheduler_fairRR.c | 1 + 1 file changed, 1 insertion(+) mode change 100644 => 100755 openair2/LAYER2/MAC/eNB_scheduler_fairRR.c diff --git a/openair2/LAYER2/MAC/eNB_scheduler_fairRR.c b/openair2/LAYER2/MAC/eNB_scheduler_fairRR.c old mode 100644 new mode 100755 index 9ab4306000..da89564b02 --- a/openair2/LAYER2/MAC/eNB_scheduler_fairRR.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_fairRR.c @@ -569,6 +569,7 @@ void dlsch_scheduler_pre_processor_fairRR (module_id_t Mod_id, LTE_eNB_UE_stats *eNB_UE_stats2 = NULL; UE_sched_ctrl *ue_sched_ctl1, *ue_sched_ctl2; #endif + memset(rballoc_sub[0],0,(MAX_NUM_CCs)*(N_RBG_MAX)*sizeof(unsigned char)); memset(min_rb_unit,0,sizeof(min_rb_unit)); for (CC_id=0; CC_id Date: Wed, 24 Oct 2018 18:58:05 +0900 Subject: [PATCH 060/233] Add comments. --- openair2/LAYER2/MAC/ue_procedures.c | 4 ++++ targets/RT/USER/lte-enb.c | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/openair2/LAYER2/MAC/ue_procedures.c b/openair2/LAYER2/MAC/ue_procedures.c index 12fbef7d80..29579517dd 100755 --- a/openair2/LAYER2/MAC/ue_procedures.c +++ b/openair2/LAYER2/MAC/ue_procedures.c @@ -2563,6 +2563,10 @@ ue_scheduler(const module_id_t module_idP, //Rrc_xface->Frame_index=Mac_rlc_xface->frameP; //if (subframe%5 == 0) //LG#ifdef EXMIMO + + // data to/from NETLINK is treated in pdcp_run. + // one socket is used in multiple UE's L2 FAPI simulator and + // only first UE need to do this. if(module_idP == 0){ pdcp_run(&ctxt); } diff --git a/targets/RT/USER/lte-enb.c b/targets/RT/USER/lte-enb.c index 17d3cd63d4..d6aeb99340 100755 --- a/targets/RT/USER/lte-enb.c +++ b/targets/RT/USER/lte-enb.c @@ -1002,7 +1002,7 @@ void init_eNB_proc(int inst) { pthread_create( &proc_rxtx[0].pthread_rxtx, attr0, eNB_thread_rxtx, proc ); pthread_create( &proc_rxtx[1].pthread_rxtx, attr1, tx_thread, proc); } - else if (nfapi_mode == 2) { + else if (nfapi_mode == 2) { // this is neccesary in VNF or L2 FAPI simulator. pthread_create( &proc_rxtx[0].pthread_rxtx, attr0, eNB_thread_rxtx, &proc_rxtx[0] ); pthread_create( &proc_rxtx[1].pthread_rxtx, attr1, eNB_thread_rxtx, &proc_rxtx[1] ); } From fd1054598d9de81643ed3d078d465c27e222c6b7 Mon Sep 17 00:00:00 2001 From: Y_Tomita Date: Wed, 24 Oct 2018 19:14:00 +0900 Subject: [PATCH 061/233] Change the conditional expression about init_eNB and add comment. --- targets/RT/USER/lte-softmodem.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/targets/RT/USER/lte-softmodem.c b/targets/RT/USER/lte-softmodem.c index 87c43fbf55..ea76e7099b 100755 --- a/targets/RT/USER/lte-softmodem.c +++ b/targets/RT/USER/lte-softmodem.c @@ -1049,7 +1049,7 @@ if (nfapi_mode==2) {// VNF number_of_cards = 1; printf("RC.nb_L1_inst:%d\n", RC.nb_L1_inst); - if (RC.nb_L1_inst > 0 && nfapi_mode != 2) { + if (RC.nb_L1_inst > 0) { printf("Initializing eNB threads single_thread_flag:%d wait_for_sync:%d\n", single_thread_flag,wait_for_sync); init_eNB(single_thread_flag,wait_for_sync); // for (inst=0;inst0 && nfapi_mode != 2) { printf("Initializing RU threads\n"); init_RU(rf_config_file); From cfab3139058cd763fdaf128eda5d32c78c5d3475 Mon Sep 17 00:00:00 2001 From: Y_Tomita Date: Wed, 24 Oct 2018 19:24:16 +0900 Subject: [PATCH 062/233] Remove a change about rrc_sdu_length.(because I don't know this modification is correct or not.) --- openair2/LAYER2/MAC/eNB_scheduler_RA.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openair2/LAYER2/MAC/eNB_scheduler_RA.c b/openair2/LAYER2/MAC/eNB_scheduler_RA.c index b6fdaab8a9..e71dba1a9c 100755 --- a/openair2/LAYER2/MAC/eNB_scheduler_RA.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_RA.c @@ -1168,7 +1168,7 @@ generate_Msg4(module_id_t module_idP, int CC_idP, frame_t frameP, mac->TX_req[CC_idP].sfn_sf = fill_nfapi_tx_req(&mac->TX_req[CC_idP].tx_request_body, (frameP * 10) + subframeP, - rrc_sdu_length + offset, + rrc_sdu_length, mac->pdu_index[CC_idP], mac->UE_list. DLSCH_pdu[CC_idP][0][(unsigned char)UE_id].payload[0]); From 342972c2ea7c29f2e1c8d57e33d6e4e742cff02c Mon Sep 17 00:00:00 2001 From: "Bi-Ruei, Chiu" Date: Thu, 25 Oct 2018 10:59:13 +0800 Subject: [PATCH 063/233] Update asn1c to commit 0a7524184f16e7093990a31d8d4db487a16e5782 Fix the problem that duplicate type names exist in OPEN TYPE. The following excerpt of ASN.1 of X2AP is one example. HandoverRequestAcknowledge-IEs X2AP-PROTOCOL-IES ::= { { ID id-Old-eNB-UE-X2AP-ID CRITICALITY ignore TYPE UE-X2AP-ID PRESENCE mandatory}| { ID id-New-eNB-UE-X2AP-ID CRITICALITY ignore TYPE UE-X2AP-ID PRESENCE mandatory}| ... } --- cmake_targets/tools/build_helper | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake_targets/tools/build_helper b/cmake_targets/tools/build_helper index 18e0d54746..ac939a2255 100755 --- a/cmake_targets/tools/build_helper +++ b/cmake_targets/tools/build_helper @@ -683,7 +683,7 @@ install_asn1c_from_source(){ # better to use a given commit than a branch in case the branch # is updated and requires modifications in the source of OAI #git checkout velichkov_s1ap_plus_option_group - git checkout d3aed06bb2bec7df1b5c6d0333f8c7dfc5993372 + git checkout 0a7524184f16e7093990a31d8d4db487a16e5782 autoreconf -iv ./configure make -j`nproc` From b60e861b148e4772362ba1dd0ab765e7c5fca785 Mon Sep 17 00:00:00 2001 From: Y_Tomita Date: Thu, 25 Oct 2018 22:09:33 +0900 Subject: [PATCH 064/233] Add --musim option for L2 FAPI simulator. --- cmake_targets/CMakeLists.txt | 1 + cmake_targets/build_oai | 6 ++++++ openair2/COMMON/platform_constants.h | 11 +++++++++++ targets/COMMON/openairinterface5g_limits.h | 15 +++++++++++++++ 4 files changed, 33 insertions(+) mode change 100644 => 100755 cmake_targets/CMakeLists.txt mode change 100644 => 100755 openair2/COMMON/platform_constants.h diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt old mode 100644 new mode 100755 index 23d96afc54..86303e3e76 --- a/cmake_targets/CMakeLists.txt +++ b/cmake_targets/CMakeLists.txt @@ -616,6 +616,7 @@ add_boolean_option(MESSAGE_CHART_GENERATOR_PHY False "trace some PHY exchang add_boolean_option(UE_EXPANSION False "enable UE_EXPANSION with max 256 UE") add_boolean_option(PHY_TX_THREAD False "enable UE_EXPANSION with max 256 UE") add_boolean_option(PRE_SCD_THREAD False "enable UE_EXPANSION with max 256 UE") +add_boolean_option(UESIM_EXPANSION False "enable UESIM_EXPANSION with max 256 UE") ######################## # Include order diff --git a/cmake_targets/build_oai b/cmake_targets/build_oai index 3954827c09..9dfe9d3ecc 100755 --- a/cmake_targets/build_oai +++ b/cmake_targets/build_oai @@ -43,6 +43,7 @@ conf_nvram_path=$OPENAIR_DIR/openair3/NAS/TOOLS/ue_eurecom_test_sfr.conf MSC_GEN=0 XFORMS="True" UE_EXPANSION="False" +UESIM_EXPANSION="False" PRINT_STATS="False" VCD_TIMING="False" DEADLINE_SCHEDULER_FLAG_USER="False" @@ -218,6 +219,10 @@ function main() { UE_EXPANSION="True" echo_info "Will compile with UE_EXPANSION" shift;; + --musim) + UESIM_EXPANSION="True" + echo_info "Will compile with UESIM_EXPANSION" + shift;; --UE-conf-nvram) conf_nvram_path=$(readlink -f $2) shift 2;; @@ -539,6 +544,7 @@ function main() { echo "set ( UE_EXPANSION $UE_EXPANSION )" >> $cmake_file # echo "set ( PHY_TX_THREAD $UE_EXPANSION )" >> $cmake_file echo "set ( PRE_SCD_THREAD $UE_EXPANSION )" >> $cmake_file + echo "set ( UESIM_EXPANSION $UESIM_EXPANSION )" >> $cmake_file echo "set ( RRC_ASN1_VERSION \"${REL}\")" >> $cmake_file echo "set ( ENABLE_VCD_FIFO $VCD_TIMING )" >> $cmake_file echo "set ( RF_BOARD \"${HW}\")" >> $cmake_file diff --git a/openair2/COMMON/platform_constants.h b/openair2/COMMON/platform_constants.h old mode 100644 new mode 100755 index 9aa912a01e..2a3dee6b23 --- a/openair2/COMMON/platform_constants.h +++ b/openair2/COMMON/platform_constants.h @@ -68,6 +68,16 @@ # define MAX_MODULES NB_MODULES_MAX #ifndef UE_EXPANSION +// TODO:L2 FAPI simulator. +// UESIM_EXPANSION is used to be same value of MAX_MOBILES_PER_ENB +// in eNB and UE. +// now , if we use --mu option in UE, compiling error will occur. +// This problem will be fixed in the future. +# ifdef UESIM_EXPANSION +# define MAX_MOBILES_PER_ENB 256 +# define MAX_MOBILES_PER_ENB_NB_IoT 256 +# define MAX_eNB 2 +# else # ifdef LARGE_SCALE # define MAX_MOBILES_PER_ENB 128 # define MAX_MOBILES_PER_ENB_NB_IoT 128 @@ -77,6 +87,7 @@ # define MAX_MOBILES_PER_ENB_NB_IoT 16 # define MAX_eNB 2 # endif +#endif #else # define MAX_MOBILES_PER_ENB 256 # define MAX_MOBILES_PER_ENB_NB_IoT 256 diff --git a/targets/COMMON/openairinterface5g_limits.h b/targets/COMMON/openairinterface5g_limits.h index 82a9f7df02..644952ca79 100755 --- a/targets/COMMON/openairinterface5g_limits.h +++ b/targets/COMMON/openairinterface5g_limits.h @@ -5,8 +5,18 @@ # define NUMBER_OF_eNB_MAX 1 # define NUMBER_OF_RU_MAX 2 # ifndef UE_EXPANSION +// TODO:L2 FAPI simulator. +// UESIM_EXPANSION is used to be same value of NUMBER_OF_UE_MAX +// in eNB and UE. +// now , if we use --mu option in UE, compiling error will occur. +// This problem will be fixed in the future. +# ifndef UESIM_EXPANSION # define NUMBER_OF_UE_MAX 16 # define NUMBER_OF_CONNECTED_eNB_MAX 3 +# else +# define NUMBER_OF_UE_MAX 256 +# define NUMBER_OF_CONNECTED_eNB_MAX 1 +# endif # else # define NUMBER_OF_UE_MAX 256 # define NUMBER_OF_CONNECTED_eNB_MAX 1 @@ -20,8 +30,13 @@ eNB process will exit because unexpected access happens. Now some parts are using NUMBER_OF_UE_MAX and the other are using MAX_MOBILES_PER_ENB in for-loop. */ +# ifndef UESIM_EXPANSION # define NUMBER_OF_UE_MAX 16 # define NUMBER_OF_CONNECTED_eNB_MAX 3 +# else +# define NUMBER_OF_UE_MAX 256 +# define NUMBER_OF_CONNECTED_eNB_MAX 1 +# endif # else # define NUMBER_OF_UE_MAX 256 # define NUMBER_OF_CONNECTED_eNB_MAX 1 From dcfe6b32e248718402980eba28a075697c67dde7 Mon Sep 17 00:00:00 2001 From: Y_Tomita Date: Thu, 25 Oct 2018 22:10:57 +0900 Subject: [PATCH 065/233] Fix for TDD L2 FAPI simulator. --- targets/RT/USER/lte-ue.c | 12 +++++++----- targets/RT/USER/lte-uesoftmodem.c | 10 ++++++---- 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/targets/RT/USER/lte-ue.c b/targets/RT/USER/lte-ue.c index 4c52b0b792..2cdbfcc27a 100755 --- a/targets/RT/USER/lte-ue.c +++ b/targets/RT/USER/lte-ue.c @@ -94,7 +94,7 @@ extern int oai_nfapi_rx_ind(nfapi_rx_indication_t *ind); extern int multicast_link_write_sock(int groupP, char *dataP, uint32_t sizeP); extern int simL1flag; - +extern uint16_t sf_ahead; //extern int tx_req_UE_MAC1(); void ue_stub_rx_handler(unsigned int, char *); @@ -379,7 +379,7 @@ void init_UE_stub_single_thread(int nb_inst,int eMBMS_active, int uecap_xer_in, for (inst=0;instsubframe_rx=timer_subframe; proc->frame_rx = timer_frame; - proc->subframe_tx=(timer_subframe+4)%10; - proc->frame_tx = proc->frame_rx + (proc->subframe_rx>5?1:0); + + // FDD and TDD tx timing settings. + proc->subframe_tx=(timer_subframe+sf_ahead)%10; + proc->frame_tx = proc->frame_rx + (proc->subframe_rx>(9-sf_ahead)?1:0); //oai_subframe_ind(proc->frame_rx, proc->subframe_rx); - oai_subframe_ind(timer_frame, timer_subframe); + oai_subframe_ind(proc->frame_tx,proc->subframe_tx); //Guessing that the next 4 lines are not needed for the phy_stub mode. /*initRefTimes(t2); diff --git a/targets/RT/USER/lte-uesoftmodem.c b/targets/RT/USER/lte-uesoftmodem.c index 2a2c874a91..be8a30c1bd 100755 --- a/targets/RT/USER/lte-uesoftmodem.c +++ b/targets/RT/USER/lte-uesoftmodem.c @@ -117,7 +117,7 @@ int nfapi_sync_var=-1; //!< protected by mutex \ref nfapi_sync_mutex uint8_t nfapi_mode = 0; uint16_t sf_ahead=2; - +int tddflag; char *emul_iface; @@ -498,7 +498,7 @@ extern int16_t dlsch_demod_shift; static void get_options(unsigned int *start_msc) { int CC_id; - int tddflag, nonbiotflag; + int nonbiotflag; char *loopfile=NULL; int dumpframe; uint32_t online_log_messages; @@ -565,8 +565,10 @@ static void get_options(unsigned int *start_msc) { UE_scan=0; if (tddflag > 0) { - for (CC_id=0; CC_idframe_type = TDD; + for (CC_id=0; CC_idframe_type = TDD; + frame_parms[CC_id]->tdd_config = tddflag; + } } if (frame_parms[0]->N_RB_DL !=0) { From a321e160cf38c54e190ede5aaddfe0504248a850 Mon Sep 17 00:00:00 2001 From: Louis Adrien Dufrene Date: Thu, 25 Oct 2018 16:03:38 +0200 Subject: [PATCH 066/233] rrc inactivity timer created, S1 ue context release request sent on timeout, timer set at RRC connection complete reception --- openair2/RRC/LTE/L2_interface.c | 7 ++-- openair2/RRC/LTE/rrc_defs.h | 13 ++++--- openair2/RRC/LTE/rrc_eNB.c | 68 ++++++++++++++++++++++++--------- 3 files changed, 62 insertions(+), 26 deletions(-) diff --git a/openair2/RRC/LTE/L2_interface.c b/openair2/RRC/LTE/L2_interface.c index d201732177..74e735bc85 100644 --- a/openair2/RRC/LTE/L2_interface.c +++ b/openair2/RRC/LTE/L2_interface.c @@ -279,6 +279,9 @@ mac_rrc_data_ind( } //------------------------------------------------------------------------------ +/* +* Get RRC status (Connected, Idle...) of UE from RNTI +*/ int mac_eNB_get_rrc_status( const module_id_t Mod_idP, @@ -287,9 +290,7 @@ mac_eNB_get_rrc_status( //------------------------------------------------------------------------------ { struct rrc_eNB_ue_context_s* ue_context_p = NULL; - ue_context_p = rrc_eNB_get_ue_context( - RC.rrc[Mod_idP], - rntiP); + ue_context_p = rrc_eNB_get_ue_context(RC.rrc[Mod_idP], rntiP); if (ue_context_p != NULL) { return(ue_context_p->ue_context.Status); diff --git a/openair2/RRC/LTE/rrc_defs.h b/openair2/RRC/LTE/rrc_defs.h index ae87075489..3756acc457 100644 --- a/openair2/RRC/LTE/rrc_defs.h +++ b/openair2/RRC/LTE/rrc_defs.h @@ -387,10 +387,10 @@ typedef enum SL_TRIGGER_e { #define RRC_TRANSACTION_IDENTIFIER_NUMBER 3 typedef struct { - unsigned short transport_block_size; /*!< \brief Minimum PDU size in bytes provided by RLC to MAC layer interface */ - unsigned short max_transport_blocks; /*!< \brief Maximum PDU size in bytes provided by RLC to MAC layer interface */ - unsigned long Guaranteed_bit_rate; /*!< \brief Guaranteed Bit Rate (average) to be offered by MAC layer scheduling*/ - unsigned long Max_bit_rate; /*!< \brief Maximum Bit Rate that can be offered by MAC layer scheduling*/ + unsigned short transport_block_size; /*!< \brief Minimum PDU size in bytes provided by RLC to MAC layer interface */ + unsigned short max_transport_blocks; /*!< \brief Maximum PDU size in bytes provided by RLC to MAC layer interface */ + unsigned long Guaranteed_bit_rate; /*!< \brief Guaranteed Bit Rate (average) to be offered by MAC layer scheduling*/ + unsigned long Max_bit_rate; /*!< \brief Maximum Bit Rate that can be offered by MAC layer scheduling*/ uint8_t Delay_class; /*!< \brief Delay class offered by MAC layer scheduling*/ uint8_t Target_bler; /*!< \brief Target Average Transport Block Error rate*/ uint8_t Lchan_t; /*!< \brief Logical Channel Type (BCCH,CCCH,DCCH,DTCH_B,DTCH,MRBCH)*/ @@ -552,7 +552,7 @@ typedef struct eNB_RRC_UE_s { CipheringAlgorithm_r12_t ciphering_algorithm; e_SecurityAlgorithmConfig__integrityProtAlgorithm integrity_algorithm; - uint8_t Status; + uint8_t Status; // RRC status, type enum UE_STATE_t rnti_t rnti; uint64_t random_ue_identity; @@ -599,6 +599,9 @@ typedef struct eNB_RRC_UE_s { uint32_t ue_release_timer_thres_rrc; uint32_t ue_reestablishment_timer; uint32_t ue_reestablishment_timer_thres; + /* RRC inactivity timer: on timeout, should release RRC connection for inactivity on all E-RABs */ + uint32_t ue_rrc_inactivity_timer; + uint32_t ue_rrc_inactivity_timer_thres; uint8_t e_rab_release_command_flag; int8_t reestablishment_xid; } eNB_RRC_UE_t; diff --git a/openair2/RRC/LTE/rrc_eNB.c b/openair2/RRC/LTE/rrc_eNB.c index 56d68117c4..54b94f8c35 100644 --- a/openair2/RRC/LTE/rrc_eNB.c +++ b/openair2/RRC/LTE/rrc_eNB.c @@ -862,13 +862,13 @@ rrc_eNB_free_UE( rnti); if (EPC_MODE_ENABLED) { - if((ue_context_pP->ue_context.ul_failure_timer >= 20000) && (mac_eNB_get_rrc_status(enb_mod_idP,rnti) >= RRC_CONNECTED)) { - LOG_I(RRC, "[eNB %d] S1AP_UE_CONTEXT_RELEASE_REQ sent for RNTI %x\n", + if((ue_context_pP->ue_context.ul_failure_timer >= 20000) && (mac_eNB_get_rrc_status(enb_mod_idP, rnti) >= RRC_CONNECTED)) { + LOG_I(RRC, "[eNB %d] S1AP_UE_CONTEXT_RELEASE_REQ sent for RNTI %x, cause 21, radio connection with ue lost\n", enb_mod_idP, rnti); rrc_eNB_send_S1AP_UE_CONTEXT_RELEASE_REQ(enb_mod_idP, ue_context_pP, S1AP_CAUSE_RADIO_NETWORK, 21); - // send cause 21: connection with ue lost + // send cause 21: radio connection with ue lost /* From 3GPP 36300v10 p129 : 19.2.2.2.2 S1 UE Context Release Request (eNB triggered) * If the E-UTRAN internal reason is a radio link failure detected in the eNB, the eNB shall wait a sufficient time before * triggering the S1 UE Context Release Request procedure in order to allow the UE to perform the NAS recovery @@ -877,7 +877,18 @@ rrc_eNB_free_UE( return; } - // TODO : add here cause ul inactivity + + if((ue_context_pP->ue_context.ue_rrc_inactivity_timer >= ue_context_pP->ue_context.ue_rrc_inactivity_timer_thres) && + (mac_eNB_get_rrc_status(enb_mod_idP, rnti) >= RRC_CONNECTED)) { + LOG_I(RRC, "[eNB %d] S1AP_UE_CONTEXT_RELEASE_REQ sent for RNTI %x, cause 20, user inactivity\n", + enb_mod_idP, + rnti); + + rrc_eNB_send_S1AP_UE_CONTEXT_RELEASE_REQ(enb_mod_idP, ue_context_pP, S1AP_CAUSE_RADIO_NETWORK, 20); + // send cause 20: user inactivity + + return; + } } // add UE info to freeList @@ -1012,11 +1023,14 @@ void release_UE_in_freeList(module_id_t mod_id) } //----------------------------------------------------------------------------- +/* +* Process the rrc connection setup complete message from UE (SRB1 Active) +*/ void rrc_eNB_process_RRCConnectionSetupComplete( - const protocol_ctxt_t* const ctxt_pP, - rrc_eNB_ue_context_t* ue_context_pP, - RRCConnectionSetupComplete_r8_IEs_t * rrcConnectionSetupComplete + const protocol_ctxt_t *const ctxt_pP, + rrc_eNB_ue_context_t *ue_context_pP, + RRCConnectionSetupComplete_r8_IEs_t *rrcConnectionSetupComplete ) //----------------------------------------------------------------------------- { @@ -1024,22 +1038,19 @@ rrc_eNB_process_RRCConnectionSetupComplete( PROTOCOL_RRC_CTXT_UE_FMT" [RAPROC] Logical Channel UL-DCCH, " "processing RRCConnectionSetupComplete from UE (SRB1 Active)\n", PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP)); - ue_context_pP->ue_context.Srb1.Active=1; + ue_context_pP->ue_context.Srb1.Active = 1; + ue_context_pP->ue_context.Status = RRC_CONNECTED; + ue_context_pP->ue_context.ue_rrc_inactivity_timer = 1; // set rrc inactivity when UE goes into RRC_CONNECTED + T(T_ENB_RRC_CONNECTION_SETUP_COMPLETE, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame), T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti)); if (EPC_MODE_ENABLED == 1) { // Forward message to S1AP layer - rrc_eNB_send_S1AP_NAS_FIRST_REQ( - ctxt_pP, - ue_context_pP, - rrcConnectionSetupComplete); + rrc_eNB_send_S1AP_NAS_FIRST_REQ(ctxt_pP, ue_context_pP, rrcConnectionSetupComplete); } else { // RRC loop back (no S1AP), send SecurityModeCommand to UE - rrc_eNB_generate_SecurityModeCommand( - ctxt_pP, - ue_context_pP); - // rrc_eNB_generate_UECapabilityEnquiry(enb_mod_idP,frameP,ue_mod_idP); + rrc_eNB_generate_SecurityModeCommand(ctxt_pP, ue_context_pP); } } @@ -5364,6 +5375,11 @@ rrc_eNB_generate_RRCConnectionReconfiguration_handover( */ //----------------------------------------------------------------------------- +/* +* TODO: * add function description +* * add ue_rrc_inactivity_timer set +* * format the function correctly +*/ void rrc_eNB_process_RRCConnectionReconfigurationComplete( const protocol_ctxt_t* const ctxt_pP, @@ -6868,7 +6884,6 @@ if (ue_context_p->ue_context.nb_of_modify_e_rabs > 0) { ctxt_pP, ue_context_p, &ul_dcch_msg->message.choice.c1.choice.rrcConnectionSetupComplete.criticalExtensions.choice.c1.choice.rrcConnectionSetupComplete_r8); - ue_context_p->ue_context.Status = RRC_CONNECTED; LOG_I(RRC, PROTOCOL_RRC_CTXT_UE_FMT" UE State = RRC_CONNECTED \n", PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP)); @@ -7901,6 +7916,18 @@ rrc_rx_tx( } // end if (rrc_release_info.num_UEs > 0) pthread_mutex_unlock(&rrc_release_freelist); + if (ue_context_p->ue_context.ue_rrc_inactivity_timer > 0) { + ue_context_p->ue_context.ue_rrc_inactivity_timer++; + + if (ue_context_p->ue_context.ue_rrc_inactivity_timer >= ue_context_p->ue_context.ue_rrc_inactivity_timer_thres) { + LOG_I(RRC, "Removing UE %x instance because of rrc_inactivity_timer timeout\n", + ue_context_p->ue_context.rnti); + + ue_to_be_removed = ue_context_p; + break; // break RB_FOREACH + } + } + if (ue_context_p->ue_context.ue_reestablishment_timer > 0) { ue_context_p->ue_context.ue_reestablishment_timer++; @@ -7935,7 +7962,8 @@ rrc_rx_tx( } // end RB_FOREACH if (ue_to_be_removed) { - if (ue_to_be_removed->ue_context.ul_failure_timer >= 20000) { + if ((ue_to_be_removed->ue_context.ul_failure_timer >= 20000) || + (ue_to_be_removed->ue_context.ue_rrc_inactivity_timer >= ue_to_be_removed->ue_context.ue_rrc_inactivity_timer_thres)) { ue_to_be_removed->ue_context.ue_release_timer_s1 = 1; ue_to_be_removed->ue_context.ue_release_timer_thres_s1 = 100; ue_to_be_removed->ue_context.ue_release_timer = 0; @@ -7947,6 +7975,10 @@ rrc_rx_tx( if (ue_to_be_removed->ue_context.ul_failure_timer >= 20000) { ue_to_be_removed->ue_context.ul_failure_timer = 0; } + + if (ue_to_be_removed->ue_context.ue_rrc_inactivity_timer >= ue_to_be_removed->ue_context.ue_rrc_inactivity_timer_thres) { + ue_to_be_removed->ue_context.ue_rrc_inactivity_timer = 0; //reset timer after S1 command UE context release request is sent + } } #ifdef RRC_LOCALIZATION From 78051a314a3b41e2b104e06262f77114ae9265ba Mon Sep 17 00:00:00 2001 From: Louis Adrien Dufrene Date: Fri, 26 Oct 2018 08:14:47 +0200 Subject: [PATCH 067/233] RRC inactivity timer on RRC connection setup: to be tested --- openair2/RRC/LTE/rrc_eNB.c | 1 + 1 file changed, 1 insertion(+) diff --git a/openair2/RRC/LTE/rrc_eNB.c b/openair2/RRC/LTE/rrc_eNB.c index 54b94f8c35..5f6580d316 100644 --- a/openair2/RRC/LTE/rrc_eNB.c +++ b/openair2/RRC/LTE/rrc_eNB.c @@ -1041,6 +1041,7 @@ rrc_eNB_process_RRCConnectionSetupComplete( ue_context_pP->ue_context.Srb1.Active = 1; ue_context_pP->ue_context.Status = RRC_CONNECTED; ue_context_pP->ue_context.ue_rrc_inactivity_timer = 1; // set rrc inactivity when UE goes into RRC_CONNECTED + ue_context_pP->ue_context.ue_rrc_inactivity_timer_thres = 10000; // SHOULD NOT BE DONE HERE !!!!! T(T_ENB_RRC_CONNECTION_SETUP_COMPLETE, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame), T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti)); From 266645d98d0af1f05f72445476fe8522f31ec978 Mon Sep 17 00:00:00 2001 From: root Date: Fri, 26 Oct 2018 09:50:01 +0200 Subject: [PATCH 068/233] Minor corrections, compilation ok --- openair2/RRC/LTE/rrc_eNB.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/openair2/RRC/LTE/rrc_eNB.c b/openair2/RRC/LTE/rrc_eNB.c index 5f6580d316..8842e8be9f 100644 --- a/openair2/RRC/LTE/rrc_eNB.c +++ b/openair2/RRC/LTE/rrc_eNB.c @@ -862,7 +862,7 @@ rrc_eNB_free_UE( rnti); if (EPC_MODE_ENABLED) { - if((ue_context_pP->ue_context.ul_failure_timer >= 20000) && (mac_eNB_get_rrc_status(enb_mod_idP, rnti) >= RRC_CONNECTED)) { + if ((ue_context_pP->ue_context.ul_failure_timer >= 20000) && (mac_eNB_get_rrc_status(enb_mod_idP, rnti) >= RRC_CONNECTED)) { LOG_I(RRC, "[eNB %d] S1AP_UE_CONTEXT_RELEASE_REQ sent for RNTI %x, cause 21, radio connection with ue lost\n", enb_mod_idP, rnti); @@ -2016,13 +2016,14 @@ rrc_eNB_generate_RRCConnectionRelease( ) //----------------------------------------------------------------------------- { - uint8_t buffer[RRC_BUF_SIZE] = 0; + uint8_t buffer[RRC_BUF_SIZE]; uint16_t size = 0; + memset(buffer, 0, RRC_BUF_SIZE); + T(T_ENB_RRC_CONNECTION_RELEASE, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame), T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti)); - memset(buffer, 0, RRC_BUF_SIZE); size = do_RRCConnectionRelease(ctxt_pP->module_id, buffer,rrc_eNB_get_next_transaction_identifier(ctxt_pP->module_id)); ue_context_pP->ue_context.ue_reestablishment_timer = 0; From bb7d63e97e6706e8493f30f358fa0014c5573a9d Mon Sep 17 00:00:00 2001 From: Y_Tomita Date: Fri, 26 Oct 2018 18:07:03 +0900 Subject: [PATCH 069/233] Fix timing setting in L2 FAPI simulator. --- targets/RT/USER/lte-ue.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/targets/RT/USER/lte-ue.c b/targets/RT/USER/lte-ue.c index 2cdbfcc27a..bc393b7371 100755 --- a/targets/RT/USER/lte-ue.c +++ b/targets/RT/USER/lte-ue.c @@ -1028,7 +1028,11 @@ static void *UE_phy_stub_single_thread_rxn_txnp4(void *arg) { //oai_subframe_ind(proc->frame_rx, proc->subframe_rx); + if(UE->frame_parms.frame_type == FDD){ + oai_subframe_ind(proc->frame_rx, proc->subframe_rx); + }else{ oai_subframe_ind(proc->frame_tx,proc->subframe_tx); + } //Guessing that the next 4 lines are not needed for the phy_stub mode. /*initRefTimes(t2); From 265f11069165ec8eab01013729839e302387e3cb Mon Sep 17 00:00:00 2001 From: Wang Tsu-Han Date: Fri, 26 Oct 2018 16:49:50 +0200 Subject: [PATCH 070/233] using mask for ru_thread_tx --- openair1/PHY/defs_eNB.h | 6 +- .../CONF/enb.band7.tm1.100PRB.usrpx310.conf | 6 +- targets/RT/USER/lte-enb.c | 70 +++++++++++-------- targets/RT/USER/lte-ru.c | 38 +++++++--- 4 files changed, 75 insertions(+), 45 deletions(-) diff --git a/openair1/PHY/defs_eNB.h b/openair1/PHY/defs_eNB.h index d9b8f9b319..a8c0ab8506 100644 --- a/openair1/PHY/defs_eNB.h +++ b/openair1/PHY/defs_eNB.h @@ -809,12 +809,16 @@ typedef struct eNB_proc_t_s { pthread_mutex_t mutex_asynch_rxtx; /// mutex for RU access to eNB processing (PDSCH/PUSCH) pthread_mutex_t mutex_RU; + /// mutex for eNB processing to access RU TX (PDSCH/PUSCH) + pthread_mutex_t mutex_RU_tx; /// mutex for RU access to eNB processing (PRACH) pthread_mutex_t mutex_RU_PRACH; /// mutex for RU access to eNB processing (PRACH BR) pthread_mutex_t mutex_RU_PRACH_br; /// mask for RUs serving eNB (PDSCH/PUSCH) int RU_mask; + /// mask for RUs serving eNB (PDSCH/PUSCH) + int RU_mask_tx; /// mask for RUs serving eNB (PRACH) int RU_mask_prach; #if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) @@ -829,8 +833,6 @@ typedef struct eNB_proc_t_s { eNB_rxtx_proc_t L1_proc,L1_proc_tx; /// stats thread pthread descriptor pthread_t process_stats_thread; - /// for waking up tx procedure - RU_proc_t *ru_proc; } eNB_proc_t; diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.100PRB.usrpx310.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.100PRB.usrpx310.conf index 60b47c5c49..728492ee83 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.100PRB.usrpx310.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.100PRB.usrpx310.conf @@ -15,7 +15,7 @@ eNBs = // Tracking area code, 0x0000 and 0xfffe are reserved values tracking_area_code = 1; - plmn_list = ( { mcc = 208; mnc = 93; mnc_length = 2; } ); + plmn_list = ( { mcc = 208; mnc = 92; mnc_length = 2; } ); tr_s_preference = "local_mac" @@ -138,7 +138,7 @@ eNBs = ////////// MME parameters: - mme_ip_address = ( { ipv4 = "192.168.12.26"; + mme_ip_address = ( { ipv4 = "192.168.12.148"; ipv6 = "192:168:30::17"; active = "yes"; preference = "ipv4"; @@ -187,7 +187,7 @@ RUs = ( max_pdschReferenceSignalPower = -27; max_rxgain = 116; eNB_instances = [0]; - + sdr_addrs = "type=x300"; } ); diff --git a/targets/RT/USER/lte-enb.c b/targets/RT/USER/lte-enb.c index f8d5a351be..271572060c 100644 --- a/targets/RT/USER/lte-enb.c +++ b/targets/RT/USER/lte-enb.c @@ -143,8 +143,8 @@ extern double cpuf; void init_eNB(int,int); void stop_eNB(int nb_inst); -int wakeup_tx(PHY_VARS_eNB *eNB,RU_proc_t *ru_proc); -int wakeup_txfh(eNB_rxtx_proc_t *proc,RU_proc_t *ru_proc); +int wakeup_tx(PHY_VARS_eNB *eNB); +int wakeup_txfh(eNB_rxtx_proc_t *proc,PHY_VARS_eNB *eNB); void wakeup_prach_eNB(PHY_VARS_eNB *eNB,RU_t *ru,int frame,int subframe); #if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) void wakeup_prach_eNB_br(PHY_VARS_eNB *eNB,RU_t *ru,int frame,int subframe); @@ -356,7 +356,7 @@ static void* L1_thread_tx(void* param) { exit_fun( "ERROR pthread_cond_signal" ); } pthread_mutex_unlock( &proc->mutex ); - wakeup_txfh(proc,eNB->proc.ru_proc); + wakeup_txfh(proc,eNB); } return 0; @@ -429,11 +429,11 @@ static void* L1_thread( void* param ) { if (release_thread(&proc->mutex,&proc->instance_cnt,thread_name)<0) break; if (nfapi_mode!=2){ - if(get_thread_parallel_conf() == PARALLEL_RU_L1_TRX_SPLIT) wakeup_tx(eNB,eNB->proc.ru_proc); + if(get_thread_parallel_conf() == PARALLEL_RU_L1_TRX_SPLIT) wakeup_tx(eNB); else if(get_thread_parallel_conf() == PARALLEL_RU_L1_SPLIT) { phy_procedures_eNB_TX(eNB, proc, 1); - wakeup_txfh(proc,eNB->proc.ru_proc); + wakeup_txfh(proc,eNB); } } @@ -473,51 +473,61 @@ void eNB_top(PHY_VARS_eNB *eNB, int frame_rx, int subframe_rx, char *string,RU_t } } -int wakeup_txfh(eNB_rxtx_proc_t *proc,RU_proc_t *ru_proc) { - - if(ru_proc == NULL) - return(0); +int wakeup_txfh(eNB_rxtx_proc_t *proc,PHY_VARS_eNB *eNB) { + + RU_t *ru; + RU_proc_t *ru_proc; + int i; + + struct timespec wait; wait.tv_sec=0; wait.tv_nsec=5000000L; -printf("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~inside wakeup_txfh %d.%d IC_RU = %d\n", proc->frame_tx, proc->subframe_tx, proc->instance_cnt_RUs); +//printf("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~inside wakeup_txfh %d.%d IC_RU = %d\n", proc->frame_tx, proc->subframe_tx, proc->instance_cnt_RUs); if(wait_on_condition(&proc->mutex_RUs,&proc->cond_RUs,&proc->instance_cnt_RUs,"wakeup_txfh")<0) { LOG_E(PHY,"Frame %d, subframe %d: TX FH not ready\n", ru_proc->frame_tx, ru_proc->subframe_tx); return(-1); } + pthread_mutex_lock(&eNB->proc.mutex_RU_tx); + eNB->proc.RU_mask_tx = 0; + pthread_mutex_unlock(&eNB->proc.mutex_RU_tx); if (release_thread(&proc->mutex_RUs,&proc->instance_cnt_RUs,"wakeup_txfh")<0) return(-1); - - if (ru_proc->instance_cnt_eNBs == 0) { - LOG_E(PHY,"Frame %d, subframe %d: TX FH thread busy, dropping Frame %d, subframe %d\n", ru_proc->frame_tx, ru_proc->subframe_tx, proc->frame_rx, proc->subframe_rx); - return(-1); - } - if (pthread_mutex_timedlock(&ru_proc->mutex_eNBs,&wait) != 0) { - LOG_E( PHY, "[eNB] ERROR pthread_mutex_lock for eNB TX1 thread %d (IC %d)\n", ru_proc->subframe_rx&1,ru_proc->instance_cnt_eNBs ); - exit_fun( "error locking mutex_eNB" ); - return(-1); - } - //for(num_RUs) + for(int i=0; inum_RU; i++) + { + ru = eNB->RU_list[i]; + ru_proc = &ru->proc; + if (ru_proc->instance_cnt_eNBs == 0) { + LOG_E(PHY,"Frame %d, subframe %d: TX FH thread busy, dropping Frame %d, subframe %d\n", ru_proc->frame_tx, ru_proc->subframe_tx, proc->frame_rx, proc->subframe_rx); + return(-1); + } + if (pthread_mutex_timedlock(&ru_proc->mutex_eNBs,&wait) != 0) { + LOG_E( PHY, "[eNB] ERROR pthread_mutex_lock for eNB TX1 thread %d (IC %d)\n", ru_proc->subframe_rx&1,ru_proc->instance_cnt_eNBs ); + exit_fun( "error locking mutex_eNB" ); + return(-1); + } + ru_proc->instance_cnt_eNBs = 0; ru_proc->timestamp_tx = proc->timestamp_tx; ru_proc->subframe_tx = proc->subframe_tx; ru_proc->frame_tx = proc->frame_tx; - // the thread can now be woken up - if (pthread_cond_signal(&ru_proc->cond_eNBs) != 0) { - LOG_E( PHY, "[eNB] ERROR pthread_cond_signal for eNB TXnp4 thread\n"); - exit_fun( "ERROR pthread_cond_signal" ); - return(-1); - } + // the thread can now be woken up + if (pthread_cond_signal(&ru_proc->cond_eNBs) != 0) { + LOG_E( PHY, "[eNB] ERROR pthread_cond_signal for eNB TXnp4 thread\n"); + exit_fun( "ERROR pthread_cond_signal" ); + return(-1); + } - pthread_mutex_unlock( &ru_proc->mutex_eNBs ); + pthread_mutex_unlock( &ru_proc->mutex_eNBs ); + } return(0); } -int wakeup_tx(PHY_VARS_eNB *eNB,RU_proc_t *ru_proc) { +int wakeup_tx(PHY_VARS_eNB *eNB) { eNB_proc_t *proc=&eNB->proc; @@ -913,6 +923,7 @@ void init_eNB_proc(int inst) { proc->first_rx =1; proc->first_tx =1; + proc->RU_mask_tx = (1<num_RU)-1; proc->RU_mask =0; proc->RU_mask_prach =0; @@ -929,6 +940,7 @@ void init_eNB_proc(int inst) { pthread_mutex_init( &proc->mutex_prach, NULL); pthread_mutex_init( &proc->mutex_asynch_rxtx, NULL); pthread_mutex_init( &proc->mutex_RU,NULL); + pthread_mutex_init( &proc->mutex_RU_tx,NULL); pthread_mutex_init( &proc->mutex_RU_PRACH,NULL); pthread_cond_init( &proc->cond_prach, NULL); diff --git a/targets/RT/USER/lte-ru.c b/targets/RT/USER/lte-ru.c index 4bf6fd6cd4..42d71cfbf4 100644 --- a/targets/RT/USER/lte-ru.c +++ b/targets/RT/USER/lte-ru.c @@ -1273,7 +1273,6 @@ void wakeup_L1s(RU_t *ru) { for (i=0;inum_eNB;i++) { LOG_D(PHY,"ru->wakeup_rxtx:%p\n", ru->wakeup_rxtx); - eNB_list[i]->proc.ru_proc = &ru->proc; if (ru->wakeup_rxtx!=0 && ru->wakeup_rxtx(eNB_list[i],ru) < 0) { LOG_E(PHY,"could not wakeup eNB rxtx process for subframe %d\n", ru->proc.subframe_rx); @@ -1559,7 +1558,7 @@ static void* ru_thread_tx( void* param ) { // wait until eNBs are finished subframe RX n and TX n+4 wait_on_condition(&proc->mutex_eNBs,&proc->cond_eNBs,&proc->instance_cnt_eNBs,"ru_thread_tx"); if (oai_exit) break; -printf("~~~~~~~~~~~~~~~~~~~~~~~~~~~~ru_thread_tx is waken up %d.%d having L1 %d\n", proc->frame_tx, proc->subframe_tx, ru->num_eNB); +//printf("~~~~~~~~~~~~~~~~~~~~~~~~~~~~ru_thread_tx is waken up %d.%d having L1 %d\n", proc->frame_tx, proc->subframe_tx, ru->num_eNB); // do TX front-end processing if needed (precoding and/or IDFTs) if (ru->feptx_prec) ru->feptx_prec(ru); @@ -1578,16 +1577,33 @@ printf("~~~~~~~~~~~~~~~~~~~~~~~~~~~~ru_thread_tx is waken up %d.%d having L1 %d\ eNB = ru->eNB_list[i]; eNB_proc = &eNB->proc; L1_proc = (get_thread_parallel_conf() == PARALLEL_RU_L1_TRX_SPLIT)? &eNB_proc->L1_proc_tx : &eNB_proc->L1_proc; -char *L1_proc_name = (get_thread_parallel_conf() == PARALLEL_RU_L1_TRX_SPLIT)? "L1_proc_tx" : "L1_proc"; -printf("~~~~~~~~~~~~~~~~~~~~~~~~~~~~ru_thread_tx signaling to eNB_list[%d] with %s IC_RU %d\n", i, L1_proc_name, L1_proc->instance_cnt_RUs); - pthread_mutex_lock( &L1_proc->mutex_RUs ); - L1_proc->instance_cnt_RUs = 0; - // the thread can now be woken up - if (pthread_cond_signal(&L1_proc->cond_RUs) != 0) { - LOG_E( PHY, "[eNB] ERROR pthread_cond_signal for eNB TXnp4 thread\n"); - exit_fun( "ERROR pthread_cond_signal" ); + pthread_mutex_lock(&eNB_proc->mutex_RU_tx); + for (int j=0;jnum_RU;j++) { + if (ru == eNB->RU_list[j]) { + if ((eNB_proc->RU_mask_tx&(1< 0) + LOG_E(PHY,"eNB %d frame %d, subframe %d : previous information from RU tx %d (num_RU %d,mask %x) has not been served yet!\n", + eNB->Mod_id,eNB_proc->frame_rx,eNB_proc->subframe_rx,ru->idx,eNB->num_RU,eNB_proc->RU_mask_tx); + eNB_proc->RU_mask_tx |= (1<RU_mask_tx != (1<num_RU)-1) { // not all RUs have provided their information so return + LOG_E(PHY,"Not all RUs TX are finished\n"); + pthread_mutex_unlock(&eNB_proc->mutex_RU_tx); + continue; + } + else { // all RUs TX are finished so send the ready signal to eNB processing + eNB_proc->RU_mask_tx = 0; + pthread_mutex_unlock(&eNB_proc->mutex_RU_tx); + + pthread_mutex_lock( &L1_proc->mutex_RUs); + L1_proc->instance_cnt_RUs = 0; + // the thread can now be woken up + if (pthread_cond_signal(&L1_proc->cond_RUs) != 0) { + LOG_E( PHY, "[eNB] ERROR pthread_cond_signal for eNB TXnp4 thread\n"); + exit_fun( "ERROR pthread_cond_signal" ); + } + pthread_mutex_unlock( &L1_proc->mutex_RUs ); } - pthread_mutex_unlock( &L1_proc->mutex_RUs ); } } release_thread(&proc->mutex_FH1,&proc->instance_cnt_FH1,"ru_thread_tx"); From 1d24208370e86894f1a3d99f625b3712f74a13d8 Mon Sep 17 00:00:00 2001 From: Wang Tsu-Han Date: Fri, 26 Oct 2018 17:33:46 +0200 Subject: [PATCH 071/233] bug fix for RU_mask_tx --- .../CONF/enb.band7.tm1.100PRB.usrpx310.conf | 12 ++++++++++++ targets/RT/USER/lte-enb.c | 5 ++--- targets/RT/USER/lte-ru.c | 11 ++++++----- 3 files changed, 20 insertions(+), 8 deletions(-) diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.100PRB.usrpx310.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.100PRB.usrpx310.conf index 728492ee83..f48357c13c 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.100PRB.usrpx310.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.100PRB.usrpx310.conf @@ -188,6 +188,18 @@ RUs = ( max_rxgain = 116; eNB_instances = [0]; sdr_addrs = "type=x300"; + }, + { + local_rf = "yes" + nb_tx = 1 + nb_rx = 1 + att_tx = 0 + att_rx = 0; + bands = [7]; + max_pdschReferenceSignalPower = -27; + max_rxgain = 116; + eNB_instances = [0]; + sdr_addrs = "type=x300"; } ); diff --git a/targets/RT/USER/lte-enb.c b/targets/RT/USER/lte-enb.c index 271572060c..70317983f6 100644 --- a/targets/RT/USER/lte-enb.c +++ b/targets/RT/USER/lte-enb.c @@ -385,7 +385,6 @@ static void* L1_thread( void* param ) { PHY_VARS_eNB *eNB = RC.eNB[0][proc->CC_id]; - //RU_proc_t *ru_proc = NULL; char thread_name[100]; @@ -477,7 +476,6 @@ int wakeup_txfh(eNB_rxtx_proc_t *proc,PHY_VARS_eNB *eNB) { RU_t *ru; RU_proc_t *ru_proc; - int i; struct timespec wait; @@ -486,7 +484,7 @@ int wakeup_txfh(eNB_rxtx_proc_t *proc,PHY_VARS_eNB *eNB) { //printf("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~inside wakeup_txfh %d.%d IC_RU = %d\n", proc->frame_tx, proc->subframe_tx, proc->instance_cnt_RUs); if(wait_on_condition(&proc->mutex_RUs,&proc->cond_RUs,&proc->instance_cnt_RUs,"wakeup_txfh")<0) { - LOG_E(PHY,"Frame %d, subframe %d: TX FH not ready\n", ru_proc->frame_tx, ru_proc->subframe_tx); + LOG_E(PHY,"Frame %d, subframe %d: TX FH not ready\n", proc->frame_tx, proc->subframe_tx); return(-1); } pthread_mutex_lock(&eNB->proc.mutex_RU_tx); @@ -924,6 +922,7 @@ void init_eNB_proc(int inst) { proc->first_rx =1; proc->first_tx =1; proc->RU_mask_tx = (1<num_RU)-1; +printf("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~proc->RU_mask_tx = %d\n", proc->RU_mask_tx); proc->RU_mask =0; proc->RU_mask_prach =0; diff --git a/targets/RT/USER/lte-ru.c b/targets/RT/USER/lte-ru.c index 42d71cfbf4..fdd364d574 100644 --- a/targets/RT/USER/lte-ru.c +++ b/targets/RT/USER/lte-ru.c @@ -1554,7 +1554,7 @@ static void* ru_thread_tx( void* param ) { if (oai_exit) break; - LOG_D(PHY,"ru_thread_tx: Waiting for TX processing\n"); + LOG_I(PHY,"ru_thread_tx: Waiting for TX processing\n"); // wait until eNBs are finished subframe RX n and TX n+4 wait_on_condition(&proc->mutex_eNBs,&proc->cond_eNBs,&proc->instance_cnt_eNBs,"ru_thread_tx"); if (oai_exit) break; @@ -1580,23 +1580,24 @@ static void* ru_thread_tx( void* param ) { pthread_mutex_lock(&eNB_proc->mutex_RU_tx); for (int j=0;jnum_RU;j++) { if (ru == eNB->RU_list[j]) { - if ((eNB_proc->RU_mask_tx&(1< 0) + if ((eNB_proc->RU_mask_tx&(1< 0) LOG_E(PHY,"eNB %d frame %d, subframe %d : previous information from RU tx %d (num_RU %d,mask %x) has not been served yet!\n", eNB->Mod_id,eNB_proc->frame_rx,eNB_proc->subframe_rx,ru->idx,eNB->num_RU,eNB_proc->RU_mask_tx); - eNB_proc->RU_mask_tx |= (1<RU_mask_tx |= (1<RU_mask_tx != (1<num_RU)-1) { // not all RUs have provided their information so return - LOG_E(PHY,"Not all RUs TX are finished\n"); +printf("~~~~~~~~~~~~~~~~~~~~~~(mask = %d)\n", eNB_proc->RU_mask_tx); pthread_mutex_unlock(&eNB_proc->mutex_RU_tx); - continue; } else { // all RUs TX are finished so send the ready signal to eNB processing +printf("~~~~~~~~~~~~~~~~~~~~~~ready to send wakeup signal\n"); eNB_proc->RU_mask_tx = 0; pthread_mutex_unlock(&eNB_proc->mutex_RU_tx); pthread_mutex_lock( &L1_proc->mutex_RUs); L1_proc->instance_cnt_RUs = 0; +printf("~~~~~~~~~~~~~~~~~~~~~~ru_thread_tx send signal to L1_thread_tx with (mask = %d)\n", eNB_proc->RU_mask_tx); // the thread can now be woken up if (pthread_cond_signal(&L1_proc->cond_RUs) != 0) { LOG_E( PHY, "[eNB] ERROR pthread_cond_signal for eNB TXnp4 thread\n"); From 29c5908731c93b1da106ba526d1b4d0745c44fbb Mon Sep 17 00:00:00 2001 From: Raymond Knopp Date: Sun, 28 Oct 2018 19:24:19 +0100 Subject: [PATCH 072/233] fixed dlsim/ulsim for L1-renaming --- openair1/SIMULATION/LTE_PHY/dlsim.c | 2 +- openair1/SIMULATION/LTE_PHY/ulsim.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/openair1/SIMULATION/LTE_PHY/dlsim.c b/openair1/SIMULATION/LTE_PHY/dlsim.c index 3583c0f25e..3cb6223278 100644 --- a/openair1/SIMULATION/LTE_PHY/dlsim.c +++ b/openair1/SIMULATION/LTE_PHY/dlsim.c @@ -1443,7 +1443,7 @@ int main(int argc, char **argv) eNB->UE_stats[1].DL_pmi_single = 0; } - eNB_rxtx_proc_t *proc_eNB = &eNB->proc.proc_rxtx[0];//UE->current_thread_id[subframe]]; + eNB_rxtx_proc_t *proc_eNB = &eNB->proc.L1_proc; if (input_fd==NULL) { diff --git a/openair1/SIMULATION/LTE_PHY/ulsim.c b/openair1/SIMULATION/LTE_PHY/ulsim.c index 8c09da1daf..7c956a833a 100644 --- a/openair1/SIMULATION/LTE_PHY/ulsim.c +++ b/openair1/SIMULATION/LTE_PHY/ulsim.c @@ -922,7 +922,7 @@ int main(int argc, char **argv) { UE->frame_parms.pusch_config_common.ul_ReferenceSignalsPUSCH.groupAssignmentPUSCH = 0; eNB->frame_parms.pusch_config_common.ul_ReferenceSignalsPUSCH.groupAssignmentPUSCH = 0; UE->mac_enabled=0; - eNB_rxtx_proc_t *proc_rxtx = &eNB->proc.proc_rxtx[subframe&1]; + eNB_rxtx_proc_t *proc_rxtx = &eNB->proc.L1_proc; UE_rxtx_proc_t *proc_rxtx_ue = &UE->proc.proc_rxtx[subframe&1]; proc_rxtx->frame_rx=1; proc_rxtx->subframe_rx=subframe; From c8e686396f7cd53c42925a91ba134b7759420210 Mon Sep 17 00:00:00 2001 From: Raymond Knopp Date: Sun, 28 Oct 2018 19:33:51 +0100 Subject: [PATCH 073/233] renaming of eNB_proc_t -> L1_proc_t --- openair1/PHY/LTE_TRANSPORT/dlsch_coding.c | 2 +- openair1/PHY/LTE_TRANSPORT/ulsch_decoding.c | 4 ++-- openair1/PHY/defs_eNB.h | 6 +++--- openair1/SCHED/phy_procedures_lte_eNb.c | 8 ++++---- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_coding.c b/openair1/PHY/LTE_TRANSPORT/dlsch_coding.c index 30c106b16b..6ca2fdc429 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_coding.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_coding.c @@ -393,7 +393,7 @@ int dlsch_encoding_2threads(PHY_VARS_eNB *eNB, //start_meas(&eNB->dlsch_turbo_encoding_preperation_stats); LTE_DL_FRAME_PARMS *frame_parms = &eNB->frame_parms; - eNB_proc_t *proc = &eNB->proc; + L1_proc_t *proc = &eNB->proc; unsigned int G; unsigned int crc=1; diff --git a/openair1/PHY/LTE_TRANSPORT/ulsch_decoding.c b/openair1/PHY/LTE_TRANSPORT/ulsch_decoding.c index 046e456916..cf3f412fda 100644 --- a/openair1/PHY/LTE_TRANSPORT/ulsch_decoding.c +++ b/openair1/PHY/LTE_TRANSPORT/ulsch_decoding.c @@ -382,7 +382,7 @@ int ulsch_decoding_data_2thread0(td_params* tdp) { extern int oai_exit; void *td_thread(void *param) { PHY_VARS_eNB *eNB = ((td_params*)param)->eNB; - eNB_proc_t *proc = &eNB->proc; + L1_proc_t *proc = &eNB->proc; cpu_set_t cpuset; CPU_ZERO(&cpuset); @@ -412,7 +412,7 @@ void *td_thread(void *param) { int ulsch_decoding_data_2thread(PHY_VARS_eNB *eNB,int UE_id,int harq_pid,int llr8_flag) { - eNB_proc_t *proc = &eNB->proc; + L1_proc_t *proc = &eNB->proc; unsigned int r,r_offset=0,Kr,Kr_bytes; uint8_t crc_type; int offset = 0; diff --git a/openair1/PHY/defs_eNB.h b/openair1/PHY/defs_eNB.h index a8c0ab8506..39f61c7fcf 100644 --- a/openair1/PHY/defs_eNB.h +++ b/openair1/PHY/defs_eNB.h @@ -698,7 +698,7 @@ typedef struct { } te_params; /// Context data structure for eNB subframe processing -typedef struct eNB_proc_t_s { +typedef struct L1_proc_t_s { /// Component Carrier index uint8_t CC_id; /// thread index @@ -833,7 +833,7 @@ typedef struct eNB_proc_t_s { eNB_rxtx_proc_t L1_proc,L1_proc_tx; /// stats thread pthread descriptor pthread_t process_stats_thread; -} eNB_proc_t; +} L1_proc_t; @@ -901,7 +901,7 @@ typedef struct PHY_VARS_eNB_s { module_id_t Mod_id; uint8_t CC_id; uint8_t configured; - eNB_proc_t proc; + L1_proc_t proc; int single_thread_flag; int abstraction_flag; int num_RU; diff --git a/openair1/SCHED/phy_procedures_lte_eNb.c b/openair1/SCHED/phy_procedures_lte_eNb.c index 276006ec3b..d0ec95f80c 100644 --- a/openair1/SCHED/phy_procedures_lte_eNb.c +++ b/openair1/SCHED/phy_procedures_lte_eNb.c @@ -1468,7 +1468,7 @@ extern void *td_thread(void*); void init_td_thread(PHY_VARS_eNB *eNB) { - eNB_proc_t *proc = &eNB->proc; + L1_proc_t *proc = &eNB->proc; proc->tdp.eNB = eNB; proc->instance_cnt_td = -1; @@ -1482,7 +1482,7 @@ void init_td_thread(PHY_VARS_eNB *eNB) { } void kill_td_thread(PHY_VARS_eNB *eNB) { - eNB_proc_t *proc = &eNB->proc; + L1_proc_t *proc = &eNB->proc; proc->instance_cnt_td = 0; pthread_cond_signal(&proc->cond_td); @@ -1495,7 +1495,7 @@ extern void *te_thread(void*); void init_te_thread(PHY_VARS_eNB *eNB) { - eNB_proc_t *proc = &eNB->proc; + L1_proc_t *proc = &eNB->proc; for(int i=0; i<3 ;i++){ proc->tep[i].eNB = eNB; @@ -1511,7 +1511,7 @@ void init_te_thread(PHY_VARS_eNB *eNB) { } void kill_te_thread(PHY_VARS_eNB *eNB) { - eNB_proc_t *proc = &eNB->proc; + L1_proc_t *proc = &eNB->proc; for(int i=0; i<3 ;i++){ proc->tep[i].instance_cnt_te = 0; From 49d6f3333525db19675c45b6ffe0bdb71988626f Mon Sep 17 00:00:00 2001 From: Raymond Knopp Date: Sun, 28 Oct 2018 20:19:39 +0100 Subject: [PATCH 074/233] renaming eNB_rxtx_proc_t -> L1_rxtx_proc_t --- openair1/PHY/LTE_ESTIMATION/lte_estimation.h | 2 +- .../LTE_ESTIMATION/lte_ul_channel_estimation.c | 2 +- openair1/PHY/LTE_TRANSPORT/dci_tools.c | 8 ++++---- openair1/PHY/LTE_TRANSPORT/phich.c | 2 +- openair1/PHY/LTE_TRANSPORT/pilots_mbsfn.c | 2 +- openair1/PHY/LTE_TRANSPORT/pmch.c | 2 +- openair1/PHY/LTE_TRANSPORT/transport_proto.h | 18 +++++++++--------- openair1/PHY/LTE_TRANSPORT/ulsch_decoding.c | 2 +- .../PHY/LTE_TRANSPORT/ulsch_demodulation.c | 4 ++-- openair1/PHY/defs_eNB.h | 4 ++-- openair1/SCHED/fapi_l1.c | 16 ++++++++-------- openair1/SCHED/fapi_l1.h | 12 ++++++------ openair1/SCHED/phy_procedures_lte_eNb.c | 14 +++++++------- openair1/SCHED/sched_common.h | 6 +++--- openair1/SCHED/sched_eNB.h | 10 +++++----- openair1/SIMULATION/LTE_PHY/dlsim.c | 2 +- 16 files changed, 53 insertions(+), 53 deletions(-) diff --git a/openair1/PHY/LTE_ESTIMATION/lte_estimation.h b/openair1/PHY/LTE_ESTIMATION/lte_estimation.h index 4512fc0d9b..9cdc2f4bf7 100644 --- a/openair1/PHY/LTE_ESTIMATION/lte_estimation.h +++ b/openair1/PHY/LTE_ESTIMATION/lte_estimation.h @@ -203,7 +203,7 @@ void phy_adjust_gain (PHY_VARS_UE *phy_vars_ue, unsigned char eNB_id); int lte_ul_channel_estimation(PHY_VARS_eNB *phy_vars_eNB, - eNB_rxtx_proc_t *proc, + L1_rxtx_proc_t *proc, module_id_t UE_id, uint8_t l, uint8_t Ns); diff --git a/openair1/PHY/LTE_ESTIMATION/lte_ul_channel_estimation.c b/openair1/PHY/LTE_ESTIMATION/lte_ul_channel_estimation.c index a8d73cfdea..206ba8b15f 100644 --- a/openair1/PHY/LTE_ESTIMATION/lte_ul_channel_estimation.c +++ b/openair1/PHY/LTE_ESTIMATION/lte_ul_channel_estimation.c @@ -35,7 +35,7 @@ static int16_t ru_90c[2*128] = {32767, 0,32766, -402,32758, -804,32746, -1206,32 #define SCALE 0x3FFF int32_t lte_ul_channel_estimation(PHY_VARS_eNB *eNB, - eNB_rxtx_proc_t *proc, + L1_rxtx_proc_t *proc, module_id_t UE_id, unsigned char l, unsigned char Ns) { diff --git a/openair1/PHY/LTE_TRANSPORT/dci_tools.c b/openair1/PHY/LTE_TRANSPORT/dci_tools.c index c33d9efe63..f003b7f36a 100644 --- a/openair1/PHY/LTE_TRANSPORT/dci_tools.c +++ b/openair1/PHY/LTE_TRANSPORT/dci_tools.c @@ -90,7 +90,7 @@ int16_t find_ulsch(uint16_t rnti, PHY_VARS_eNB *eNB,find_type_t type) -void fill_pdcch_order(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,DCI_ALLOC_t *dci_alloc,nfapi_dl_config_dci_dl_pdu *pdu) +void fill_pdcch_order(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc,DCI_ALLOC_t *dci_alloc,nfapi_dl_config_dci_dl_pdu *pdu) { LTE_DL_FRAME_PARMS *fp = &eNB->frame_parms; uint8_t *dci_pdu = &dci_alloc->dci_pdu[0]; @@ -224,7 +224,7 @@ void fill_pdcch_order(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,DCI_ALLOC_t *dci_a proc->frame_tx, proc->subframe_tx, rel8->rnti); } -void fill_dci_and_dlsch(PHY_VARS_eNB *eNB,int frame,int subframe,eNB_rxtx_proc_t *proc,DCI_ALLOC_t *dci_alloc,nfapi_dl_config_dci_dl_pdu *pdu) +void fill_dci_and_dlsch(PHY_VARS_eNB *eNB,int frame,int subframe,L1_rxtx_proc_t *proc,DCI_ALLOC_t *dci_alloc,nfapi_dl_config_dci_dl_pdu *pdu) { LTE_DL_FRAME_PARMS *fp = &eNB->frame_parms; uint8_t *dci_pdu = &dci_alloc->dci_pdu[0]; @@ -1497,7 +1497,7 @@ void fill_dci_and_dlsch(PHY_VARS_eNB *eNB,int frame,int subframe,eNB_rxtx_proc_t } -void fill_mdci_and_dlsch(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,mDCI_ALLOC_t *dci_alloc,nfapi_dl_config_mpdcch_pdu *pdu) { +void fill_mdci_and_dlsch(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc,mDCI_ALLOC_t *dci_alloc,nfapi_dl_config_mpdcch_pdu *pdu) { LTE_DL_FRAME_PARMS *fp = &eNB->frame_parms; @@ -1770,7 +1770,7 @@ void fill_mdci_and_dlsch(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,mDCI_ALLOC_t *d } -void fill_dci0(PHY_VARS_eNB *eNB,int frame,int subframe,eNB_rxtx_proc_t *proc, +void fill_dci0(PHY_VARS_eNB *eNB,int frame,int subframe,L1_rxtx_proc_t *proc, DCI_ALLOC_t *dci_alloc,nfapi_hi_dci0_dci_pdu *pdu) { LTE_DL_FRAME_PARMS *frame_parms = &eNB->frame_parms; diff --git a/openair1/PHY/LTE_TRANSPORT/phich.c b/openair1/PHY/LTE_TRANSPORT/phich.c index cc466ce3e2..dd82699fe9 100644 --- a/openair1/PHY/LTE_TRANSPORT/phich.c +++ b/openair1/PHY/LTE_TRANSPORT/phich.c @@ -705,7 +705,7 @@ void generate_phich(LTE_DL_FRAME_PARMS *frame_parms, void generate_phich_top(PHY_VARS_eNB *eNB, - eNB_rxtx_proc_t *proc, + L1_rxtx_proc_t *proc, int16_t amp) { diff --git a/openair1/PHY/LTE_TRANSPORT/pilots_mbsfn.c b/openair1/PHY/LTE_TRANSPORT/pilots_mbsfn.c index fddc29b524..475102b57c 100644 --- a/openair1/PHY/LTE_TRANSPORT/pilots_mbsfn.c +++ b/openair1/PHY/LTE_TRANSPORT/pilots_mbsfn.c @@ -34,7 +34,7 @@ #include "PHY/LTE_REFSIG/lte_refsig.h" int generate_mbsfn_pilot(PHY_VARS_eNB *eNB, - eNB_rxtx_proc_t *proc, + L1_rxtx_proc_t *proc, int32_t **txdataF, int16_t amp) diff --git a/openair1/PHY/LTE_TRANSPORT/pmch.c b/openair1/PHY/LTE_TRANSPORT/pmch.c index 23bc07f174..6fab3dc59b 100644 --- a/openair1/PHY/LTE_TRANSPORT/pmch.c +++ b/openair1/PHY/LTE_TRANSPORT/pmch.c @@ -83,7 +83,7 @@ void fill_eNB_dlsch_MCH(PHY_VARS_eNB *eNB,int mcs,int ndi,int rvidx) } -void generate_mch(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,uint8_t *a) +void generate_mch(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc,uint8_t *a) { int G; diff --git a/openair1/PHY/LTE_TRANSPORT/transport_proto.h b/openair1/PHY/LTE_TRANSPORT/transport_proto.h index 37ac335d02..c51ce5e1d0 100644 --- a/openair1/PHY/LTE_TRANSPORT/transport_proto.h +++ b/openair1/PHY/LTE_TRANSPORT/transport_proto.h @@ -273,7 +273,7 @@ int mch_modulation(int32_t **txdataF, @param abstraction_flag */ -void generate_mch(PHY_VARS_eNB *phy_vars_eNB,eNB_rxtx_proc_t *proc,uint8_t *a); +void generate_mch(PHY_VARS_eNB *phy_vars_eNB,L1_rxtx_proc_t *proc,uint8_t *a); /** \brief This function generates the frequency-domain pilots (cell-specific downlink reference signals) @param phy_vars_eNB Pointer to eNB variables @@ -317,7 +317,7 @@ int32_t generate_pilots_slot(PHY_VARS_eNB *phy_vars_eNB, int first_pilot_only); int32_t generate_mbsfn_pilot(PHY_VARS_eNB *phy_vars_eNB, - eNB_rxtx_proc_t *proc, + L1_rxtx_proc_t *proc, int32_t **txdataF, int16_t amp); @@ -410,13 +410,13 @@ void ulsch_extract_rbs_single(int32_t **rxdataF, void fill_dci_and_dlsch(PHY_VARS_eNB *eNB, int frame, int subframe, - eNB_rxtx_proc_t *proc, + L1_rxtx_proc_t *proc, DCI_ALLOC_t *dci_alloc, nfapi_dl_config_dci_dl_pdu *pdu); -void fill_mdci_and_dlsch(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,mDCI_ALLOC_t *dci_alloc,nfapi_dl_config_mpdcch_pdu *pdu); +void fill_mdci_and_dlsch(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc,mDCI_ALLOC_t *dci_alloc,nfapi_dl_config_mpdcch_pdu *pdu); -void fill_dci0(PHY_VARS_eNB *eNB,int frame,int subframe,eNB_rxtx_proc_t *proc,DCI_ALLOC_t *dci_alloc, +void fill_dci0(PHY_VARS_eNB *eNB,int frame,int subframe,L1_rxtx_proc_t *proc,DCI_ALLOC_t *dci_alloc, nfapi_hi_dci0_dci_pdu *pdu); void fill_ulsch(PHY_VARS_eNB *eNB,int UE_id,nfapi_ul_config_ulsch_pdu *ulsch_pdu,int frame,int subframe); @@ -427,7 +427,7 @@ int generate_eNB_ulsch_params_from_rar(PHY_VARS_eNB *eNB, unsigned char subframe); int generate_eNB_ulsch_params_from_dci(PHY_VARS_eNB *PHY_vars_eNB, - eNB_rxtx_proc_t *proc, + L1_rxtx_proc_t *proc, void *dci_pdu, rnti_t rnti, DCI_format_t dci_format, @@ -466,7 +466,7 @@ void init_transport_channels(uint8_t); void rx_ulsch(PHY_VARS_eNB *eNB, - eNB_rxtx_proc_t *proc, + L1_rxtx_proc_t *proc, uint8_t UE_id); @@ -487,7 +487,7 @@ int ulsch_decoding_data_all(PHY_VARS_eNB *eNB, @returns 0 on success */ unsigned int ulsch_decoding(PHY_VARS_eNB *phy_vars_eNB, - eNB_rxtx_proc_t *proc, + L1_rxtx_proc_t *proc, uint8_t UE_id, uint8_t control_only_flag, uint8_t Nbundled, @@ -520,7 +520,7 @@ int ulsch_decoding_data(PHY_VARS_eNB *eNB, int llr8_flag); void generate_phich_top(PHY_VARS_eNB *phy_vars_eNB, - eNB_rxtx_proc_t *proc, + L1_rxtx_proc_t *proc, int16_t amp); diff --git a/openair1/PHY/LTE_TRANSPORT/ulsch_decoding.c b/openair1/PHY/LTE_TRANSPORT/ulsch_decoding.c index cf3f412fda..3264b76a1a 100644 --- a/openair1/PHY/LTE_TRANSPORT/ulsch_decoding.c +++ b/openair1/PHY/LTE_TRANSPORT/ulsch_decoding.c @@ -762,7 +762,7 @@ static inline unsigned int lte_gold_unscram(unsigned int *x1, unsigned int *x2, } -unsigned int ulsch_decoding(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc, +unsigned int ulsch_decoding(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc, uint8_t UE_id, uint8_t control_only_flag, uint8_t Nbundled, diff --git a/openair1/PHY/LTE_TRANSPORT/ulsch_demodulation.c b/openair1/PHY/LTE_TRANSPORT/ulsch_demodulation.c index 61076f2aae..f4137697cf 100644 --- a/openair1/PHY/LTE_TRANSPORT/ulsch_demodulation.c +++ b/openair1/PHY/LTE_TRANSPORT/ulsch_demodulation.c @@ -1104,7 +1104,7 @@ void init_ulsch_power_LUT(void) { } void rx_ulsch(PHY_VARS_eNB *eNB, - eNB_rxtx_proc_t *proc, + L1_rxtx_proc_t *proc, uint8_t UE_id) { @@ -1305,7 +1305,7 @@ void rx_ulsch(PHY_VARS_eNB *eNB, } void rx_ulsch_emul(PHY_VARS_eNB *eNB, - eNB_rxtx_proc_t *proc, + L1_rxtx_proc_t *proc, uint8_t UE_index) { LOG_I(PHY,"[PHY] EMUL eNB %d rx_ulsch_emul : subframe %d, UE_index %d\n",eNB->Mod_id,proc->subframe_rx,UE_index); diff --git a/openair1/PHY/defs_eNB.h b/openair1/PHY/defs_eNB.h index 39f61c7fcf..44d8b6ab9b 100644 --- a/openair1/PHY/defs_eNB.h +++ b/openair1/PHY/defs_eNB.h @@ -666,7 +666,7 @@ typedef struct { pthread_cond_t cond_RUs; /// mutex for RXn-TXnp4 processing thread pthread_mutex_t mutex_RUs; -} eNB_rxtx_proc_t; +} L1_rxtx_proc_t; typedef struct { struct PHY_VARS_eNB_s *eNB; @@ -830,7 +830,7 @@ typedef struct L1_proc_t_s { /// parameters for turbo-encoding worker thread te_params tep[3]; /// set of scheduling variables RXn-TXnp4 threads - eNB_rxtx_proc_t L1_proc,L1_proc_tx; + L1_rxtx_proc_t L1_proc,L1_proc_tx; /// stats thread pthread descriptor pthread_t process_stats_thread; } L1_proc_t; diff --git a/openair1/SCHED/fapi_l1.c b/openair1/SCHED/fapi_l1.c index 3aafc0059b..1956446654 100644 --- a/openair1/SCHED/fapi_l1.c +++ b/openair1/SCHED/fapi_l1.c @@ -48,7 +48,7 @@ extern uint8_t nfapi_mode; void handle_nfapi_dci_dl_pdu(PHY_VARS_eNB *eNB, int frame, int subframe, - eNB_rxtx_proc_t *proc, + L1_rxtx_proc_t *proc, nfapi_dl_config_request_pdu_t *dl_config_pdu) { int idx = subframe&1; @@ -66,7 +66,7 @@ void handle_nfapi_dci_dl_pdu(PHY_VARS_eNB *eNB, #if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) void handle_nfapi_mpdcch_pdu(PHY_VARS_eNB *eNB, - eNB_rxtx_proc_t *proc, + L1_rxtx_proc_t *proc, nfapi_dl_config_request_pdu_t *dl_config_pdu) { int idx = proc->subframe_tx&1; @@ -81,7 +81,7 @@ void handle_nfapi_mpdcch_pdu(PHY_VARS_eNB *eNB, #endif -void handle_nfapi_hi_dci0_dci_pdu(PHY_VARS_eNB *eNB,int frame,int subframe,eNB_rxtx_proc_t *proc, +void handle_nfapi_hi_dci0_dci_pdu(PHY_VARS_eNB *eNB,int frame,int subframe,L1_rxtx_proc_t *proc, nfapi_hi_dci0_request_pdu_t *hi_dci0_config_pdu) { int idx = subframe&1; @@ -93,7 +93,7 @@ void handle_nfapi_hi_dci0_dci_pdu(PHY_VARS_eNB *eNB,int frame,int subframe,eNB_r fill_dci0(eNB,frame,subframe,proc,&pdcch_vars->dci_alloc[pdcch_vars->num_dci], &hi_dci0_config_pdu->dci_pdu); } -void handle_nfapi_hi_dci0_hi_pdu(PHY_VARS_eNB *eNB,int frame,int subframe,eNB_rxtx_proc_t *proc, +void handle_nfapi_hi_dci0_hi_pdu(PHY_VARS_eNB *eNB,int frame,int subframe,L1_rxtx_proc_t *proc, nfapi_hi_dci0_request_pdu_t *hi_dci0_config_pdu) { LTE_eNB_PHICH *phich = &eNB->phich_vars[subframe&1]; @@ -112,7 +112,7 @@ void handle_nfapi_hi_dci0_hi_pdu(PHY_VARS_eNB *eNB,int frame,int subframe,eNB_rx AssertFatal(phich->num_hi<32,"Maximum number of phich reached in subframe\n"); } -void handle_nfapi_bch_pdu(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc, +void handle_nfapi_bch_pdu(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc, nfapi_dl_config_request_pdu_t *dl_config_pdu, uint8_t *sdu) { @@ -139,7 +139,7 @@ extern uint32_t localRIV2alloc_LUT100_2[6000]; extern uint32_t localRIV2alloc_LUT100_3[6000]; #endif -void handle_nfapi_dlsch_pdu(PHY_VARS_eNB *eNB,int frame,int subframe,eNB_rxtx_proc_t *proc, +void handle_nfapi_dlsch_pdu(PHY_VARS_eNB *eNB,int frame,int subframe,L1_rxtx_proc_t *proc, nfapi_dl_config_request_pdu_t *dl_config_pdu, uint8_t codeword_index, uint8_t *sdu) @@ -569,7 +569,7 @@ void handle_srs_pdu(PHY_VARS_eNB *eNB,nfapi_ul_config_request_pdu_t *ul_config_p AssertFatal(imodule_id; uint8_t CC_id = Sched_INFO->CC_id; diff --git a/openair1/SCHED/fapi_l1.h b/openair1/SCHED/fapi_l1.h index efb028f464..3bd469b685 100644 --- a/openair1/SCHED/fapi_l1.h +++ b/openair1/SCHED/fapi_l1.h @@ -43,17 +43,17 @@ void fill_ulsch_cqi_indication(PHY_VARS_eNB *eNB,uint16_t frame,uint8_t subframe void fill_sr_indication(PHY_VARS_eNB *eNB,uint16_t rnti,int frame,int subframe,uint32_t stat); void fill_rx_indication(PHY_VARS_eNB *eNB,int UE_id,int frame,int subframe); void fill_crc_indication(PHY_VARS_eNB *eNB,int UE_id,int frame,int subframe,uint8_t crc_flag); -void handle_nfapi_dci_dl_pdu(PHY_VARS_eNB *eNB,int frame,int subframe,eNB_rxtx_proc_t *proc,nfapi_dl_config_request_pdu_t *dl_config_pdu); -void handle_nfapi_mpdcch_pdu(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc,nfapi_dl_config_request_pdu_t *dl_config_pdu); -void handle_nfapi_hi_dci0_dci_pdu(PHY_VARS_eNB *eNB,int frame,int subframe,eNB_rxtx_proc_t *proc, +void handle_nfapi_dci_dl_pdu(PHY_VARS_eNB *eNB,int frame,int subframe,L1_rxtx_proc_t *proc,nfapi_dl_config_request_pdu_t *dl_config_pdu); +void handle_nfapi_mpdcch_pdu(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc,nfapi_dl_config_request_pdu_t *dl_config_pdu); +void handle_nfapi_hi_dci0_dci_pdu(PHY_VARS_eNB *eNB,int frame,int subframe,L1_rxtx_proc_t *proc, nfapi_hi_dci0_request_pdu_t *hi_dci0_config_pdu); -void handle_nfapi_hi_dci0_hi_pdu(PHY_VARS_eNB *eNB,int frame,int subframe,eNB_rxtx_proc_t *proc, +void handle_nfapi_hi_dci0_hi_pdu(PHY_VARS_eNB *eNB,int frame,int subframe,L1_rxtx_proc_t *proc, nfapi_hi_dci0_request_pdu_t *hi_dci0_config_pdu); -void handle_nfapi_dlsch_pdu(PHY_VARS_eNB *eNB,int frame,int subframe,eNB_rxtx_proc_t *proc, +void handle_nfapi_dlsch_pdu(PHY_VARS_eNB *eNB,int frame,int subframe,L1_rxtx_proc_t *proc, nfapi_dl_config_request_pdu_t *dl_config_pdu, uint8_t codeword_index, uint8_t *sdu); -void handle_nfapi_ul_pdu(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc, +void handle_nfapi_ul_pdu(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc, nfapi_ul_config_request_pdu_t *ul_config_pdu, uint16_t frame,uint8_t subframe,uint8_t srs_present); diff --git a/openair1/SCHED/phy_procedures_lte_eNb.c b/openair1/SCHED/phy_procedures_lte_eNb.c index d0ec95f80c..10c11eda63 100644 --- a/openair1/SCHED/phy_procedures_lte_eNb.c +++ b/openair1/SCHED/phy_procedures_lte_eNb.c @@ -133,7 +133,7 @@ lte_subframe_t get_subframe_direction(uint8_t Mod_id,uint8_t CC_id,uint8_t subfr } -void pmch_procedures(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc) { +void pmch_procedures(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc) { #if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) @@ -312,7 +312,7 @@ void common_signal_procedures (PHY_VARS_eNB *eNB,int frame, int subframe) { void pdsch_procedures(PHY_VARS_eNB *eNB, - eNB_rxtx_proc_t *proc, + L1_rxtx_proc_t *proc, int harq_pid, LTE_eNB_DLSCH_t *dlsch, LTE_eNB_DLSCH_t *dlsch1, @@ -463,7 +463,7 @@ void pdsch_procedures(PHY_VARS_eNB *eNB, void phy_procedures_eNB_TX(PHY_VARS_eNB *eNB, - eNB_rxtx_proc_t *proc, + L1_rxtx_proc_t *proc, int do_meas) { int frame=proc->frame_tx; @@ -650,7 +650,7 @@ void phy_procedures_eNB_TX(PHY_VARS_eNB *eNB, } -void srs_procedures(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc) { +void srs_procedures(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc) { LTE_DL_FRAME_PARMS *fp = &eNB->frame_parms; const int subframe = proc->subframe_rx; @@ -713,7 +713,7 @@ void fill_sr_indication(PHY_VARS_eNB *eNB,uint16_t rnti,int frame,int subframe,u pthread_mutex_unlock(&eNB->UL_INFO_mutex); } -void uci_procedures(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc) +void uci_procedures(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc) { LTE_DL_FRAME_PARMS *fp=&eNB->frame_parms; uint8_t SR_payload = 0,pucch_b0b1[4][2]= {{0,0},{0,0},{0,0},{0,0}},harq_ack[4]={0,0,0,0}; @@ -1247,7 +1247,7 @@ void uci_procedures(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc) } } -void pusch_procedures(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc) +void pusch_procedures(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc) { uint32_t ret=0,i; uint32_t harq_pid; @@ -2027,7 +2027,7 @@ void fill_crc_indication(PHY_VARS_eNB *eNB,int UE_id,int frame,int subframe,uint pthread_mutex_unlock(&eNB->UL_INFO_mutex); } -void phy_procedures_eNB_uespec_RX(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc) +void phy_procedures_eNB_uespec_RX(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc) { //RX processing for ue-specific resources (i LTE_DL_FRAME_PARMS *fp=&eNB->frame_parms; diff --git a/openair1/SCHED/sched_common.h b/openair1/SCHED/sched_common.h index e579110a78..5a4a5d5275 100644 --- a/openair1/SCHED/sched_common.h +++ b/openair1/SCHED/sched_common.h @@ -180,7 +180,7 @@ uint8_t is_SR_TXOp(PHY_VARS_UE *phy_vars_ue,UE_rxtx_proc_t *proc,uint8_t eNB_id) @param UE_id ID of UE which may be issuing the SR @returns 1 if TXOp is active. */ -uint8_t is_SR_subframe(PHY_VARS_eNB *phy_vars_eNB,eNB_rxtx_proc_t *proc,uint8_t UE_id); +uint8_t is_SR_subframe(PHY_VARS_eNB *phy_vars_eNB,L1_rxtx_proc_t *proc,uint8_t UE_id); /*! \brief Gives the UL subframe corresponding to a PDDCH order in subframe n @param frame_parms Pointer to DL frame parameters @@ -247,7 +247,7 @@ TDD, this routine computes the procedure described in Section 10.1 of 36.213 (th @param n1_pucch3 Pointer to n1_pucch3 */ void get_n1_pucch_eNB(PHY_VARS_eNB *phy_vars_eNB, - eNB_rxtx_proc_t *proc, + L1_rxtx_proc_t *proc, uint8_t UE_id, int16_t *n1_pucch0, int16_t *n1_pucch1, @@ -266,7 +266,7 @@ void get_n1_pucch_eNB(PHY_VARS_eNB *phy_vars_eNB, */ void process_HARQ_feedback(uint8_t UE_id, PHY_VARS_eNB *phy_vars_eNB, - eNB_rxtx_proc_t *proc, + L1_rxtx_proc_t *proc, uint8_t pusch_flag, uint8_t *pucch_payload, uint8_t pucch_sel, diff --git a/openair1/SCHED/sched_eNB.h b/openair1/SCHED/sched_eNB.h index cf6c5815f2..e54e4afd3b 100644 --- a/openair1/SCHED/sched_eNB.h +++ b/openair1/SCHED/sched_eNB.h @@ -92,13 +92,13 @@ enum openair_HARQ_TYPE { @param abstraction_flag Indicator of PHY abstraction @param do_meas Do inline timing measurement */ -void phy_procedures_eNB_TX(PHY_VARS_eNB *phy_vars_eNB,eNB_rxtx_proc_t *proc,int do_meas); +void phy_procedures_eNB_TX(PHY_VARS_eNB *phy_vars_eNB,L1_rxtx_proc_t *proc,int do_meas); /*! \brief Scheduling for eNB RX UE-specific procedures in normal subframes. @param phy_vars_eNB Pointer to eNB variables on which to act @param proc Pointer to RXn-TXnp4 proc information */ -void phy_procedures_eNB_uespec_RX(PHY_VARS_eNB *phy_vars_eNB,eNB_rxtx_proc_t *proc); +void phy_procedures_eNB_uespec_RX(PHY_VARS_eNB *phy_vars_eNB,L1_rxtx_proc_t *proc); /*! \brief Scheduling for eNB TX procedures in TDD S-subframes. @param phy_vars_eNB Pointer to eNB variables on which to act @@ -110,7 +110,7 @@ void phy_procedures_eNB_uespec_RX(PHY_VARS_eNB *phy_vars_eNB,eNB_rxtx_proc_t *pr @param phy_vars_eNB Pointer to eNB variables on which to act @param abstraction_flag Indicator of PHY abstraction */ -void phy_procedures_eNB_common_RX(PHY_VARS_eNB *phy_vars_eNB,eNB_rxtx_proc_t *proc); +void phy_procedures_eNB_common_RX(PHY_VARS_eNB *phy_vars_eNB,L1_rxtx_proc_t *proc); /*! \brief Scheduling for eNB TX procedures in TDD S-subframes. @param phy_vars_eNB Pointer to eNB variables on which to act @@ -121,7 +121,7 @@ void phy_procedures_eNB_S_TX(PHY_VARS_eNB *phy_vars_eNB); /*! \brief Scheduling for eNB RX procedures in TDD S-subframes. @param phy_vars_eNB Pointer to eNB variables on which to act */ -void phy_procedures_eNB_S_RX(PHY_VARS_eNB *phy_vars_eNB,eNB_rxtx_proc_t *proc); +void phy_procedures_eNB_S_RX(PHY_VARS_eNB *phy_vars_eNB,L1_rxtx_proc_t *proc); /*! \brief Scheduling for eNB PRACH RX procedures @param phy_vars_eNB Pointer to eNB variables on which to act @@ -186,7 +186,7 @@ void ra_failed(uint8_t Mod_id,uint8_t CC_id,uint8_t eNB_index); @param UE_id ID of UE which may be issuing the SR @returns 1 if TXOp is active. */ -uint8_t is_SR_subframe(PHY_VARS_eNB *phy_vars_eNB,eNB_rxtx_proc_t *proc,uint8_t UE_id); +uint8_t is_SR_subframe(PHY_VARS_eNB *phy_vars_eNB,L1_rxtx_proc_t *proc,uint8_t UE_id); int8_t find_ue_dlsch(uint16_t rnti, PHY_VARS_eNB *phy_vars_eNB); int8_t find_ue_ulsch(uint16_t rnti, PHY_VARS_eNB *phy_vars_eNB); diff --git a/openair1/SIMULATION/LTE_PHY/dlsim.c b/openair1/SIMULATION/LTE_PHY/dlsim.c index 3cb6223278..383b2d75eb 100644 --- a/openair1/SIMULATION/LTE_PHY/dlsim.c +++ b/openair1/SIMULATION/LTE_PHY/dlsim.c @@ -1443,7 +1443,7 @@ int main(int argc, char **argv) eNB->UE_stats[1].DL_pmi_single = 0; } - eNB_rxtx_proc_t *proc_eNB = &eNB->proc.L1_proc; + L1_rxtx_proc_t *proc_eNB = &eNB->proc.L1_proc; if (input_fd==NULL) { From 3fa0f5a93f1573861b307d0c8dfc722ad9cc8fdd Mon Sep 17 00:00:00 2001 From: Raphael Defosseux Date: Tue, 30 Oct 2018 14:18:49 +0100 Subject: [PATCH 075/233] CI: workaround to allow running slave jobs from develop-nr Signed-off-by: Raphael Defosseux --- ci-scripts/main.py | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/ci-scripts/main.py b/ci-scripts/main.py index 52c742fbcb..b54c6f3fab 100644 --- a/ci-scripts/main.py +++ b/ci-scripts/main.py @@ -268,12 +268,15 @@ class SSHConnection(): self.command('git merge --ff origin/develop -m "Temporary merge for CI"', '\$', 5) self.command('source oaienv', '\$', 5) self.command('cd cmake_targets', '\$', 5) - self.command('mkdir -p log', '\$', 5) + self.command('mkdir -p log', '\$', 5) + self.command('chmod 777 log', '\$', 5) # no need to remove in log (git clean did the trick) - self.command('echo ' + self.eNBPassword + ' | sudo -S stdbuf -o0 ./build_oai ' + self.Build_eNB_args + ' 2>&1 | stdbuf -o0 tee -a compile_oai_enb.log', 'Bypassing the Tests', 600) + self.command('stdbuf -o0 ./build_oai ' + self.Build_eNB_args + ' 2>&1 | stdbuf -o0 tee -a compile_oai_enb.log', 'Bypassing the Tests', 600) self.command('mkdir -p build_log_' + SSH.testCase_id, '\$', 5) - self.command('echo ' + self.eNBPassword + ' | sudo -S mv log/* ' + 'build_log_' + SSH.testCase_id, '\$', 5) - self.command('echo ' + self.eNBPassword + ' | sudo -S mv compile_oai_enb.log ' + 'build_log_' + SSH.testCase_id, '\$', 5) + self.command('mv log/* ' + 'build_log_' + SSH.testCase_id, '\$', 5) + self.command('mv compile_oai_enb.log ' + 'build_log_' + SSH.testCase_id, '\$', 5) + # Workaround to run with develop-nr + self.command('if [ -e ran_build ]; then cp -rf ran_build lte_build_oai; fi', '\$', 30) self.close() self.CreateHtmlTestRow(self.Build_eNB_args, 'OK', ALL_PROCESSES_OK) From 12b81a5b77cef7e72c8c936c7bef06c9b0fe0065 Mon Sep 17 00:00:00 2001 From: Wang Tsu-Han Date: Tue, 30 Oct 2018 17:29:20 +0100 Subject: [PATCH 076/233] fixes after the raneming of eNB_proc_t and eNB_rxtx_proc_t --- nfapi/oai_integration/nfapi_pnf.c | 18 +++++----- nfapi/oai_integration/nfapi_vnf.c | 4 +-- targets/RT/USER/lte-enb.c | 58 +++++++++++++++---------------- targets/RT/USER/lte-ru.c | 10 +++--- 4 files changed, 45 insertions(+), 45 deletions(-) diff --git a/nfapi/oai_integration/nfapi_pnf.c b/nfapi/oai_integration/nfapi_pnf.c index 684668f086..78c058ad00 100644 --- a/nfapi/oai_integration/nfapi_pnf.c +++ b/nfapi/oai_integration/nfapi_pnf.c @@ -69,12 +69,12 @@ char uecap_xer_in; extern void init_eNB_afterRU(void); extern void init_UE_stub(int nb_inst,int,int); -extern void handle_nfapi_dci_dl_pdu(PHY_VARS_eNB *eNB, int frame, int subframe, eNB_rxtx_proc_t *proc, nfapi_dl_config_request_pdu_t *dl_config_pdu); -extern void handle_nfapi_ul_pdu(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc, nfapi_ul_config_request_pdu_t *ul_config_pdu, uint16_t frame,uint8_t subframe,uint8_t srs_present); -extern void handle_nfapi_dlsch_pdu(PHY_VARS_eNB *eNB,int frame, int subframe, eNB_rxtx_proc_t *proc, nfapi_dl_config_request_pdu_t *dl_config_pdu, uint8_t codeword_index, uint8_t *sdu); -extern void handle_nfapi_hi_dci0_dci_pdu(PHY_VARS_eNB *eNB,int frame, int subframe, eNB_rxtx_proc_t *proc, nfapi_hi_dci0_request_pdu_t *hi_dci0_config_pdu); -extern void handle_nfapi_hi_dci0_hi_pdu(PHY_VARS_eNB *eNB,int frame, int subframe, eNB_rxtx_proc_t *proc, nfapi_hi_dci0_request_pdu_t *hi_dci0_config_pdu); -extern void handle_nfapi_bch_pdu(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc, nfapi_dl_config_request_pdu_t *dl_config_pdu, uint8_t *sdu); +extern void handle_nfapi_dci_dl_pdu(PHY_VARS_eNB *eNB, int frame, int subframe, L1_rxtx_proc_t *proc, nfapi_dl_config_request_pdu_t *dl_config_pdu); +extern void handle_nfapi_ul_pdu(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc, nfapi_ul_config_request_pdu_t *ul_config_pdu, uint16_t frame,uint8_t subframe,uint8_t srs_present); +extern void handle_nfapi_dlsch_pdu(PHY_VARS_eNB *eNB,int frame, int subframe, L1_rxtx_proc_t *proc, nfapi_dl_config_request_pdu_t *dl_config_pdu, uint8_t codeword_index, uint8_t *sdu); +extern void handle_nfapi_hi_dci0_dci_pdu(PHY_VARS_eNB *eNB,int frame, int subframe, L1_rxtx_proc_t *proc, nfapi_hi_dci0_request_pdu_t *hi_dci0_config_pdu); +extern void handle_nfapi_hi_dci0_hi_pdu(PHY_VARS_eNB *eNB,int frame, int subframe, L1_rxtx_proc_t *proc, nfapi_hi_dci0_request_pdu_t *hi_dci0_config_pdu); +extern void handle_nfapi_bch_pdu(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc, nfapi_dl_config_request_pdu_t *dl_config_pdu, uint8_t *sdu); extern uint8_t nfapi_mode; @@ -741,7 +741,7 @@ int pnf_phy_hi_dci0_req(nfapi_pnf_p7_config_t* pnf_p7, nfapi_hi_dci0_request_t* //phy_info* phy = (phy_info*)(pnf_p7->user_data); struct PHY_VARS_eNB_s *eNB = RC.eNB[0][0]; - eNB_rxtx_proc_t *proc = &eNB->proc.L1_proc; + L1_rxtx_proc_t *proc = &eNB->proc.L1_proc; for (int i=0; ihi_dci0_request_body.number_of_dci + req->hi_dci0_request_body.number_of_hi; i++) { @@ -798,7 +798,7 @@ int pnf_phy_dl_config_req(nfapi_pnf_p7_config_t* pnf_p7, nfapi_dl_config_request int sf = NFAPI_SFNSF2SF(req->sfn_sf); struct PHY_VARS_eNB_s *eNB = RC.eNB[0][0]; - eNB_rxtx_proc_t *proc = &eNB->proc.L1_proc; + L1_rxtx_proc_t *proc = &eNB->proc.L1_proc; nfapi_dl_config_request_pdu_t* dl_config_pdu_list = req->dl_config_request_body.dl_config_pdu_list; LTE_eNB_PDCCH *pdcch_vars = &eNB->pdcch_vars[sf&1]; @@ -945,7 +945,7 @@ int pnf_phy_ul_config_req(nfapi_pnf_p7_config_t* pnf_p7, nfapi_ul_config_request uint16_t curr_sf = NFAPI_SFNSF2SF(req->sfn_sf); struct PHY_VARS_eNB_s *eNB = RC.eNB[0][0]; - eNB_rxtx_proc_t *proc = &eNB->proc.L1_proc; + L1_rxtx_proc_t *proc = &eNB->proc.L1_proc; nfapi_ul_config_request_pdu_t* ul_config_pdu_list = req->ul_config_request_body.ul_config_pdu_list; for (int i=0;iul_config_request_body.number_of_pdus;i++) { diff --git a/nfapi/oai_integration/nfapi_vnf.c b/nfapi/oai_integration/nfapi_vnf.c index e9d0ad35a3..51ff501666 100644 --- a/nfapi/oai_integration/nfapi_vnf.c +++ b/nfapi/oai_integration/nfapi_vnf.c @@ -343,9 +343,9 @@ int pnf_config_resp_cb(nfapi_vnf_config_t* config, int p5_idx, nfapi_pnf_config_ int wake_eNB_rxtx(PHY_VARS_eNB *eNB, uint16_t sfn, uint16_t sf) { - eNB_proc_t *proc=&eNB->proc; + L1_proc_t *proc=&eNB->proc; - eNB_rxtx_proc_t *L1_proc= (sf&1)? &proc->L1_proc : &proc->L1_proc_tx; + L1_rxtx_proc_t *L1_proc= (sf&1)? &proc->L1_proc : &proc->L1_proc_tx; LTE_DL_FRAME_PARMS *fp = &eNB->frame_parms; diff --git a/targets/RT/USER/lte-enb.c b/targets/RT/USER/lte-enb.c index 70317983f6..4439609104 100644 --- a/targets/RT/USER/lte-enb.c +++ b/targets/RT/USER/lte-enb.c @@ -144,7 +144,7 @@ void init_eNB(int,int); void stop_eNB(int nb_inst); int wakeup_tx(PHY_VARS_eNB *eNB); -int wakeup_txfh(eNB_rxtx_proc_t *proc,PHY_VARS_eNB *eNB); +int wakeup_txfh(L1_rxtx_proc_t *proc,PHY_VARS_eNB *eNB); void wakeup_prach_eNB(PHY_VARS_eNB *eNB,RU_t *ru,int frame,int subframe); #if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) void wakeup_prach_eNB_br(PHY_VARS_eNB *eNB,RU_t *ru,int frame,int subframe); @@ -160,9 +160,9 @@ extern void add_subframe(uint16_t *frameP, uint16_t *subframeP, int offset); #define TICK_TO_US(ts) (ts.trials==0?0:ts.diff/ts.trials) -static inline int rxtx(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc, char *thread_name) { +static inline int rxtx(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc, char *thread_name) { start_meas(&softmodem_stats_rxtx_sf); - //eNB_rxtx_proc_t *L1_proc_tx = &eNB->proc.L1_proc_tx; + //L1_rxtx_proc_t *L1_proc_tx = &eNB->proc.L1_proc_tx; // ******************************************************************* @@ -321,8 +321,8 @@ static inline int rxtx(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc, char *thread_nam static void* L1_thread_tx(void* param) { - eNB_proc_t *eNB_proc = (eNB_proc_t*)param; - eNB_rxtx_proc_t *proc = &eNB_proc->L1_proc_tx; + L1_proc_t *eNB_proc = (L1_proc_t*)param; + L1_rxtx_proc_t *proc = &eNB_proc->L1_proc_tx; PHY_VARS_eNB *eNB = RC.eNB[0][proc->CC_id]; char thread_name[100]; @@ -364,22 +364,22 @@ static void* L1_thread_tx(void* param) { /*! * \brief The RX UE-specific and TX thread of eNB. - * \param param is a \ref eNB_proc_t structure which contains the info what to process. + * \param param is a \ref L1_proc_t structure which contains the info what to process. * \returns a pointer to an int. The storage is not on the heap and must not be freed. */ static void* L1_thread( void* param ) { static int eNB_thread_rxtx_status; - //eNB_proc_t *eNB_proc = (eNB_proc_t*)param; - eNB_rxtx_proc_t *proc; + //L1_proc_t *eNB_proc = (L1_proc_t*)param; + L1_rxtx_proc_t *proc; // Working if(nfapi_mode ==2){ - proc = (eNB_rxtx_proc_t*)param; + proc = (L1_rxtx_proc_t*)param; } else{ - eNB_proc_t *eNB_proc = (eNB_proc_t*)param; + L1_proc_t *eNB_proc = (L1_proc_t*)param; proc = &eNB_proc->L1_proc; } @@ -448,8 +448,8 @@ static void* L1_thread( void* param ) { void eNB_top(PHY_VARS_eNB *eNB, int frame_rx, int subframe_rx, char *string,RU_t *ru) { - eNB_proc_t *proc = &eNB->proc; - eNB_rxtx_proc_t *L1_proc = &proc->L1_proc; + L1_proc_t *proc = &eNB->proc; + L1_rxtx_proc_t *L1_proc = &proc->L1_proc; LTE_DL_FRAME_PARMS *fp = &ru->frame_parms; RU_proc_t *ru_proc=&ru->proc; @@ -472,7 +472,7 @@ void eNB_top(PHY_VARS_eNB *eNB, int frame_rx, int subframe_rx, char *string,RU_t } } -int wakeup_txfh(eNB_rxtx_proc_t *proc,PHY_VARS_eNB *eNB) { +int wakeup_txfh(L1_rxtx_proc_t *proc,PHY_VARS_eNB *eNB) { RU_t *ru; RU_proc_t *ru_proc; @@ -527,10 +527,10 @@ int wakeup_txfh(eNB_rxtx_proc_t *proc,PHY_VARS_eNB *eNB) { int wakeup_tx(PHY_VARS_eNB *eNB) { - eNB_proc_t *proc=&eNB->proc; + L1_proc_t *proc=&eNB->proc; - eNB_rxtx_proc_t *L1_proc_tx = &proc->L1_proc_tx; - eNB_rxtx_proc_t *L1_proc = &proc->L1_proc; + L1_rxtx_proc_t *L1_proc_tx = &proc->L1_proc_tx; + L1_rxtx_proc_t *L1_proc = &proc->L1_proc; struct timespec wait; @@ -570,10 +570,10 @@ int wakeup_tx(PHY_VARS_eNB *eNB) { int wakeup_rxtx(PHY_VARS_eNB *eNB,RU_t *ru) { - eNB_proc_t *proc=&eNB->proc; + L1_proc_t *proc=&eNB->proc; RU_proc_t *ru_proc=&ru->proc; - eNB_rxtx_proc_t *L1_proc=&proc->L1_proc; + L1_rxtx_proc_t *L1_proc=&proc->L1_proc; LTE_DL_FRAME_PARMS *fp = &eNB->frame_parms; @@ -649,7 +649,7 @@ int wakeup_rxtx(PHY_VARS_eNB *eNB,RU_t *ru) { void wakeup_prach_eNB(PHY_VARS_eNB *eNB,RU_t *ru,int frame,int subframe) { - eNB_proc_t *proc = &eNB->proc; + L1_proc_t *proc = &eNB->proc; LTE_DL_FRAME_PARMS *fp=&eNB->frame_parms; int i; @@ -709,7 +709,7 @@ void wakeup_prach_eNB(PHY_VARS_eNB *eNB,RU_t *ru,int frame,int subframe) { #if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) void wakeup_prach_eNB_br(PHY_VARS_eNB *eNB,RU_t *ru,int frame,int subframe) { - eNB_proc_t *proc = &eNB->proc; + L1_proc_t *proc = &eNB->proc; LTE_DL_FRAME_PARMS *fp=&eNB->frame_parms; int i; @@ -770,7 +770,7 @@ void wakeup_prach_eNB_br(PHY_VARS_eNB *eNB,RU_t *ru,int frame,int subframe) { /*! * \brief The prach receive thread of eNB. - * \param param is a \ref eNB_proc_t structure which contains the info what to process. + * \param param is a \ref L1_proc_t structure which contains the info what to process. * \returns a pointer to an int. The storage is not on the heap and must not be freed. */ static void* eNB_thread_prach( void* param ) { @@ -778,7 +778,7 @@ static void* eNB_thread_prach( void* param ) { PHY_VARS_eNB *eNB= (PHY_VARS_eNB *)param; - eNB_proc_t *proc = &eNB->proc; + L1_proc_t *proc = &eNB->proc; // set default return value eNB_thread_prach_status = 0; @@ -813,7 +813,7 @@ static void* eNB_thread_prach( void* param ) { #if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) /*! * \brief The prach receive thread of eNB for BL/CE UEs. - * \param param is a \ref eNB_proc_t structure which contains the info what to process. + * \param param is a \ref L1_proc_t structure which contains the info what to process. * \returns a pointer to an int. The storage is not on the heap and must not be freed. */ static void* eNB_thread_prach_br( void* param ) { @@ -821,7 +821,7 @@ static void* eNB_thread_prach_br( void* param ) { PHY_VARS_eNB *eNB= (PHY_VARS_eNB *)param; - eNB_proc_t *proc = &eNB->proc; + L1_proc_t *proc = &eNB->proc; // set default return value eNB_thread_prach_status = 0; @@ -892,8 +892,8 @@ void init_eNB_proc(int inst) { /*int i=0;*/ int CC_id; PHY_VARS_eNB *eNB; - eNB_proc_t *proc; - eNB_rxtx_proc_t *L1_proc, *L1_proc_tx; + L1_proc_t *proc; + L1_rxtx_proc_t *L1_proc, *L1_proc_tx; pthread_attr_t *attr0=NULL,*attr1=NULL,*attr_prach=NULL; #if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) pthread_attr_t *attr_prach_br=NULL; @@ -1002,7 +1002,7 @@ printf("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~proc->RU_mask_tx = %d\n", proc if (eNB->node_timing == synch_to_ext_device) { //master eNB->proc.num_slaves = MAX_NUM_CCs-1; - eNB->proc.slave_proc = (eNB_proc_t**)malloc(eNB->proc.num_slaves*sizeof(eNB_proc_t*)); + eNB->proc.slave_proc = (L1_proc_t**)malloc(eNB->proc.num_slaves*sizeof(L1_proc_t*)); for (i=0; i< eNB->proc.num_slaves; i++) { if (i < CC_id) eNB->proc.slave_proc[i] = &(PHY_vars_eNB_g[inst][i]->proc); @@ -1029,8 +1029,8 @@ void kill_eNB_proc(int inst) { int *status; PHY_VARS_eNB *eNB; - eNB_proc_t *proc; - eNB_rxtx_proc_t *L1_proc, *L1_proc_tx; + L1_proc_t *proc; + L1_rxtx_proc_t *L1_proc, *L1_proc_tx; for (int CC_id=0; CC_idproc; PHY_VARS_eNB *eNB; - eNB_proc_t *eNB_proc; - eNB_rxtx_proc_t *L1_proc; + L1_proc_t *eNB_proc; + L1_rxtx_proc_t *L1_proc; cpu_set_t cpuset; CPU_ZERO(&cpuset); @@ -1992,7 +1992,7 @@ void* pre_scd_thread( void* param ){ #ifdef PHY_TX_THREAD /*! * \brief The phy tx thread of eNB. - * \param param is a \ref eNB_proc_t structure which contains the info what to process. + * \param param is a \ref L1_proc_t structure which contains the info what to process. * \returns a pointer to an int. The storage is not on the heap and must not be freed. */ static void* eNB_thread_phy_tx( void* param ) { @@ -2003,7 +2003,7 @@ static void* eNB_thread_phy_tx( void* param ) { RU_proc_t *proc = &ru->proc; PHY_VARS_eNB **eNB_list = ru->eNB_list; - eNB_rxtx_proc_t L1_proc; + L1_rxtx_proc_t L1_proc; // set default return value eNB_thread_phy_tx_status = 0; From a46443b2a910eee6f7c904f5f811ee06a028084e Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Wed, 31 Oct 2018 12:05:08 +0100 Subject: [PATCH 077/233] T: textlog: add option to dump 'raw time' 'raw time' is the tv_sec element in the struct tm as returned by 'localtime'. This can be useful to extract events from a dump based on their time. --- common/utils/T/tracer/logger/logger.h | 1 + common/utils/T/tracer/logger/textlog.c | 17 ++++++++++++++--- common/utils/T/tracer/textlog.c | 4 ++++ 3 files changed, 19 insertions(+), 3 deletions(-) diff --git a/common/utils/T/tracer/logger/logger.h b/common/utils/T/tracer/logger/logger.h index 434cf5a90f..7c019b4797 100644 --- a/common/utils/T/tracer/logger/logger.h +++ b/common/utils/T/tracer/logger/logger.h @@ -30,6 +30,7 @@ void framelog_set_skip(logger *_this, int skip_delay); void framelog_set_update_only_at_sf9(logger *_this, int update_only_at_sf9); void textlog_dump_buffer(logger *_this, int dump_buffer); +void textlog_raw_time(logger *_this, int raw_time); #include "view/view.h" diff --git a/common/utils/T/tracer/logger/textlog.c b/common/utils/T/tracer/logger/textlog.c index 9eb6fd02d8..76f920e1e2 100644 --- a/common/utils/T/tracer/logger/textlog.c +++ b/common/utils/T/tracer/logger/textlog.c @@ -33,6 +33,7 @@ struct textlog { /* local output buffer */ OBUF o; int dump_buffer; + int raw_time; }; static void _event(void *p, event e) @@ -51,9 +52,13 @@ static void _event(void *p, event e) #ifdef T_SEND_TIME t = localtime(&e.sending_time.tv_sec); - /* round tv_nsec to nearest millisecond */ - sprintf(tt, "%2.2d:%2.2d:%2.2d.%9.9ld: ", t->tm_hour, t->tm_min, t->tm_sec, - e.sending_time.tv_nsec); + if (l->raw_time) + sprintf(tt, "%2.2d:%2.2d:%2.2d.%9.9ld [%ld]: ", + t->tm_hour, t->tm_min, t->tm_sec, + e.sending_time.tv_nsec, e.sending_time.tv_sec); + else + sprintf(tt, "%2.2d:%2.2d:%2.2d.%9.9ld: ", t->tm_hour, t->tm_min, t->tm_sec, + e.sending_time.tv_nsec); PUTS(&l->o, tt); #endif @@ -215,3 +220,9 @@ void textlog_dump_buffer(logger *_this, int dump_buffer) struct textlog *l = _this; l->dump_buffer = dump_buffer; } + +void textlog_raw_time(logger *_this, int raw_time) +{ + struct textlog *l = _this; + l->raw_time = raw_time; +} diff --git a/common/utils/T/tracer/textlog.c b/common/utils/T/tracer/textlog.c index dba9d55483..a123bf9bf5 100644 --- a/common/utils/T/tracer/textlog.c +++ b/common/utils/T/tracer/textlog.c @@ -52,6 +52,7 @@ void usage(void) " they will be processed in order\n" " by default, all is off\n" " -full also dump buffers' content\n" +" -raw-time also prints 'raw time'\n" " -ip connect to given IP address (default %s)\n" " -p connect to given port (default %d)\n" " -x GUI output\n" @@ -91,6 +92,7 @@ int main(int n, char **v) int gui_active = 1; textlog_data textlog_data; int full = 0; + int raw_time = 0; /* write on a socket fails if the other end is closed and we get SIGPIPE */ if (signal(SIGPIPE, SIG_IGN) == SIG_ERR) abort(); @@ -117,6 +119,7 @@ int main(int n, char **v) if (!strcmp(v[i], "-debug-gui")) { gui_logd = 1; continue; } if (!strcmp(v[i], "-no-gui")) { gui_active = 0; continue; } if (!strcmp(v[i], "-full")) { full = 1; continue; } + if (!strcmp(v[i], "-raw-time")) { raw_time = 1; continue; } usage(); } @@ -162,6 +165,7 @@ int main(int n, char **v) // "ev: {} eNB_id [eNB_ID] frame [frame] subframe [subframe]"); logger_add_view(textlog, out); if (full) textlog_dump_buffer(textlog, 1); + if (raw_time) textlog_raw_time(textlog, 1); free(name); free(desc); } From 6ae27efac0d1f259b5fcf73572a4f3ddef809e17 Mon Sep 17 00:00:00 2001 From: OAI-admin Date: Wed, 31 Oct 2018 16:24:29 +0100 Subject: [PATCH 078/233] minor update in format, variable ctxt removed in rrc_eNB_free_UE() --- openair2/RRC/LTE/rrc_eNB.c | 76 ++++++++++++++++----------------- openair2/RRC/LTE/rrc_eNB_S1AP.c | 2 +- 2 files changed, 38 insertions(+), 40 deletions(-) diff --git a/openair2/RRC/LTE/rrc_eNB.c b/openair2/RRC/LTE/rrc_eNB.c index 8842e8be9f..6beeb9e68c 100644 --- a/openair2/RRC/LTE/rrc_eNB.c +++ b/openair2/RRC/LTE/rrc_eNB.c @@ -842,11 +842,11 @@ rrc_eNB_free_UE( const struct rrc_eNB_ue_context_s *const ue_context_pP) //----------------------------------------------------------------------------- { - protocol_ctxt_t ctxt; + //protocol_ctxt_t ctxt; // rm ? rnti_t rnti = ue_context_pP->ue_context.rnti; if (enb_mod_idP >= NB_eNB_INST) { - LOG_I(RRC, "eNB instance invalid (%d/%d) for UE %x!\n", + LOG_E(RRC, "eNB instance invalid (%d/%d) for UE %x!\n", enb_mod_idP, NB_eNB_INST, rnti); @@ -854,49 +854,47 @@ rrc_eNB_free_UE( return; } - if (NULL != ue_context_pP) { - PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, enb_mod_idP, ENB_FLAG_YES, rnti, 0, 0, enb_mod_idP); + //PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, enb_mod_idP, ENB_FLAG_YES, rnti, 0, 0, enb_mod_idP); // rm ? - LOG_W(RRC, "[eNB %d] Removing UE RNTI %x\n", - enb_mod_idP, - rnti); - - if (EPC_MODE_ENABLED) { - if ((ue_context_pP->ue_context.ul_failure_timer >= 20000) && (mac_eNB_get_rrc_status(enb_mod_idP, rnti) >= RRC_CONNECTED)) { - LOG_I(RRC, "[eNB %d] S1AP_UE_CONTEXT_RELEASE_REQ sent for RNTI %x, cause 21, radio connection with ue lost\n", - enb_mod_idP, - rnti); - - rrc_eNB_send_S1AP_UE_CONTEXT_RELEASE_REQ(enb_mod_idP, ue_context_pP, S1AP_CAUSE_RADIO_NETWORK, 21); - // send cause 21: radio connection with ue lost - /* From 3GPP 36300v10 p129 : 19.2.2.2.2 S1 UE Context Release Request (eNB triggered) - * If the E-UTRAN internal reason is a radio link failure detected in the eNB, the eNB shall wait a sufficient time before - * triggering the S1 UE Context Release Request procedure in order to allow the UE to perform the NAS recovery - * procedure, see TS 23.401 [17]. - */ - - return; - } + if (EPC_MODE_ENABLED) { + if ((ue_context_pP->ue_context.ul_failure_timer >= 20000) && (mac_eNB_get_rrc_status(enb_mod_idP, rnti) >= RRC_CONNECTED)) { + LOG_I(RRC, "[eNB %d] S1AP_UE_CONTEXT_RELEASE_REQ sent for RNTI %x, cause 21, radio connection with ue lost\n", + enb_mod_idP, + rnti); - if((ue_context_pP->ue_context.ue_rrc_inactivity_timer >= ue_context_pP->ue_context.ue_rrc_inactivity_timer_thres) && - (mac_eNB_get_rrc_status(enb_mod_idP, rnti) >= RRC_CONNECTED)) { - LOG_I(RRC, "[eNB %d] S1AP_UE_CONTEXT_RELEASE_REQ sent for RNTI %x, cause 20, user inactivity\n", - enb_mod_idP, - rnti); + rrc_eNB_send_S1AP_UE_CONTEXT_RELEASE_REQ(enb_mod_idP, ue_context_pP, S1AP_CAUSE_RADIO_NETWORK, 21); + // send cause 21: radio connection with ue lost + /* From 3GPP 36300v10 p129 : 19.2.2.2.2 S1 UE Context Release Request (eNB triggered) + * If the E-UTRAN internal reason is a radio link failure detected in the eNB, the eNB shall wait a sufficient time before + * triggering the S1 UE Context Release Request procedure in order to allow the UE to perform the NAS recovery + * procedure, see TS 23.401 [17]. + */ - rrc_eNB_send_S1AP_UE_CONTEXT_RELEASE_REQ(enb_mod_idP, ue_context_pP, S1AP_CAUSE_RADIO_NETWORK, 20); - // send cause 20: user inactivity - - return; - } + return; } + + if((ue_context_pP->ue_context.ue_rrc_inactivity_timer >= ue_context_pP->ue_context.ue_rrc_inactivity_timer_thres) && + (mac_eNB_get_rrc_status(enb_mod_idP, rnti) >= RRC_CONNECTED)) { + LOG_I(RRC, "[eNB %d] S1AP_UE_CONTEXT_RELEASE_REQ sent for RNTI %x, cause 20, user inactivity\n", + enb_mod_idP, + rnti); + + rrc_eNB_send_S1AP_UE_CONTEXT_RELEASE_REQ(enb_mod_idP, ue_context_pP, S1AP_CAUSE_RADIO_NETWORK, 20); + // send cause 20: user inactivity - // add UE info to freeList - LOG_I(RRC, "Put UE %x into freeList\n", - rnti); - - put_UE_in_freelist(enb_mod_idP, rnti, 1); + return; + } } + + LOG_W(RRC, "[eNB %d] Removing UE RNTI %x\n", + enb_mod_idP, + rnti); + + // add UE info to freeList + LOG_I(RRC, "Put UE %x into freeList\n", + rnti); + + put_UE_in_freelist(enb_mod_idP, rnti, 1); } void remove_UE_from_freelist(module_id_t mod_id, rnti_t rnti) diff --git a/openair2/RRC/LTE/rrc_eNB_S1AP.c b/openair2/RRC/LTE/rrc_eNB_S1AP.c index 6aa4f9485e..bb3f5a3851 100644 --- a/openair2/RRC/LTE/rrc_eNB_S1AP.c +++ b/openair2/RRC/LTE/rrc_eNB_S1AP.c @@ -1184,7 +1184,7 @@ rrc_eNB_send_S1AP_UE_CONTEXT_RELEASE_REQ( //------------------------------------------------------------------------------ { if (ue_context_pP == NULL) { - LOG_W(RRC, "[eNB] In S1AP_UE_CONTEXT_RELEASE_REQ: invalid UE\n"); + LOG_E(RRC, "[eNB] In S1AP_UE_CONTEXT_RELEASE_REQ: invalid UE\n"); } else { MSC_LOG_TX_MESSAGE(MSC_RRC_ENB, MSC_S1AP_ENB, From e13c962d24c0f66a6ae5d39db6d7b3bec206bff0 Mon Sep 17 00:00:00 2001 From: "yoshio.inoue" Date: Fri, 2 Nov 2018 16:54:19 +0900 Subject: [PATCH 079/233] Fixed bug that u-plane is not transferred with multiple UEs --- openair2/LAYER2/PDCP_v10.1.0/pdcp.c | 14 ++++++++++-- openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c | 15 +++++++++++-- openair2/NETWORK_DRIVER/UE_IP/common.c | 11 +++++++++- openair2/NETWORK_DRIVER/UE_IP/device.c | 10 ++++----- openair3/NAS/UE/ESM/esm_ebr_context.c | 28 +++++++++++++++++++++--- targets/RT/USER/lte-uesoftmodem.c | 12 ++++++++-- 6 files changed, 75 insertions(+), 15 deletions(-) diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp.c b/openair2/LAYER2/PDCP_v10.1.0/pdcp.c index b16b7ad062..0112fe10ef 100755 --- a/openair2/LAYER2/PDCP_v10.1.0/pdcp.c +++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp.c @@ -64,7 +64,9 @@ #endif extern int otg_enabled; - +#if defined(ENABLE_USE_MME) +extern uint8_t nfapi_mode; +#endif #include "common/ran_context.h" extern RAN_CONTEXT_t RC; hash_table_t *pdcp_coll_p = NULL; @@ -796,7 +798,15 @@ pdcp_data_ind( * for the UE compiled in noS1 mode, we need 0 * TODO: be sure of this */ - ((pdcp_data_ind_header_t*) new_sdu_p->data)->inst = 1; + if (nfapi_mode == 3) { +#ifdef UESIM_EXPANSION + ((pdcp_data_ind_header_t*) new_sdu_p->data)->inst = 1; +#else + ((pdcp_data_ind_header_t*) new_sdu_p->data)->inst = ctxt_pP->module_id + 1; +#endif + } else { + ((pdcp_data_ind_header_t*) new_sdu_p->data)->inst = 1; + } #endif } else { ((pdcp_data_ind_header_t*) new_sdu_p->data)->rb_id = rb_id + (ctxt_pP->module_id * maxDRB); diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c b/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c index 3b0283525e..0a49c7d94c 100755 --- a/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c +++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c @@ -82,10 +82,13 @@ extern struct msghdr nas_msg_tx; extern struct msghdr nas_msg_rx; unsigned char pdcp_read_state_g = 0; +extern uint8_t nfapi_mode; +#ifdef UESIM_EXPANSION +extern uint16_t inst_pdcp_list[NUMBER_OF_UE_MAX]; +#endif #endif extern Packet_OTG_List_t *otg_pdcp_buffer; -extern uint8_t nfapi_mode; #if defined(LINK_ENB_PDCP_TO_GTPV1U) # include "gtpv1u_eNB_task.h" # include "gtpv1u_eNB_defs.h" @@ -931,7 +934,15 @@ int pdcp_fifo_read_input_sdus (const protocol_ctxt_t* const ctxt_pP) rab_id = pdcp_read_header_g.rb_id % maxDRB; ctxt.rnti = pdcp_eNB_UE_instance_to_rnti[pdcp_read_header_g.rb_id / maxDRB]; } else { - ctxt.module_id = 0; + if (nfapi_mode == 3) { +#ifdef UESIM_EXPANSION + ctxt.module_id = inst_pdcp_list[pdcp_read_header_g.inst]; +#else + ctxt.module_id = pdcp_read_header_g.inst - 1; +#endif + } else { + ctxt.module_id = 0; + } rab_id = pdcp_read_header_g.rb_id % maxDRB; ctxt.rnti = pdcp_UE_UE_module_id_to_rnti[ctxt.module_id]; } diff --git a/openair2/NETWORK_DRIVER/UE_IP/common.c b/openair2/NETWORK_DRIVER/UE_IP/common.c index b21ca5f2dc..1b15ea8aed 100644 --- a/openair2/NETWORK_DRIVER/UE_IP/common.c +++ b/openair2/NETWORK_DRIVER/UE_IP/common.c @@ -304,7 +304,16 @@ ue_ip_common_ip2wireless( if (dst_addr) { printk("[UE_IP_DRV][%s] Dest %d.%d.%d.%d\n",__FUNCTION__, dst_addr[0],dst_addr[1],dst_addr[2],dst_addr[3]); } - + // modify inst by IP address for the U-Plane of multiple UEs while L2 fapi simulator start +#ifdef UESIM_EXPANSION + if ((src_addr[3] - 1)> instP) { + pdcph.inst = src_addr[3] - 1; + printk("[UE_IP_DRV] change INST from %d to %d\n",instP, pdcph.inst); + instP = src_addr[3] - 1; + priv_p=netdev_priv(ue_ip_dev[instP]); + } +#endif + // modify inst by IP address for the U-Plane of multiple UEs while L2 fapi simulator end //get Ipv4 address and pass to PCDP header printk("[UE_IP_DRV] source Id: 0x%08x\n",pdcph.sourceL2Id ); printk("[UE_IP_DRV] destinationL2Id Id: 0x%08x\n",pdcph.destinationL2Id ); diff --git a/openair2/NETWORK_DRIVER/UE_IP/device.c b/openair2/NETWORK_DRIVER/UE_IP/device.c index 47c820fe77..e67f67d6e3 100644 --- a/openair2/NETWORK_DRIVER/UE_IP/device.c +++ b/openair2/NETWORK_DRIVER/UE_IP/device.c @@ -61,7 +61,7 @@ int ue_ip_find_inst(struct net_device *dev_pP) //--------------------------------------------------------------------------- int i; - for (i=0; i=UE_IP_NB_INSTANCES_MAX)) { + if ((inst<=0) || (inst>UE_IP_NB_INSTANCES_MAX)) { printk("[UE_IP_DRV][%s] ERROR, couldn't find instance\n", __FUNCTION__); return; } @@ -243,7 +243,7 @@ int ue_ip_hard_start_xmit(struct sk_buff *skb_pP, struct net_device *dev_pP) return -1; } - if ((inst>=0) && (inst0) && (inst<=UE_IP_NB_INSTANCES_MAX)) { #ifdef OAI_DRV_OAI_DRV_DEBUG_DEVICE printk("[UE_IP_DRV][%s] inst %d, begin\n", __FUNCTION__,inst); #endif @@ -392,7 +392,7 @@ int init_module (void) // Initialize parameters shared with RRC printk("[UE_IP_DRV][%s] Starting OAI IP driver", __FUNCTION__); - for (inst=0; inst #include #include - +#ifdef PDCP_USE_NETLINK +#ifdef UESIM_EXPANSION + #include "openairinterface5g_limits.h" + extern uint16_t inst_pdcp_list[NUMBER_OF_UE_MAX]; +#endif +#endif extern uint8_t nfapi_mode; /****************************************************************************/ @@ -277,15 +282,32 @@ int esm_ebr_context_create( // this is for L2 FAPI simulator. // change for multiple UE's like 256UEs. // if it's made too many tables , OS may crush so we use one table. +#ifdef PDCP_USE_NETLINK +#ifdef UESIM_EXPANSION + uint16_t inst_nic = (pdn->ip_addr[3] & 0x000000FF) - 1; res = sprintf(command_line, "ifconfig oip%d %s netmask %s broadcast %s up && " "ip rule add from %s/24 table %d && " "ip rule add to %s/24 table %d && " "ip route add default dev oip%d table %d", - ueid+1, ipv4_addr, netmask, broadcast, + inst_nic, ipv4_addr, netmask, broadcast, ipv4_addr, 201, ipv4_addr, 201, - ueid+1, 201); + inst_nic, 201); + + inst_pdcp_list[inst_nic] = ueid; +#else + res = sprintf(command_line, + "ifconfig oip%d %s netmask %s broadcast %s up && " + "ip rule add from %s/32 table %d && " + "ip rule add to %s/32 table %d && " + "ip route add default dev oip%d table %d", + ueid + 1, ipv4_addr, netmask, broadcast, + ipv4_addr, ueid + 201, + ipv4_addr, ueid + 201, + ueid + 1, ueid + 201); +#endif +#endif } else { res = sprintf(command_line, "ifconfig oip%d %s netmask %s broadcast %s up && " diff --git a/targets/RT/USER/lte-uesoftmodem.c b/targets/RT/USER/lte-uesoftmodem.c index be8a30c1bd..9ae1ead95e 100755 --- a/targets/RT/USER/lte-uesoftmodem.c +++ b/targets/RT/USER/lte-uesoftmodem.c @@ -115,7 +115,11 @@ pthread_mutex_t nfapi_sync_mutex; int nfapi_sync_var=-1; //!< protected by mutex \ref nfapi_sync_mutex uint8_t nfapi_mode = 0; - +#ifdef PDCP_USE_NETLINK +#ifdef UESIM_EXPANSION +uint16_t inst_pdcp_list[NUMBER_OF_UE_MAX]; +#endif +#endif uint16_t sf_ahead=2; int tddflag; char *emul_iface; @@ -821,7 +825,11 @@ int main( int argc, char **argv ) int CC_id; uint8_t abstraction_flag=0; unsigned int start_msc=0; - +#ifdef PDCP_USE_NETLINK +#ifdef UESIM_EXPANSION + memset(inst_pdcp_list, 0, sizeof(inst_pdcp_list)); +#endif +#endif // Default value for the number of UEs. It will hold, // if not changed from the command line option --num-ues NB_UE_INST=1; From 3ec3a1af3478eed544b7aec064f2ae6c206e3f56 Mon Sep 17 00:00:00 2001 From: "yoshio.inoue" Date: Fri, 2 Nov 2018 16:55:13 +0900 Subject: [PATCH 080/233] Add comment --- targets/RT/USER/lte-ue.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/targets/RT/USER/lte-ue.c b/targets/RT/USER/lte-ue.c index bc393b7371..18a47409e5 100755 --- a/targets/RT/USER/lte-ue.c +++ b/targets/RT/USER/lte-ue.c @@ -1023,11 +1023,12 @@ static void *UE_phy_stub_single_thread_rxn_txnp4(void *arg) { proc->frame_rx = timer_frame; // FDD and TDD tx timing settings. + // XXX:It is the result of timing adjustment in debug. + // It is necessary to investigate why this will work in the future. proc->subframe_tx=(timer_subframe+sf_ahead)%10; proc->frame_tx = proc->frame_rx + (proc->subframe_rx>(9-sf_ahead)?1:0); //oai_subframe_ind(proc->frame_rx, proc->subframe_rx); - if(UE->frame_parms.frame_type == FDD){ oai_subframe_ind(proc->frame_rx, proc->subframe_rx); }else{ From 633534c2f0227672188368c17b0b15ff2705be9f Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Fri, 2 Nov 2018 09:50:02 +0100 Subject: [PATCH 081/233] T: extract: add time and count criteria --- common/utils/T/tracer/extract.c | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/common/utils/T/tracer/extract.c b/common/utils/T/tracer/extract.c index 2aec38831f..d66e8a3bb8 100644 --- a/common/utils/T/tracer/extract.c +++ b/common/utils/T/tracer/extract.c @@ -16,6 +16,8 @@ void usage(void) " -f field 'name' of 'event' has to match 'value'\n" " type of 'name' must be int\n" " (you can use several -f options)\n" +" -after 'event' time has to be greater than this\n" +" -count dump 'n' matching events (less if EOF reached)\n" ); exit(1); } @@ -51,6 +53,10 @@ int main(int n, char **v) int filter_count = 0; int buffer_arg; int found; + int count = 1; + int check_time = 0; + time_t sec; + long nsec; for (i = 1; i < n; i++) { if (!strcmp(v[i], "-h") || !strcmp(v[i], "--help")) usage(); @@ -63,6 +69,14 @@ int main(int n, char **v) filter_value[filter_count++] = atoi(v[++i]); continue; } + if (!strcmp(v[i], "-after")) { if (i>n-3) usage(); + check_time = 1; + sec = atoll(v[++i]); + nsec = atol(v[++i]); + continue; + } + if (!strcmp(v[i], "-count")) + { if (i > n-2) usage(); count = atoi(v[++i]); continue; } if (file == NULL) { file = v[i]; continue; } if (event_name == NULL) { event_name = v[i]; continue; } if (buffer_name == NULL) { buffer_name = v[i]; continue; } @@ -111,13 +125,20 @@ int main(int n, char **v) break; if (i != filter_count) continue; + if (check_time && + !(e.sending_time.tv_sec > sec || + (e.sending_time.tv_sec == sec && e.sending_time.tv_nsec >= nsec))) + continue; if (fwrite(e.e[buffer_arg].b, e.e[buffer_arg].bsize, 1, out) != 1) { perror(output_file); exit(1); } - found = 1; - break; + found++; + if (found == count) + break; } if (found == 0) printf("ERROR: event not found\n"); + if (found != count) + printf("WARNING: dumped %d events (wanted %d)\n", found, count); fclose(out); From 64b395c64a3346bfa1cebf7f62442034d44cb6e7 Mon Sep 17 00:00:00 2001 From: "yoshio.inoue" Date: Fri, 2 Nov 2018 19:28:15 +0900 Subject: [PATCH 082/233] Fixed overflow related to oip generation --- openair2/LAYER2/PDCP_v10.1.0/pdcp.c | 4 ++-- openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c | 2 +- openair2/NETWORK_DRIVER/UE_IP/common.c | 6 +++--- openair2/NETWORK_DRIVER/UE_IP/device.c | 12 ++++++------ openair3/NAS/UE/ESM/esm_ebr_context.c | 6 +++--- 5 files changed, 15 insertions(+), 15 deletions(-) diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp.c b/openair2/LAYER2/PDCP_v10.1.0/pdcp.c index 0112fe10ef..7bbbbef4f8 100755 --- a/openair2/LAYER2/PDCP_v10.1.0/pdcp.c +++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp.c @@ -800,9 +800,9 @@ pdcp_data_ind( */ if (nfapi_mode == 3) { #ifdef UESIM_EXPANSION - ((pdcp_data_ind_header_t*) new_sdu_p->data)->inst = 1; + ((pdcp_data_ind_header_t*) new_sdu_p->data)->inst = 0; #else - ((pdcp_data_ind_header_t*) new_sdu_p->data)->inst = ctxt_pP->module_id + 1; + ((pdcp_data_ind_header_t*) new_sdu_p->data)->inst = ctxt_pP->module_id; #endif } else { ((pdcp_data_ind_header_t*) new_sdu_p->data)->inst = 1; diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c b/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c index 0a49c7d94c..9d0ed19a59 100755 --- a/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c +++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c @@ -938,7 +938,7 @@ int pdcp_fifo_read_input_sdus (const protocol_ctxt_t* const ctxt_pP) #ifdef UESIM_EXPANSION ctxt.module_id = inst_pdcp_list[pdcp_read_header_g.inst]; #else - ctxt.module_id = pdcp_read_header_g.inst - 1; + ctxt.module_id = pdcp_read_header_g.inst; #endif } else { ctxt.module_id = 0; diff --git a/openair2/NETWORK_DRIVER/UE_IP/common.c b/openair2/NETWORK_DRIVER/UE_IP/common.c index 1b15ea8aed..d23132d96a 100644 --- a/openair2/NETWORK_DRIVER/UE_IP/common.c +++ b/openair2/NETWORK_DRIVER/UE_IP/common.c @@ -306,10 +306,10 @@ ue_ip_common_ip2wireless( } // modify inst by IP address for the U-Plane of multiple UEs while L2 fapi simulator start #ifdef UESIM_EXPANSION - if ((src_addr[3] - 1)> instP) { - pdcph.inst = src_addr[3] - 1; + if ((src_addr[3] - 2)> instP) { + pdcph.inst = src_addr[3] - 2; printk("[UE_IP_DRV] change INST from %d to %d\n",instP, pdcph.inst); - instP = src_addr[3] - 1; + instP = src_addr[3] - 2; priv_p=netdev_priv(ue_ip_dev[instP]); } #endif diff --git a/openair2/NETWORK_DRIVER/UE_IP/device.c b/openair2/NETWORK_DRIVER/UE_IP/device.c index e67f67d6e3..4f295543dc 100644 --- a/openair2/NETWORK_DRIVER/UE_IP/device.c +++ b/openair2/NETWORK_DRIVER/UE_IP/device.c @@ -61,7 +61,7 @@ int ue_ip_find_inst(struct net_device *dev_pP) //--------------------------------------------------------------------------- int i; - for (i=1; i<=UE_IP_NB_INSTANCES_MAX; i++) + for (i=0; iUE_IP_NB_INSTANCES_MAX)) { + if ((inst<0) || (inst>=UE_IP_NB_INSTANCES_MAX)) { printk("[UE_IP_DRV][%s] ERROR, couldn't find instance\n", __FUNCTION__); return; } @@ -243,7 +243,7 @@ int ue_ip_hard_start_xmit(struct sk_buff *skb_pP, struct net_device *dev_pP) return -1; } - if ((inst>0) && (inst<=UE_IP_NB_INSTANCES_MAX)) { + if ((inst>=0) && (instip_addr[3] & 0x000000FF) - 1; + uint16_t inst_nic = (pdn->ip_addr[3] & 0x000000FF) - 2; res = sprintf(command_line, "ifconfig oip%d %s netmask %s broadcast %s up && " "ip rule add from %s/24 table %d && " "ip rule add to %s/24 table %d && " "ip route add default dev oip%d table %d", - inst_nic, ipv4_addr, netmask, broadcast, + inst_nic + 1, ipv4_addr, netmask, broadcast, ipv4_addr, 201, ipv4_addr, 201, - inst_nic, 201); + inst_nic + 1, 201); inst_pdcp_list[inst_nic] = ueid; #else From 1bb53286bb5fa6beafc7bef461eb191f8929bc4d Mon Sep 17 00:00:00 2001 From: Louis Adrien Dufrene Date: Fri, 2 Nov 2018 16:23:32 +0100 Subject: [PATCH 083/233] Bug fixed: S1 setup requst sends the correct default DRX value --- openair2/ENB_APP/enb_config.c | 270 +++++++++++++++++++++++---- openair2/RRC/LTE/MESSAGES/asn1_msg.c | 2 +- openair2/RRC/LTE/rrc_eNB.c | 3 - 3 files changed, 233 insertions(+), 42 deletions(-) diff --git a/openair2/ENB_APP/enb_config.c b/openair2/ENB_APP/enb_config.c index 2675e4454c..40d9551ef2 100644 --- a/openair2/ENB_APP/enb_config.c +++ b/openair2/ENB_APP/enb_config.c @@ -2041,37 +2041,162 @@ int RCconfig_gtpu(void ) { return 0; } - -int RCconfig_S1(MessageDef *msg_p, uint32_t i) { - int j,k = 0; - int enb_id; - int32_t my_int; - const char *active_enb[MAX_ENB]; - char *address = NULL; - char *cidr = NULL; +//----------------------------------------------------------------------------- +/* +* Configure the s1ap_register_enb_req in itti message for future +* communications between eNB(s) and MME. +*/ +int RCconfig_S1( + MessageDef *msg_p, + uint32_t i) +//----------------------------------------------------------------------------- +{ + int enb_id = 0; + int32_t my_int = 0; + const char *active_enb[MAX_ENB]; + char *address = NULL; + char *cidr = NULL; + /*------------------------------------------------------------------------------*/ + /* + * the only reason for all these variables is, that they are "hard-encoded" into + * the CCPARAMS_DESC macro and we need it for the default_DRX value ... + */ + char *frame_type = NULL; + int32_t tdd_config = 0; + int32_t tdd_config_s = 0; + char *prefix_type = NULL; + char *pbch_repetition = NULL; + int32_t eutra_band = 0; + long long int downlink_frequency = 0; + int32_t uplink_frequency_offset = 0; + int32_t Nid_cell = 0; + int32_t Nid_cell_mbsfn = 0; + int32_t N_RB_DL = 0; + int32_t nb_antenna_ports = 0; + int32_t prach_root = 0; + int32_t prach_config_index = 0; + char *prach_high_speed = NULL; + int32_t prach_zero_correlation = 0; + int32_t prach_freq_offset = 0; + int32_t pucch_delta_shift = 0; + int32_t pucch_nRB_CQI = 0; + int32_t pucch_nCS_AN = 0; + int32_t pucch_n1_AN = 0; + int32_t pdsch_referenceSignalPower = 0; + int32_t pdsch_p_b = 0; + int32_t pusch_n_SB = 0; + char *pusch_hoppingMode = NULL; + int32_t pusch_hoppingOffset = 0; + char *pusch_enable64QAM = NULL; + char *pusch_groupHoppingEnabled = NULL; + int32_t pusch_groupAssignment = 0; + char *pusch_sequenceHoppingEnabled = NULL; + int32_t pusch_nDMRS1 = 0; + char *phich_duration = NULL; + char *phich_resource = NULL; + char *srs_enable = NULL; + int32_t srs_BandwidthConfig = 0; + int32_t srs_SubframeConfig = 0; + char *srs_ackNackST = NULL; + char *srs_MaxUpPts = NULL; + int32_t pusch_p0_Nominal = 0; + char *pusch_alpha = NULL; + int32_t pucch_p0_Nominal = 0; + int32_t msg3_delta_Preamble = 0; + char *pucch_deltaF_Format1 = NULL; + char *pucch_deltaF_Format1b = NULL; + char *pucch_deltaF_Format2 = NULL; + char *pucch_deltaF_Format2a = NULL; + char *pucch_deltaF_Format2b = NULL; + int32_t rach_numberOfRA_Preambles = 0; + char *rach_preamblesGroupAConfig = NULL; + int32_t rach_sizeOfRA_PreamblesGroupA = 0; + int32_t rach_messageSizeGroupA = 0; + char *rach_messagePowerOffsetGroupB = NULL; + int32_t rach_powerRampingStep = 0; + int32_t rach_preambleInitialReceivedTargetPower = 0; + int32_t rach_preambleTransMax = 0; + int32_t rach_raResponseWindowSize = 10; + int32_t rach_macContentionResolutionTimer = 0; + int32_t rach_maxHARQ_Msg3Tx = 0; + int32_t pcch_defaultPagingCycle = 0; + char *pcch_nB = NULL; + int32_t bcch_modificationPeriodCoeff = 0; + int32_t ue_TimersAndConstants_t300 = 0; + int32_t ue_TimersAndConstants_t301 = 0; + int32_t ue_TimersAndConstants_t310 = 0; + int32_t ue_TimersAndConstants_t311 = 0; + int32_t ue_TimersAndConstants_n310 = 0; + int32_t ue_TimersAndConstants_n311 = 0; + int32_t ue_TransmissionMode = 0; + int32_t ue_multiple_max = 0; + //TTN - for D2D + //SIB18 + const char *rxPool_sc_CP_Len = NULL; + const char *rxPool_sc_Period = NULL; + const char *rxPool_data_CP_Len = NULL; + libconfig_int rxPool_ResourceConfig_prb_Num = 0; + libconfig_int rxPool_ResourceConfig_prb_Start = 0; + libconfig_int rxPool_ResourceConfig_prb_End = 0; + const char *rxPool_ResourceConfig_offsetIndicator_present = NULL; + libconfig_int rxPool_ResourceConfig_offsetIndicator_choice = 0; + const char *rxPool_ResourceConfig_subframeBitmap_present = NULL; + char *rxPool_ResourceConfig_subframeBitmap_choice_bs_buf = NULL; + libconfig_int rxPool_ResourceConfig_subframeBitmap_choice_bs_size = 0; + libconfig_int rxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused = 0; + //SIB19 + //For discRxPool + const char *discRxPool_cp_Len = NULL; + const char *discRxPool_discPeriod = NULL; + libconfig_int discRxPool_numRetx = 0; + libconfig_int discRxPool_numRepetition = 0; + libconfig_int discRxPool_ResourceConfig_prb_Num = 0; + libconfig_int discRxPool_ResourceConfig_prb_Start = 0; + libconfig_int discRxPool_ResourceConfig_prb_End = 0; + const char *discRxPool_ResourceConfig_offsetIndicator_present = NULL; + libconfig_int discRxPool_ResourceConfig_offsetIndicator_choice = 0; + const char *discRxPool_ResourceConfig_subframeBitmap_present = NULL; + char *discRxPool_ResourceConfig_subframeBitmap_choice_bs_buf = NULL; + libconfig_int discRxPool_ResourceConfig_subframeBitmap_choice_bs_size = 0; + libconfig_int discRxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused = 0; + //For discRxPoolPS + const char *discRxPoolPS_cp_Len = NULL; + const char *discRxPoolPS_discPeriod = NULL; + libconfig_int discRxPoolPS_numRetx = 0; + libconfig_int discRxPoolPS_numRepetition = 0; + libconfig_int discRxPoolPS_ResourceConfig_prb_Num = 0; + libconfig_int discRxPoolPS_ResourceConfig_prb_Start = 0; + libconfig_int discRxPoolPS_ResourceConfig_prb_End = 0; + const char *discRxPoolPS_ResourceConfig_offsetIndicator_present = NULL; + libconfig_int discRxPoolPS_ResourceConfig_offsetIndicator_choice = 0; + const char *discRxPoolPS_ResourceConfig_subframeBitmap_present = NULL; + char *discRxPoolPS_ResourceConfig_subframeBitmap_choice_bs_buf = NULL; + libconfig_int discRxPoolPS_ResourceConfig_subframeBitmap_choice_bs_size = 0; + libconfig_int discRxPoolPS_ResourceConfig_subframeBitmap_choice_bs_bits_unused = 0; + /*------------------------------------------------------------------------------*/ // for no gcc warnings (void)my_int; - memset((char *)active_enb, 0, MAX_ENB * sizeof(char *)); + memset((char *)active_enb, 0, MAX_ENB * sizeof(char *)); paramdef_t ENBSParams[] = ENBSPARAMS_DESC; - paramdef_t ENBParams[] = ENBPARAMS_DESC; - paramlist_def_t ENBParamList = {ENB_CONFIG_STRING_ENB_LIST,NULL,0}; + paramdef_t ENBParams[] = ENBPARAMS_DESC; + paramlist_def_t ENBParamList = {ENB_CONFIG_STRING_ENB_LIST, NULL, 0}; /* get global parameters, defined outside any section in the config file */ - config_get( ENBSParams,sizeof(ENBSParams)/sizeof(paramdef_t),NULL); - AssertFatal (i0) { + if (ENBSParams[ENB_ACTIVE_ENBS_IDX].numelt > 0) { // Output a list of all eNBs. - config_getlist( &ENBParamList,ENBParams,sizeof(ENBParams)/sizeof(paramdef_t),NULL); + config_getlist(&ENBParamList, ENBParams, sizeof(ENBParams)/sizeof(paramdef_t), NULL); if (ENBParamList.numelt > 0) { - for (k = 0; k < ENBParamList.numelt; k++) { + for (int k = 0; k < ENBParamList.numelt; k++) { if (ENBParamList.paramarray[k][ENB_ENB_ID_IDX].uptr == NULL) { // Calculate a default eNB ID if (EPC_MODE_ENABLED) { - uint32_t hash; - hash = s1ap_generate_eNB_id (); + uint32_t hash = 0; + hash = s1ap_generate_eNB_id(); enb_id = k + (hash & 0xFFFF8); } else { enb_id = k; @@ -2081,22 +2206,33 @@ int RCconfig_S1(MessageDef *msg_p, uint32_t i) { } // search if in active list - for (j=0; j < ENBSParams[ENB_ACTIVE_ENBS_IDX].numelt; j++) { + for (int j = 0; j < ENBSParams[ENB_ACTIVE_ENBS_IDX].numelt; j++) { if (strcmp(ENBSParams[ENB_ACTIVE_ENBS_IDX].strlistptr[j], *(ENBParamList.paramarray[k][ENB_ENB_NAME_IDX].strptr)) == 0) { paramdef_t PLMNParams[] = PLMNPARAMS_DESC; paramlist_def_t PLMNParamList = {ENB_CONFIG_STRING_PLMN_LIST, NULL, 0}; + + paramdef_t CCsParams[] = CCPARAMS_DESC; + + /* map parameter checking array instances to parameter definition array instances */ + checkedparam_t config_check_CCparams[] = CCPARAMS_CHECK; + for (int I = 0; I < (sizeof(CCsParams) / sizeof(paramdef_t)); I++) { + CCsParams[I].chkPptr = &(config_check_CCparams[I]); + } + /* map parameter checking array instances to parameter definition array instances */ checkedparam_t config_check_PLMNParams [] = PLMNPARAMS_CHECK; - - for (int I = 0; I < sizeof(PLMNParams) / sizeof(paramdef_t); ++I) + for (int I = 0; I < sizeof(PLMNParams) / sizeof(paramdef_t); ++I) { PLMNParams[I].chkPptr = &(config_check_PLMNParams[I]); + } + + paramdef_t S1Params[] = S1PARAMS_DESC; + paramlist_def_t S1ParamList = {ENB_CONFIG_STRING_MME_IP_ADDRESS, NULL, 0}; + paramdef_t SCTPParams[] = SCTPPARAMS_DESC; + paramdef_t NETParams[] = NETPARAMS_DESC; - paramdef_t S1Params[] = S1PARAMS_DESC; - paramlist_def_t S1ParamList = {ENB_CONFIG_STRING_MME_IP_ADDRESS,NULL,0}; - paramdef_t SCTPParams[] = SCTPPARAMS_DESC; - paramdef_t NETParams[] = NETPARAMS_DESC; char aprefix[MAX_OPTNAME_SIZE*2 + 8]; - sprintf(aprefix,"%s.[%i]",ENB_CONFIG_STRING_ENB_LIST,k); + sprintf(aprefix, "%s.[%i]", ENB_CONFIG_STRING_ENB_LIST, k); + S1AP_REGISTER_ENB_REQ (msg_p).eNB_id = enb_id; if (strcmp(*(ENBParamList.paramarray[k][ENB_CELL_TYPE_IDX].strptr), "CELL_MACRO_ENB") == 0) { @@ -2104,13 +2240,16 @@ int RCconfig_S1(MessageDef *msg_p, uint32_t i) { } else if (strcmp(*(ENBParamList.paramarray[k][ENB_CELL_TYPE_IDX].strptr), "CELL_HOME_ENB") == 0) { S1AP_REGISTER_ENB_REQ (msg_p).cell_type = CELL_HOME_ENB; } else { - AssertFatal (0, - "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for cell_type choice: CELL_MACRO_ENB or CELL_HOME_ENB !\n", - RC.config_file_name, i, *(ENBParamList.paramarray[k][ENB_CELL_TYPE_IDX].strptr)); + AssertFatal(0, + "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for cell_type choice: CELL_MACRO_ENB or CELL_HOME_ENB !\n", + RC.config_file_name, + i, + *(ENBParamList.paramarray[k][ENB_CELL_TYPE_IDX].strptr)); } - S1AP_REGISTER_ENB_REQ (msg_p).eNB_name = strdup(*(ENBParamList.paramarray[k][ENB_ENB_NAME_IDX].strptr)); - S1AP_REGISTER_ENB_REQ(msg_p).tac = *ENBParamList.paramarray[k][ENB_TRACKING_AREA_CODE_IDX].uptr; + S1AP_REGISTER_ENB_REQ (msg_p).eNB_name = strdup(*(ENBParamList.paramarray[k][ENB_ENB_NAME_IDX].strptr)); + S1AP_REGISTER_ENB_REQ(msg_p).tac = *ENBParamList.paramarray[k][ENB_TRACKING_AREA_CODE_IDX].uptr; + AssertFatal(!ENBParamList.paramarray[k][ENB_MOBILE_COUNTRY_CODE_IDX_OLD].strptr && !ENBParamList.paramarray[k][ENB_MOBILE_NETWORK_CODE_IDX_OLD].strptr, "It seems that you use an old configuration file. Please change the existing\n" @@ -2120,11 +2259,13 @@ int RCconfig_S1(MessageDef *msg_p, uint32_t i) { "to\n" " tracking_area_code = 1; // no string!!\n" " plmn_list = ( { mcc = 208; mnc = 93; mnc_length = 2; } )\n"); + config_getlist(&PLMNParamList, PLMNParams, sizeof(PLMNParams)/sizeof(paramdef_t), aprefix); - if (PLMNParamList.numelt < 1 || PLMNParamList.numelt > 6) + if (PLMNParamList.numelt < 1 || PLMNParamList.numelt > 6){ AssertFatal(0, "The number of PLMN IDs must be in [1,6], but is %d\n", PLMNParamList.numelt); + } S1AP_REGISTER_ENB_REQ(msg_p).num_plmn = PLMNParamList.numelt; @@ -2132,34 +2273,82 @@ int RCconfig_S1(MessageDef *msg_p, uint32_t i) { S1AP_REGISTER_ENB_REQ(msg_p).mcc[l] = *PLMNParamList.paramarray[l][ENB_MOBILE_COUNTRY_CODE_IDX].uptr; S1AP_REGISTER_ENB_REQ(msg_p).mnc[l] = *PLMNParamList.paramarray[l][ENB_MOBILE_NETWORK_CODE_IDX].uptr; S1AP_REGISTER_ENB_REQ(msg_p).mnc_digit_length[l] = *PLMNParamList.paramarray[l][ENB_MNC_DIGIT_LENGTH].u8ptr; + AssertFatal(S1AP_REGISTER_ENB_REQ(msg_p).mnc_digit_length[l] == 3 || S1AP_REGISTER_ENB_REQ(msg_p).mnc[l] < 100, "MNC %d cannot be encoded in two digits as requested (change mnc_digit_length to 3)\n", S1AP_REGISTER_ENB_REQ(msg_p).mnc[l]); } - S1AP_REGISTER_ENB_REQ(msg_p).default_drx = 0; - config_getlist( &S1ParamList,S1Params,sizeof(S1Params)/sizeof(paramdef_t),aprefix); + /* Default DRX param */ + /* + * Here we get the config of the first CC, since the s1ap_register_enb_req_t doesn't support multiple CC. + * It is not clear in the spec if the eNB can have different default paging values in case of several SIB2 from the same eNB. + * Yet, from the spec and logically, there should be a unique value associated with eNB. + * Hence, it should be stated somewhere that the value should be the same for every CC, or put the value outside the CC + * in the conf file. + */ + sprintf(aprefix, "%s.[%i].%s.[%i]", ENB_CONFIG_STRING_ENB_LIST, k, ENB_CONFIG_STRING_COMPONENT_CARRIERS, 0); + config_get(CCsParams, sizeof(CCsParams)/sizeof(paramdef_t), aprefix); + switch (pcch_defaultPagingCycle) { + case 32: { + S1AP_REGISTER_ENB_REQ(msg_p).default_drx = 0; + break; + } + + case 64: { + S1AP_REGISTER_ENB_REQ(msg_p).default_drx = 1; + break; + } + + case 128: { + S1AP_REGISTER_ENB_REQ(msg_p).default_drx = 2; + break; + } + + case 256: { + S1AP_REGISTER_ENB_REQ(msg_p).default_drx = 3; + break; + } + + default: { + LOG_E(S1AP, "Default I-DRX value in conf file is invalid (%i). Should be 32, 64, 128 or 256. \ + Default DRX set to 32 in MME configuration\n", + pcch_defaultPagingCycle); + + S1AP_REGISTER_ENB_REQ(msg_p).default_drx = 0; + } + } + + /* MME connection params */ + sprintf(aprefix, "%s.[%i]", ENB_CONFIG_STRING_ENB_LIST, k); + + config_getlist(&S1ParamList, S1Params, sizeof(S1Params)/sizeof(paramdef_t), aprefix); + S1AP_REGISTER_ENB_REQ (msg_p).nb_mme = 0; for (int l = 0; l < S1ParamList.numelt; l++) { S1AP_REGISTER_ENB_REQ (msg_p).nb_mme += 1; + strcpy(S1AP_REGISTER_ENB_REQ (msg_p).mme_ip_address[l].ipv4_address,*(S1ParamList.paramarray[l][ENB_MME_IPV4_ADDRESS_IDX].strptr)); strcpy(S1AP_REGISTER_ENB_REQ (msg_p).mme_ip_address[l].ipv6_address,*(S1ParamList.paramarray[l][ENB_MME_IPV6_ADDRESS_IDX].strptr)); if (strcmp(*(S1ParamList.paramarray[l][ENB_MME_IP_ADDRESS_PREFERENCE_IDX].strptr), "ipv4") == 0) { S1AP_REGISTER_ENB_REQ (msg_p).mme_ip_address[l].ipv4 = 1; + } else if (strcmp(*(S1ParamList.paramarray[l][ENB_MME_IP_ADDRESS_PREFERENCE_IDX].strptr), "ipv6") == 0) { S1AP_REGISTER_ENB_REQ (msg_p).mme_ip_address[l].ipv6 = 1; + } else if (strcmp(*(S1ParamList.paramarray[l][ENB_MME_IP_ADDRESS_PREFERENCE_IDX].strptr), "no") == 0) { S1AP_REGISTER_ENB_REQ (msg_p).mme_ip_address[l].ipv4 = 1; S1AP_REGISTER_ENB_REQ (msg_p).mme_ip_address[l].ipv6 = 1; } - if (S1ParamList.paramarray[l][ENB_MME_BROADCAST_PLMN_INDEX].iptr) + if (S1ParamList.paramarray[l][ENB_MME_BROADCAST_PLMN_INDEX].iptr) { S1AP_REGISTER_ENB_REQ(msg_p).broadcast_plmn_num[l] = S1ParamList.paramarray[l][ENB_MME_BROADCAST_PLMN_INDEX].numelt; - else + } else { S1AP_REGISTER_ENB_REQ(msg_p).broadcast_plmn_num[l] = 0; + } AssertFatal(S1AP_REGISTER_ENB_REQ(msg_p).broadcast_plmn_num[l] <= S1AP_REGISTER_ENB_REQ(msg_p).num_plmn, "List of broadcast PLMN to be sent to MME can not be longer than actual " @@ -2170,6 +2359,7 @@ int RCconfig_S1(MessageDef *msg_p, uint32_t i) { for (int el = 0; el < S1AP_REGISTER_ENB_REQ(msg_p).broadcast_plmn_num[l]; ++el) { /* UINTARRAY gets mapped to int, see config_libconfig.c:223 */ S1AP_REGISTER_ENB_REQ(msg_p).broadcast_plmn_index[l][el] = S1ParamList.paramarray[l][ENB_MME_BROADCAST_PLMN_INDEX].iptr[el]; + AssertFatal(S1AP_REGISTER_ENB_REQ(msg_p).broadcast_plmn_index[l][el] >= 0 && S1AP_REGISTER_ENB_REQ(msg_p).broadcast_plmn_index[l][el] < S1AP_REGISTER_ENB_REQ(msg_p).num_plmn, "index for MME's MCC/MNC (%d) is an invalid index for the registered PLMN IDs (%d)\n", @@ -2181,8 +2371,9 @@ int RCconfig_S1(MessageDef *msg_p, uint32_t i) { if (S1AP_REGISTER_ENB_REQ(msg_p).broadcast_plmn_num[l] == 0) { S1AP_REGISTER_ENB_REQ(msg_p).broadcast_plmn_num[l] = S1AP_REGISTER_ENB_REQ(msg_p).num_plmn; - for (int el = 0; el < S1AP_REGISTER_ENB_REQ(msg_p).num_plmn; ++el) + for (int el = 0; el < S1AP_REGISTER_ENB_REQ(msg_p).num_plmn; ++el){ S1AP_REGISTER_ENB_REQ(msg_p).broadcast_plmn_index[l][el] = el; + } } } @@ -2192,15 +2383,18 @@ int RCconfig_S1(MessageDef *msg_p, uint32_t i) { if (EPC_MODE_ENABLED) { sprintf(aprefix,"%s.[%i].%s",ENB_CONFIG_STRING_ENB_LIST,k,ENB_CONFIG_STRING_SCTP_CONFIG); + config_get( SCTPParams,sizeof(SCTPParams)/sizeof(paramdef_t),aprefix); + S1AP_REGISTER_ENB_REQ (msg_p).sctp_in_streams = (uint16_t)*(SCTPParams[ENB_SCTP_INSTREAMS_IDX].uptr); S1AP_REGISTER_ENB_REQ (msg_p).sctp_out_streams = (uint16_t)*(SCTPParams[ENB_SCTP_OUTSTREAMS_IDX].uptr); } sprintf(aprefix,"%s.[%i].%s",ENB_CONFIG_STRING_ENB_LIST,k,ENB_CONFIG_STRING_NETWORK_INTERFACES_CONFIG); + // NETWORK_INTERFACES config_get( NETParams,sizeof(NETParams)/sizeof(paramdef_t),aprefix); - // S1AP_REGISTER_ENB_REQ (msg_p).enb_interface_name_for_S1U = strdup(enb_interface_name_for_S1U); + cidr = *(NETParams[ENB_IPV4_ADDRESS_FOR_S1_MME_IDX].strptr); address = strtok(cidr, "/"); S1AP_REGISTER_ENB_REQ (msg_p).enb_ip_address.ipv6 = 0; diff --git a/openair2/RRC/LTE/MESSAGES/asn1_msg.c b/openair2/RRC/LTE/MESSAGES/asn1_msg.c index d70550c82d..70bb3dda49 100644 --- a/openair2/RRC/LTE/MESSAGES/asn1_msg.c +++ b/openair2/RRC/LTE/MESSAGES/asn1_msg.c @@ -704,7 +704,7 @@ uint8_t do_SIB23(uint8_t Mod_id, = configuration->pcch_defaultPagingCycle[CC_id]; (*sib2)->radioResourceConfigCommon.pcch_Config.nB = configuration->pcch_nB[CC_id]; - LOG_E(RRC,"[SIB2] With ITTI. Basic config of paging cycle DRX: radio frame cycle length %x, paging occasion number %x\n", + LOG_I(RRC,"[SIB2] With ITTI. Basic config of paging cycle DRX: radio frame cycle length %x, paging occasion number %x\n", (uint32_t)configuration->pcch_defaultPagingCycle[CC_id], (uint32_t)configuration->pcch_nB[CC_id]); diff --git a/openair2/RRC/LTE/rrc_eNB.c b/openair2/RRC/LTE/rrc_eNB.c index 6beeb9e68c..8673567e6b 100644 --- a/openair2/RRC/LTE/rrc_eNB.c +++ b/openair2/RRC/LTE/rrc_eNB.c @@ -842,7 +842,6 @@ rrc_eNB_free_UE( const struct rrc_eNB_ue_context_s *const ue_context_pP) //----------------------------------------------------------------------------- { - //protocol_ctxt_t ctxt; // rm ? rnti_t rnti = ue_context_pP->ue_context.rnti; if (enb_mod_idP >= NB_eNB_INST) { @@ -853,8 +852,6 @@ rrc_eNB_free_UE( return; } - - //PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, enb_mod_idP, ENB_FLAG_YES, rnti, 0, 0, enb_mod_idP); // rm ? if (EPC_MODE_ENABLED) { if ((ue_context_pP->ue_context.ul_failure_timer >= 20000) && (mac_eNB_get_rrc_status(enb_mod_idP, rnti) >= RRC_CONNECTED)) { From 49f69810e9eb6e8ab7418e0e8d869d673c962159 Mon Sep 17 00:00:00 2001 From: "Wolfgang A. Mozart" Date: Sat, 27 Oct 2018 16:35:04 +0200 Subject: [PATCH 084/233] removing reference to uesoftmodem from load_configmodule (don't understand why this dependence is there in fist place. Also makes unitary sims break) --- common/config/config_load_configmodule.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/common/config/config_load_configmodule.c b/common/config/config_load_configmodule.c index 2c6700c73e..a41f395edd 100644 --- a/common/config/config_load_configmodule.c +++ b/common/config/config_load_configmodule.c @@ -201,13 +201,9 @@ int i; /* default */ if (cfgparam == NULL) { - tmpflags = tmpflags | CONFIG_NOOOPT; - if (strstr(argv[0],"uesoftmodem") == NULL) { - cfgparam = CONFIG_LIBCONFIGFILE ":" DEFAULT_CFGFILENAME; - } else { - cfgparam = CONFIG_CMDLINEONLY ":dbgl0" ; - } - } + tmpflags = tmpflags | CONFIG_NOOOPT; + cfgparam = CONFIG_CMDLINEONLY ":dbgl0" ; + } /* parse the config parameters to set the config source */ i = sscanf(cfgparam,"%m[^':']:%ms",&cfgmode,&modeparams); From d7e7d008068709efdc87694a3aa49cd7c3710d30 Mon Sep 17 00:00:00 2001 From: Florian Kaltenberger Date: Tue, 30 Oct 2018 15:11:01 +0100 Subject: [PATCH 085/233] removing use of a default config file --- common/config/config_load_configmodule.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/common/config/config_load_configmodule.c b/common/config/config_load_configmodule.c index a41f395edd..ea6dc3fa86 100644 --- a/common/config/config_load_configmodule.c +++ b/common/config/config_load_configmodule.c @@ -209,13 +209,13 @@ int i; i = sscanf(cfgparam,"%m[^':']:%ms",&cfgmode,&modeparams); if (i< 0) { fprintf(stderr,"[CONFIG] %s, %d, sscanf error parsing config source %s: %s\n", __FILE__, __LINE__,cfgparam, strerror(errno)); - exit(-1); + exit(-1) ; } else if ( i == 1 ) { /* -O argument doesn't contain ":" separator, assume -O option, default cfgmode to libconfig with one parameter, the path to the configuration file */ modeparams=cfgmode; - cfgmode=strdup(CONFIG_LIBCONFIGFILE); + cfgmode=NULL; //strdup(CONFIG_LIBCONFIGFILE); } cfgptr = malloc(sizeof(configmodule_interface_t)); From 2811dc7c0def3dd94424400bb6d99833a2986253 Mon Sep 17 00:00:00 2001 From: Florian Kaltenberger Date: Tue, 30 Oct 2018 15:11:50 +0100 Subject: [PATCH 086/233] adding params_libconfig to compilation of phy_simulators --- cmake_targets/build_oai | 3 +++ 1 file changed, 3 insertions(+) diff --git a/cmake_targets/build_oai b/cmake_targets/build_oai index 3954827c09..37f8d711db 100755 --- a/cmake_targets/build_oai +++ b/cmake_targets/build_oai @@ -651,6 +651,9 @@ function main() { compilations \ lte-simulators coding \ libcoding.so $dbin/libcoding.so + compilations \ + phy_simulators $config_libconfig_shlib \ + lib$config_libconfig_shlib.so $dbin/lib$config_libconfig_shlib.so fi # Core simulators From 18ec5d8047a33cf15eb5d0710d6c53e7e5f3e355 Mon Sep 17 00:00:00 2001 From: frtabu Date: Fri, 2 Nov 2018 15:58:01 +0100 Subject: [PATCH 087/233] abort execution when an unknown option is passed via the command line: add config_check_cmdlineopt API to config module, create lte-softmodem-common.c source to remove duplicate code in lte-softmodem.c and lte-uesoftmodem.c, fix segfaults in exec_function of lte-uesoftmodem --- cmake_targets/CMakeLists.txt | 5 +- common/config/config_cmdline.c | 44 ++- common/config/config_load_configmodule.c | 13 +- common/config/config_load_configmodule.h | 10 +- common/config/config_paramdesc.h | 3 +- common/config/config_userapi.c | 22 +- common/config/config_userapi.h | 4 +- common/utils/LOG/log.c | 26 +- common/utils/LOG/log.h | 12 +- openair2/ENB_APP/enb_config.c | 18 +- openair2/LAYER2/MAC/eNB_scheduler.c | 6 +- openair2/LAYER2/MAC/ue_procedures.c | 3 +- openair2/RRC/LTE/MESSAGES/asn1_msg.c | 374 ++---------------- openair3/NAS/UE/EMM/Authentication.c | 9 +- .../UE/EMM/SAP/EmmDeregisteredNormalService.c | 6 +- targets/COMMON/create_tasks.c | 4 +- targets/RT/USER/lte-ru.c | 26 +- targets/RT/USER/lte-softmodem-common.c | 126 ++++++ targets/RT/USER/lte-softmodem.c | 178 ++------- targets/RT/USER/lte-softmodem.h | 155 +++++--- targets/RT/USER/lte-ue.c | 17 +- targets/RT/USER/lte-uesoftmodem.c | 179 +++------ targets/RT/USER/rfsim.c | 1 - 23 files changed, 489 insertions(+), 752 deletions(-) create mode 100644 targets/RT/USER/lte-softmodem-common.c diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt index f205e3f5fa..143cd6fc7b 100644 --- a/cmake_targets/CMakeLists.txt +++ b/cmake_targets/CMakeLists.txt @@ -630,7 +630,6 @@ add_boolean_option(ENABLE_VCD True "always true now, time measurem add_boolean_option(ENABLE_VCD_FIFO True "time measurements of proc calls and var displays sent to FIFO (one more thread)") add_boolean_option(LINUX False "used in weird memcpy() in pdcp.c ???") add_boolean_option(LINUX_LIST False "used only in lists.c: either use OAI implementation of lists or Linux one (should be True, but it is False") -add_boolean_option(LOG_NO_THREAD True "Disable thread for log, seems always set to true") add_boolean_option(OPENAIR_LTE True "Seems legacy: keep it to true") ########################## @@ -1927,6 +1926,7 @@ add_executable(lte-softmodem ${OPENAIR_TARGETS}/RT/USER/lte-enb.c ${OPENAIR_TARGETS}/RT/USER/lte-ru.c ${OPENAIR_TARGETS}/RT/USER/lte-softmodem.c + ${OPENAIR_TARGETS}/RT/USER/lte-softmodem-common.c ${OPENAIR2_DIR}/ENB_APP/NB_IoT_interface.c ${OPENAIR1_DIR}/SIMULATION/TOOLS/taus.c ${OPENAIR_TARGETS}/COMMON/create_tasks.c @@ -1966,6 +1966,7 @@ add_executable(lte-softmodem-nos1 ${OPENAIR_TARGETS}/RT/USER/lte-enb.c ${OPENAIR_TARGETS}/RT/USER/lte-ru.c ${OPENAIR_TARGETS}/RT/USER/lte-softmodem.c + ${OPENAIR_TARGETS}/RT/USER/lte-softmodem-common.c ${OPENAIR2_DIR}/ENB_APP/NB_IoT_interface.c ${OPENAIR1_DIR}/SIMULATION/TOOLS/taus.c ${OPENAIR_TARGETS}/COMMON/create_tasks.c @@ -2003,6 +2004,7 @@ add_executable(lte-uesoftmodem ${OPENAIR_TARGETS}/RT/USER/rt_wrapper.c ${OPENAIR_TARGETS}/RT/USER/lte-ue.c ${OPENAIR_TARGETS}/RT/USER/lte-uesoftmodem.c + ${OPENAIR_TARGETS}/RT/USER/lte-softmodem-common.c ${OPENAIR_TARGETS}/RT/USER/lte-ru.c ${OPENAIR_TARGETS}/RT/USER/rfsim.c ${OPENAIR1_DIR}/SIMULATION/TOOLS/taus.c @@ -2041,6 +2043,7 @@ add_executable(lte-uesoftmodem-nos1 ${OPENAIR_TARGETS}/RT/USER/rt_wrapper.c ${OPENAIR_TARGETS}/RT/USER/lte-ue.c ${OPENAIR_TARGETS}/RT/USER/lte-uesoftmodem.c + ${OPENAIR_TARGETS}/RT/USER/lte-softmodem-common.c ${OPENAIR_TARGETS}/RT/USER/lte-ru.c ${OPENAIR_TARGETS}/RT/USER/rfsim.c ${OPENAIR1_DIR}/SIMULATION/TOOLS/taus.c diff --git a/common/config/config_cmdline.c b/common/config/config_cmdline.c index 3bd41cf6cc..c28cf33758 100644 --- a/common/config/config_cmdline.c +++ b/common/config/config_cmdline.c @@ -140,12 +140,43 @@ char defbool[2]="1"; return optisset; } +int config_check_cmdlineopt(char *prefix) +{ +int unknowndetected=0; +char testprefix[CONFIG_MAXOPTLENGTH]=""; +int finalcheck = 0; + + if (prefix != NULL) { + if (strcmp(prefix,CONFIG_CHECKALLSECTIONS) == 0) + finalcheck = 1; + else if (strlen(prefix) > 0) { + sprintf(testprefix,"--%s.",prefix); + } + } + + for (int i=1; iargc ; i++) { + if ( !finalcheck && strstr(config_get_if()->argv[i],testprefix) == NULL ) continue; + if ( !finalcheck && testprefix[0]==0 && index(config_get_if()->argv[i],'.') != NULL) continue; + if ( !finalcheck && config_get_if()->argv[i][0] == '-' && isdigit(config_get_if()->argv[i][1])) continue; + if ( (config_get_if()->argv_info[i] & CONFIG_CMDLINEOPT_PROCESSED) == 0 ) { + fprintf(stderr,"[CONFIG] unknown option: %s\n", + config_get_if()->argv[i] ); + unknowndetected++; + } + } + + + printf_cmdl("[CONFIG] %i unknown option(s) in command line starting with %s (section %s)\n", + unknowndetected,testprefix,((prefix==NULL)?"":prefix)); + return unknowndetected; +} /* parse_cmdline*/ + int config_process_cmdline(paramdef_t *cfgoptions,int numoptions, char *prefix) { int c = config_get_if()->argc; int i,j; char *pp; - char cfgpath[512]; /* 512 should be enough for the sprintf below */ + char cfgpath[CONFIG_MAXOPTLENGTH]; j = 0; i = 0; @@ -155,6 +186,7 @@ int config_process_cmdline(paramdef_t *cfgoptions,int numoptions, char *prefix) if (strncmp(oneargv, "-h",2) == 0 || strncmp(oneargv, "--help",6) == 0 ) { char *tokctx; pp=strtok_r(oneargv, "_",&tokctx); + config_get_if()->argv_info[i] |= CONFIG_CMDLINEOPT_PROCESSED; if (pp == NULL || strcasecmp(pp,config_get_if()->argv[i] ) == 0 ) { if( prefix == NULL) { config_printhelp(cfgoptions,numoptions); @@ -189,6 +221,7 @@ int config_process_cmdline(paramdef_t *cfgoptions,int numoptions, char *prefix) ((strlen(oneargv) > 2) && (strcmp(oneargv + 2,cfgpath ) == 0 )) ) { char *valptr=NULL; int ret; + config_get_if()->argv_info[i] |= CONFIG_CMDLINEOPT_PROCESSED; if (c > 0) { pp = config_get_if()->argv[i+1]; if (pp != NULL ) { @@ -204,6 +237,7 @@ int config_process_cmdline(paramdef_t *cfgoptions,int numoptions, char *prefix) j += processoption(&(cfgoptions[n]), valptr); if ( valptr != NULL ) { i++; + config_get_if()->argv_info[i] |= CONFIG_CMDLINEOPT_PROCESSED; c--; } break; @@ -215,5 +249,13 @@ int config_process_cmdline(paramdef_t *cfgoptions,int numoptions, char *prefix) c--; } /* fin du while */ printf_cmdl("[CONFIG] %s %i options set from command line\n",((prefix == NULL) ? "(root)":prefix),j); + if ( !(CONFIG_ISFLAGSET( CONFIG_NOCHECKUNKOPT )) ) { + i=config_check_cmdlineopt(prefix); + if (i > 0) { + fprintf(stderr,"[CONFIG] %i unknown options for section %s detected in command line\n", + i,((prefix==NULL)?"\"root section\"":prefix)); + exit_fun(" Exiting after detecting errors in command line \n"); + } + } return j; } /* parse_cmdline*/ diff --git a/common/config/config_load_configmodule.c b/common/config/config_load_configmodule.c index ea6dc3fa86..7c8c61135b 100644 --- a/common/config/config_load_configmodule.c +++ b/common/config/config_load_configmodule.c @@ -178,12 +178,14 @@ char *strtokctx=NULL; char *atoken; uint32_t tmpflags=0; int i; +int OoptIdx=-1; /* first parse the command line to look for the -O option */ for (i = 0;iargv_info = calloc(sizeof(int32_t), argc); + cfgptr->argv_info[0] |= CONFIG_CMDLINEOPT_PROCESSED; + if (OoptIdx >= 0) { + cfgptr->argv_info[OoptIdx] |= CONFIG_CMDLINEOPT_PROCESSED; + cfgptr->argv_info[OoptIdx+1] |= CONFIG_CMDLINEOPT_PROCESSED; + } cfgptr->rtflags = cfgptr->rtflags | tmpflags; cfgptr->argc = argc; diff --git a/common/config/config_load_configmodule.h b/common/config/config_load_configmodule.h index ff3fa80f4e..1f4ebde92d 100644 --- a/common/config/config_load_configmodule.h +++ b/common/config/config_load_configmodule.h @@ -37,6 +37,7 @@ #include #include #include "common/config/config_paramdesc.h" +#include "common/utils/T/T.h" #define CONFIG_MAX_OOPT_PARAMS 10 // maximum number of parameters in the -O option (-O :P1:P2... #define CONFIG_MAX_ALLOCATEDPTRS 1024 // maximum number of parameters that can be dynamicaly allocated in the config module @@ -44,12 +45,14 @@ #define CONFIG_LIBCONFIGFILE "libconfig" // use libconfig file #define CONFIG_CMDLINEONLY "cmdline" // use only command line options #define DEFAULT_CFGFILENAME "oai.conf" // default config file - -/* rtflags bit position definitions */ +/* bit position definition for the argv_info mask of the configmodule_interface_t structure */ +#define CONFIG_CMDLINEOPT_PROCESSED (1<<0) // command line option has been processed +/* bit position definitions for the rtflags mask of the configmodule_interface_t structure*/ #define CONFIG_PRINTPARAMS 1 // print parameters values while processing #define CONFIG_DEBUGPTR (1<<1) // print memory allocation/free debug messages #define CONFIG_DEBUGCMDLINE (1<<2) // print command line processing messages -#define CONFIG_NOABORTONCHKF (1<<3) // disable abort execution when parameter checking function fails +#define CONFIG_NOCHECKUNKOPT (1<<3) // disable check unprocessed (so invalid) command line options +#define CONFIG_NOABORTONCHKF (1<<4) // disable abort execution when parameter checking function fails #define CONFIG_NOEXITONHELP (1<<19) // do not exit after printing help #define CONFIG_HELP (1<<20) // print help message #define CONFIG_ABORT (1<<21) // config failed,abort execution @@ -62,6 +65,7 @@ typedef struct configmodule_interface { int argc; char **argv; + uint32_t *argv_info; char *cfgmode; int num_cfgP; char *cfgP[CONFIG_MAX_OOPT_PARAMS]; diff --git a/common/config/config_paramdesc.h b/common/config/config_paramdesc.h index c65e298dfb..60ab00a5ed 100644 --- a/common/config/config_paramdesc.h +++ b/common/config/config_paramdesc.h @@ -38,7 +38,7 @@ #define MAX_OPTNAME_SIZE 64 - +#define CONFIG_MAXOPTLENGTH 512 /* max full option length, full option name exemple: (prefix1.[].prefix2.optname */ /* parameter flags definitions */ @@ -55,7 +55,6 @@ #define PARAMFLAG_PARAMSET (1 << 16) // parameter has been explicitely set in get functions #define PARAMFLAG_PARAMSETDEF (1 << 17) // parameter has been set to default value in get functions - /* checkedparam_t is possibly used in paramdef_t for specific parameter value validation */ #define CONFIG_MAX_NUMCHECKVAL 20 typedef struct paramdef paramdef_t; diff --git a/common/config/config_userapi.c b/common/config/config_userapi.c index 0ec2e23790..d6e4beeaf5 100644 --- a/common/config/config_userapi.c +++ b/common/config/config_userapi.c @@ -197,20 +197,20 @@ int config_get(paramdef_t *params,int numparams, char *prefix) { int ret= -1; -if (CONFIG_ISFLAGSET(CONFIG_ABORT)) { + if (CONFIG_ISFLAGSET(CONFIG_ABORT)) { fprintf(stderr,"[CONFIG] config_get, section %s skipped, config module not properly initialized\n",prefix); return ret; -} -configmodule_interface_t *cfgif = config_get_if(); - if (cfgif != NULL) { - ret = config_get_if()->get(params, numparams,prefix); - if (ret >= 0) { - config_process_cmdline(params,numparams,prefix); - config_execcheck(params,numparams,prefix); - } - return ret; } -return ret; + configmodule_interface_t *cfgif = config_get_if(); + if (cfgif != NULL) { + ret = config_get_if()->get(params, numparams,prefix); + if (ret >= 0) { + config_process_cmdline(params,numparams,prefix); + config_execcheck(params,numparams,prefix); + } + return ret; + } + return ret; } int config_getlist(paramlist_def_t *ParamList, paramdef_t *params, int numparams, char *prefix) diff --git a/common/config/config_userapi.h b/common/config/config_userapi.h index 2b40f8401b..f4b592bafb 100644 --- a/common/config/config_userapi.h +++ b/common/config/config_userapi.h @@ -55,7 +55,9 @@ extern void config_assign_processedint(paramdef_t *cfgoption, int val); extern void config_assign_int(paramdef_t *cfgoptions, char *fullname, int val); extern int config_assign_ipv4addr(paramdef_t *cfgoptions, char *ipv4addr); -/* apis to get parameters, to be used by oai modules, at configuration time */ +/* apis to get/check parameters, to be used by oai modules, at configuration time */ +#define CONFIG_CHECKALLSECTIONS "ALLSECTIONS" +extern int config_check_cmdlineopt(char *prefix); extern int config_get(paramdef_t *params,int numparams, char *prefix); extern int config_getlist(paramlist_def_t *ParamList, paramdef_t *params, int numparams, char *prefix); diff --git a/common/utils/LOG/log.c b/common/utils/LOG/log.c index d6dd97e34f..a65aa1e4a5 100644 --- a/common/utils/LOG/log.c +++ b/common/utils/LOG/log.c @@ -39,9 +39,6 @@ #include "vcd_signal_dumper.h" #include "assertions.h" -#if defined(ENABLE_ITTI) -# include "intertask_interface.h" -#endif # include # include @@ -242,7 +239,7 @@ void log_getconfig(log_t *g_log) { paramdef_t logparams_logfile[MAX_LOG_PREDEF_COMPONENTS]; paramdef_t logparams_debug[sizeof(log_maskmap)/sizeof(mapping)]; paramdef_t logparams_dump[sizeof(log_maskmap)/sizeof(mapping)]; - + CONFIG_SETRTFLAG(CONFIG_NOCHECKUNKOPT); int ret = config_get( logparams_defaults,sizeof(logparams_defaults)/sizeof(paramdef_t),CONFIG_STRING_LOG_PREFIX); if (ret <0) { fprintf(stderr,"[LOG] init aborted, configuration couldn't be performed"); @@ -319,6 +316,7 @@ void log_getconfig(log_t *g_log) { logparams_dump[i].numelt = 0; } config_get( logparams_debug,(sizeof(log_maskmap)/sizeof(mapping)) - 1 ,CONFIG_STRING_LOG_PREFIX); + CONFIG_CLEARRTFLAG(CONFIG_NOCHECKUNKOPT); config_get( logparams_dump,(sizeof(log_maskmap)/sizeof(mapping)) - 1 ,CONFIG_STRING_LOG_PREFIX); /* set the debug mask according to the debug parameters values */ for (int i=0; log_maskmap[i].name != NULL ; i++) { @@ -358,6 +356,14 @@ int computed_compidx=compidx; return computed_compidx; } +int isLogInitDone (void){ + if (g_log == NULL) + return 0; + if (!(g_log->flag & FLAG_INITIALIZED)) + return 0; + return 1; +} + int logInit (void) { int i; @@ -437,6 +443,7 @@ int logInit (void) for (i=MAX_LOG_PREDEF_COMPONENTS; i < MAX_LOG_COMPONENTS; i++) { memset(&(g_log->log_component[i]),0,sizeof(log_component_t)); } + g_log->flag = g_log->flag | FLAG_INITIALIZED; printf("log init done\n"); return 0; @@ -656,13 +663,12 @@ int is_newline( char *str, int size) void logClean (void) { int i; - LOG_UI(PHY,"\n"); - - - - for (i=MIN_LOG_COMPONENTS; i < MAX_LOG_COMPONENTS; i++) { - close_component_filelog(i); + if(isLogInitDone()) { + LOG_UI(PHY,"\n"); + for (i=MIN_LOG_COMPONENTS; i < MAX_LOG_COMPONENTS; i++) { + close_component_filelog(i); + } } } diff --git a/common/utils/LOG/log.h b/common/utils/LOG/log.h index 767c1dbb35..2a7a51a0a6 100644 --- a/common/utils/LOG/log.h +++ b/common/utils/LOG/log.h @@ -115,12 +115,11 @@ extern "C" { * @{*/ -#define FLAG_NOCOLOR 0x0001 /*!< \brief use colors in log messages, depending on level */ -#define FLAG_THREAD 0x0008 /*!< \brief display thread name in log messages */ -#define FLAG_LEVEL 0x0010 /*!< \brief display log level in log messages */ -#define FLAG_FUNCT 0x0020 -#define FLAG_FILE_LINE 0x0040 -#define FLAG_TIME 0x0100 +#define FLAG_NOCOLOR 0x0001 /*!< \brief use colors in log messages, depending on level */ +#define FLAG_THREAD 0x0008 /*!< \brief display thread name in log messages */ +#define FLAG_LEVEL 0x0010 /*!< \brief display log level in log messages */ +#define FLAG_TIME 0x0100 +#define FLAG_INITIALIZED 0x8000 #define SET_LOG_OPTION(O) g_log->flag = (g_log->flag | O) #define CLEAR_LOG_OPTION(O) g_log->flag = (g_log->flag & (~O)) @@ -283,6 +282,7 @@ extern log_t *g_log; # include "log_if.h" /*----------------------------------------------------------------------------*/ int logInit (void); +int isLogInitDone (void); void logRecord_mt(const char *file, const char *func, int line,int comp, int level, const char *format, ...) __attribute__ ((format (printf, 6, 7))); void log_dump(int component, void *buffer, int buffsize,int datatype, const char* format, ... ); int set_log(int component, int level); diff --git a/openair2/ENB_APP/enb_config.c b/openair2/ENB_APP/enb_config.c index 74494ba818..9cbfb8741e 100644 --- a/openair2/ENB_APP/enb_config.c +++ b/openair2/ENB_APP/enb_config.c @@ -289,7 +289,7 @@ void RCconfig_L1(void) { } }// j=0..num_inst - printf("Initializing northbound interface for L1\n"); + LOG_I(ENB_APP,"Initializing northbound interface for L1\n"); l1_north_init_eNB(); } else { LOG_I(PHY,"No " CONFIG_STRING_L1_LIST " configuration found"); @@ -360,16 +360,16 @@ void RCconfig_macrlc() { RC.mac[j]->eth_params_s.remote_portd = *(MacRLC_ParamList.paramarray[j][MACRLC_REMOTE_S_PORTD_IDX].iptr); RC.mac[j]->eth_params_s.transp_preference = ETH_UDP_MODE; sf_ahead = 2; // Cannot cope with 4 subframes betweem RX and TX - set it to 2 - printf("**************** vnf_port:%d\n", RC.mac[j]->eth_params_s.my_portc); + LOG_I(ENB_APP,"**************** vnf_port:%d\n", RC.mac[j]->eth_params_s.my_portc); configure_nfapi_vnf(RC.mac[j]->eth_params_s.my_addr, RC.mac[j]->eth_params_s.my_portc); - printf("**************** RETURNED FROM configure_nfapi_vnf() vnf_port:%d\n", RC.mac[j]->eth_params_s.my_portc); + LOG_I(ENB_APP,"**************** RETURNED FROM configure_nfapi_vnf() vnf_port:%d\n", RC.mac[j]->eth_params_s.my_portc); } else { // other midhaul AssertFatal(1==0,"MACRLC %d: %s unknown southbound midhaul\n",j,*(MacRLC_ParamList.paramarray[j][MACRLC_TRANSPORT_S_PREFERENCE_IDX].strptr)); } if (strcmp(*(MacRLC_ParamList.paramarray[j][MACRLC_SCHED_MODE_IDX].strptr), "default") == 0) { global_scheduler_mode=SCHED_MODE_DEFAULT; - printf("sched mode = default %d [%s]\n",global_scheduler_mode,*(MacRLC_ParamList.paramarray[j][MACRLC_SCHED_MODE_IDX].strptr)); + LOG_I(ENB_APP,"sched mode = default %d [%s]\n",global_scheduler_mode,*(MacRLC_ParamList.paramarray[j][MACRLC_SCHED_MODE_IDX].strptr)); } else if (strcmp(*(MacRLC_ParamList.paramarray[j][MACRLC_SCHED_MODE_IDX].strptr), "fairRR") == 0) { global_scheduler_mode=SCHED_MODE_FAIR_RR; printf("sched mode = fairRR %d [%s]\n",global_scheduler_mode,*(MacRLC_ParamList.paramarray[j][MACRLC_SCHED_MODE_IDX].strptr)); @@ -550,7 +550,7 @@ int RCconfig_RRC(MessageDef *msg_p, uint32_t i, eNB_RRC_INST *rrc) { enb_id = *(ENBParamList.paramarray[i][ENB_ENB_ID_IDX].uptr); } - printf("RRC %d: Southbound Transport %s\n",i,*(ENBParamList.paramarray[i][ENB_TRANSPORT_S_PREFERENCE_IDX].strptr)); + LOG_I(ENB_APP,"RRC %d: Southbound Transport %s\n",i,*(ENBParamList.paramarray[i][ENB_TRANSPORT_S_PREFERENCE_IDX].strptr)); if (strcmp(*(ENBParamList.paramarray[i][ENB_TRANSPORT_S_PREFERENCE_IDX].strptr), "local_mac") == 0) { } else if (strcmp(*(ENBParamList.paramarray[i][ENB_TRANSPORT_S_PREFERENCE_IDX].strptr), "cudu") == 0) { @@ -2494,8 +2494,7 @@ int RCconfig_X2(MessageDef *msg_p, uint32_t i) { int RCconfig_parallel(void) { char *parallel_conf = NULL; char *worker_conf = NULL; - extern char *parallel_config; - extern char *worker_config; + paramdef_t ThreadParams[] = THREAD_CONF_DESC; paramlist_def_t THREADParamList = {THREAD_CONFIG_STRING_THREAD_STRUCT,NULL,0}; config_getlist( &THREADParamList,NULL,0,NULL); @@ -2514,9 +2513,10 @@ int RCconfig_parallel(void) { worker_conf = strdup("WORKER_ENABLE"); } - if(parallel_config == NULL) set_parallel_conf(parallel_conf); - if(worker_config == NULL) set_worker_conf(worker_conf); + set_parallel_conf(parallel_conf); + set_worker_conf(worker_conf); + return 0; } diff --git a/openair2/LAYER2/MAC/eNB_scheduler.c b/openair2/LAYER2/MAC/eNB_scheduler.c index 866855c456..8648fa5771 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler.c +++ b/openair2/LAYER2/MAC/eNB_scheduler.c @@ -30,7 +30,7 @@ */ #include "assertions.h" - +#include "targets/RT/USER/lte-softmodem.h" #include "LAYER2/MAC/mac.h" #include "LAYER2/MAC/mac_extern.h" @@ -64,7 +64,7 @@ #define DEBUG_eNB_SCHEDULER 1 extern RAN_CONTEXT_t RC; -extern int phy_test; + uint16_t pdcch_order_table[6] = { 31, 31, 511, 2047, 2047, 8191 }; @@ -660,7 +660,7 @@ eNB_dlsch_ulsch_scheduler(module_id_t module_idP, frame_t frameP, if ((subframeP == 0) && (frameP & 3) == 0) schedule_mib(module_idP, frameP, subframeP); - if (phy_test == 0){ + if (get_softmodem_params()->phy_test == 0){ // This schedules SI for legacy LTE and eMTC starting in subframeP schedule_SI(module_idP, frameP, subframeP); // This schedules Paging in subframeP diff --git a/openair2/LAYER2/MAC/ue_procedures.c b/openair2/LAYER2/MAC/ue_procedures.c index 3d86187e88..207815b122 100644 --- a/openair2/LAYER2/MAC/ue_procedures.c +++ b/openair2/LAYER2/MAC/ue_procedures.c @@ -65,7 +65,6 @@ #define DEBUG_HEADER_PARSING 1 #define ENABLE_MAC_PAYLOAD_DEBUG 1 -extern uint8_t usim_test; extern UL_IND_t *UL_INFO; @@ -2020,7 +2019,7 @@ ue_get_sdu(module_id_t module_idP, int CC_id, frame_t frameP, { // Workaround for issue in OAI eNB or EPC which are not able to process SRB2 message multiplexed with SRB1 on the same MAC PDU - if ((usim_test == 0) && (lcid == DCCH1) + if (( get_softmodem_params()->usim_test == 0) && (lcid == DCCH1) && (lcid_rlc_pdu_count == 0) && (num_sdus)) { // Skip SRB2 multiplex if at least one SRB1 SDU is already multiplexed diff --git a/openair2/RRC/LTE/MESSAGES/asn1_msg.c b/openair2/RRC/LTE/MESSAGES/asn1_msg.c index 8d0992f17a..02f0e059e0 100644 --- a/openair2/RRC/LTE/MESSAGES/asn1_msg.c +++ b/openair2/RRC/LTE/MESSAGES/asn1_msg.c @@ -39,7 +39,7 @@ #include #include /* for _ASN_DEFAULT_STACK_MAX */ #include - +#include "targets/RT/USER/lte-softmodem.h" #include "assertions.h" #include "LTE_RRCConnectionRequest.h" #include "LTE_UL-CCCH-Message.h" @@ -99,7 +99,7 @@ typedef struct xer_sprint_string_s { } xer_sprint_string_t; extern unsigned char NB_eNB_INST; -extern uint8_t usim_test; + extern RAN_CONTEXT_t RC; @@ -247,26 +247,7 @@ uint8_t do_MIB(rrc_eNB_carrier_data_t *carrier, uint32_t N_RB_DL, uint32_t phich AssertFatal (enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %lu)!\n", enc_rval.failed_type->name, enc_rval.encoded); - /* -#if defined(ENABLE_ITTI) -# if !defined(DISABLE_XER_SPRINT) - { - char message_string[20000]; - size_t message_string_size; - if ((message_string_size = xer_sprint(message_string, sizeof(message_string), &asn_DEF_BCCH_BCH_Message, (void *) &mib)) > 0) { - MessageDef *msg_p; - - msg_p = itti_alloc_new_message_sized (TASK_RRC_ENB, RRC_DL_BCCH, message_string_size + sizeof (IttiMsgText)); - msg_p->ittiMsg.rrc_dl_bcch.size = message_string_size; - memcpy(&msg_p->ittiMsg.rrc_dl_bcch.text, message_string, message_string_size); - - itti_send_msg_to_task(TASK_UNKNOWN, enb_module_idP, msg_p); - } - } -# endif -#endif - */ if (enc_rval.encoded==-1) { return(-1); } @@ -470,7 +451,7 @@ uint8_t do_SIB1(rrc_eNB_carrier_data_t *carrier, (*sib1)->cellSelectionInfo.q_RxLevMin=-65; (*sib1)->cellSelectionInfo.q_RxLevMinOffset=NULL; //(*sib1)->p_Max = CALLOC(1, sizeof(P_Max_t)); - //*((*sib1)->p_Max) = 23; + // *((*sib1)->p_Max) = 23; (*sib1)->freqBandIndicator = #if defined(ENABLE_ITTI) configuration->eutra_band[CC_id]; @@ -513,9 +494,10 @@ uint8_t do_SIB1(rrc_eNB_carrier_data_t *carrier, (*sib1)->systemInfoValueTag=0; // (*sib1).nonCriticalExtension = calloc(1,sizeof(*(*sib1).nonCriticalExtension)); -#ifdef XER_PRINT - xer_fprint(stdout, &asn_DEF_BCCH_DL_SCH_Message, (void*)bcch_message); -#endif + if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) { + xer_fprint(stdout, &asn_DEF_LTE_BCCH_DL_SCH_Message, (void*)bcch_message); + } + enc_rval = uper_encode_to_buffer(&asn_DEF_LTE_BCCH_DL_SCH_Message, NULL, (void*)bcch_message, @@ -524,23 +506,7 @@ uint8_t do_SIB1(rrc_eNB_carrier_data_t *carrier, AssertFatal (enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %lu)!\n", enc_rval.failed_type->name, enc_rval.encoded); -#if defined(ENABLE_ITTI) -# if !defined(DISABLE_XER_SPRINT) - { - char message_string[10000]; - size_t message_string_size; - if ((message_string_size = xer_sprint(message_string, sizeof(message_string), &asn_DEF_LTE_BCCH_DL_SCH_Message, (void *)bcch_message)) > 0) { - MessageDef *msg_p; - - msg_p = itti_alloc_new_message_sized (TASK_RRC_ENB, RRC_DL_BCCH, message_string_size + sizeof (IttiMsgText)); - msg_p->ittiMsg.rrc_dl_bcch.size = message_string_size; - memcpy(&msg_p->ittiMsg.rrc_dl_bcch.text, message_string, message_string_size); - itti_send_msg_to_task(TASK_UNKNOWN, Mod_id, msg_p); - } - } -# endif -#endif LOG_D(RRC,"[eNB] SystemInformationBlockType1 Encoded %zd bits (%zd bytes)\n",enc_rval.encoded,(enc_rval.encoded+7)/8); @@ -1371,24 +1337,6 @@ uint8_t do_SIB23(uint8_t Mod_id, enc_rval.failed_type->name, enc_rval.encoded); -#if defined(ENABLE_ITTI) -# if !defined(DISABLE_XER_SPRINT) - { - char message_string[15000]; - size_t message_string_size; - - if ((message_string_size = xer_sprint(message_string, sizeof(message_string), &asn_DEF_LTE_BCCH_DL_SCH_Message, (void *)bcch_message)) > 0) { - MessageDef *msg_p; - - msg_p = itti_alloc_new_message_sized (TASK_RRC_ENB, RRC_DL_BCCH, message_string_size + sizeof (IttiMsgText)); - msg_p->ittiMsg.rrc_dl_bcch.size = message_string_size; - memcpy(&msg_p->ittiMsg.rrc_dl_bcch.text, message_string, message_string_size); - - itti_send_msg_to_task(TASK_UNKNOWN, Mod_id, msg_p); - } - } -# endif -#endif LOG_D(RRC,"[eNB] SystemInformation Encoded %zd bits (%zd bytes)\n",enc_rval.encoded,(enc_rval.encoded+7)/8); @@ -1449,7 +1397,9 @@ uint8_t do_RRCConnectionRequest(uint8_t Mod_id, uint8_t *buffer,uint8_t *rv) rrcConnectionRequest->criticalExtensions.choice.rrcConnectionRequest_r8.spare.size=1; rrcConnectionRequest->criticalExtensions.choice.rrcConnectionRequest_r8.spare.bits_unused = 7; - + if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) { + xer_fprint(stdout, &asn_DEF_LTE_UL_CCCH_Message, (void*)&ul_ccch_msg); + } enc_rval = uper_encode_to_buffer(&asn_DEF_LTE_UL_CCCH_Message, NULL, (void*)&ul_ccch_msg, @@ -1458,24 +1408,6 @@ uint8_t do_RRCConnectionRequest(uint8_t Mod_id, uint8_t *buffer,uint8_t *rv) AssertFatal (enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %lu)!\n", enc_rval.failed_type->name, enc_rval.encoded); -#if defined(ENABLE_ITTI) -# if !defined(DISABLE_XER_SPRINT) - { - char message_string[20000]; - size_t message_string_size; - - if ((message_string_size = xer_sprint(message_string, sizeof(message_string), &asn_DEF_LTE_UL_CCCH_Message, (void *) &ul_ccch_msg)) > 0) { - MessageDef *msg_p; - - msg_p = itti_alloc_new_message_sized (TASK_RRC_UE, RRC_UL_CCCH, message_string_size + sizeof (IttiMsgText)); - msg_p->ittiMsg.rrc_ul_ccch.size = message_string_size; - memcpy(&msg_p->ittiMsg.rrc_ul_ccch.text, message_string, message_string_size); - - itti_send_msg_to_task(TASK_UNKNOWN, NB_eNB_INST + Mod_id, msg_p); - } - } -# endif -#endif LOG_D(RRC,"[UE] RRCConnectionRequest Encoded %zd bits (%zd bytes) \n",enc_rval.encoded,(enc_rval.encoded+7)/8); @@ -1626,28 +1558,9 @@ uint8_t do_SidelinkUEInformation(uint8_t Mod_id, uint8_t *buffer, LTE_SL_Destin AssertFatal (enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %lu)!\n", enc_rval.failed_type->name, enc_rval.encoded); -#if defined(ENABLE_ITTI) -# if !defined(DISABLE_XER_SPRINT) - { - char message_string[20000]; - size_t message_string_size; - if ((message_string_size = xer_sprint(message_string, sizeof(message_string), &asn_DEF_LTE_UL_DCCH_Message, (void *) &ul_dcch_msg)) > 0) { - MessageDef *msg_p; + LOG_D(RRC,"SidelinkUEInformation Encoded %d bits (%d bytes)\n",(uint32_t)enc_rval.encoded,(uint32_t)((enc_rval.encoded+7)/8)); - msg_p = itti_alloc_new_message_sized (TASK_RRC_UE, RRC_UL_DCCH, message_string_size + sizeof (IttiMsgText)); - msg_p->ittiMsg.rrc_ul_dcch.size = message_string_size; - memcpy(&msg_p->ittiMsg.rrc_ul_dcch.text, message_string, message_string_size); - - itti_send_msg_to_task(TASK_UNKNOWN, NB_eNB_INST + Mod_id, msg_p); - } - } -# endif -#endif - -#ifdef USER_MODE - LOG_D(RRC,"SidelinkUEInformation Encoded %d bits (%d bytes)\n",enc_rval.encoded,(enc_rval.encoded+7)/8); -#endif return((enc_rval.encoded+7)/8); @@ -1699,7 +1612,9 @@ uint8_t do_RRCConnectionSetupComplete(uint8_t Mod_id, uint8_t *buffer, const uin rrcConnectionSetupComplete->criticalExtensions.choice.c1.choice.rrcConnectionSetupComplete_r8.registeredMME->mmec.size=1; rrcConnectionSetupComplete->criticalExtensions.choice.c1.choice.rrcConnectionSetupComplete_r8.registeredMME->mmec.bits_unused=0; */ - + if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) { + xer_fprint(stdout, &asn_DEF_LTE_UL_DCCH_Message, (void*)&ul_dcch_msg); + } enc_rval = uper_encode_to_buffer(&asn_DEF_LTE_UL_DCCH_Message, NULL, (void*)&ul_dcch_msg, @@ -1708,24 +1623,6 @@ uint8_t do_RRCConnectionSetupComplete(uint8_t Mod_id, uint8_t *buffer, const uin AssertFatal (enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %lu)!\n", enc_rval.failed_type->name, enc_rval.encoded); -#if defined(ENABLE_ITTI) -# if !defined(DISABLE_XER_SPRINT) - { - char message_string[20000]; - size_t message_string_size; - - if ((message_string_size = xer_sprint(message_string, sizeof(message_string), &asn_DEF_LTE_UL_DCCH_Message, (void *) &ul_dcch_msg)) > 0) { - MessageDef *msg_p; - - msg_p = itti_alloc_new_message_sized (TASK_RRC_UE, RRC_UL_DCCH, message_string_size + sizeof (IttiMsgText)); - msg_p->ittiMsg.rrc_ul_dcch.size = message_string_size; - memcpy(&msg_p->ittiMsg.rrc_ul_dcch.text, message_string, message_string_size); - - itti_send_msg_to_task(TASK_UNKNOWN, NB_eNB_INST + Mod_id, msg_p); - } - } -# endif -#endif LOG_D(RRC,"RRCConnectionSetupComplete Encoded %zd bits (%zd bytes)\n",enc_rval.encoded,(enc_rval.encoded+7)/8); @@ -1760,7 +1657,9 @@ do_RRCConnectionReconfigurationComplete( rrcConnectionReconfigurationComplete->criticalExtensions.present = LTE_RRCConnectionReconfigurationComplete__criticalExtensions_PR_rrcConnectionReconfigurationComplete_r8; rrcConnectionReconfigurationComplete->criticalExtensions.choice.rrcConnectionReconfigurationComplete_r8.nonCriticalExtension=NULL; - + if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) { + xer_fprint(stdout, &asn_DEF_LTE_UL_DCCH_Message, (void*)&ul_dcch_msg); + } enc_rval = uper_encode_to_buffer(&asn_DEF_LTE_UL_DCCH_Message, NULL, (void*)&ul_dcch_msg, @@ -1769,24 +1668,6 @@ do_RRCConnectionReconfigurationComplete( AssertFatal (enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %lu)!\n", enc_rval.failed_type->name, enc_rval.encoded); -#if defined(ENABLE_ITTI) -# if !defined(DISABLE_XER_SPRINT) - { - char message_string[20000]; - size_t message_string_size; - - if ((message_string_size = xer_sprint(message_string, sizeof(message_string), &asn_DEF_LTE_UL_DCCH_Message, (void *) &ul_dcch_msg)) > 0) { - MessageDef *msg_p; - - msg_p = itti_alloc_new_message_sized (TASK_RRC_UE, RRC_UL_DCCH, message_string_size + sizeof (IttiMsgText)); - msg_p->ittiMsg.rrc_ul_dcch.size = message_string_size; - memcpy(&msg_p->ittiMsg.rrc_ul_dcch.text, message_string, message_string_size); - - itti_send_msg_to_task(TASK_UNKNOWN, ctxt_pP->instance, msg_p); - } - } -# endif -#endif LOG_D(RRC,"RRCConnectionReconfigurationComplete Encoded %zd bits (%zd bytes)\n",enc_rval.encoded,(enc_rval.encoded+7)/8); @@ -2182,24 +2063,7 @@ do_RRCConnectionSetup( enc_rval.failed_type->name, enc_rval.encoded); return -1; } -#if defined(ENABLE_ITTI) -# if !defined(DISABLE_XER_SPRINT) - { - char message_string[20000]; - size_t message_string_size; - if ((message_string_size = xer_sprint(message_string, sizeof(message_string), &asn_DEF_LTE_DL_CCCH_Message, (void *) &dl_ccch_msg)) > 0) { - MessageDef *msg_p; - - msg_p = itti_alloc_new_message_sized (TASK_RRC_ENB, RRC_DL_CCCH, message_string_size + sizeof (IttiMsgText)); - msg_p->ittiMsg.rrc_dl_ccch.size = message_string_size; - memcpy(&msg_p->ittiMsg.rrc_dl_ccch.text, message_string, message_string_size); - - itti_send_msg_to_task(TASK_UNKNOWN, ctxt_pP->instance, msg_p); - } - } -# endif -#endif LOG_D(RRC,"RRCConnectionSetup Encoded %zd bits (%zd bytes) \n", enc_rval.encoded,(enc_rval.encoded+7)/8); @@ -2257,24 +2121,7 @@ do_SecurityModeCommand( enc_rval.failed_type->name, enc_rval.encoded); return -1; } -#if defined(ENABLE_ITTI) -# if !defined(DISABLE_XER_SPRINT) - { - char message_string[20000]; - size_t message_string_size; - if ((message_string_size = xer_sprint(message_string, sizeof(message_string), &asn_DEF_LTE_DL_DCCH_Message, (void *) &dl_dcch_msg)) > 0) { - MessageDef *msg_p; - - msg_p = itti_alloc_new_message_sized (TASK_RRC_ENB, RRC_DL_DCCH, message_string_size + sizeof (IttiMsgText)); - msg_p->ittiMsg.rrc_dl_dcch.size = message_string_size; - memcpy(&msg_p->ittiMsg.rrc_dl_dcch.text, message_string, message_string_size); - - itti_send_msg_to_task(TASK_UNKNOWN, ctxt_pP->instance, msg_p); - } - } -# endif -#endif LOG_D(RRC,"[eNB %d] securityModeCommand for UE %x Encoded %zd bits (%zd bytes)\n", ctxt_pP->module_id, @@ -2337,24 +2184,6 @@ do_UECapabilityEnquiry( enc_rval.failed_type->name, enc_rval.encoded); return -1; } -#if defined(ENABLE_ITTI) -# if !defined(DISABLE_XER_SPRINT) - { - char message_string[20000]; - size_t message_string_size; - - if ((message_string_size = xer_sprint(message_string, sizeof(message_string), &asn_DEF_LTE_DL_DCCH_Message, (void *) &dl_dcch_msg)) > 0) { - MessageDef *msg_p; - - msg_p = itti_alloc_new_message_sized (TASK_RRC_ENB, RRC_DL_CCCH, message_string_size + sizeof (IttiMsgText)); - msg_p->ittiMsg.rrc_dl_ccch.size = message_string_size; - memcpy(&msg_p->ittiMsg.rrc_dl_ccch.text, message_string, message_string_size); - - itti_send_msg_to_task(TASK_UNKNOWN, ctxt_pP->instance, msg_p); - } - } -# endif -#endif LOG_D(RRC,"[eNB %d] UECapabilityRequest for UE %x Encoded %zd bits (%zd bytes)\n", ctxt_pP->module_id, @@ -2546,24 +2375,6 @@ do_RRCConnectionReconfiguration( xer_fprint(stdout,&asn_DEF_LTE_DL_DCCH_Message,(void*)&dl_dcch_msg); } -#if defined(ENABLE_ITTI) -# if !defined(DISABLE_XER_SPRINT) - { - char message_string[30000]; - size_t message_string_size; - - if ((message_string_size = xer_sprint(message_string, sizeof(message_string), &asn_DEF_LTE_DL_DCCH_Message, (void *) &dl_dcch_msg)) > 0) { - MessageDef *msg_p; - - msg_p = itti_alloc_new_message_sized (TASK_RRC_ENB, RRC_DL_DCCH, message_string_size + sizeof (IttiMsgText)); - msg_p->ittiMsg.rrc_dl_dcch.size = message_string_size; - memcpy(&msg_p->ittiMsg.rrc_dl_dcch.text, message_string, message_string_size); - - itti_send_msg_to_task(TASK_UNKNOWN, ctxt_pP->instance, msg_p); - } - } -# endif -#endif LOG_I(RRC,"RRCConnectionReconfiguration Encoded %zd bits (%zd bytes)\n",enc_rval.encoded,(enc_rval.encoded+7)/8); // for (i=0;i<30;i++) @@ -2755,33 +2566,10 @@ do_RRCConnectionReestablishment( 100); if(enc_rval.encoded == -1) { - LOG_I(RRC, "[eNB AssertFatal]ASN1 message encoding failed (%s, %lu)!\n", + LOG_E(RRC, "[eNB AssertFatal]ASN1 message encoding failed (%s, %lu)!\n", enc_rval.failed_type->name, enc_rval.encoded); return -1; } -#if defined(ENABLE_ITTI) -# if !defined(DISABLE_XER_SPRINT) - { - char message_string[20000]; - size_t message_string_size; - - if ((message_string_size = xer_sprint(message_string, sizeof(message_string), &asn_DEF_LTE_DL_CCCH_Message, (void *) &dl_ccch_msg)) > 0) { - MessageDef *msg_p; - - msg_p = itti_alloc_new_message_sized (TASK_RRC_ENB, RRC_DL_CCCH, message_string_size + sizeof (IttiMsgText)); - msg_p->ittiMsg.rrc_dl_ccch.size = message_string_size; - memcpy(&msg_p->ittiMsg.rrc_dl_ccch.text, message_string, message_string_size); - - itti_send_msg_to_task(TASK_UNKNOWN, ctxt_pP->instance, msg_p); - } - } -# endif -#endif - -#ifdef USER_MODE - LOG_D(RRC,"RRCConnectionReestablishment Encoded %zd bits (%zd bytes)\n", - enc_rval.encoded,(enc_rval.encoded+7)/8); -#endif return((enc_rval.encoded+7)/8); } @@ -2817,28 +2605,11 @@ do_RRCConnectionReestablishmentReject( 100); if(enc_rval.encoded == -1) { - LOG_I(RRC, "[eNB AssertFatal]ASN1 message encoding failed (%s, %lu)!\n", + LOG_E(RRC, "[eNB AssertFatal]ASN1 message encoding failed (%s, %lu)!\n", enc_rval.failed_type->name, enc_rval.encoded); return -1; } -#if defined(ENABLE_ITTI) -# if !defined(DISABLE_XER_SPRINT) - { - char message_string[20000]; - size_t message_string_size; - if ((message_string_size = xer_sprint(message_string, sizeof(message_string), &asn_DEF_LTE_DL_CCCH_Message, (void *) &dl_ccch_msg)) > 0) { - MessageDef *msg_p; - - msg_p = itti_alloc_new_message_sized (TASK_RRC_ENB, RRC_DL_CCCH, message_string_size + sizeof (IttiMsgText)); - msg_p->ittiMsg.rrc_dl_ccch.size = message_string_size; - memcpy(&msg_p->ittiMsg.rrc_dl_ccch.text, message_string, message_string_size); - - itti_send_msg_to_task(TASK_UNKNOWN, Mod_id, msg_p); - } - } -# endif -#endif LOG_D(RRC,"RRCConnectionReestablishmentReject Encoded %zd bits (%zd bytes)\n", enc_rval.encoded,(enc_rval.encoded+7)/8); @@ -2884,24 +2655,6 @@ do_RRCConnectionReject( enc_rval.failed_type->name, enc_rval.encoded); return -1; } -#if defined(ENABLE_ITTI) -# if !defined(DISABLE_XER_SPRINT) - { - char message_string[20000]; - size_t message_string_size; - - if ((message_string_size = xer_sprint(message_string, sizeof(message_string), &asn_DEF_LTE_DL_CCCH_Message, (void *) &dl_ccch_msg)) > 0) { - MessageDef *msg_p; - - msg_p = itti_alloc_new_message_sized (TASK_RRC_ENB, RRC_DL_CCCH, message_string_size + sizeof (IttiMsgText)); - msg_p->ittiMsg.rrc_dl_ccch.size = message_string_size; - memcpy(&msg_p->ittiMsg.rrc_dl_ccch.text, message_string, message_string_size); - - itti_send_msg_to_task(TASK_UNKNOWN, Mod_id, msg_p); - } - } -# endif -#endif LOG_D(RRC,"RRCConnectionReject Encoded %zd bits (%zd bytes)\n", enc_rval.encoded,(enc_rval.encoded+7)/8); @@ -3078,24 +2831,6 @@ uint8_t do_MBSFNAreaConfig(uint8_t Mod_id, enc_rval.failed_type->name, enc_rval.encoded); return -1; } -#if defined(ENABLE_ITTI) -# if !defined(DISABLE_XER_SPRINT) - { - char message_string[20000]; - size_t message_string_size; - - if ((message_string_size = xer_sprint(message_string, sizeof(message_string), &asn_DEF_LTE_MCCH_Message, (void *) &mcch_message)) > 0) { - MessageDef *msg_p; - - msg_p = itti_alloc_new_message_sized (TASK_RRC_ENB, RRC_DL_MCCH, message_string_size); - msg_p->ittiMsg.rrc_dl_mcch.size = message_string_size; - memcpy(&msg_p->ittiMsg.rrc_dl_mcch.text, message_string, message_string_size); - - itti_send_msg_to_task(TASK_UNKNOWN, Mod_id, msg_p); - } - } -# endif -#endif LOG_D(RRC,"[eNB] MCCH Message Encoded %zd bits (%zd bytes)\n",enc_rval.encoded,(enc_rval.encoded+7)/8); @@ -3199,6 +2934,10 @@ uint8_t do_MeasurementReport(uint8_t Mod_id, uint8_t *buffer,int measid,int phy_ ASN_SEQUENCE_ADD(&measResultListEUTRA2->list,measresulteutra2); measurementReport->criticalExtensions.choice.c1.choice.measurementReport_r8.measResults.measResultNeighCells->choice.measResultListEUTRA=*(measResultListEUTRA2); + if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) { + xer_fprint(stdout, &asn_DEF_LTE_UL_DCCH_Message, (void*)&ul_dcch_msg); + } + enc_rval = uper_encode_to_buffer(&asn_DEF_LTE_UL_DCCH_Message, NULL, @@ -3211,26 +2950,7 @@ uint8_t do_MeasurementReport(uint8_t Mod_id, uint8_t *buffer,int measid,int phy_ enc_rval.failed_type->name, enc_rval.encoded); return -1; } -#if defined(ENABLE_ITTI) -# if !defined(DISABLE_XER_SPRINT) - { - char message_string[20000]; - size_t message_string_size; - if ((message_string_size = xer_sprint(message_string, sizeof(message_string), &asn_DEF_LTE_UL_DCCH_Message, (void *) &ul_dcch_msg)) > 0) { - MessageDef *msg_p; - - msg_p = itti_alloc_new_message_sized (TASK_RRC_UE, RRC_DL_DCCH, message_string_size + sizeof (IttiMsgText)); - msg_p->ittiMsg.rrc_dl_dcch.size = message_string_size; - memcpy(&msg_p->ittiMsg.rrc_dl_dcch.text, message_string, message_string_size); - - itti_send_msg_to_task(TASK_UNKNOWN, NB_eNB_INST + Mod_id, msg_p); - } - } -# endif -#endif - - printf("Measurement Report Encoded %zu bits (%zu bytes)\n",enc_rval.encoded,(enc_rval.encoded+7)/8); return((enc_rval.encoded+7)/8); } @@ -3255,26 +2975,6 @@ uint8_t do_DLInformationTransfer(uint8_t Mod_id, uint8_t **buffer, uint8_t trans encoded = uper_encode_to_new_buffer (&asn_DEF_LTE_DL_DCCH_Message, NULL, (void*) &dl_dcch_msg, (void **) buffer); - /* -#if defined(ENABLE_ITTI) -# if !defined(DISABLE_XER_SPRINT) - { - char message_string[10000]; - size_t message_string_size; - - if ((message_string_size = xer_sprint(message_string, sizeof(message_string), &asn_DEF_DL_DCCH_Message, (void *)&dl_dcch_msg)) > 0) { - MessageDef *msg_p; - - msg_p = itti_alloc_new_message_sized (TASK_RRC_ENB, RRC_DL_DCCH, message_string_size + sizeof (IttiMsgText)); - msg_p->ittiMsg.rrc_dl_dcch.size = message_string_size; - memcpy(&msg_p->ittiMsg.rrc_dl_dcch.text, message_string, message_string_size); - - itti_send_msg_to_task(TASK_UNKNOWN, Mod_id, msg_p); - } - } -# endif -#endif - */ return encoded; } @@ -3476,7 +3176,7 @@ OAI_UECapability_t *fill_ue_capability(char *UE_EUTRA_Capability_xer_fname) // UE_EUTRA_Capability->measParameters.bandListEUTRA.list.count = 0; // no measurements on other bands // UE_EUTRA_Capability->featureGroupIndicators // null - if(usim_test == 1) + if(get_softmodem_params()->usim_test == 1) { // featureGroup is mandatory for CMW tests // featureGroup is filled only for usim-test mode @@ -3519,33 +3219,7 @@ OAI_UECapability_t *fill_ue_capability(char *UE_EUTRA_Capability_xer_fname) AssertFatal (enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %lu)!\n", enc_rval.failed_type->name, enc_rval.encoded); -#if defined(ENABLE_ITTI) -# if defined(DISABLE_XER_SPRINT) - { - MessageDef *msg_p; - msg_p = itti_alloc_new_message (TASK_RRC_UE, RRC_UE_EUTRA_CAPABILITY); - memcpy (&msg_p->ittiMsg, (void *) UE_EUTRA_Capability, sizeof(RrcUeEutraCapability)); - - itti_send_msg_to_task (TASK_UNKNOWN, NB_eNB_INST, msg_p); - } -# else - { - char message_string[10000]; - size_t message_string_size; - - if ((message_string_size = xer_sprint(message_string, sizeof(message_string), &asn_DEF_LTE_UE_EUTRA_Capability, (void *)UE_EUTRA_Capability)) > 0) { - MessageDef *msg_p; - - msg_p = itti_alloc_new_message_sized (TASK_RRC_UE, RRC_UE_EUTRA_CAPABILITY, message_string_size + sizeof (IttiMsgText)); - msg_p->ittiMsg.rrc_ue_eutra_capability.size = message_string_size; - memcpy(&msg_p->ittiMsg.rrc_ue_eutra_capability.text, message_string, message_string_size); - - itti_send_msg_to_task(TASK_UNKNOWN, INSTANCE_DEFAULT, msg_p); - } - } -# endif -#endif UECapability.sdu_size = (enc_rval.encoded + 7) / 8; LOG_I(PHY, "[RRC]UE Capability encoded, %d bytes (%zd bits)\n", diff --git a/openair3/NAS/UE/EMM/Authentication.c b/openair3/NAS/UE/EMM/Authentication.c index 5b10e60893..850f97150a 100644 --- a/openair3/NAS/UE/EMM/Authentication.c +++ b/openair3/NAS/UE/EMM/Authentication.c @@ -68,14 +68,9 @@ Description Defines the authentication EMM procedure executed by the #include "usim_api.h" #include "secu_defs.h" #include "Authentication.h" +#include "targets/RT/USER/lte-softmodem.h" -/****************************************************************************/ -/**************** E X T E R N A L D E F I N I T I O N S ****************/ -/****************************************************************************/ - -extern uint8_t usim_test; - /****************************************************************************/ /******************* L O C A L D E F I N I T I O N S *******************/ /****************************************************************************/ @@ -211,7 +206,7 @@ int emm_proc_authentication_request(nas_user_t *user, int native_ksi, int ksi, * of the core network by means of the received AUTN parameter and * request the USIM to compute RES, CK and IK for given RAND */ - if(usim_test == 0) + if(get_softmodem_params()->usim_test == 0) { rc = usim_api_authenticate(&user->usim_data, rand, autn, &auts, &res, &ck, &ik); } diff --git a/openair3/NAS/UE/EMM/SAP/EmmDeregisteredNormalService.c b/openair3/NAS/UE/EMM/SAP/EmmDeregisteredNormalService.c index fe18a98d38..f77c2921a3 100644 --- a/openair3/NAS/UE/EMM/SAP/EmmDeregisteredNormalService.c +++ b/openair3/NAS/UE/EMM/SAP/EmmDeregisteredNormalService.c @@ -47,7 +47,7 @@ Description Implements the EPS Mobility Management procedures executed #include "commonDef.h" #include "networkDef.h" #include "nas_log.h" - +#include "targets/RT/USER/lte-softmodem.h" #include "emm_proc.h" #include @@ -55,7 +55,7 @@ Description Implements the EPS Mobility Management procedures executed /****************************************************************************/ /**************** E X T E R N A L D E F I N I T I O N S ****************/ /****************************************************************************/ -extern uint8_t usim_test; + /****************************************************************************/ /******************* L O C A L D E F I N I T I O N S *******************/ @@ -110,7 +110,7 @@ int EmmDeregisteredNormalService(nas_user_t *user, const emm_reg_t *evt) /* * Initiate the attach procedure for EPS services */ - if(usim_test == 0) + if(get_softmodem_params()->usim_test == 0) { rc = emm_proc_attach(user, EMM_ATTACH_TYPE_EPS); } diff --git a/targets/COMMON/create_tasks.c b/targets/COMMON/create_tasks.c index 0d306ee50b..047d8b4037 100644 --- a/targets/COMMON/create_tasks.c +++ b/targets/COMMON/create_tasks.c @@ -23,6 +23,7 @@ # include "intertask_interface.h" # include "create_tasks.h" # include "common/utils/LOG/log.h" +# include "targets/RT/USER/lte-softmodem.h" # ifdef OPENAIR2 # if defined(ENABLE_USE_MME) @@ -43,7 +44,6 @@ # endif # include "enb_app.h" -extern int emulate_rf; int create_tasks(uint32_t enb_nb) { @@ -79,7 +79,7 @@ int create_tasks(uint32_t enb_nb) LOG_E(S1AP, "Create task for S1AP failed\n"); return -1; } - if(!emulate_rf){ + if(!(get_softmodem_params()->emulate_rf)){ if (itti_create_task (TASK_UDP, udp_eNB_task, NULL) < 0) { LOG_E(UDP_, "Create task for UDP failed\n"); return -1; diff --git a/targets/RT/USER/lte-ru.c b/targets/RT/USER/lte-ru.c index 4a0d2d5266..3f0fe77647 100644 --- a/targets/RT/USER/lte-ru.c +++ b/targets/RT/USER/lte-ru.c @@ -90,6 +90,7 @@ #include "common/utils/LOG/vcd_signal_dumper.h" #include "UTIL/OPT/opt.h" #include "enb_config.h" +#include "targets/RT/USER/lte-softmodem.h" //#include "PHY/TOOLS/time_meas.h" /* these variables have to be defined before including ENB_APP/enb_paramdef.h */ @@ -117,16 +118,14 @@ static int DEFENBS[] = {0}; #include "pdcp.h" extern volatile int oai_exit; -extern int emulate_rf; -extern int numerology; -extern clock_source_t clock_source; + extern PARALLEL_CONF_t get_thread_parallel_conf(void); extern WORKER_CONF_t get_thread_worker_conf(void); extern void phy_init_RU(RU_t*); extern void phy_free_RU(RU_t*); -void init_RU(char*); + void stop_RU(int nb_ru); void do_ru_sync(RU_t *ru); @@ -699,6 +698,7 @@ static void* emulatedRF_thread(void* param) { RU_proc_t *proc = (RU_proc_t *) param; int microsec = 500; // length of time to sleep, in miliseconds struct timespec req = {0}; + int numerology = get_softmodem_params()->numerology; req.tv_sec = 0; req.tv_nsec = (numerology>0)? ((microsec * 1000L)/numerology):(microsec * 1000L)*2; cpu_set_t cpuset; @@ -743,7 +743,7 @@ void rx_rf(RU_t *ru,int *frame,int *subframe) { VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ, 1 ); old_ts = proc->timestamp_rx; - if(emulate_rf){ + if(get_softmodem_params()->emulate_rf){ wait_on_condition(&proc->mutex_emulateRF,&proc->cond_emulateRF,&proc->instance_cnt_emulateRF,"emulatedRF_thread"); release_thread(&proc->mutex_emulateRF,&proc->instance_cnt_emulateRF,"emulatedRF_thread"); rxs = fp->samples_per_tti; @@ -1352,7 +1352,7 @@ void fill_rf_config(RU_t *ru, char *rf_config_file) { LTE_DL_FRAME_PARMS *fp = &ru->frame_parms; openair0_config_t *cfg = &ru->openair0_cfg; //printf("////////////////numerology in config = %d\n",numerology); - + int numerology = get_softmodem_params()->numerology; if(fp->N_RB_DL == 100) { if(numerology == 0){ if (fp->threequarter_fs) { @@ -1411,7 +1411,7 @@ void fill_rf_config(RU_t *ru, char *rf_config_file) { cfg->num_rb_dl=fp->N_RB_DL; cfg->tx_num_channels=ru->nb_tx; cfg->rx_num_channels=ru->nb_rx; - cfg->clock_source=clock_source; + cfg->clock_source=get_softmodem_params()->clock_source; for (i=0; inb_tx; i++) { @@ -1561,7 +1561,7 @@ static void* ru_thread_tx( void* param ) { // do OFDM if needed if ((ru->fh_north_asynch_in == NULL) && (ru->feptx_ofdm)) ru->feptx_ofdm(ru); - if(!emulate_rf){ + if(!(get_softmodem_params()->emulate_rf)){ // do outgoing fronthaul (south) if needed if ((ru->fh_north_asynch_in == NULL) && (ru->fh_south_out)) ru->fh_south_out(ru); @@ -1613,7 +1613,7 @@ static void* ru_thread( void* param ) { LOG_I(PHY,"Starting RU %d (%s,%s),\n",ru->idx,eNB_functions[ru->function],eNB_timing[ru->if_timing]); - if(emulate_rf){ + if(get_softmodem_params()->emulate_rf){ fill_rf_config(ru,ru->rf_config_file); init_frame_parms(&ru->frame_parms,1); phy_init_RU(ru); @@ -1659,7 +1659,7 @@ static void* ru_thread( void* param ) { wait_sync("ru_thread"); - if(!emulate_rf){ + if(!(get_softmodem_params()->emulate_rf)){ // Start RF device if any if (ru->start_rf) { if (ru->start_rf(ru) != 0) @@ -1794,7 +1794,7 @@ static void* ru_thread( void* param ) { // do OFDM if needed if ((ru->fh_north_asynch_in == NULL) && (ru->feptx_ofdm)) ru->feptx_ofdm(ru); - if(!emulate_rf){ + if(!(get_softmodem_params()->emulate_rf)){ // do outgoing fronthaul (south) if needed if ((ru->fh_north_asynch_in == NULL) && (ru->fh_south_out)) ru->fh_south_out(ru); @@ -1817,7 +1817,7 @@ static void* ru_thread( void* param ) { printf( "Exiting ru_thread \n"); - if (!emulate_rf){ + if (!(get_softmodem_params()->emulate_rf)){ if (ru->stop_rf != NULL) { if (ru->stop_rf(ru) != 0) LOG_E(HW,"Could not stop the RF device\n"); @@ -2198,7 +2198,7 @@ void init_RU_proc(RU_t *ru) { pthread_create( &proc->pthread_rf_tx, NULL, rf_tx, (void*)ru ); #endif - if(emulate_rf) + if(get_softmodem_params()->emulate_rf) pthread_create( &proc->pthread_emulateRF, attr_emulateRF, emulatedRF_thread, (void*)proc ); if (get_thread_parallel_conf() == PARALLEL_RU_L1_SPLIT || get_thread_parallel_conf() == PARALLEL_RU_L1_TRX_SPLIT) diff --git a/targets/RT/USER/lte-softmodem-common.c b/targets/RT/USER/lte-softmodem-common.c new file mode 100644 index 0000000000..4eb0d3e888 --- /dev/null +++ b/targets/RT/USER/lte-softmodem-common.c @@ -0,0 +1,126 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/*! \file lte-softmodem-common.c + * \brief Top-level threads for eNodeB + * \author Nokia BellLabs France, francois Taburet + * \date 2012 + * \version 0.1 + * \company Eurecom + * \email: francois.taburet@nokia-bell-labs.com + * \note + * \warning + */ + +#include "lte-softmodem.h" +#include "UTIL/OPT/opt.h" +#include "common/config/config_userapi.h" +#include "common/utils/load_module_shlib.h" +static softmodem_params_t softmodem_params; + +uint64_t get_softmodem_optmask(void) { + return softmodem_params.optmask; +} + +uint64_t set_softmodem_optmask(uint64_t bitmask) { + softmodem_params.optmask = softmodem_params.optmask | bitmask; + return softmodem_params.optmask; +} + +softmodem_params_t* get_softmodem_params(void) { + return &softmodem_params; +} + +void set_parallel_conf(char *parallel_conf) +{ + if(strcmp(parallel_conf,"PARALLEL_SINGLE_THREAD")==0) softmodem_params.thread_struct.parallel_conf = PARALLEL_SINGLE_THREAD; + else if(strcmp(parallel_conf,"PARALLEL_RU_L1_SPLIT")==0) softmodem_params.thread_struct.parallel_conf = PARALLEL_RU_L1_SPLIT; + else if(strcmp(parallel_conf,"PARALLEL_RU_L1_TRX_SPLIT")==0) softmodem_params.thread_struct.parallel_conf = PARALLEL_RU_L1_TRX_SPLIT; + printf("[CONFIG] parallel conf is set to %d\n",softmodem_params.thread_struct.parallel_conf); +} +void set_worker_conf(char *worker_conf) +{ + if(strcmp(worker_conf,"WORKER_DISABLE")==0) softmodem_params.thread_struct.worker_conf = WORKER_DISABLE; + else if(strcmp(worker_conf,"WORKER_ENABLE")==0) softmodem_params.thread_struct.worker_conf = WORKER_ENABLE; + printf("[CONFIG] worker conf is set to %d\n",softmodem_params.thread_struct.worker_conf); +} +PARALLEL_CONF_t get_thread_parallel_conf(void) +{ + return softmodem_params.thread_struct.parallel_conf; +} +WORKER_CONF_t get_thread_worker_conf(void) +{ + return softmodem_params.thread_struct.worker_conf; +} +void get_common_options(void) +{ +char *parallel_config=NULL; +char *worker_config=NULL; + + +uint32_t online_log_messages; +uint32_t glog_level ; +uint32_t start_telnetsrv; +uint32_t noS1; +uint32_t nokrnmod; +uint32_t nonbiot; +paramdef_t cmdline_params[] =CMDLINE_PARAMS_DESC ; +paramdef_t cmdline_logparams[] =CMDLINE_LOGPARAMS_DESC ; + + + + config_process_cmdline( cmdline_params,sizeof(cmdline_params)/sizeof(paramdef_t),NULL); + + if (strlen(in_path) > 0) { + opt_type = OPT_PCAP; + opt_enabled=1; + printf("Enabling OPT for PCAP with the following file %s \n",in_path); + } + if (strlen(in_ip) > 0) { + opt_enabled=1; + opt_type = OPT_WIRESHARK; + printf("Enabling OPT for wireshark for local interface"); + } + + config_process_cmdline( cmdline_logparams,sizeof(cmdline_logparams)/sizeof(paramdef_t),NULL); + + if(config_isparamset(cmdline_logparams,CMDLINE_ONLINELOG_IDX)) { + set_glog_onlinelog(online_log_messages); + } + if(config_isparamset(cmdline_logparams,CMDLINE_GLOGLEVEL_IDX)) { + set_glog(glog_level); + } + if (start_telnetsrv) { + load_module_shlib("telnetsrv",NULL,0,NULL); + } + + if (noS1) { + set_softmodem_optmask(SOFTMODEM_NOS1_BIT); + } + if (nokrnmod) { + set_softmodem_optmask(SOFTMODEM_NOKRNMOD_BIT); + } + if (nonbiot) { + set_softmodem_optmask(SOFTMODEM_NONBIOT_BIT); + } + if(parallel_config != NULL) set_parallel_conf(parallel_config); + if(worker_config != NULL) set_worker_conf(worker_config); +} diff --git a/targets/RT/USER/lte-softmodem.c b/targets/RT/USER/lte-softmodem.c index 03a461454f..00ae350ea2 100644 --- a/targets/RT/USER/lte-softmodem.c +++ b/targets/RT/USER/lte-softmodem.c @@ -19,7 +19,7 @@ * contact@openairinterface.org */ -/*! \file lte-enb.c +/*! \file lte-softmodem.c * \brief Top-level threads for eNodeB * \author R. Knopp, F. Kaltenberger, Navid Nikaein * \date 2012 @@ -133,26 +133,13 @@ volatile int start_UE = 0; #endif volatile int oai_exit = 0; -clock_source_t clock_source = internal; -static int wait_for_sync = 0; - -unsigned int mmapped_dma=0; -int single_thread_flag = 0; - -static int8_t threequarter_fs=0; - uint32_t downlink_frequency[MAX_NUM_CCs][4]; int32_t uplink_frequency_offset[MAX_NUM_CCs][4]; - -// This is a dummy declaration (dlsch_demodulation.c is no longer compiled for eNodeB) -int16_t dlsch_demod_shift = 0; - int UE_scan = 1; int UE_scan_carrier = 0; runmode_t mode = normal_txrx; int simL1flag; -int snr_dB; FILE *input_fd=NULL; @@ -171,11 +158,6 @@ double rx_gain_off = 0.0; double sample_rate=30.72e6; double bw = 10.0e6; -char rf_config_file[1024]; - -int chain_offset=0; -int phy_test = 0; -uint8_t usim_test = 0; uint8_t dci_Format = 0; uint8_t agregation_Level =0xFF; @@ -190,16 +172,12 @@ int rx_input_level_dBm; #ifdef XFORMS extern int otg_enabled; -static char do_forms=0; #else int otg_enabled; #endif //int number_of_cards = 1; -uint32_t target_dl_mcs = 28; //maximum allowed mcs -uint32_t target_ul_mcs = 20; -uint32_t timing_advance = 0; uint8_t exit_missed_slots=1; uint64_t num_missed_slots=0; // counter for the number of missed slots @@ -207,58 +185,16 @@ uint64_t num_missed_slots=0; // counter for the number of missed slots extern void reset_opp_meas(void); extern void print_opp_meas(void); -extern PHY_VARS_UE* init_ue_vars(LTE_DL_FRAME_PARMS *frame_parms, - uint8_t UE_id, - uint8_t abstraction_flag); extern void init_eNB_afterRU(void); int transmission_mode=1; -int emulate_rf = 0; -int numerology = 0; -char *parallel_config = NULL; -char *worker_config = NULL; - -static THREAD_STRUCT thread_struct; -void set_parallel_conf(char *parallel_conf) -{ - if(strcmp(parallel_conf,"PARALLEL_SINGLE_THREAD")==0) thread_struct.parallel_conf = PARALLEL_SINGLE_THREAD; - else if(strcmp(parallel_conf,"PARALLEL_RU_L1_SPLIT")==0) thread_struct.parallel_conf = PARALLEL_RU_L1_SPLIT; - else if(strcmp(parallel_conf,"PARALLEL_RU_L1_TRX_SPLIT")==0) thread_struct.parallel_conf = PARALLEL_RU_L1_TRX_SPLIT; - printf("[CONFIG] parallel conf is set to %d\n",thread_struct.parallel_conf); -} -void set_worker_conf(char *worker_conf) -{ - if(strcmp(worker_conf,"WORKER_DISABLE")==0) thread_struct.worker_conf = WORKER_DISABLE; - else if(strcmp(worker_conf,"WORKER_ENABLE")==0) thread_struct.worker_conf = WORKER_ENABLE; - printf("[CONFIG] worker conf is set to %d\n",thread_struct.worker_conf); -} -PARALLEL_CONF_t get_thread_parallel_conf(void) -{ - return thread_struct.parallel_conf; -} -WORKER_CONF_t get_thread_worker_conf(void) -{ - return thread_struct.worker_conf; -} -/* struct for ethernet specific parameters given in eNB conf file */ -eth_params_t *eth_params; - double cpuf; -extern char uecap_xer[1024]; -char uecap_xer_in=0; -int oaisim_flag=0; -threads_t threads= {-1,-1,-1,-1,-1,-1,-1}; - -/* see file openair2/LAYER2/MAC/main.c for why abstraction_flag is needed - * this is very hackish - find a proper solution - */ -uint8_t abstraction_flag=0; /* forward declarations */ void set_default_frame_parms(LTE_DL_FRAME_PARMS *frame_parms[MAX_NUM_CCs]); @@ -314,7 +250,7 @@ unsigned int build_rfdc(int dcoff_i_rxfe, int dcoff_q_rxfe) { return (dcoff_i_rxfe + (dcoff_q_rxfe<<8)); } -#if !defined(ENABLE_ITTI) + void signal_handler(int sig) { void *array[10]; size_t size; @@ -328,26 +264,13 @@ void signal_handler(int sig) { backtrace_symbols_fd(array, size, 2); exit(-1); } else { - printf("trying to exit gracefully...\n"); - oai_exit = 1; + printf("Linux signal %s...\n",strsignal(sig)); + exit_function(__FILE__, __FUNCTION__, __LINE__,"softmodem starting exit procedure\n"); + + } } -#endif -#define KNRM "\x1B[0m" -#define KRED "\x1B[31m" -#define KGRN "\x1B[32m" -#define KBLU "\x1B[34m" -#define RESET "\033[0m" -#if defined(ENABLE_ITTI) -void signal_handler_itti(int sig) { - // Call exit function - char msg[256]; - memset(msg, 0, 256); - sprintf(msg, "caught signal %s\n", strsignal(sig)); - exit_function(__FILE__, __FUNCTION__, __LINE__, msg); -} -#endif void exit_function(const char* file, const char* function, const int line, const char* s) { @@ -520,42 +443,12 @@ void *l2l1_task(void *arg) { #endif -static void get_options(unsigned int *start_msc) { +static void get_options(void) { - int tddflag, nonbiotflag; - - - uint32_t online_log_messages; - uint32_t glog_level ; - uint32_t start_telnetsrv; - paramdef_t cmdline_params[] =CMDLINE_PARAMS_DESC ; - paramdef_t cmdline_logparams[] =CMDLINE_LOGPARAMS_DESC ; CONFIG_SETRTFLAG(CONFIG_NOEXITONHELP); - config_process_cmdline( cmdline_params,sizeof(cmdline_params)/sizeof(paramdef_t),NULL); - - if (strlen(in_path) > 0) { - opt_type = OPT_PCAP; - opt_enabled=1; - printf("Enabling OPT for PCAP with the following file %s \n",in_path); - } - if (strlen(in_ip) > 0) { - opt_enabled=1; - opt_type = OPT_WIRESHARK; - printf("Enabling OPT for wireshark for local interface"); - } + get_common_options(); CONFIG_CLEARRTFLAG(CONFIG_NOEXITONHELP); - config_process_cmdline( cmdline_logparams,sizeof(cmdline_logparams)/sizeof(paramdef_t),NULL); - - if(config_isparamset(cmdline_logparams,CMDLINE_ONLINELOG_IDX)) { - set_glog_onlinelog(online_log_messages); - } - if(config_isparamset(cmdline_logparams,CMDLINE_GLOGLEVEL_IDX)) { - set_glog(glog_level); - } - if (start_telnetsrv) { - load_module_shlib("telnetsrv",NULL,0,NULL); - } if ( !(CONFIG_ISFLAGSET(CONFIG_ABORT)) ) { memset((void*)&RC,0,sizeof(RC)); @@ -563,7 +456,7 @@ static void get_options(unsigned int *start_msc) { RCConfig(); NB_eNB_INST = RC.nb_inst; printf("Configuration: nb_rrc_inst %d, nb_L1_inst %d, nb_ru %d\n",NB_eNB_INST,RC.nb_L1_inst,RC.nb_RU); - if (nonbiotflag <= 0) { + if (!SOFTMODEM_NONBIOT) { load_NB_IoT(); printf(" nb_nbiot_rrc_inst %d, nb_nbiot_L1_inst %d, nb_nbiot_macrlc_inst %d\n", RC.nb_nb_iot_rrc_inst, RC.nb_nb_iot_L1_inst, RC.nb_nb_iot_macrlc_inst); @@ -572,8 +465,7 @@ static void get_options(unsigned int *start_msc) { RC.nb_nb_iot_rrc_inst=RC.nb_nb_iot_L1_inst=RC.nb_nb_iot_macrlc_inst=0; } } - if(parallel_config != NULL) set_parallel_conf(parallel_config); - if(worker_config != NULL) set_worker_conf(worker_config); + } @@ -803,8 +695,6 @@ int main( int argc, char **argv ) #if defined (XFORMS) int ret; #endif - unsigned int start_msc=0; - if ( load_configmodule(argc,argv) == NULL) { exit_fun("[SOFTMODEM] Error, configuration module init failed\n"); } @@ -818,7 +708,8 @@ int main( int argc, char **argv ) printf("Reading in command-line options\n"); - get_options (&start_msc); + CONFIG_SETRTFLAG(CONFIG_NOCHECKUNKOPT); + get_options (); if (CONFIG_ISFLAGSET(CONFIG_ABORT) ) { fprintf(stderr,"Getting configuration failed\n"); exit(-1); @@ -826,11 +717,16 @@ int main( int argc, char **argv ) #if T_TRACER + T_Config_Init(); #endif - - + ret=config_check_cmdlineopt(NULL); + if (ret != 0) { + LOG_E(ENB_APP, "%i unknown options in command line\n",ret); + exit_fun(""); + } + CONFIG_CLEARRTFLAG(CONFIG_NOCHECKUNKOPT); //randominit (0); set_taus_seed (0); @@ -848,7 +744,7 @@ int main( int argc, char **argv ) itti_init(TASK_MAX, THREAD_MAX, MESSAGES_ID_MAX, tasks_info, messages_info); // initialize mscgen log after ITTI - if (start_msc) { + if (get_softmodem_params()->start_msc) { load_module_shlib("msc",NULL,0,&msc_interface); } MSC_INIT(MSC_E_UTRAN, THREAD_MAX+TASK_MAX); @@ -867,17 +763,14 @@ int main( int argc, char **argv ) #endif #endif -#if !defined(ENABLE_ITTI) + // to make a graceful exit when ctrl-c is pressed signal(SIGSEGV, signal_handler); signal(SIGINT, signal_handler); -#endif + signal(SIGTERM, signal_handler); + signal(SIGABRT, signal_handler); + -#if defined(ENABLE_ITTI) - signal(SIGINT, signal_handler_itti); - signal(SIGTERM, signal_handler_itti); - signal(SIGABRT, signal_handler_itti); -#endif check_clock(); @@ -887,11 +780,6 @@ int main( int argc, char **argv ) LOG_I(HW, "Version: %s\n", PACKAGE_VERSION); - - - - printf("Before CC \n"); - printf("Runtime table\n"); fill_modeled_runtime_table(runtime_phy_rx,runtime_phy_tx); @@ -973,7 +861,7 @@ int main( int argc, char **argv ) printf("XFORMS\n"); - if (do_forms==1) { + if (get_softmodem_params()->do_forms==1) { fl_initialize (&argc, argv, NULL, 0, 0); form_stats_l2 = create_form_stats_form(); @@ -1044,8 +932,8 @@ int main( int argc, char **argv ) number_of_cards = 1; printf("RC.nb_L1_inst:%d\n", RC.nb_L1_inst); if (RC.nb_L1_inst > 0) { - printf("Initializing eNB threads single_thread_flag:%d wait_for_sync:%d\n", single_thread_flag,wait_for_sync); - init_eNB(single_thread_flag,wait_for_sync); + printf("Initializing eNB threads single_thread_flag:%d wait_for_sync:%d\n", get_softmodem_params()->single_thread_flag,get_softmodem_params()->wait_for_sync); + init_eNB(get_softmodem_params()->single_thread_flag,get_softmodem_params()->wait_for_sync); // for (inst=0;inst0) { printf("Initializing RU threads\n"); - init_RU(rf_config_file); + init_RU(get_softmodem_params()->rf_config_file); for (ru_id=0;ru_idrf_map.card=0; - RC.ru[ru_id]->rf_map.chain=CC_id+chain_offset; + RC.ru[ru_id]->rf_map.chain=CC_id+(get_softmodem_params()->chain_offset); } } @@ -1102,6 +990,12 @@ int main( int argc, char **argv ) pthread_cond_broadcast(&sync_cond); pthread_mutex_unlock(&sync_mutex); + ret=config_check_cmdlineopt(CONFIG_CHECKALLSECTIONS); + if (ret != 0) { + LOG_E(ENB_APP, "%i unknown options in command line (invalid section name)\n",ret); + exit_fun(""); + } + // wait for end of program printf("TYPE TO TERMINATE\n"); //getchar(); @@ -1124,7 +1018,7 @@ int main( int argc, char **argv ) #ifdef XFORMS printf("waiting for XFORMS thread\n"); - if (do_forms==1) { + if (get_softmodem_params()->do_forms==1) { pthread_join(forms_thread,&status); fl_hide_form(form_stats->stats_form); fl_free_form(form_stats->stats_form); diff --git a/targets/RT/USER/lte-softmodem.h b/targets/RT/USER/lte-softmodem.h index 96ab799c3d..6d182b16cf 100644 --- a/targets/RT/USER/lte-softmodem.h +++ b/targets/RT/USER/lte-softmodem.h @@ -95,7 +95,8 @@ #define CONFIG_HLP_EMULATE_RF "Emulated RF enabled(disable by defult)\n" #define CONFIG_HLP_PARALLEL_CMD "three config for level of parallelism 'PARALLEL_SINGLE_THREAD', 'PARALLEL_RU_L1_SPLIT', or 'PARALLEL_RU_L1_TRX_SPLIT'\n" #define CONFIG_HLP_WORKER_CMD "two option for worker 'WORKER_DISABLE' or 'WORKER_ENABLE'\n" - +#define CONFIG_HLP_NOS1 "Disable s1 interface\n" +#define CONFIG_HLP_NOKRNMOD "(noS1 only): Use tun instead of namesh module \n" #define CONFIG_HLP_DISABLNBIOT "disable nb-iot, even if defined in config\n" #define CONFIG_HLP_USRP_ARGS "set the arguments to identify USRP (same syntax as in UHD)\n" @@ -130,29 +131,48 @@ #define CMDLINE_DUMPMEMORY_IDX 7 /*------------------------------------------------------------------------------------------------------------------------------------------*/ +#define START_MSC softmodem_params.start_msc +/*-------------------------------------------------------------------------------------------------------------------------------------------------------*/ +/* command line parameters specific to UE */ +/* optname helpstr paramflags XXXptr defXXXval type numelt */ +/*-------------------------------------------------------------------------------------------------------------------------------------------------------*/ -/*--------------------------------------------------------------------------------------------------------------------------------------------------*/ -/* command line parameters specific to UE */ -/* optname helpstr paramflags XXXptr defXXXval type numelt */ -/*--------------------------------------------------------------------------------------------------------------------------------------------------*/ #define CMDLINE_UEPARAMS_DESC { \ -{"siml1", CONFIG_HLP_SIML1, PARAMFLAG_BOOL, iptr:&simL1flag, defintval:0, TYPE_INT, 0}, \ -{"U", CONFIG_HLP_NUMUE, 0, u8ptr:&NB_UE_INST, defuintval:1, TYPE_UINT, 0}, \ -{"ue-rxgain", CONFIG_HLP_UERXG, 0, dblptr:&(rx_gain[0][0]), defdblval:130, TYPE_DOUBLE, 0}, \ -{"ue-rxgain-off", CONFIG_HLP_UERXGOFF, 0, dblptr:&rx_gain_off, defdblval:0, TYPE_DOUBLE, 0}, \ -{"ue-txgain", CONFIG_HLP_UETXG, 0, dblptr:&(tx_gain[0][0]), defdblval:0, TYPE_DOUBLE, 0}, \ -{"ue-nb-ant-rx", CONFIG_HLP_UENANTR, 0, u8ptr:&nb_antenna_rx, defuintval:1, TYPE_UINT8, 0}, \ -{"ue-nb-ant-tx", CONFIG_HLP_UENANTT, 0, u8ptr:&nb_antenna_tx, defuintval:1, TYPE_UINT8, 0}, \ -{"ue-scan-carrier", CONFIG_HLP_UESCAN, PARAMFLAG_BOOL, iptr:&UE_scan_carrier, defintval:0, TYPE_INT, 0}, \ -{"ue-max-power", NULL, 0, iptr:&(tx_max_power[0]), defintval:23, TYPE_INT, 0}, \ -{"emul-iface", CONFIG_HLP_EMULIFACE, 0, strptr:&emul_iface, defstrval:"lo", TYPE_STRING, 100}, \ -{"L2-emul", NULL, 0, u8ptr:&nfapi_mode, defuintval:3, TYPE_UINT8, 0}, \ -{"num-ues", NULL, 0, u8ptr:&(NB_UE_INST), defuintval:1, TYPE_UINT8, 0}, \ -{"r" , CONFIG_HLP_PRB, 0, u8ptr:&(frame_parms[0]->N_RB_DL), defintval:25, TYPE_UINT8, 0}, \ -{"dlsch-demod-shift", CONFIG_HLP_DLSHIFT, 0, iptr:(int32_t *)&dlsch_demod_shift, defintval:0, TYPE_INT, 0}, \ -{"usrp-args", CONFIG_HLP_USRP_ARGS, 0, strptr:(char **)&usrp_args, defstrval:"type=b200", TYPE_STRING, 0}, \ -{"usrp-clksrc", CONFIG_HLP_USRP_CLK_SRC,0, strptr:(char **)&usrp_clksrc, defstrval:"internal", TYPE_STRING, 0} \ - } +{"siml1", CONFIG_HLP_SIML1, PARAMFLAG_BOOL, iptr:&simL1flag, defintval:0, TYPE_INT, 0}, \ +{"U", CONFIG_HLP_NUMUE, 0, u8ptr:&NB_UE_INST, defuintval:1, TYPE_UINT, 0}, \ +{"ue-rxgain", CONFIG_HLP_UERXG, 0, dblptr:&(rx_gain[0][0]), defdblval:130, TYPE_DOUBLE, 0}, \ +{"ue-rxgain-off", CONFIG_HLP_UERXGOFF, 0, dblptr:&rx_gain_off, defdblval:0, TYPE_DOUBLE, 0}, \ +{"ue-txgain", CONFIG_HLP_UETXG, 0, dblptr:&(tx_gain[0][0]), defdblval:0, TYPE_DOUBLE, 0}, \ +{"ue-nb-ant-rx", CONFIG_HLP_UENANTR, 0, u8ptr:&nb_antenna_rx, defuintval:1, TYPE_UINT8, 0}, \ +{"ue-nb-ant-tx", CONFIG_HLP_UENANTT, 0, u8ptr:&nb_antenna_tx, defuintval:1, TYPE_UINT8, 0}, \ +{"ue-scan-carrier", CONFIG_HLP_UESCAN, PARAMFLAG_BOOL, iptr:&UE_scan_carrier, defintval:0, TYPE_INT, 0}, \ +{"ue-max-power", NULL, 0, iptr:&(tx_max_power[0]), defintval:23, TYPE_INT, 0}, \ +{"emul-iface", CONFIG_HLP_EMULIFACE, 0, strptr:&emul_iface, defstrval:"lo", TYPE_STRING, 100}, \ +{"L2-emul", NULL, 0, u8ptr:&nfapi_mode, defuintval:3, TYPE_UINT8, 0}, \ +{"num-ues", NULL, 0, u8ptr:&(NB_UE_INST), defuintval:1, TYPE_UINT8, 0}, \ +{"r" , CONFIG_HLP_PRB, 0, u8ptr:&(frame_parms[0]->N_RB_DL), defintval:25, TYPE_UINT8, 0}, \ +{"dlsch-demod-shift", CONFIG_HLP_DLSHIFT, 0, iptr:(int32_t *)&dlsch_demod_shift, defintval:0, TYPE_INT, 0}, \ +{"usrp-args", CONFIG_HLP_USRP_ARGS, 0, strptr:(char **)&usrp_args, defstrval:"type=b200",TYPE_STRING, 0}, \ +{"usrp-clksrc", CONFIG_HLP_USRP_CLK_SRC,0, strptr:(char **)&usrp_clksrc, defstrval:"internal", TYPE_STRING, 0}, \ +{"mmapped-dma", CONFIG_HLP_DMAMAP, PARAMFLAG_BOOL, uptr:&mmapped_dma, defintval:0, TYPE_INT, 0}, \ +{"clock", CONFIG_HLP_CLK, 0, uptr:&clock_source, defintval:0, TYPE_UINT, 0}, \ +{"s" , CONFIG_HLP_SNR, 0, iptr:&snr_dB, defintval:25, TYPE_INT, 0}, \ +{"T" , CONFIG_HLP_TDD, PARAMFLAG_BOOL, iptr:&tddflag, defintval:0, TYPE_INT, 0}, \ +{"A", CONFIG_HLP_TADV, 0, iptr:&(timingadv), defintval:0, TYPE_INT, 0} \ +} + +/*-------------------------------------------------------------------------------------------------------------------------------------------------------*/ +/* command line parameters specific to UE threads */ +/* optname helpstr paramflags XXXptr defXXXval type numelt */ +/*-------------------------------------------------------------------------------------------------------------------------------------------------------*/ +#define CMDLINE_UETHREADSPARAMS_DESC { \ +{"threadIQ", NULL, 0, iptr:&(threads.iq), defintval:1, TYPE_INT, 0}, \ +{"threadOneSubframe", NULL, 0, iptr:&(threads.one), defintval:1, TYPE_INT, 0}, \ +{"threadTwoSubframe", NULL, 0, iptr:&(threads.two), defintval:1, TYPE_INT, 0}, \ +{"threadThreeSubframe", NULL, 0, iptr:&(threads.three), defintval:1, TYPE_INT, 0}, \ +{"threadSlot1ProcOne", NULL, 0, iptr:&(threads.slot1_proc_one), defintval:1, TYPE_INT, 0}, \ +{"threadSlot1ProcTwo", NULL, 0, iptr:&(threads.slot1_proc_two), defintval:1, TYPE_INT, 0}, \ +} #define DEFAULT_DLF 2680000000 @@ -160,40 +180,38 @@ /* command line parameters common to eNodeB and UE */ /* optname helpstr paramflags XXXptr defXXXval type numelt */ /*---------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ +#define RF_CONFIG_FILE softmodem_params.rf_config_file +#define PHY_TEST softmodem_params.phy_test +#define WAIT_FOR_SYNC softmodem_params.wait_for_sync +#define SINGLE_THREAD_FLAG softmodem_params.single_thread_flag +#define CHAIN_OFFSET softmodem_params.chain_offset +#define DO_FORMS softmodem_params.do_forms +#define NUMEROLOGY softmodem_params.numerology +#define EMULATE_RF softmodem_params.emulate_rf +#define CLOCK_SOURCE softmodem_params.clock_source +#define USIM_TEST softmodem_params.usim_test #define CMDLINE_PARAMS_DESC { \ -{"rf-config-file", CONFIG_HLP_RFCFGF, 0, strptr:(char **)&rf_config_file, defstrval:NULL, TYPE_STRING, sizeof(rf_config_file)}, \ +{"rf-config-file", CONFIG_HLP_RFCFGF, 0, strptr:(char **)&RF_CONFIG_FILE, defstrval:NULL, TYPE_STRING, sizeof(RF_CONFIG_FILE)}, \ {"ulsch-max-errors", CONFIG_HLP_ULMAXE, 0, uptr:&ULSCH_max_consecutive_errors, defuintval:0, TYPE_UINT, 0}, \ -{"phy-test", CONFIG_HLP_PHYTST, PARAMFLAG_BOOL, iptr:&phy_test, defintval:0, TYPE_INT, 0}, \ -{"usim-test", CONFIG_HLP_USIM, PARAMFLAG_BOOL, u8ptr:&usim_test, defintval:0, TYPE_UINT8, 0}, \ -{"mmapped-dma", CONFIG_HLP_DMAMAP, PARAMFLAG_BOOL, uptr:&mmapped_dma, defintval:0, TYPE_INT, 0}, \ -{"clock", CONFIG_HLP_CLK, 0, uptr:&clock_source, defintval:0, TYPE_UINT, 0}, \ -{"wait-for-sync", NULL, PARAMFLAG_BOOL, iptr:&wait_for_sync, defintval:0, TYPE_INT, 0}, \ -{"single-thread-enable", CONFIG_HLP_NOSNGLT, PARAMFLAG_BOOL, iptr:&single_thread_flag, defintval:0, TYPE_INT, 0}, \ -{"threadIQ", NULL, 0, iptr:&(threads.iq), defintval:1, TYPE_INT, 0}, \ -{"threadOneSubframe", NULL, 0, iptr:&(threads.one), defintval:1, TYPE_INT, 0}, \ -{"threadTwoSubframe", NULL, 0, iptr:&(threads.two), defintval:1, TYPE_INT, 0}, \ -{"threadThreeSubframe", NULL, 0, iptr:&(threads.three), defintval:1, TYPE_INT, 0}, \ -{"threadSlot1ProcOne", NULL, 0, iptr:&(threads.slot1_proc_one), defintval:1, TYPE_INT, 0}, \ -{"threadSlot1ProcTwo", NULL, 0, iptr:&(threads.slot1_proc_two), defintval:1, TYPE_INT, 0}, \ -{"dlsch-demod-shift", CONFIG_HLP_DLSHIFT, 0, iptr:(int32_t *)&dlsch_demod_shift, defintval:0, TYPE_INT, 0}, \ -{"A" , CONFIG_HLP_TADV, 0, uptr:&timing_advance, defintval:0, TYPE_UINT, 0}, \ +{"phy-test", CONFIG_HLP_PHYTST, PARAMFLAG_BOOL, iptr:&PHY_TEST, defintval:0, TYPE_INT, 0}, \ +{"usim-test", CONFIG_HLP_USIM, PARAMFLAG_BOOL, u8ptr:&USIM_TEST, defintval:0, TYPE_UINT8, 0}, \ +{"emulate-rf" , CONFIG_HLP_EMULATE_RF, PARAMFLAG_BOOL, iptr:&EMULATE_RF, defintval:0, TYPE_INT, 0}, \ +{"clock", CONFIG_HLP_CLK, 0, uptr:&CLOCK_SOURCE, defintval:0, TYPE_UINT, 0}, \ +{"wait-for-sync", NULL, PARAMFLAG_BOOL, iptr:&WAIT_FOR_SYNC, defintval:0, TYPE_INT, 0}, \ +{"single-thread-enable", CONFIG_HLP_NOSNGLT, PARAMFLAG_BOOL, iptr:&SINGLE_THREAD_FLAG, defintval:0, TYPE_INT, 0}, \ {"C" , CONFIG_HLP_DLF, 0, uptr:&(downlink_frequency[0][0]), defuintval:2680000000, TYPE_UINT, 0}, \ -{"a" , CONFIG_HLP_CHOFF, 0, iptr:&chain_offset, defintval:0, TYPE_INT, 0}, \ -{"d" , CONFIG_HLP_SOFTS, PARAMFLAG_BOOL, uptr:(uint32_t *)&do_forms, defintval:0, TYPE_INT8, 0}, \ -{"E" , CONFIG_HLP_TQFS, PARAMFLAG_BOOL, i8ptr:&threequarter_fs, defintval:0, TYPE_INT8, 0}, \ -{"m" , CONFIG_HLP_DLMCS, 0, uptr:&target_dl_mcs, defintval:0, TYPE_UINT, 0}, \ -{"t" , CONFIG_HLP_ULMCS, 0, uptr:&target_ul_mcs, defintval:0, TYPE_UINT, 0}, \ +{"a" , CONFIG_HLP_CHOFF, 0, iptr:&CHAIN_OFFSET, defintval:0, TYPE_INT, 0}, \ +{"d" , CONFIG_HLP_SOFTS, PARAMFLAG_BOOL, uptr:(uint32_t *)&DO_FORMS, defintval:0, TYPE_INT8, 0}, \ {"W" , CONFIG_HLP_L2MONW, 0, strptr:(char **)&in_ip, defstrval:"127.0.0.1", TYPE_STRING, sizeof(in_ip)}, \ {"P" , CONFIG_HLP_L2MONP, 0, strptr:(char **)&in_path, defstrval:"/tmp/oai_opt.pcap", TYPE_STRING, sizeof(in_path)}, \ {"q" , CONFIG_HLP_STMON, PARAMFLAG_BOOL, iptr:&opp_enabled, defintval:0, TYPE_INT, 0}, \ {"S" , CONFIG_HLP_MSLOTS, PARAMFLAG_BOOL, u8ptr:&exit_missed_slots, defintval:1, TYPE_UINT8, 0}, \ -{"T" , CONFIG_HLP_TDD, PARAMFLAG_BOOL, iptr:&tddflag, defintval:0, TYPE_INT, 0}, \ -{"s" , CONFIG_HLP_SNR, 0, iptr:&snr_dB, defintval:25, TYPE_INT, 0}, \ -{"numerology" , CONFIG_HLP_NUMEROLOGY, PARAMFLAG_BOOL, iptr:&numerology, defintval:0, TYPE_INT, 0}, \ -{"emulate-rf" , CONFIG_HLP_EMULATE_RF, PARAMFLAG_BOOL, iptr:&emulate_rf, defintval:0, TYPE_INT, 0}, \ +{"numerology" , CONFIG_HLP_NUMEROLOGY, PARAMFLAG_BOOL, iptr:&NUMEROLOGY, defintval:0, TYPE_INT, 0}, \ {"parallel-config", CONFIG_HLP_PARALLEL_CMD,0, strptr:(char **)¶llel_config, defstrval:NULL, TYPE_STRING, 0}, \ {"worker-config", CONFIG_HLP_WORKER_CMD, 0, strptr:(char **)&worker_config, defstrval:NULL, TYPE_STRING, 0}, \ -{"nbiot-disable", CONFIG_HLP_DISABLNBIOT, PARAMFLAG_BOOL, iptr:&nonbiotflag, defintval:0, TYPE_INT, 0} \ +{"noS1", CONFIG_HLP_NOS1, PARAMFLAG_BOOL, uptr:&noS1, defintval:0, TYPE_INT, 0}, \ +{"nokrnmod", CONFIG_HLP_NOKRNMOD, PARAMFLAG_BOOL, uptr:&nokrnmod, defintval:0, TYPE_INT, 0}, \ +{"nbiot-disable", CONFIG_HLP_DISABLNBIOT, PARAMFLAG_BOOL, uptr:&nonbiot, defuintval:0, TYPE_INT, 0}, \ } #define CONFIG_HLP_FLOG "Enable online log \n" @@ -204,11 +222,12 @@ /* command line parameters for LOG utility */ /* optname helpstr paramflags XXXptr defXXXval type numelt */ /*---------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ +#define START_MSC softmodem_params.start_msc #define CMDLINE_LOGPARAMS_DESC { \ {"R" , CONFIG_HLP_FLOG, 0, uptr:&online_log_messages, defintval:1, TYPE_INT, 0}, \ {"g" , CONFIG_HLP_LOGL, 0, uptr:&glog_level, defintval:0, TYPE_UINT, 0}, \ {"telnetsrv", CONFIG_HLP_TELN, PARAMFLAG_BOOL, uptr:&start_telnetsrv, defintval:0, TYPE_UINT, 0}, \ -{"msc", CONFIG_HLP_MSC, PARAMFLAG_BOOL, uptr:start_msc, defintval:0, TYPE_UINT, 0}, \ +{"msc", CONFIG_HLP_MSC, PARAMFLAG_BOOL, uptr:&START_MSC, defintval:0, TYPE_UINT, 0}, \ } #define CMDLINE_ONLINELOG_IDX 0 #define CMDLINE_GLOGLEVEL_IDX 1 @@ -217,6 +236,38 @@ /***************************************************************************************************************************************/ /* */ +#include "threads_t.h" + +#define SOFTMODEM_NOS1_BIT (1<<0) +#define SOFTMODEM_NOKRNMOD_BIT (1<<1) +#define SOFTMODEM_NONBIOT_BIT (1<<2) +typedef struct { + uint64_t optmask; + THREAD_STRUCT thread_struct; + char rf_config_file[1024]; + int phy_test; + uint8_t usim_test; + int emulate_rf; + int wait_for_sync; //eNodeB only + int single_thread_flag; //eNodeB only + int chain_offset; + uint32_t do_forms; + int numerology; + unsigned int start_msc; + int nonbiotflag; + uint32_t clock_source; + int hw_timing_advance; +} softmodem_params_t; + +#define SOFTMODEM_NOS1 ( get_softmodem_optmask() & SOFTMODEM_NOS1_BIT) +#define SOFTMODEM_NOKRNMOD ( get_softmodem_optmask() & SOFTMODEM_NOKRNMOD_BIT) +#define SOFTMODEM_NONBIOT ( get_softmodem_optmask() & SOFTMODEM_NONBIOT_BIT) +extern uint64_t get_softmodem_optmask(void); +extern uint64_t set_softmodem_optmask(uint64_t bitmask); +extern void get_common_options(void); +extern softmodem_params_t* get_softmodem_params(void); + +uint64_t get_pdcp_optmask(void); extern pthread_cond_t sync_cond; extern pthread_mutex_t sync_mutex; extern int sync_var; @@ -244,8 +295,8 @@ extern volatile int start_eNB; extern volatile int start_UE; #endif -#include "threads_t.h" -extern threads_t threads; + + // In lte-enb.c extern void init_eNB(int single_thread_flag,int wait_for_sync); @@ -253,7 +304,7 @@ extern void stop_eNB(int); extern void kill_eNB_proc(int inst); // In lte-ru.c -extern void init_RU(const char*); +extern void init_RU(char*); extern void stop_ru(RU_t *ru); extern void init_RU_proc(RU_t *ru); extern void stop_RU(int nb_ru); @@ -270,7 +321,7 @@ extern void init_thread(int sched_runtime, int sched_deadline, int sched_fifo, c extern void reset_opp_meas(void); extern void print_opp_meas(void); -extern void init_fep_thread(PHY_VARS_eNB *, pthread_attr_t *); + extern void init_td_thread(PHY_VARS_eNB *); extern void init_te_thread(PHY_VARS_eNB *); extern void kill_td_thread(PHY_VARS_eNB *); diff --git a/targets/RT/USER/lte-ue.c b/targets/RT/USER/lte-ue.c index fa67165693..784c14fa4d 100644 --- a/targets/RT/USER/lte-ue.c +++ b/targets/RT/USER/lte-ue.c @@ -58,8 +58,8 @@ #include "UTIL/MATH/oml.h" #include "common/utils/LOG/vcd_signal_dumper.h" #include "UTIL/OPT/opt.h" - - +#include "lte-softmodem.h" +#include "common/config/config_userapi.h" #include "T.h" extern double cpuf; @@ -158,12 +158,21 @@ static const eutra_band_t eutra_bands[] = { }; - +threads_t threads= {-1,-1,-1,-1,-1,-1,-1}; pthread_t main_ue_thread; pthread_attr_t attr_UE_thread; struct sched_param sched_param_UE_thread; + +void get_uethreads_params(void) { + paramdef_t cmdline_threadsparams[] =CMDLINE_UETHREADSPARAMS_DESC; + + + config_process_cmdline( cmdline_threadsparams,sizeof(cmdline_threadsparams)/sizeof(paramdef_t),NULL); +} + + void phy_init_lte_ue_transport(PHY_VARS_UE *ue,int absraction_flag); PHY_VARS_UE* init_ue_vars(LTE_DL_FRAME_PARMS *frame_parms, @@ -179,7 +188,7 @@ PHY_VARS_UE* init_ue_vars(LTE_DL_FRAME_PARMS *frame_parms, memcpy(&(ue->frame_parms), frame_parms, sizeof(LTE_DL_FRAME_PARMS)); } - + ue->hw_timing_advance=get_softmodem_params()->hw_timing_advance; ue->Mod_id = UE_id; ue->mac_enabled = 1; diff --git a/targets/RT/USER/lte-uesoftmodem.c b/targets/RT/USER/lte-uesoftmodem.c index 3071544133..2306dbc725 100644 --- a/targets/RT/USER/lte-uesoftmodem.c +++ b/targets/RT/USER/lte-uesoftmodem.c @@ -19,7 +19,7 @@ * contact@openairinterface.org */ -/*! \file lte-enb.c +/*! \file lte-uesoftmodem.c * \brief Top-level threads for eNodeB * \author R. Knopp, F. Kaltenberger, Navid Nikaein * \date 2012 @@ -34,9 +34,6 @@ #define _GNU_SOURCE /* See feature_test_macros(7) */ #include - -#include "T.h" - #include "rt_wrapper.h" @@ -76,8 +73,6 @@ #include "UTIL/MATH/oml.h" #include "common/utils/LOG/vcd_signal_dumper.h" #include "UTIL/OPT/opt.h" -#include "enb_config.h" -//#include "PHY/TOOLS/time_meas.h" #ifndef OPENAIR2 #include "UTIL/OTG/otg_vars.h" @@ -95,7 +90,7 @@ #endif #include "lte-softmodem.h" -RAN_CONTEXT_t RC; + /* temporary compilation wokaround (UE/eNB split */ uint16_t sf_ahead; @@ -136,12 +131,10 @@ volatile int start_UE = 0; volatile int oai_exit = 0; clock_source_t clock_source = internal; -static int wait_for_sync = 0; + unsigned int mmapped_dma=0; -int single_thread_flag=1; -static int8_t threequarter_fs=0; uint32_t downlink_frequency[MAX_NUM_CCs][4]; int32_t uplink_frequency_offset[MAX_NUM_CCs][4]; @@ -175,11 +168,6 @@ double bw = 10.0e6; static int tx_max_power[MAX_NUM_CCs]; /* = {0,0}*/; -char rf_config_file[1024]; - -int chain_offset=0; -int phy_test = 0; -uint8_t usim_test = 0; uint8_t dci_Format = 0; uint8_t agregation_Level =0xFF; @@ -194,60 +182,33 @@ int rx_input_level_dBm; #ifdef XFORMS extern int otg_enabled; -static char do_forms=0; -#else -int otg_enabled; #endif //int number_of_cards = 1; static LTE_DL_FRAME_PARMS *frame_parms[MAX_NUM_CCs]; -uint32_t target_dl_mcs = 28; //maximum allowed mcs -uint32_t target_ul_mcs = 20; -uint32_t timing_advance = 0; + uint8_t exit_missed_slots=1; uint64_t num_missed_slots=0; // counter for the number of missed slots - +/* prototypes from function implemented in lte-ue.c, probably should be elsewhere in a include + file */ extern void init_UE_stub_single_thread(int nb_inst,int eMBMS_active, int uecap_xer_in, char *emul_iface); extern PHY_VARS_UE* init_ue_vars(LTE_DL_FRAME_PARMS *frame_parms, uint8_t UE_id, uint8_t abstraction_flag); +extern void get_uethreads_params(void); int transmission_mode=1; -int emulate_rf = 0; -int numerology = 0; -char *parallel_config = NULL; -char *worker_config = NULL; + char* usrp_args=NULL; char* usrp_clksrc=NULL; -static THREAD_STRUCT thread_struct; -void set_parallel_conf(char *parallel_conf) -{ - if(strcmp(parallel_conf,"PARALLEL_SINGLE_THREAD")==0) thread_struct.parallel_conf = PARALLEL_SINGLE_THREAD; - else if(strcmp(parallel_conf,"PARALLEL_RU_L1_SPLIT")==0) thread_struct.parallel_conf = PARALLEL_RU_L1_SPLIT; - else if(strcmp(parallel_conf,"PARALLEL_RU_L1_TRX_SPLIT")==0) thread_struct.parallel_conf = PARALLEL_RU_L1_TRX_SPLIT; - printf("[CONFIG] parallel conf is set to %d\n",thread_struct.parallel_conf); -} -void set_worker_conf(char *worker_conf) -{ - if(strcmp(worker_conf,"WORKER_DISABLE")==0) thread_struct.worker_conf = WORKER_DISABLE; - else if(strcmp(worker_conf,"WORKER_ENABLE")==0) thread_struct.worker_conf = WORKER_ENABLE; - printf("[CONFIG] worker conf is set to %d\n",thread_struct.worker_conf); -} -PARALLEL_CONF_t get_thread_parallel_conf(void) -{ - return thread_struct.parallel_conf; -} -WORKER_CONF_t get_thread_worker_conf(void) -{ - return thread_struct.worker_conf; -} + /* struct for ethernet specific parameters given in eNB conf file */ eth_params_t *eth_params; @@ -260,7 +221,7 @@ extern char uecap_xer[1024]; char uecap_xer_in=0; int oaisim_flag=0; -threads_t threads= {-1,-1,-1,-1,-1,-1,-1}; + /* see file openair2/LAYER2/MAC/main.c for why abstraction_flag is needed * this is very hackish - find a proper solution @@ -321,7 +282,8 @@ unsigned int build_rfdc(int dcoff_i_rxfe, int dcoff_q_rxfe) { return (dcoff_i_rxfe + (dcoff_q_rxfe<<8)); } -#if !defined(ENABLE_ITTI) + + void signal_handler(int sig) { void *array[10]; size_t size; @@ -335,17 +297,13 @@ void signal_handler(int sig) { backtrace_symbols_fd(array, size, 2); exit(-1); } else { - printf("trying to exit gracefully...\n"); - oai_exit = 1; + char msg[64]; + sprintf(msg,"Received linux signal %s...\n",strsignal(sig)); + exit_function(__FILE__, __FUNCTION__, __LINE__,msg); + + } } -#endif -#define KNRM "\x1B[0m" -#define KRED "\x1B[31m" -#define KGRN "\x1B[32m" -#define KBLU "\x1B[34m" -#define RESET "\033[0m" - void exit_function(const char* file, const char* function, const int line, const char* s) @@ -353,9 +311,8 @@ void exit_function(const char* file, const char* function, const int line, const int CC_id; logClean(); - if (s != NULL) { - printf("%s:%d %s() Exiting OAI softmodem: %s\n",file,line, function, s); - } + printf("%s:%d %s() Exiting OAI softmodem: %s\n",file,line, function, ((s==NULL)?"":s)); + oai_exit = 1; @@ -369,7 +326,8 @@ void exit_function(const char* file, const char* function, const int line, const sleep(1); //allow lte-softmodem threads to exit first #if defined(ENABLE_ITTI) - itti_terminate_tasks (TASK_UNKNOWN); + if(PHY_vars_UE_g != NULL ) + itti_terminate_tasks (TASK_UNKNOWN); #endif exit(1); } @@ -496,50 +454,27 @@ void *l2l1_task(void *arg) { extern int16_t dlsch_demod_shift; -static void get_options(unsigned int *start_msc) { +static void get_options(void) { int CC_id; - int tddflag, nonbiotflag; + int tddflag; char *loopfile=NULL; int dumpframe; - uint32_t online_log_messages; - uint32_t glog_level; - uint32_t start_telnetsrv; - - paramdef_t cmdline_params[] =CMDLINE_PARAMS_DESC ; - paramdef_t cmdline_logparams[] =CMDLINE_LOGPARAMS_DESC ; + int timingadv; set_default_frame_parms(frame_parms); CONFIG_SETRTFLAG(CONFIG_NOEXITONHELP); - config_process_cmdline( cmdline_params,sizeof(cmdline_params)/sizeof(paramdef_t),NULL); - - if (strlen(in_path) > 0) { - opt_type = OPT_PCAP; - opt_enabled=1; - printf("Enabling OPT for PCAP with the following file %s \n",in_path); - } - if (strlen(in_ip) > 0) { - opt_enabled=1; - opt_type = OPT_WIRESHARK; - printf("Enabling OPT for wireshark for local interface"); - } - - config_process_cmdline( cmdline_logparams,sizeof(cmdline_logparams)/sizeof(paramdef_t),NULL); - if(config_isparamset(cmdline_logparams,CMDLINE_ONLINELOG_IDX)) { - set_glog_onlinelog(online_log_messages); - } - if(config_isparamset(cmdline_logparams,CMDLINE_GLOGLEVEL_IDX)) { - set_glog(glog_level); - } - if (start_telnetsrv) { - load_module_shlib("telnetsrv",NULL,0,NULL); - } +/* unknown parameters on command line will be checked in main + after all init have been performed */ + CONFIG_SETRTFLAG(CONFIG_NOCHECKUNKOPT); + get_common_options(); + get_uethreads_params(); paramdef_t cmdline_uemodeparams[] =CMDLINE_UEMODEPARAMS_DESC; paramdef_t cmdline_ueparams[] =CMDLINE_UEPARAMS_DESC; config_process_cmdline( cmdline_uemodeparams,sizeof(cmdline_uemodeparams)/sizeof(paramdef_t),NULL); - CONFIG_CLEARRTFLAG(CONFIG_NOEXITONHELP); + config_process_cmdline( cmdline_ueparams,sizeof(cmdline_ueparams)/sizeof(paramdef_t),NULL); if (loopfile != NULL) { printf("Input file for hardware emulation: %s",loopfile); @@ -547,7 +482,7 @@ static void get_options(unsigned int *start_msc) { input_fd = fopen(loopfile,"r"); AssertFatal(input_fd != NULL,"Please provide a valid input file\n"); } - + get_softmodem_params()->hw_timing_advance = timingadv; if ( (cmdline_uemodeparams[CMDLINE_CALIBUERX_IDX].paramflags & PARAMFLAG_PARAMSET) != 0) mode = rx_calib_ue; if ( (cmdline_uemodeparams[CMDLINE_CALIBUERXMED_IDX].paramflags & PARAMFLAG_PARAMSET) != 0) mode = rx_calib_ue_med; if ( (cmdline_uemodeparams[CMDLINE_CALIBUERXBYP_IDX].paramflags & PARAMFLAG_PARAMSET) != 0) mode = rx_calib_ue_byp; @@ -609,8 +544,6 @@ static void get_options(unsigned int *start_msc) { if(nfapi_mode!=3) uecap_xer_in=1; } *//* UE with config file */ - if(parallel_config != NULL) set_parallel_conf(parallel_config); - if(worker_config != NULL) set_worker_conf(worker_config); } @@ -735,7 +668,7 @@ void init_openair0(LTE_DL_FRAME_PARMS *frame_parms,int rxgain) { openair0_cfg[card].rx_gain[i] = rxgain - rx_gain_off; - openair0_cfg[card].configFilename = rf_config_file; + openair0_cfg[card].configFilename = get_softmodem_params()->rf_config_file; printf("Card %d, channel %d, Setting tx_gain %f, rx_gain %f, tx_freq %f, rx_freq %f\n", card,i, openair0_cfg[card].tx_gain[i], openair0_cfg[card].rx_gain[i], @@ -818,7 +751,6 @@ int main( int argc, char **argv ) int CC_id; uint8_t abstraction_flag=0; - unsigned int start_msc=0; // Default value for the number of UEs. It will hold, // if not changed from the command line option --num-ues @@ -845,10 +777,11 @@ int main( int argc, char **argv ) printf("Reading in command-line options\n"); - for (int i=0;istart_msc) { load_module_shlib("msc",NULL,0,&msc_interface); } MSC_INIT(MSC_E_UTRAN, THREAD_MAX+TASK_MAX); @@ -921,12 +844,11 @@ printf("~~~~~~~~~~~~~~~~~~~~successfully get the parallel config[%d], worker con pdcp_pc5_socket_init(); #endif -#if !defined(ENABLE_ITTI) // to make a graceful exit when ctrl-c is pressed signal(SIGSEGV, signal_handler); signal(SIGINT, signal_handler); -#endif - + signal(SIGTERM, signal_handler); + signal(SIGABRT, signal_handler); check_clock(); @@ -954,7 +876,7 @@ printf("~~~~~~~~~~~~~~~~~~~~successfully get the parallel config[%d], worker con PHY_vars_UE_g[i][CC_id] = init_ue_vars(frame_parms[CC_id], i,abstraction_flag); - if (phy_test==1) + if (get_softmodem_params()->phy_test==1) PHY_vars_UE_g[i][CC_id]->mac_enabled = 0; else PHY_vars_UE_g[i][CC_id]->mac_enabled = 1; @@ -983,12 +905,12 @@ printf("~~~~~~~~~~~~~~~~~~~~successfully get the parallel config[%d], worker con init_UE_stub_single_thread(NB_UE_INST,eMBMS_active,uecap_xer_in,emul_iface); } else { - init_UE(NB_UE_INST,eMBMS_active,uecap_xer_in,0,phy_test,UE_scan,UE_scan_carrier,mode,(int)rx_gain[0][0],tx_max_power[0], + init_UE(NB_UE_INST,eMBMS_active,uecap_xer_in,0,get_softmodem_params()->phy_test,UE_scan,UE_scan_carrier,mode,(int)rx_gain[0][0],tx_max_power[0], frame_parms[0]); } - if (phy_test==0) { + if (get_softmodem_params()->phy_test==0) { printf("Filling UE band info\n"); fill_ue_band_info(); dl_phy_sync_success (0, 0, 0, 1); @@ -998,7 +920,7 @@ printf("~~~~~~~~~~~~~~~~~~~~successfully get the parallel config[%d], worker con number_of_cards = 1; for(CC_id=0; CC_idrf_map.card=0; - PHY_vars_UE_g[0][CC_id]->rf_map.chain=CC_id+chain_offset; + PHY_vars_UE_g[0][CC_id]->rf_map.chain=CC_id+(get_softmodem_params()->chain_offset); } } @@ -1128,7 +1050,7 @@ printf("~~~~~~~~~~~~~~~~~~~~successfully get the parallel config[%d], worker con printf("XFORMS\n"); - if (do_forms==1) { + if (get_softmodem_params()->do_forms==1) { fl_initialize (&argc, argv, NULL, 0, 0); form_stats = create_form_stats_form(); @@ -1157,7 +1079,12 @@ printf("~~~~~~~~~~~~~~~~~~~~successfully get the parallel config[%d], worker con } #endif - + ret=config_check_cmdlineopt(CONFIG_CHECKALLSECTIONS); + if (ret != 0) { + LOG_E(ENB_APP, "%i unknown options in command line (invalid section name)\n",ret); + exit_fun(""); + } + printf("Sending sync to all threads (%p,%p,%p)\n",&sync_var,&sync_cond,&sync_mutex); @@ -1195,7 +1122,7 @@ printf("~~~~~~~~~~~~~~~~~~~~successfully get the parallel config[%d], worker con #ifdef XFORMS printf("waiting for XFORMS thread\n"); - if (do_forms==1) { + if (get_softmodem_params()->do_forms==1) { pthread_join(forms_thread,&status); fl_hide_form(form_stats->stats_form); fl_free_form(form_stats->stats_form); diff --git a/targets/RT/USER/rfsim.c b/targets/RT/USER/rfsim.c index cdf8f1ad0d..37ce9f92ea 100644 --- a/targets/RT/USER/rfsim.c +++ b/targets/RT/USER/rfsim.c @@ -62,7 +62,6 @@ sim_t sim; void init_ru_devices(void); -void init_RU(const char*); void *rfsim_top(void *n_frames); void wait_RUs(void) From 8dd62b32e3edf5b0d78baea47d97cba1f244ee64 Mon Sep 17 00:00:00 2001 From: frtabu Date: Fri, 2 Nov 2018 17:29:05 +0100 Subject: [PATCH 088/233] fix bad build_oai directive to compile libconfig for phy-simulators, fix load_configmodule crash because config source not set. --- cmake_targets/build_oai | 2 +- common/config/config_load_configmodule.c | 18 +++++++++++++----- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/cmake_targets/build_oai b/cmake_targets/build_oai index 37f8d711db..51d6ac6d01 100755 --- a/cmake_targets/build_oai +++ b/cmake_targets/build_oai @@ -652,7 +652,7 @@ function main() { lte-simulators coding \ libcoding.so $dbin/libcoding.so compilations \ - phy_simulators $config_libconfig_shlib \ + lte-simulators $config_libconfig_shlib \ lib$config_libconfig_shlib.so $dbin/lib$config_libconfig_shlib.so fi diff --git a/common/config/config_load_configmodule.c b/common/config/config_load_configmodule.c index 7c8c61135b..cfb6e38440 100644 --- a/common/config/config_load_configmodule.c +++ b/common/config/config_load_configmodule.c @@ -201,12 +201,20 @@ int OoptIdx=-1; cfgparam = getenv("OAI_CONFIGMODULE"); } -/* default */ +/* default different for UE and softmodem because UE doesn't use config file*/ +/* and -O option is not mandatory for UE */ +/* phy simulators behave as UE */ +/* test of exec name would better be replaced by a parameter to the l */ +/* oad_configmodule function */ if (cfgparam == NULL) { tmpflags = tmpflags | CONFIG_NOOOPT; - cfgparam = CONFIG_CMDLINEONLY ":dbgl0" ; + if (strstr(argv[0],"uesoftmodem") == NULL || strstr(argv[0],"lsim") == NULL) { + cfgparam = CONFIG_LIBCONFIGFILE ":" DEFAULT_CFGFILENAME; + } else { + cfgparam = CONFIG_CMDLINEONLY ":dbgl0" ; + } } - + /* parse the config parameters to set the config source */ i = sscanf(cfgparam,"%m[^':']:%ms",&cfgmode,&modeparams); if (i< 0) { @@ -215,9 +223,9 @@ int OoptIdx=-1; } else if ( i == 1 ) { /* -O argument doesn't contain ":" separator, assume -O option, default cfgmode to libconfig - with one parameter, the path to the configuration file */ + with one parameter, the path to the configuration file cfgmode must not be NULL */ modeparams=cfgmode; - cfgmode=NULL; //strdup(CONFIG_LIBCONFIGFILE); + cfgmode=strdup(CONFIG_LIBCONFIGFILE); } cfgptr = calloc(sizeof(configmodule_interface_t),1); From 519708b6ec81debf79e95581df8e02947d78ec66 Mon Sep 17 00:00:00 2001 From: Raphael Defosseux Date: Mon, 5 Nov 2018 11:03:14 +0100 Subject: [PATCH 089/233] CI: optimization to build incrementally in time --- cherry-picked from develop-nr (d354ededf459d79ded19fbda68b825924773d893) Signed-off-by: Raphael Defosseux --- ci-scripts/Jenkinsfile-gitlab | 54 ++--- ci-scripts/buildOnVM.sh | 61 +++++- ci-scripts/waitBuildOnVM.sh | 372 ++++++++++++++++++++++++++++++++++ 3 files changed, 451 insertions(+), 36 deletions(-) create mode 100755 ci-scripts/waitBuildOnVM.sh diff --git a/ci-scripts/Jenkinsfile-gitlab b/ci-scripts/Jenkinsfile-gitlab index 54ceca9603..7ef68e36cf 100644 --- a/ci-scripts/Jenkinsfile-gitlab +++ b/ci-scripts/Jenkinsfile-gitlab @@ -115,10 +115,10 @@ pipeline { } } - stage ("Start VM -- cppcheck") { + stage ("Start VM -- basic-sim") { steps { timeout (time: 5, unit: 'MINUTES') { - sh "./ci-scripts/createVM.sh --variant cppcheck --job-name ${JOB_NAME} --build-id ${BUILD_ID}" + sh "./ci-scripts/buildOnVM.sh --workspace $WORKSPACE --variant basic-sim --job-name ${JOB_NAME} --build-id ${BUILD_ID} --daemon" } } } @@ -126,23 +126,7 @@ pipeline { stage ("Start VM -- enb-usrp") { steps { timeout (time: 5, unit: 'MINUTES') { - sh "./ci-scripts/createVM.sh --variant enb-usrp --job-name ${JOB_NAME} --build-id ${BUILD_ID}" - } - } - } - - stage ("Start VM -- basic-sim") { - steps { - timeout (time: 5, unit: 'MINUTES') { - sh "./ci-scripts/createVM.sh --variant basic-sim --job-name ${JOB_NAME} --build-id ${BUILD_ID}" - } - } - } - - stage ("Start VM -- phy-sim") { - steps { - timeout (time: 5, unit: 'MINUTES') { - sh "./ci-scripts/createVM.sh --variant phy-sim --job-name ${JOB_NAME} --build-id ${BUILD_ID}" + sh "./ci-scripts/buildOnVM.sh --workspace $WORKSPACE --variant enb-usrp --job-name ${JOB_NAME} --build-id ${BUILD_ID} --daemon" } } } @@ -150,7 +134,7 @@ pipeline { stage ("Start VM -- enb-ethernet") { steps { timeout (time: 5, unit: 'MINUTES') { - sh "./ci-scripts/createVM.sh --variant enb-ethernet --job-name ${JOB_NAME} --build-id ${BUILD_ID}" + sh "./ci-scripts/buildOnVM.sh --workspace $WORKSPACE --variant enb-ethernet --job-name ${JOB_NAME} --build-id ${BUILD_ID} --daemon" } } } @@ -158,7 +142,23 @@ pipeline { stage ("Start VM -- ue-ethernet") { steps { timeout (time: 5, unit: 'MINUTES') { - sh "./ci-scripts/createVM.sh --variant ue-ethernet --job-name ${JOB_NAME} --build-id ${BUILD_ID}" + sh "./ci-scripts/buildOnVM.sh --workspace $WORKSPACE --variant ue-ethernet --job-name ${JOB_NAME} --build-id ${BUILD_ID} --daemon" + } + } + } + + stage ("Start VM -- phy-sim") { + steps { + timeout (time: 5, unit: 'MINUTES') { + sh "./ci-scripts/buildOnVM.sh --workspace $WORKSPACE --variant phy-sim --job-name ${JOB_NAME} --build-id ${BUILD_ID} --daemon" + } + } + } + + stage ("Start VM -- cppcheck") { + steps { + timeout (time: 5, unit: 'MINUTES') { + sh "./ci-scripts/buildOnVM.sh --workspace $WORKSPACE --variant cppcheck --job-name ${JOB_NAME} --build-id ${BUILD_ID} --daemon" } } } @@ -169,7 +169,7 @@ pipeline { steps { gitlabCommitStatus(name: "Analysis with cppcheck") { timeout (time: 20, unit: 'MINUTES') { - sh "./ci-scripts/buildOnVM.sh --workspace $WORKSPACE --variant cppcheck --job-name ${JOB_NAME} --build-id ${BUILD_ID}" + sh "./ci-scripts/waitBuildOnVM.sh --workspace $WORKSPACE --variant cppcheck --job-name ${JOB_NAME} --build-id ${BUILD_ID}" } } } @@ -178,7 +178,7 @@ pipeline { steps { gitlabCommitStatus(name: "Build eNb-USRP") { timeout (time: 20, unit: 'MINUTES') { - sh "./ci-scripts/buildOnVM.sh --workspace $WORKSPACE --variant enb-usrp --job-name ${JOB_NAME} --build-id ${BUILD_ID}" + sh "./ci-scripts/waitBuildOnVM.sh --workspace $WORKSPACE --variant enb-usrp --job-name ${JOB_NAME} --build-id ${BUILD_ID}" } } } @@ -187,7 +187,7 @@ pipeline { steps { gitlabCommitStatus(name: "Build basic-sim") { timeout (time: 20, unit: 'MINUTES') { - sh "./ci-scripts/buildOnVM.sh --workspace $WORKSPACE --variant basic-sim --job-name ${JOB_NAME} --build-id ${BUILD_ID} --keep-vm-alive" + sh "./ci-scripts/waitBuildOnVM.sh --workspace $WORKSPACE --variant basic-sim --job-name ${JOB_NAME} --build-id ${BUILD_ID} --keep-vm-alive" } } } @@ -196,7 +196,7 @@ pipeline { steps { gitlabCommitStatus(name: "Build phy-sim") { timeout (time: 20, unit: 'MINUTES') { - sh "./ci-scripts/buildOnVM.sh --workspace $WORKSPACE --variant phy-sim --job-name ${JOB_NAME} --build-id ${BUILD_ID} --keep-vm-alive" + sh "./ci-scripts/waitBuildOnVM.sh --workspace $WORKSPACE --variant phy-sim --job-name ${JOB_NAME} --build-id ${BUILD_ID} --keep-vm-alive" } } } @@ -205,7 +205,7 @@ pipeline { steps { gitlabCommitStatus(name: "Build eNb-ethernet") { timeout (time: 20, unit: 'MINUTES') { - sh "./ci-scripts/buildOnVM.sh --workspace $WORKSPACE --variant enb-ethernet --job-name ${JOB_NAME} --build-id ${BUILD_ID} --keep-vm-alive" + sh "./ci-scripts/waitBuildOnVM.sh --workspace $WORKSPACE --variant enb-ethernet --job-name ${JOB_NAME} --build-id ${BUILD_ID} --keep-vm-alive" } } } @@ -214,7 +214,7 @@ pipeline { steps { gitlabCommitStatus(name: "Build UE-ethernet") { timeout (time: 20, unit: 'MINUTES') { - sh "./ci-scripts/buildOnVM.sh --workspace $WORKSPACE --variant ue-ethernet --job-name ${JOB_NAME} --build-id ${BUILD_ID} --keep-vm-alive" + sh "./ci-scripts/waitBuildOnVM.sh --workspace $WORKSPACE --variant ue-ethernet --job-name ${JOB_NAME} --build-id ${BUILD_ID} --keep-vm-alive" } } } diff --git a/ci-scripts/buildOnVM.sh b/ci-scripts/buildOnVM.sh index 2a358c9bac..0fb85b24eb 100755 --- a/ci-scripts/buildOnVM.sh +++ b/ci-scripts/buildOnVM.sh @@ -55,6 +55,9 @@ function usage { echo " --keep-vm-alive OR -k" echo " Keep the VM alive after the build." echo "" + echo " --daemon OR -D" + echo " Run as daemon" + echo "" echo " --help OR -h" echo " Print this help message." echo "" @@ -92,6 +95,7 @@ LOG_PATTERN=.Rel14.txt NB_PATTERN_FILES=4 BUILD_OPTIONS="--eNB -w USRP" KEEP_VM_ALIVE=0 +DAEMON=0 while [[ $# -gt 0 ]] do @@ -122,6 +126,10 @@ case $key in KEEP_VM_ALIVE=1 shift ;; + -D|--daemon) + DAEMON=1 + shift + ;; -v1) VM_NAME=ci-enb-usrp ARCHIVES_LOC=enb_usrp @@ -297,13 +305,27 @@ echo "sudo cp 01proxy /etc/apt/apt.conf.d/" > $VM_CMDS echo "touch /home/ubuntu/.hushlogin" >> $VM_CMDS if [[ "$VM_NAME" == *"-cppcheck"* ]] then - echo "echo \"sudo apt-get --yes --quiet install zip cppcheck \"" >> $VM_CMDS - echo "sudo apt-get update > zip-install.txt 2>&1" >> $VM_CMDS - echo "sudo apt-get --yes install zip cppcheck >> zip-install.txt 2>&1" >> $VM_CMDS + if [ $DAEMON -eq 0 ] + then + echo "echo \"sudo apt-get --yes --quiet install zip cppcheck \"" >> $VM_CMDS + echo "sudo apt-get update > zip-install.txt 2>&1" >> $VM_CMDS + echo "sudo apt-get --yes install zip cppcheck >> zip-install.txt 2>&1" >> $VM_CMDS + else + echo "echo \"sudo apt-get --yes --quiet install zip daemon cppcheck \"" >> $VM_CMDS + echo "sudo apt-get update > zip-install.txt 2>&1" >> $VM_CMDS + echo "sudo apt-get --yes install zip daemon cppcheck >> zip-install.txt 2>&1" >> $VM_CMDS + fi else - echo "echo \"sudo apt-get --yes --quiet install zip subversion libboost-dev \"" >> $VM_CMDS - echo "sudo apt-get update > zip-install.txt 2>&1" >> $VM_CMDS - echo "sudo apt-get --yes install zip subversion libboost-dev >> zip-install.txt 2>&1" >> $VM_CMDS + if [ $DAEMON -eq 0 ] + then + echo "echo \"sudo apt-get --yes --quiet install zip subversion libboost-dev \"" >> $VM_CMDS + echo "sudo apt-get update > zip-install.txt 2>&1" >> $VM_CMDS + echo "sudo apt-get --yes install zip subversion libboost-dev >> zip-install.txt 2>&1" >> $VM_CMDS + else + echo "echo \"sudo apt-get --yes --quiet install zip daemon subversion libboost-dev \"" >> $VM_CMDS + echo "sudo apt-get update > zip-install.txt 2>&1" >> $VM_CMDS + echo "sudo apt-get --yes install zip daemon subversion libboost-dev >> zip-install.txt 2>&1" >> $VM_CMDS + fi fi echo "mkdir tmp" >> $VM_CMDS echo "cd tmp" >> $VM_CMDS @@ -314,17 +336,38 @@ then echo "mkdir cmake_targets/log" >> $VM_CMDS echo "cp /home/ubuntu/zip-install.txt cmake_targets/log" >> $VM_CMDS echo "echo \"cppcheck $BUILD_OPTIONS . \"" >> $VM_CMDS - echo "cppcheck $BUILD_OPTIONS . 2> cmake_targets/log/cppcheck.xml 1> cmake_targets/log/cppcheck_build.txt" >> $VM_CMDS + if [ $DAEMON -eq 0 ] + then + echo "cppcheck $BUILD_OPTIONS . 2> cmake_targets/log/cppcheck.xml 1> cmake_targets/log/cppcheck_build.txt" >> $VM_CMDS + else + echo "echo \"cppcheck $BUILD_OPTIONS .\" > ./my-vm-build.sh" >> $VM_CMDS + echo "chmod 775 ./my-vm-build.sh " >> $VM_CMDS + echo "sudo -E daemon --inherit --unsafe --name=build_daemon --chdir=/home/ubuntu/tmp -O /home/ubuntu/tmp/cmake_targets/log/cppcheck_build.txt -E /home/ubuntu/tmp/cmake_targets/log/cppcheck.xml ./my-vm-build.sh" >> $VM_CMDS + fi else echo "echo \"source oaienv\"" >> $VM_CMDS echo "source oaienv" >> $VM_CMDS echo "cd cmake_targets/" >> $VM_CMDS echo "mkdir log" >> $VM_CMDS echo "cp /home/ubuntu/zip-install.txt log" >> $VM_CMDS - echo "echo \"./build_oai -I $BUILD_OPTIONS \"" >> $VM_CMDS - echo "./build_oai -I $BUILD_OPTIONS > log/install-build.txt 2>&1" >> $VM_CMDS + if [ $DAEMON -eq 0 ] + then + echo "echo \"./build_oai -I $BUILD_OPTIONS \"" >> $VM_CMDS + echo "./build_oai -I $BUILD_OPTIONS > log/install-build.txt 2>&1" >> $VM_CMDS + else + echo "echo \"./build_oai -I $BUILD_OPTIONS\" > ./my-vm-build.sh" >> $VM_CMDS + echo "chmod 775 ./my-vm-build.sh " >> $VM_CMDS + echo "echo \"sudo -E daemon --inherit --unsafe --name=build_daemon --chdir=/home/ubuntu/tmp/cmake_targets -o /home/ubuntu/tmp/cmake_targets/log/install-build.txt ./my-vm-build.sh\"" >> $VM_CMDS + echo "sudo -E daemon --inherit --unsafe --name=build_daemon --chdir=/home/ubuntu/tmp/cmake_targets -o /home/ubuntu/tmp/cmake_targets/log/install-build.txt ./my-vm-build.sh" >> $VM_CMDS + fi fi ssh -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR < $VM_CMDS +if [ $DAEMON -eq 1 ] +then + rm -f $VM_CMDS + echo "STATUS is OK" + exit 0 +fi echo "############################################################" echo "Creating a tmp folder to store results and artifacts" diff --git a/ci-scripts/waitBuildOnVM.sh b/ci-scripts/waitBuildOnVM.sh new file mode 100755 index 0000000000..48429cb7e2 --- /dev/null +++ b/ci-scripts/waitBuildOnVM.sh @@ -0,0 +1,372 @@ +#!/bin/bash +#/* +# * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more +# * contributor license agreements. See the NOTICE file distributed with +# * this work for additional information regarding copyright ownership. +# * The OpenAirInterface Software Alliance licenses this file to You under +# * the OAI Public License, Version 1.1 (the "License"); you may not use this file +# * except in compliance with the License. +# * You may obtain a copy of the License at +# * +# * http://www.openairinterface.org/?page_id=698 +# * +# * Unless required by applicable law or agreed to in writing, software +# * distributed under the License is distributed on an "AS IS" BASIS, +# * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# * See the License for the specific language governing permissions and +# * limitations under the License. +# *------------------------------------------------------------------------------- +# * For more information about the OpenAirInterface (OAI) Software Alliance: +# * contact@openairinterface.org +# */ + +function usage { + echo "OAI VM Build Check script" + echo " Original Author: Raphael Defosseux" + echo " Requirements:" + echo " -- uvtool uvtool-libvirt apt-cacher" + echo " -- xenial image already synced" + echo " Default:" + echo " -- eNB with USRP" + echo "" + echo "Usage:" + echo "------" + echo " waitBuildOnVM.sh [OPTIONS]" + echo "" + echo "Options:" + echo "--------" + echo " --job-name #### OR -jn ####" + echo " Specify the name of the Jenkins job." + echo "" + echo " --build-id #### OR -id ####" + echo " Specify the build ID of the Jenkins job." + echo "" + echo " --workspace #### OR -ws ####" + echo " Specify the workspace." + echo "" + echo " --variant enb-usrp OR -v1" + echo " --variant basic-sim OR -v2" + echo " --variant phy-sim OR -v3" + echo " --variant cppcheck OR -v4" + echo " --variant enb-ethernet OR -v7" + echo " --variant ue-ethernet OR -v8" + echo " Specify the variant to build." + echo "" + echo " --keep-vm-alive OR -k" + echo " Keep the VM alive after the build." + echo "" + echo " --help OR -h" + echo " Print this help message." + echo "" +} + +function variant_usage { + echo "OAI VM Build Check script" + echo " Original Author: Raphael Defosseux" + echo "" + echo " --variant enb-usrp OR -v1" + echo " --variant basic-sim OR -v2" + echo " --variant phy-sim OR -v3" + echo " --variant cppcheck OR -v4" + echo " --variant enb-ethernet OR -v7" + echo " --variant ue-ethernet OR -v8" + echo "" +} + +if [ $# -lt 1 ] || [ $# -gt 9 ] +then + echo "Syntax Error: not the correct number of arguments" + echo "" + usage + exit 1 +fi + +VM_TEMPLATE=ci- +JOB_NAME=XX +BUILD_ID=XX +VM_NAME=ci-enb-usrp +VM_MEMORY=2048 +VM_CPU=4 +ARCHIVES_LOC=enb_usrp +LOG_PATTERN=.Rel14.txt +NB_PATTERN_FILES=4 +BUILD_OPTIONS="--eNB -w USRP" +KEEP_VM_ALIVE=0 + +while [[ $# -gt 0 ]] +do +key="$1" + +case $key in + -h|--help) + shift + usage + exit 0 + ;; + -jn|--job-name) + JOB_NAME="$2" + shift + shift + ;; + -id|--build-id) + BUILD_ID="$2" + shift + shift + ;; + -ws|--workspace) + JENKINS_WKSP="$2" + shift + shift + ;; + -k|--keep-vm-alive) + KEEP_VM_ALIVE=1 + shift + ;; + -v1) + VM_NAME=ci-enb-usrp + ARCHIVES_LOC=enb_usrp + LOG_PATTERN=.Rel14.txt + NB_PATTERN_FILES=4 + BUILD_OPTIONS="--eNB -w USRP --mu" + shift + ;; + -v2) + VM_NAME=ci-basic-sim + ARCHIVES_LOC=basic_sim + LOG_PATTERN=basic_simulator + NB_PATTERN_FILES=2 + BUILD_OPTIONS="--basic-simulator" + VM_MEMORY=8192 + VM_CPU=4 + shift + ;; + -v3) + VM_NAME=ci-phy-sim + ARCHIVES_LOC=phy_sim + LOG_PATTERN=.Rel14.txt + NB_PATTERN_FILES=3 + BUILD_OPTIONS="--phy_simulators" + shift + ;; + -v4) + VM_NAME=ci-cppcheck + VM_MEMORY=4096 + ARCHIVES_LOC=cppcheck + LOG_PATTERN=cppcheck.xml + NB_PATTERN_FILES=1 + BUILD_OPTIONS="--enable=warning --force --xml --xml-version=2" + shift + ;; + -v7) + VM_NAME=ci-enb-ethernet + ARCHIVES_LOC=enb_eth + LOG_PATTERN=.Rel14.txt + NB_PATTERN_FILES=6 + BUILD_OPTIONS="--eNB -t ETHERNET --noS1" + shift + ;; + -v8) + VM_NAME=ci-ue-ethernet + ARCHIVES_LOC=ue_eth + LOG_PATTERN=.Rel14.txt + NB_PATTERN_FILES=6 + BUILD_OPTIONS="--UE -t ETHERNET --noS1" + shift + ;; + --variant) + variant="$2" + case $variant in + enb-usrp) + VM_NAME=ci-enb-usrp + ARCHIVES_LOC=enb_usrp + LOG_PATTERN=.Rel14.txt + NB_PATTERN_FILES=4 + BUILD_OPTIONS="--eNB -w USRP --mu" + ;; + basic-sim) + VM_NAME=ci-basic-sim + ARCHIVES_LOC=basic_sim + LOG_PATTERN=basic_simulator + NB_PATTERN_FILES=2 + BUILD_OPTIONS="--basic-simulator" + VM_MEMORY=8192 + VM_CPU=4 + ;; + phy-sim) + VM_NAME=ci-phy-sim + ARCHIVES_LOC=phy_sim + LOG_PATTERN=.Rel14.txt + NB_PATTERN_FILES=3 + BUILD_OPTIONS="--phy_simulators" + ;; + cppcheck) + VM_NAME=ci-cppcheck + VM_MEMORY=4096 + ARCHIVES_LOC=cppcheck + LOG_PATTERN=cppcheck.xml + NB_PATTERN_FILES=1 + BUILD_OPTIONS="--enable=warning --force --xml --xml-version=2" + ;; + enb-ethernet) + VM_NAME=ci-enb-ethernet + ARCHIVES_LOC=enb_eth + LOG_PATTERN=.Rel14.txt + NB_PATTERN_FILES=6 + BUILD_OPTIONS="--eNB -t ETHERNET --noS1" + ;; + ue-ethernet) + VM_NAME=ci-ue-ethernet + ARCHIVES_LOC=ue_eth + LOG_PATTERN=.Rel14.txt + NB_PATTERN_FILES=6 + BUILD_OPTIONS="--UE -t ETHERNET --noS1" + ;; + *) + echo "" + echo "Syntax Error: Invalid Variant option -> $variant" + echo "" + variant_usage + exit 1 + esac + shift + shift + ;; + *) + echo "Syntax Error: unknown option: $key" + echo "" + usage + exit 1 +esac +done + +if [ ! -f $JENKINS_WKSP/localZip.zip ] +then + echo "Missing localZip.zip file!" + exit 1 +fi +if [ ! -f /etc/apt/apt.conf.d/01proxy ] +then + echo "Missing /etc/apt/apt.conf.d/01proxy file!" + echo "Is apt-cacher installed and configured?" + exit 1 +fi + +if [ "$JOB_NAME" == "XX" ] || [ "$BUILD_ID" == "XX" ] +then + VM_TEMPLATE=ci- +else + VM_TEMPLATE=${JOB_NAME}-b${BUILD_ID}- +fi + +VM_NAME=`echo $VM_NAME | sed -e "s#ci-#$VM_TEMPLATE#"` +VM_CMDS=${VM_NAME}_cmds.txt +ARCHIVES_LOC=${JENKINS_WKSP}/archives/${ARCHIVES_LOC} + +echo "VM_NAME = $VM_NAME" +echo "VM_CMD_FILE = $VM_CMDS" +echo "JENKINS_WKSP = $JENKINS_WKSP" +echo "ARCHIVES_LOC = $ARCHIVES_LOC" +echo "BUILD_OPTIONS = $BUILD_OPTIONS" + +IS_VM_ALIVE=`uvt-kvm list | grep -c $VM_NAME` + +if [ $IS_VM_ALIVE -eq 0 ] +then + echo "############################################################" + echo "You should have created the VM before doing anything" + echo "############################################################" + exit 1 +fi + +echo "Waiting for VM to be started" +uvt-kvm wait $VM_NAME --insecure + +VM_IP_ADDR=`uvt-kvm ip $VM_NAME` +echo "$VM_NAME has for IP addr = $VM_IP_ADDR" + +echo "############################################################" +echo "Waiting build process to end on VM ($VM_NAME)" +echo "############################################################" + +if [[ "$VM_NAME" == *"-cppcheck"* ]] +then + echo "echo \"ps -aux | grep cppcheck \"" >> $VM_CMDS + echo "while [ \$(ps -aux | grep --color=never cppcheck | grep -v grep | wc -l) -gt 0 ]; do sleep 3; done" >> $VM_CMDS +else + echo "echo \"ps -aux | grep build \"" >> $VM_CMDS + echo "while [ \$(ps -aux | grep --color=never build_oai | grep -v grep | wc -l) -gt 0 ]; do sleep 3; done" >> $VM_CMDS +fi + +ssh -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR < $VM_CMDS + +echo "############################################################" +echo "Creating a tmp folder to store results and artifacts" +echo "############################################################" +if [ ! -d $JENKINS_WKSP/archives ] +then + mkdir $JENKINS_WKSP/archives +fi + +if [ ! -d $ARCHIVES_LOC ] +then + mkdir $ARCHIVES_LOC +fi + +scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/*.txt $ARCHIVES_LOC +if [[ "$VM_NAME" == *"-cppcheck"* ]] +then + scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/*.xml $ARCHIVES_LOC +fi + +if [ $KEEP_VM_ALIVE -eq 0 ] +then + echo "############################################################" + echo "Destroying VM" + echo "############################################################" + uvt-kvm destroy $VM_NAME + ssh-keygen -R $VM_IP_ADDR +fi +rm -f $VM_CMDS + +echo "############################################################" +echo "Checking build status" +echo "############################################################" + +LOG_FILES=`ls $ARCHIVES_LOC/*.txt $ARCHIVES_LOC/*.xml` +STATUS=0 +NB_FOUND_FILES=0 + +for FULLFILE in $LOG_FILES +do + if [[ $FULLFILE == *"$LOG_PATTERN"* ]] + then + filename=$(basename -- "$FULLFILE") + if [ "$LOG_PATTERN" == ".Rel14.txt" ] + then + PASS_PATTERN=`echo $filename | sed -e "s#$LOG_PATTERN##"` + fi + if [ "$LOG_PATTERN" == "basic_simulator" ] + then + PASS_PATTERN="lte-" + fi + if [ "$LOG_PATTERN" == "cppcheck.xml" ] + then + PASS_PATTERN="results version" + LOCAL_STAT=`egrep -c "$PASS_PATTERN" $FULLFILE` + else + LOCAL_STAT=`egrep -c "Built target $PASS_PATTERN" $FULLFILE` + fi + if [ $LOCAL_STAT -eq 0 ]; then STATUS=-1; fi + NB_FOUND_FILES=$((NB_FOUND_FILES + 1)) + fi +done + +if [ $NB_PATTERN_FILES -ne $NB_FOUND_FILES ]; then STATUS=-1; fi + +if [ $STATUS -eq 0 ] +then + echo "STATUS seems OK" +else + echo "STATUS failed?" +fi +exit $STATUS From 5eb2bd7d475ae34b884619f2d52e375103f99a7f Mon Sep 17 00:00:00 2001 From: Raphael Defosseux Date: Mon, 5 Nov 2018 11:07:03 +0100 Subject: [PATCH 090/233] CI: fix basic simulator run cherry-picked from 5d4cde099e44dcaa37fc547e9aa52d200471d307 Signed-off-by: Raphael Defosseux --- ci-scripts/buildOnVM.sh | 2 ++ ci-scripts/runTestOnVM.sh | 5 ++++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/ci-scripts/buildOnVM.sh b/ci-scripts/buildOnVM.sh index 0fb85b24eb..c1f554093d 100755 --- a/ci-scripts/buildOnVM.sh +++ b/ci-scripts/buildOnVM.sh @@ -334,6 +334,7 @@ echo "unzip -qq -DD ../localZip.zip" >> $VM_CMDS if [[ "$VM_NAME" == *"-cppcheck"* ]] then echo "mkdir cmake_targets/log" >> $VM_CMDS + echo "chmod 777 cmake_targets/log" >> $VM_CMDS echo "cp /home/ubuntu/zip-install.txt cmake_targets/log" >> $VM_CMDS echo "echo \"cppcheck $BUILD_OPTIONS . \"" >> $VM_CMDS if [ $DAEMON -eq 0 ] @@ -349,6 +350,7 @@ else echo "source oaienv" >> $VM_CMDS echo "cd cmake_targets/" >> $VM_CMDS echo "mkdir log" >> $VM_CMDS + echo "chmod 777 log" >> $VM_CMDS echo "cp /home/ubuntu/zip-install.txt log" >> $VM_CMDS if [ $DAEMON -eq 0 ] then diff --git a/ci-scripts/runTestOnVM.sh b/ci-scripts/runTestOnVM.sh index efdfcec3e0..94af2d75ef 100755 --- a/ci-scripts/runTestOnVM.sh +++ b/ci-scripts/runTestOnVM.sh @@ -89,6 +89,8 @@ function start_basic_sim_enb { echo "echo \"grep N_RB_DL ci-$LOC_CONF_FILE\"" >> $1 echo "grep N_RB_DL ci-$LOC_CONF_FILE | sed -e 's#N_RB_DL.*=#N_RB_DL =#'" >> $1 echo "echo \"cd /home/ubuntu/tmp/cmake_targets/basic_simulator/enb/\"" >> $1 + echo "sudo chmod 777 /home/ubuntu/tmp/cmake_targets/basic_simulator" >> $1 + echo "sudo chmod 777 /home/ubuntu/tmp/cmake_targets/basic_simulator/enb/" >> $1 echo "cd /home/ubuntu/tmp/cmake_targets/basic_simulator/enb/" >> $1 echo "echo \"ulimit -c unlimited && ./lte-softmodem -O /home/ubuntu/tmp/ci-scripts/conf_files/ci-$LOC_CONF_FILE\" > ./my-lte-softmodem-run.sh " >> $1 echo "chmod 775 ./my-lte-softmodem-run.sh" >> $1 @@ -105,7 +107,8 @@ function start_basic_sim_ue { local LOC_NB_RBS=$4 local LOC_FREQUENCY=$5 echo "echo \"cd /home/ubuntu/tmp/cmake_targets/basic_simulator/ue\"" > $1 - echo "cd /home/ubuntu/tmp/cmake_targets/basic_simulator/ue" > $1 + echo "sudo chmod 777 /home/ubuntu/tmp/cmake_targets/basic_simulator/ue" >> $1 + echo "cd /home/ubuntu/tmp/cmake_targets/basic_simulator/ue" >> $1 echo "echo \"./lte-uesoftmodem -C ${LOC_FREQUENCY}000000 -r $LOC_NB_RBS --ue-rxgain 140\" > ./my-lte-uesoftmodem-run.sh" >> $1 echo "chmod 775 ./my-lte-uesoftmodem-run.sh" >> $1 echo "cat ./my-lte-uesoftmodem-run.sh" >> $1 From df6030540a374cdb9b40def26ebb3cd41da28b3e Mon Sep 17 00:00:00 2001 From: frtabu Date: Mon, 5 Nov 2018 11:28:25 +0100 Subject: [PATCH 091/233] reduce compilation warnings in noS1 build to try to pass CI --- openair2/ENB_APP/enb_app.c | 12 ++++++++---- openair2/RRC/LTE/rrc_eNB.c | 7 ++++++- targets/COMMON/create_tasks.c | 5 +++++ 3 files changed, 19 insertions(+), 5 deletions(-) diff --git a/openair2/ENB_APP/enb_app.c b/openair2/ENB_APP/enb_app.c index 37bcd36653..35871b15d2 100644 --- a/openair2/ENB_APP/enb_app.c +++ b/openair2/ENB_APP/enb_app.c @@ -43,10 +43,14 @@ # include "s1ap_eNB.h" # include "sctp_eNB_task.h" # include "gtpv1u_eNB_task.h" -# else -# define EPC_MODE_ENABLED 0 -# endif - +/* temporary warning removale while implementing noS1 */ +/* as config option */ +# else +# ifdef EPC_MODE_ENABLED +# undef EPC_MODE_ENABLED +# endif +# define EPC_MODE_ENABLED 0 +# endif # include "x2ap_eNB.h" # include "x2ap_messages_types.h" # define X2AP_ENB_REGISTER_RETRY_DELAY 10 diff --git a/openair2/RRC/LTE/rrc_eNB.c b/openair2/RRC/LTE/rrc_eNB.c index e8c52f72f5..6f269b93cb 100644 --- a/openair2/RRC/LTE/rrc_eNB.c +++ b/openair2/RRC/LTE/rrc_eNB.c @@ -85,8 +85,13 @@ # else # include "../../S1AP/s1ap_eNB.h" # endif +/* temporary warning removale while implementing noS1 */ +/* as config option */ #else -# define EPC_MODE_ENABLED 0 +# ifdef EPC_MODE_ENABLED +# undef EPC_MODE_ENABLED +# endif +# define EPC_MODE_ENABLED 0 #endif #include "pdcp.h" diff --git a/targets/COMMON/create_tasks.c b/targets/COMMON/create_tasks.c index 047d8b4037..2c27cc29e8 100644 --- a/targets/COMMON/create_tasks.c +++ b/targets/COMMON/create_tasks.c @@ -33,7 +33,12 @@ # include "nas_ue_task.h" # include "udp_eNB_task.h" # include "gtpv1u_eNB_task.h" +/* temporary warning removale while implementing noS1 */ +/* as config option */ # else +# ifdef EPC_MODE_ENABLED +# undef EPC_MODE_ENABLED +# endif # define EPC_MODE_ENABLED 0 # endif # if ENABLE_RAL From 47437903f9c6ee6feebb78f6ad90b43dc2264d66 Mon Sep 17 00:00:00 2001 From: Raphael Defosseux Date: Mon, 5 Nov 2018 15:18:40 +0100 Subject: [PATCH 092/233] CI: lock mechanism improvement -- in slave job, the lock is now properly done for the whole job -- in master job, all slave jobs are really sent in parallel they should now now appear as failed (if fails) Signed-off-by: Raphael Defosseux --- ci-scripts/Jenkinsfile-gitlab | 328 ++++++++++++++++----------------- ci-scripts/Jenkinsfile-tmp-ran | 3 +- 2 files changed, 155 insertions(+), 176 deletions(-) diff --git a/ci-scripts/Jenkinsfile-gitlab b/ci-scripts/Jenkinsfile-gitlab index 7ef68e36cf..0def0c916a 100644 --- a/ci-scripts/Jenkinsfile-gitlab +++ b/ci-scripts/Jenkinsfile-gitlab @@ -294,200 +294,180 @@ pipeline { } } } - stage ("Test on CI bench #1") { - stages { - stage ("Test FDD - Band 7 - B210") { - steps { - script { - try { - if ("MERGE".equals(env.gitlabActionType)) { - gitlabCommitStatus(name: "Test-FDD-Band7") { - build job: 'eNB-CI-FDD-Band7-B210', - parameters: [ - string(name: 'eNB_Repository', value: String.valueOf(GIT_URL)), - string(name: 'eNB_Branch', value: String.valueOf(env.gitlabSourceBranch)), - string(name: 'eNB_CommitID', value: String.valueOf(env.gitlabMergeRequestLastCommit)), - booleanParam(name: 'eNB_mergeRequest', value: true) - ] - } - } else { - gitlabCommitStatus(name: "Test-FDD-Band7") { - build job: 'eNB-CI-FDD-Band7-B210', - parameters: [ - string(name: 'eNB_Repository', value: String.valueOf(GIT_URL)), - string(name: 'eNB_Branch', value: String.valueOf(GIT_BRANCH)), - string(name: 'eNB_CommitID', value: String.valueOf(GIT_COMMIT)), - booleanParam(name: 'eNB_mergeRequest', value: false) - ] - } - } - } catch (Exception e) { - currentBuild.result = 'FAILURE' - } + stage ("Test FDD - Band 7 - B210") { + steps { + script { + if ("MERGE".equals(env.gitlabActionType)) { + gitlabCommitStatus(name: "Test-FDD-Band7") { + build job: 'eNB-CI-FDD-Band7-B210', + parameters: [ + string(name: 'eNB_Repository', value: String.valueOf(GIT_URL)), + string(name: 'eNB_Branch', value: String.valueOf(env.gitlabSourceBranch)), + string(name: 'eNB_CommitID', value: String.valueOf(env.gitlabMergeRequestLastCommit)), + booleanParam(name: 'eNB_mergeRequest', value: true) + ] + } + } else { + gitlabCommitStatus(name: "Test-FDD-Band7") { + build job: 'eNB-CI-FDD-Band7-B210', + parameters: [ + string(name: 'eNB_Repository', value: String.valueOf(GIT_URL)), + string(name: 'eNB_Branch', value: String.valueOf(GIT_BRANCH)), + string(name: 'eNB_CommitID', value: String.valueOf(GIT_COMMIT)), + booleanParam(name: 'eNB_mergeRequest', value: false) + ] } } - post { - // In case of any non-success, we are retrieving the HTML report of the last completed - // slave job. - // The only drop-back is that we may retrieve the HTML report of a previous build - always { - script { - if (!fileExists('test_results-eNB-CI-FDD-Band7-B210.html')) { - copyArtifacts(projectName: 'eNB-CI-FDD-Band7-B210', - filter: 'test_results*.html', - selector: lastCompleted()) - if (fileExists('test_results-eNB-CI-FDD-Band7-B210.html')) { - sh "sed -i -e 's#TEMPLATE_BUILD_TIME#${JOB_TIMESTAMP}#' test_results-eNB-CI-FDD-Band7-B210.html" - archiveArtifacts artifacts: 'test_results-eNB-CI-FDD-Band7-B210.html' - } - } + } + } + post { + // In case of any non-success, we are retrieving the HTML report of the last completed + // slave job. + // The only drop-back is that we may retrieve the HTML report of a previous build + always { + script { + if (!fileExists('test_results-eNB-CI-FDD-Band7-B210.html')) { + copyArtifacts(projectName: 'eNB-CI-FDD-Band7-B210', + filter: 'test_results*.html', + selector: lastCompleted()) + if (fileExists('test_results-eNB-CI-FDD-Band7-B210.html')) { + sh "sed -i -e 's#TEMPLATE_BUILD_TIME#${JOB_TIMESTAMP}#' test_results-eNB-CI-FDD-Band7-B210.html" + archiveArtifacts artifacts: 'test_results-eNB-CI-FDD-Band7-B210.html' } } } } - stage ("Test TDD - Band 40 - B210") { - steps { - script { - try { - if ("MERGE".equals(env.gitlabActionType)) { - gitlabCommitStatus(name: "Test-TDD-Band40") { - build job: 'eNB-CI-TDD-Band40-B210', - parameters: [ - string(name: 'eNB_Repository', value: String.valueOf(GIT_URL)), - string(name: 'eNB_Branch', value: String.valueOf(env.gitlabSourceBranch)), - string(name: 'eNB_CommitID', value: String.valueOf(env.gitlabMergeRequestLastCommit)), - booleanParam(name: 'eNB_mergeRequest', value: true) - ] - } - } else { - gitlabCommitStatus(name: "Test-TDD-Band40") { - build job: 'eNB-CI-TDD-Band40-B210', - parameters: [ - string(name: 'eNB_Repository', value: String.valueOf(GIT_URL)), - string(name: 'eNB_Branch', value: String.valueOf(GIT_BRANCH)), - string(name: 'eNB_CommitID', value: String.valueOf(GIT_COMMIT)), - booleanParam(name: 'eNB_mergeRequest', value: false) - ] - } - } - } catch (Exception e) { - currentBuild.result = 'FAILURE' - } + } + } + stage ("Test TDD - Band 40 - B210") { + steps { + script { + if ("MERGE".equals(env.gitlabActionType)) { + gitlabCommitStatus(name: "Test-TDD-Band40") { + build job: 'eNB-CI-TDD-Band40-B210', + parameters: [ + string(name: 'eNB_Repository', value: String.valueOf(GIT_URL)), + string(name: 'eNB_Branch', value: String.valueOf(env.gitlabSourceBranch)), + string(name: 'eNB_CommitID', value: String.valueOf(env.gitlabMergeRequestLastCommit)), + booleanParam(name: 'eNB_mergeRequest', value: true) + ] + } + } else { + gitlabCommitStatus(name: "Test-TDD-Band40") { + build job: 'eNB-CI-TDD-Band40-B210', + parameters: [ + string(name: 'eNB_Repository', value: String.valueOf(GIT_URL)), + string(name: 'eNB_Branch', value: String.valueOf(GIT_BRANCH)), + string(name: 'eNB_CommitID', value: String.valueOf(GIT_COMMIT)), + booleanParam(name: 'eNB_mergeRequest', value: false) + ] } } - post { - // In case of any non-success, we are retrieving the HTML report of the last completed - // slave job. - // The only drop-back is that we may retrieve the HTML report of a previous build - always { - script { - if (!fileExists('test_results-eNB-CI-TDD-Band40-B210.html')) { - copyArtifacts(projectName: 'eNB-CI-TDD-Band40-B210', - filter: 'test_results*.html', - selector: lastCompleted()) - if (fileExists('test_results-eNB-CI-TDD-Band40-B210.html')) { - sh "sed -i -e 's#TEMPLATE_BUILD_TIME#${JOB_TIMESTAMP}#' test_results-eNB-CI-TDD-Band40-B210.html" - archiveArtifacts artifacts: 'test_results-eNB-CI-TDD-Band40-B210.html' - } - } + } + } + post { + // In case of any non-success, we are retrieving the HTML report of the last completed + // slave job. + // The only drop-back is that we may retrieve the HTML report of a previous build + always { + script { + if (!fileExists('test_results-eNB-CI-TDD-Band40-B210.html')) { + copyArtifacts(projectName: 'eNB-CI-TDD-Band40-B210', + filter: 'test_results*.html', + selector: lastCompleted()) + if (fileExists('test_results-eNB-CI-TDD-Band40-B210.html')) { + sh "sed -i -e 's#TEMPLATE_BUILD_TIME#${JOB_TIMESTAMP}#' test_results-eNB-CI-TDD-Band40-B210.html" + archiveArtifacts artifacts: 'test_results-eNB-CI-TDD-Band40-B210.html' } } } } - stage ("Test IF4p5 - FDD - Band 7 - B210") { - steps { - script { - try { - if ("MERGE".equals(env.gitlabActionType)) { - gitlabCommitStatus(name: "Test-IF4p5-FDD-Band7") { - build job: 'eNB-CI-IF4p5-FDD-Band7-B210', - parameters: [ - string(name: 'eNB_Repository', value: String.valueOf(GIT_URL)), - string(name: 'eNB_Branch', value: String.valueOf(env.gitlabSourceBranch)), - string(name: 'eNB_CommitID', value: String.valueOf(env.gitlabMergeRequestLastCommit)), - booleanParam(name: 'eNB_mergeRequest', value: true) - ] - } - } else { - gitlabCommitStatus(name: "Test-IF4p5-FDD-Band7") { - build job: 'eNB-CI-IF4p5-FDD-Band7-B210', - parameters: [ - string(name: 'eNB_Repository', value: String.valueOf(GIT_URL)), - string(name: 'eNB_Branch', value: String.valueOf(GIT_BRANCH)), - string(name: 'eNB_CommitID', value: String.valueOf(GIT_COMMIT)), - booleanParam(name: 'eNB_mergeRequest', value: false) - ] - } - } - } catch (Exception e) { - currentBuild.result = 'FAILURE' - } + } + } + stage ("Test IF4p5 - FDD - Band 7 - B210") { + steps { + script { + if ("MERGE".equals(env.gitlabActionType)) { + gitlabCommitStatus(name: "Test-IF4p5-FDD-Band7") { + build job: 'eNB-CI-IF4p5-FDD-Band7-B210', + parameters: [ + string(name: 'eNB_Repository', value: String.valueOf(GIT_URL)), + string(name: 'eNB_Branch', value: String.valueOf(env.gitlabSourceBranch)), + string(name: 'eNB_CommitID', value: String.valueOf(env.gitlabMergeRequestLastCommit)), + booleanParam(name: 'eNB_mergeRequest', value: true) + ] + } + } else { + gitlabCommitStatus(name: "Test-IF4p5-FDD-Band7") { + build job: 'eNB-CI-IF4p5-FDD-Band7-B210', + parameters: [ + string(name: 'eNB_Repository', value: String.valueOf(GIT_URL)), + string(name: 'eNB_Branch', value: String.valueOf(GIT_BRANCH)), + string(name: 'eNB_CommitID', value: String.valueOf(GIT_COMMIT)), + booleanParam(name: 'eNB_mergeRequest', value: false) + ] } } - post { - // In case of any non-success, we are retrieving the HTML report of the last completed - // slave job. - // The only drop-back is that we may retrieve the HTML report of a previous build - always { - script { - if (!fileExists('test_results-eNB-CI-IF4p5-FDD-Band7-B210.html')) { - copyArtifacts(projectName: 'eNB-CI-IF4p5-FDD-Band7-B210', - filter: 'test_results*.html', - selector: lastCompleted()) - if (fileExists('test_results-eNB-CI-IF4p5-FDD-Band7-B210.html')) { - sh "sed -i -e 's#TEMPLATE_BUILD_TIME#${JOB_TIMESTAMP}#' test_results-eNB-CI-IF4p5-FDD-Band7-B210.html" - archiveArtifacts artifacts: 'test_results-eNB-CI-IF4p5-FDD-Band7-B210.html' - } - } + } + } + post { + // In case of any non-success, we are retrieving the HTML report of the last completed + // slave job. + // The only drop-back is that we may retrieve the HTML report of a previous build + always { + script { + if (!fileExists('test_results-eNB-CI-IF4p5-FDD-Band7-B210.html')) { + copyArtifacts(projectName: 'eNB-CI-IF4p5-FDD-Band7-B210', + filter: 'test_results*.html', + selector: lastCompleted()) + if (fileExists('test_results-eNB-CI-IF4p5-FDD-Band7-B210.html')) { + sh "sed -i -e 's#TEMPLATE_BUILD_TIME#${JOB_TIMESTAMP}#' test_results-eNB-CI-IF4p5-FDD-Band7-B210.html" + archiveArtifacts artifacts: 'test_results-eNB-CI-IF4p5-FDD-Band7-B210.html' } } } } - stage ("Test IF4p5 - TDD - Band 40 - B210") { - steps { - script { - try { - if ("MERGE".equals(env.gitlabActionType)) { - gitlabCommitStatus(name: "Test-IF4p5-TDD-Band40") { - build job: 'eNB-CI-IF4p5-TDD-Band40-B210', - parameters: [ - string(name: 'eNB_Repository', value: String.valueOf(GIT_URL)), - string(name: 'eNB_Branch', value: String.valueOf(env.gitlabSourceBranch)), - string(name: 'eNB_CommitID', value: String.valueOf(env.gitlabMergeRequestLastCommit)), - booleanParam(name: 'eNB_mergeRequest', value: true) - ] - } - } else { - gitlabCommitStatus(name: "Test-IF4p5-TDD-Band40") { - build job: 'eNB-CI-IF4p5-TDD-Band40-B210', - parameters: [ - string(name: 'eNB_Repository', value: String.valueOf(GIT_URL)), - string(name: 'eNB_Branch', value: String.valueOf(GIT_BRANCH)), - string(name: 'eNB_CommitID', value: String.valueOf(GIT_COMMIT)), - booleanParam(name: 'eNB_mergeRequest', value: false) - ] - } - } - } catch (Exception e) { - currentBuild.result = 'FAILURE' - } + } + } + stage ("Test IF4p5 - TDD - Band 40 - B210") { + steps { + script { + if ("MERGE".equals(env.gitlabActionType)) { + gitlabCommitStatus(name: "Test-IF4p5-TDD-Band40") { + build job: 'eNB-CI-IF4p5-TDD-Band40-B210', + parameters: [ + string(name: 'eNB_Repository', value: String.valueOf(GIT_URL)), + string(name: 'eNB_Branch', value: String.valueOf(env.gitlabSourceBranch)), + string(name: 'eNB_CommitID', value: String.valueOf(env.gitlabMergeRequestLastCommit)), + booleanParam(name: 'eNB_mergeRequest', value: true) + ] + } + } else { + gitlabCommitStatus(name: "Test-IF4p5-TDD-Band40") { + build job: 'eNB-CI-IF4p5-TDD-Band40-B210', + parameters: [ + string(name: 'eNB_Repository', value: String.valueOf(GIT_URL)), + string(name: 'eNB_Branch', value: String.valueOf(GIT_BRANCH)), + string(name: 'eNB_CommitID', value: String.valueOf(GIT_COMMIT)), + booleanParam(name: 'eNB_mergeRequest', value: false) + ] } } - post { - // In case of any non-success, we are retrieving the HTML report of the last completed - // slave job. - // The only drop-back is that we may retrieve the HTML report of a previous build - always { - script { - if (!fileExists('test_results-eNB-CI-IF4p5-TDD-Band40-B210.html')) { - copyArtifacts(projectName: 'eNB-CI-IF4p5-TDD-Band40-B210', - filter: 'test_results*.html', - selector: lastCompleted()) - if (fileExists('test_results-eNB-CI-IF4p5-TDD-Band40-B210.html')) { - sh "sed -i -e 's#TEMPLATE_BUILD_TIME#${JOB_TIMESTAMP}#' test_results-eNB-CI-IF4p5-TDD-Band40-B210.html" - archiveArtifacts artifacts: 'test_results-eNB-CI-IF4p5-TDD-Band40-B210.html' - } - } + } + } + post { + // In case of any non-success, we are retrieving the HTML report of the last completed + // slave job. + // The only drop-back is that we may retrieve the HTML report of a previous build + always { + script { + if (!fileExists('test_results-eNB-CI-IF4p5-TDD-Band40-B210.html')) { + copyArtifacts(projectName: 'eNB-CI-IF4p5-TDD-Band40-B210', + filter: 'test_results*.html', + selector: lastCompleted()) + if (fileExists('test_results-eNB-CI-IF4p5-TDD-Band40-B210.html')) { + sh "sed -i -e 's#TEMPLATE_BUILD_TIME#${JOB_TIMESTAMP}#' test_results-eNB-CI-IF4p5-TDD-Band40-B210.html" + archiveArtifacts artifacts: 'test_results-eNB-CI-IF4p5-TDD-Band40-B210.html' } } } diff --git a/ci-scripts/Jenkinsfile-tmp-ran b/ci-scripts/Jenkinsfile-tmp-ran index 5fd2a09598..6795eab9b8 100644 --- a/ci-scripts/Jenkinsfile-tmp-ran +++ b/ci-scripts/Jenkinsfile-tmp-ran @@ -61,6 +61,7 @@ pipeline { options { disableConcurrentBuilds() ansiColor('xterm') + lock (ciSmartPhoneResource) } // the following parameter options are commented out so it shows the ones // that you SHALL have to run the job. @@ -184,7 +185,6 @@ pipeline { steps { script { dir ('ci-scripts') { - lock (ciSmartPhoneResource) { try { echo "\u2705 \u001B[32m${testStageName}\u001B[0m" withCredentials([ @@ -197,7 +197,6 @@ pipeline { } catch (Exception e) { currentBuild.result = 'FAILURE' } - } } } } From 1c196a9eff54c115923f26ded3a9f706442a7b9c Mon Sep 17 00:00:00 2001 From: Louis Adrien Dufrene Date: Mon, 5 Nov 2018 16:48:50 +0100 Subject: [PATCH 093/233] rrc inactivity timer reset in RRC Connection Release generation --- openair2/ENB_APP/enb_config.c | 3 +-- openair2/RRC/LTE/rrc_eNB.c | 1 + 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/openair2/ENB_APP/enb_config.c b/openair2/ENB_APP/enb_config.c index 40d9551ef2..036a4cdd91 100644 --- a/openair2/ENB_APP/enb_config.c +++ b/openair2/ENB_APP/enb_config.c @@ -2283,8 +2283,7 @@ int RCconfig_S1( /* Default DRX param */ /* * Here we get the config of the first CC, since the s1ap_register_enb_req_t doesn't support multiple CC. - * It is not clear in the spec if the eNB can have different default paging values in case of several SIB2 from the same eNB. - * Yet, from the spec and logically, there should be a unique value associated with eNB. + * There is a unique value of defaultPagingCycle per eNB (same for multiple cells). * Hence, it should be stated somewhere that the value should be the same for every CC, or put the value outside the CC * in the conf file. */ diff --git a/openair2/RRC/LTE/rrc_eNB.c b/openair2/RRC/LTE/rrc_eNB.c index 8673567e6b..d63b289e32 100644 --- a/openair2/RRC/LTE/rrc_eNB.c +++ b/openair2/RRC/LTE/rrc_eNB.c @@ -2023,6 +2023,7 @@ rrc_eNB_generate_RRCConnectionRelease( ue_context_pP->ue_context.ue_reestablishment_timer = 0; ue_context_pP->ue_context.ue_release_timer = 0; + ue_context_pP->ue_context.ue_rrc_inactivity_timer = 0; LOG_I(RRC, PROTOCOL_RRC_CTXT_UE_FMT" Logical Channel DL-DCCH, Generate RRCConnectionRelease (bytes %d)\n", From d151ce6feb8fe73da39f3c8cf2870a9bbd45c0c4 Mon Sep 17 00:00:00 2001 From: frtabu Date: Mon, 5 Nov 2018 17:28:00 +0100 Subject: [PATCH 094/233] Add a parameter to load_configmodule API to allow an exec to specify that it may be run with only command line options --- cmake_targets/build_oai | 6 +++--- common/config/config_load_configmodule.c | 8 ++++---- common/config/config_load_configmodule.h | 5 +++-- openair1/SIMULATION/LTE_PHY/dlsim.c | 2 +- openair1/SIMULATION/LTE_PHY/ulsim.c | 2 +- targets/RT/USER/lte-softmodem.c | 2 +- targets/RT/USER/lte-uesoftmodem.c | 4 ++-- 7 files changed, 15 insertions(+), 14 deletions(-) diff --git a/cmake_targets/build_oai b/cmake_targets/build_oai index 51d6ac6d01..c6f8199af2 100755 --- a/cmake_targets/build_oai +++ b/cmake_targets/build_oai @@ -651,9 +651,9 @@ function main() { compilations \ lte-simulators coding \ libcoding.so $dbin/libcoding.so - compilations \ - lte-simulators $config_libconfig_shlib \ - lib$config_libconfig_shlib.so $dbin/lib$config_libconfig_shlib.so +# compilations \ +# lte-simulators $config_libconfig_shlib \ +# lib$config_libconfig_shlib.so $dbin/lib$config_libconfig_shlib.so fi # Core simulators diff --git a/common/config/config_load_configmodule.c b/common/config/config_load_configmodule.c index cfb6e38440..15211aec8a 100644 --- a/common/config/config_load_configmodule.c +++ b/common/config/config_load_configmodule.c @@ -169,7 +169,7 @@ int config_cmdlineonly_get(paramdef_t *cfgoptions,int numoptions, char *prefix ) return numdefvals; } -configmodule_interface_t *load_configmodule(int argc, char **argv) +configmodule_interface_t *load_configmodule(int argc, char **argv, uint32_t initflags) { char *cfgparam=NULL; char *modeparams=NULL; @@ -208,10 +208,10 @@ int OoptIdx=-1; /* oad_configmodule function */ if (cfgparam == NULL) { tmpflags = tmpflags | CONFIG_NOOOPT; - if (strstr(argv[0],"uesoftmodem") == NULL || strstr(argv[0],"lsim") == NULL) { - cfgparam = CONFIG_LIBCONFIGFILE ":" DEFAULT_CFGFILENAME; + if ( initflags & CONFIG_ENABLECMDLINEONLY) { + cfgparam = CONFIG_CMDLINEONLY ":dbgl0" ; } else { - cfgparam = CONFIG_CMDLINEONLY ":dbgl0" ; + cfgparam = CONFIG_CMDLINEONLY ":dbgl0" ;cfgparam = CONFIG_LIBCONFIGFILE ":" DEFAULT_CFGFILENAME; } } diff --git a/common/config/config_load_configmodule.h b/common/config/config_load_configmodule.h index 1f4ebde92d..d98e825095 100644 --- a/common/config/config_load_configmodule.h +++ b/common/config/config_load_configmodule.h @@ -106,8 +106,9 @@ extern configmodule_interface_t *cfgptr; #define printf_params(...) if ( (cfgptr->rtflags & (CONFIG_PRINTPARAMS)) != 0 ) { printf ( __VA_ARGS__ ); } #define printf_ptrs(...) if ( (cfgptr->rtflags & (CONFIG_DEBUGPTR)) != 0 ) { printf ( __VA_ARGS__ ); } #define printf_cmdl(...) if ( (cfgptr->rtflags & (CONFIG_DEBUGCMDLINE)) != 0 ) { printf ( __VA_ARGS__ ); } - -extern configmodule_interface_t *load_configmodule(int argc, char **argv); + +#define CONFIG_ENABLECMDLINEONLY (1<<1) +extern configmodule_interface_t *load_configmodule(int argc, char **argv, uint32_t initflags); extern void end_configmodule(void); #endif /* INCLUDE_CONFIG_LOADCONFIGMODULE_H */ diff --git a/openair1/SIMULATION/LTE_PHY/dlsim.c b/openair1/SIMULATION/LTE_PHY/dlsim.c index 0f4655eb2c..246bdd7007 100644 --- a/openair1/SIMULATION/LTE_PHY/dlsim.c +++ b/openair1/SIMULATION/LTE_PHY/dlsim.c @@ -988,7 +988,7 @@ int main(int argc, char **argv) if (transmission_mode>1) pa=dBm3; printf("dlsim: tmode %d, pa %d\n",transmission_mode,pa); - AssertFatal(load_configmodule(argc,argv) != NULL, + AssertFatal(load_configmodule(argc,argv, CONFIG_ENABLECMDLINEONLY) != NULL, "cannot load configuration module, exiting\n"); logInit(); set_glog_onlinelog(true); diff --git a/openair1/SIMULATION/LTE_PHY/ulsim.c b/openair1/SIMULATION/LTE_PHY/ulsim.c index c015063b60..53a2c22f15 100644 --- a/openair1/SIMULATION/LTE_PHY/ulsim.c +++ b/openair1/SIMULATION/LTE_PHY/ulsim.c @@ -429,7 +429,7 @@ int main(int argc, char **argv) { cpu_freq_GHz = (double)get_cpu_freq_GHz(); cpuf = cpu_freq_GHz; printf("Detected cpu_freq %f GHz\n",cpu_freq_GHz); - AssertFatal(load_configmodule(argc,argv) != NULL, + AssertFatal(load_configmodule(argc,argv,CONFIG_ENABLECMDLINEONLY) != NULL, "cannot load configuration module, exiting\n"); logInit(); // enable these lines if you need debug info diff --git a/targets/RT/USER/lte-softmodem.c b/targets/RT/USER/lte-softmodem.c index 00ae350ea2..4cf257f353 100644 --- a/targets/RT/USER/lte-softmodem.c +++ b/targets/RT/USER/lte-softmodem.c @@ -695,7 +695,7 @@ int main( int argc, char **argv ) #if defined (XFORMS) int ret; #endif - if ( load_configmodule(argc,argv) == NULL) { + if ( load_configmodule(argc,argv,0) == NULL) { exit_fun("[SOFTMODEM] Error, configuration module init failed\n"); } diff --git a/targets/RT/USER/lte-uesoftmodem.c b/targets/RT/USER/lte-uesoftmodem.c index 2306dbc725..593b64ea40 100644 --- a/targets/RT/USER/lte-uesoftmodem.c +++ b/targets/RT/USER/lte-uesoftmodem.c @@ -761,7 +761,7 @@ int main( int argc, char **argv ) #endif start_background_system(); - if ( load_configmodule(argc,argv) == NULL) { + if ( load_configmodule(argc,argv,CONFIG_ENABLECMDLINEONLY) == NULL) { exit_fun("[SOFTMODEM] Error, configuration module init failed\n"); } @@ -887,7 +887,7 @@ int main( int argc, char **argv ) if (simL1flag==1) { - AssertFatal(NULL!=load_configmodule(argc,argv), + AssertFatal(NULL!=load_configmodule(argc,argv,CONFIG_ENABLECMDLINEONLY), "[SOFTMODEM] Error, configuration module init failed\n"); RCConfig_sim(); From 2c5e5c7a0c9aef79b9853a1fa61427dddaa34af4 Mon Sep 17 00:00:00 2001 From: Wang Tsu-Han Date: Mon, 5 Nov 2018 18:41:04 +0100 Subject: [PATCH 095/233] print removel and config file chenge back to one RU --- .../CONF/enb.band7.tm1.100PRB.usrpx310.conf | 12 ------- targets/RT/USER/lte-enb.c | 31 ++++++++++--------- targets/RT/USER/lte-ru.c | 4 --- 3 files changed, 16 insertions(+), 31 deletions(-) diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.100PRB.usrpx310.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.100PRB.usrpx310.conf index f48357c13c..728492ee83 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.100PRB.usrpx310.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.100PRB.usrpx310.conf @@ -188,18 +188,6 @@ RUs = ( max_rxgain = 116; eNB_instances = [0]; sdr_addrs = "type=x300"; - }, - { - local_rf = "yes" - nb_tx = 1 - nb_rx = 1 - att_tx = 0 - att_rx = 0; - bands = [7]; - max_pdschReferenceSignalPower = -27; - max_rxgain = 116; - eNB_instances = [0]; - sdr_addrs = "type=x300"; } ); diff --git a/targets/RT/USER/lte-enb.c b/targets/RT/USER/lte-enb.c index 4439609104..f2b01dbc8b 100644 --- a/targets/RT/USER/lte-enb.c +++ b/targets/RT/USER/lte-enb.c @@ -426,14 +426,11 @@ static void* L1_thread( void* param ) { if (rxtx(eNB,proc,thread_name) < 0) break; } + if(get_thread_parallel_conf() == PARALLEL_RU_L1_SPLIT) phy_procedures_eNB_TX(eNB, proc, 1); if (release_thread(&proc->mutex,&proc->instance_cnt,thread_name)<0) break; if (nfapi_mode!=2){ if(get_thread_parallel_conf() == PARALLEL_RU_L1_TRX_SPLIT) wakeup_tx(eNB); - else if(get_thread_parallel_conf() == PARALLEL_RU_L1_SPLIT) - { - phy_procedures_eNB_TX(eNB, proc, 1); - wakeup_txfh(proc,eNB); - } + else if(get_thread_parallel_conf() == PARALLEL_RU_L1_SPLIT) wakeup_txfh(proc,eNB); } } // while !oai_exit @@ -481,7 +478,6 @@ int wakeup_txfh(L1_rxtx_proc_t *proc,PHY_VARS_eNB *eNB) { struct timespec wait; wait.tv_sec=0; wait.tv_nsec=5000000L; -//printf("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~inside wakeup_txfh %d.%d IC_RU = %d\n", proc->frame_tx, proc->subframe_tx, proc->instance_cnt_RUs); if(wait_on_condition(&proc->mutex_RUs,&proc->cond_RUs,&proc->instance_cnt_RUs,"wakeup_txfh")<0) { LOG_E(PHY,"Frame %d, subframe %d: TX FH not ready\n", proc->frame_tx, proc->subframe_tx); @@ -922,7 +918,6 @@ void init_eNB_proc(int inst) { proc->first_rx =1; proc->first_tx =1; proc->RU_mask_tx = (1<num_RU)-1; -printf("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~proc->RU_mask_tx = %d\n", proc->RU_mask_tx); proc->RU_mask =0; proc->RU_mask_prach =0; @@ -1045,15 +1040,17 @@ void kill_eNB_proc(int inst) { } LOG_I(PHY, "Killing TX CC_id %d inst %d\n", CC_id, inst ); - pthread_mutex_lock(&L1_proc->mutex); - L1_proc->instance_cnt = 0; - pthread_cond_signal(&L1_proc->cond); - pthread_mutex_unlock(&L1_proc->mutex); + if ((get_thread_parallel_conf() == PARALLEL_RU_L1_SPLIT || get_thread_parallel_conf() == PARALLEL_RU_L1_TRX_SPLIT) && nfapi_mode!=2) { + pthread_mutex_lock(&L1_proc->mutex); + L1_proc->instance_cnt = 0; + pthread_cond_signal(&L1_proc->cond); + pthread_mutex_unlock(&L1_proc->mutex); - pthread_mutex_lock(&L1_proc_tx->mutex); - L1_proc_tx->instance_cnt = 0; - pthread_cond_signal(&L1_proc_tx->cond); - pthread_mutex_unlock(&L1_proc_tx->mutex); + pthread_mutex_lock(&L1_proc_tx->mutex); + L1_proc_tx->instance_cnt = 0; + pthread_cond_signal(&L1_proc_tx->cond); + pthread_mutex_unlock(&L1_proc_tx->mutex); + } pthread_mutex_lock(&proc->mutex_prach); proc->instance_cnt_prach = 0; @@ -1088,9 +1085,13 @@ void kill_eNB_proc(int inst) { LOG_I(PHY, "Destroying L1_proc mutex/cond\n"); pthread_mutex_destroy( &L1_proc->mutex ); pthread_cond_destroy( &L1_proc->cond ); + pthread_mutex_destroy( &L1_proc->mutex_RUs ); + pthread_cond_destroy( &L1_proc->cond_RUs ); LOG_I(PHY, "Destroying L1_proc_tx mutex/cond\n"); pthread_mutex_destroy( &L1_proc_tx->mutex ); pthread_cond_destroy( &L1_proc_tx->cond ); + pthread_mutex_destroy( &L1_proc_tx->mutex_RUs ); + pthread_cond_destroy( &L1_proc_tx->cond_RUs ); pthread_attr_destroy(&proc->attr_prach); pthread_attr_destroy(&proc->attr_asynch_rxtx); diff --git a/targets/RT/USER/lte-ru.c b/targets/RT/USER/lte-ru.c index e819233448..3fbb1e983d 100644 --- a/targets/RT/USER/lte-ru.c +++ b/targets/RT/USER/lte-ru.c @@ -1558,7 +1558,6 @@ static void* ru_thread_tx( void* param ) { // wait until eNBs are finished subframe RX n and TX n+4 wait_on_condition(&proc->mutex_eNBs,&proc->cond_eNBs,&proc->instance_cnt_eNBs,"ru_thread_tx"); if (oai_exit) break; -//printf("~~~~~~~~~~~~~~~~~~~~~~~~~~~~ru_thread_tx is waken up %d.%d having L1 %d\n", proc->frame_tx, proc->subframe_tx, ru->num_eNB); // do TX front-end processing if needed (precoding and/or IDFTs) if (ru->feptx_prec) ru->feptx_prec(ru); @@ -1587,17 +1586,14 @@ static void* ru_thread_tx( void* param ) { } } if (eNB_proc->RU_mask_tx != (1<num_RU)-1) { // not all RUs have provided their information so return -printf("~~~~~~~~~~~~~~~~~~~~~~(mask = %d)\n", eNB_proc->RU_mask_tx); pthread_mutex_unlock(&eNB_proc->mutex_RU_tx); } else { // all RUs TX are finished so send the ready signal to eNB processing -printf("~~~~~~~~~~~~~~~~~~~~~~ready to send wakeup signal\n"); eNB_proc->RU_mask_tx = 0; pthread_mutex_unlock(&eNB_proc->mutex_RU_tx); pthread_mutex_lock( &L1_proc->mutex_RUs); L1_proc->instance_cnt_RUs = 0; -printf("~~~~~~~~~~~~~~~~~~~~~~ru_thread_tx send signal to L1_thread_tx with (mask = %d)\n", eNB_proc->RU_mask_tx); // the thread can now be woken up if (pthread_cond_signal(&L1_proc->cond_RUs) != 0) { LOG_E( PHY, "[eNB] ERROR pthread_cond_signal for eNB TXnp4 thread\n"); From b8ce24febb3e0cb6e588137889534f45bfb9fc63 Mon Sep 17 00:00:00 2001 From: Louis Adrien Dufrene Date: Tue, 6 Nov 2018 07:42:04 +0100 Subject: [PATCH 096/233] add changes to s1ap_eNB.c --- openair3/S1AP/s1ap_eNB.c | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/openair3/S1AP/s1ap_eNB.c b/openair3/S1AP/s1ap_eNB.c index 3edc5be0d5..2e89bf97f7 100644 --- a/openair3/S1AP/s1ap_eNB.c +++ b/openair3/S1AP/s1ap_eNB.c @@ -444,16 +444,22 @@ void *s1ap_eNB_task(void *arg) return NULL; } +//----------------------------------------------------------------------------- +/* +* eNB generate a S1 setup request towards MME +*/ static int s1ap_eNB_generate_s1_setup_request( - s1ap_eNB_instance_t *instance_p, s1ap_eNB_mme_data_t *s1ap_mme_data_p) + s1ap_eNB_instance_t *instance_p, + s1ap_eNB_mme_data_t *s1ap_mme_data_p) +//----------------------------------------------------------------------------- { - S1AP_S1AP_PDU_t pdu; - S1AP_S1SetupRequest_t *out; - S1AP_S1SetupRequestIEs_t *ie; - S1AP_SupportedTAs_Item_t *ta; - S1AP_PLMNidentity_t *plmn; - uint8_t *buffer; - uint32_t len; + S1AP_S1AP_PDU_t pdu; + S1AP_S1SetupRequest_t *out = NULL; + S1AP_S1SetupRequestIEs_t *ie = NULL; + S1AP_SupportedTAs_Item_t *ta = NULL; + S1AP_PLMNidentity_t *plmn = NULL; + uint8_t *buffer = NULL; + uint32_t len = 0; int ret = 0; DevAssert(instance_p != NULL); From 0a829e3eebbff10d8dc96860dd0ab300806a3ad5 Mon Sep 17 00:00:00 2001 From: Raphael Defosseux Date: Tue, 6 Nov 2018 11:37:49 +0100 Subject: [PATCH 097/233] CI: removing obsolete options from CI scenarios Signed-off-by: Raphael Defosseux --- ci-scripts/xml_files/enb_usrp210_band7.xml | 6 +++--- ci-scripts/xml_files/enb_usrpb210_band40.xml | 6 +++--- ci-scripts/xml_files/if4p5_usrp210_band40.xml | 12 ++++++------ ci-scripts/xml_files/if4p5_usrp210_band7.xml | 12 ++++++------ 4 files changed, 18 insertions(+), 18 deletions(-) diff --git a/ci-scripts/xml_files/enb_usrp210_band7.xml b/ci-scripts/xml_files/enb_usrp210_band7.xml index 0785ad815d..c408dc7882 100644 --- a/ci-scripts/xml_files/enb_usrp210_band7.xml +++ b/ci-scripts/xml_files/enb_usrp210_band7.xml @@ -40,19 +40,19 @@ Initialize_eNB Initialize eNB (FDD/Band7/5MHz) - -O ci-scripts/conf_files/enb.band7.tm1.25PRB.usrpb210.conf --codingw --fepw + -O ci-scripts/conf_files/enb.band7.tm1.25PRB.usrpb210.conf Initialize_eNB Initialize eNB (FDD/Band7/10MHz) - -O ci-scripts/conf_files/enb.band7.tm1.50PRB.usrpb210.conf --codingw --fepw + -O ci-scripts/conf_files/enb.band7.tm1.50PRB.usrpb210.conf Initialize_eNB Initialize eNB (FDD/Band7/20MHz) - -O ci-scripts/conf_files/enb.band7.tm1.100PRB.usrpb210.conf --codingw --fepw + -O ci-scripts/conf_files/enb.band7.tm1.100PRB.usrpb210.conf diff --git a/ci-scripts/xml_files/enb_usrpb210_band40.xml b/ci-scripts/xml_files/enb_usrpb210_band40.xml index 1af1c319cf..53a0dc9380 100644 --- a/ci-scripts/xml_files/enb_usrpb210_band40.xml +++ b/ci-scripts/xml_files/enb_usrpb210_band40.xml @@ -43,19 +43,19 @@ Initialize_eNB Initialize eNB (TDD/Band40/5MHz) - -O ci-scripts/conf_files/enb.band40.tm1.25PRB.FairScheduler.usrpb210.conf --codingw --fepw + -O ci-scripts/conf_files/enb.band40.tm1.25PRB.FairScheduler.usrpb210.conf Initialize_eNB Initialize eNB (TDD/Band40/10MHz/info) - -O ci-scripts/conf_files/enb.band40.tm1.50PRB.FairScheduler.usrpb210.conf --codingw --fepw + -O ci-scripts/conf_files/enb.band40.tm1.50PRB.FairScheduler.usrpb210.conf Initialize_eNB Initialize eNB (TDD/Band40/20MHz/info) - -O ci-scripts/conf_files/enb.band40.tm1.100PRB.FairScheduler.usrpb210.conf --codingw --fepw + -O ci-scripts/conf_files/enb.band40.tm1.100PRB.FairScheduler.usrpb210.conf diff --git a/ci-scripts/xml_files/if4p5_usrp210_band40.xml b/ci-scripts/xml_files/if4p5_usrp210_band40.xml index 9c1b721bef..b7877009fd 100644 --- a/ci-scripts/xml_files/if4p5_usrp210_band40.xml +++ b/ci-scripts/xml_files/if4p5_usrp210_band40.xml @@ -46,42 +46,42 @@ Initialize_eNB Initialize RRU (TDD/Band40) - -O ci-scripts/conf_files/rru.tdd.band40.conf --codingw --fepw + -O ci-scripts/conf_files/rru.tdd.band40.conf 0 Initialize_eNB Initialize RCC (TDD/Band40/5MHz) - -O ci-scripts/conf_files/rcc.band40.tm1.25PRB.FairScheduler.usrpb210.conf --codingw --fepw + -O ci-scripts/conf_files/rcc.band40.tm1.25PRB.FairScheduler.usrpb210.conf 1 Initialize_eNB Initialize RRU (TDD/Band40) - -O ci-scripts/conf_files/rru.tdd.band40.conf --codingw --fepw + -O ci-scripts/conf_files/rru.tdd.band40.conf 0 Initialize_eNB Initialize RCC (TDD/Band40/10MHz/info) - -O ci-scripts/conf_files/rcc.band40.tm1.50PRB.FairScheduler.usrpb210.conf --codingw --fepw + -O ci-scripts/conf_files/rcc.band40.tm1.50PRB.FairScheduler.usrpb210.conf 1 Initialize_eNB Initialize RRU (TDD/Band40) - -O ci-scripts/conf_files/rru.tdd.band40.conf --codingw --fepw + -O ci-scripts/conf_files/rru.tdd.band40.conf 0 Initialize_eNB Initialize RCC (TDD/Band40/20MHz/info) - -O ci-scripts/conf_files/rcc.band40.tm1.100PRB.FairScheduler.usrpb210.conf --codingw --fepw + -O ci-scripts/conf_files/rcc.band40.tm1.100PRB.FairScheduler.usrpb210.conf 1 diff --git a/ci-scripts/xml_files/if4p5_usrp210_band7.xml b/ci-scripts/xml_files/if4p5_usrp210_band7.xml index a3e5ecd72c..9ca3a113bf 100644 --- a/ci-scripts/xml_files/if4p5_usrp210_band7.xml +++ b/ci-scripts/xml_files/if4p5_usrp210_band7.xml @@ -44,42 +44,42 @@ Initialize_eNB Initialize RRU (FDD/Band7) - -O ci-scripts/conf_files/rru.fdd.band7.conf --codingw --fepw + -O ci-scripts/conf_files/rru.fdd.band7.conf 1 Initialize_eNB Initialize RCC (FDD/Band7/5MHz) - -O ci-scripts/conf_files/rcc.band7.tm1.if4p5.lo.25PRB.usrpb210.conf --codingw --fepw + -O ci-scripts/conf_files/rcc.band7.tm1.if4p5.lo.25PRB.usrpb210.conf 0 Initialize_eNB Initialize RRU (FDD/Band7) - -O ci-scripts/conf_files/rru.fdd.band7.conf --codingw --fepw + -O ci-scripts/conf_files/rru.fdd.band7.conf 1 Initialize_eNB Initialize RCC (FDD/Band7/10MHz) - -O ci-scripts/conf_files/rcc.band7.tm1.if4p5.lo.50PRB.usrpb210.conf --codingw --fepw + -O ci-scripts/conf_files/rcc.band7.tm1.if4p5.lo.50PRB.usrpb210.conf 0 Initialize_eNB Initialize RRU (FDD/Band7) - -O ci-scripts/conf_files/rru.fdd.band7.conf --codingw --fepw + -O ci-scripts/conf_files/rru.fdd.band7.conf 1 Initialize_eNB Initialize RCC (FDD/Band7/20MHz) - -O ci-scripts/conf_files/rcc.band7.tm1.if4p5.lo.100PRB.usrpb210.conf --codingw --fepw + -O ci-scripts/conf_files/rcc.band7.tm1.if4p5.lo.100PRB.usrpb210.conf 0 From 74dc481133519e06ad236b1406d051c11522575e Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Tue, 6 Nov 2018 16:50:48 +0100 Subject: [PATCH 098/233] bladeRF: have it functional with libbladerf 2.0 Not much has been changed in the driver (that used libbladerf 1.0). Some bugs have been fixed. Documentation has been added. A configuration file has been added too, put in the directory ./configuration/bladeRF. To use a bladeRF device, see documentation in targets/ARCH/BLADERF/README. Only the BladeRF x40 has been tested. Performance is not too bad at 5MHz, a bit worse at 10MHz and on the test machine I used I face realtime problems at 20MHz when I push downlink throughput. So, there is still some work to do to have a good support of bladeRF. --- configuration/bladeRF/enb-band7-5mhz.conf | 274 ++++++++++++++++++ targets/ARCH/BLADERF/README | 138 +++++++++ .../ARCH/BLADERF/USERSPACE/LIB/bladerf_lib.c | 43 ++- 3 files changed, 431 insertions(+), 24 deletions(-) create mode 100644 configuration/bladeRF/enb-band7-5mhz.conf create mode 100644 targets/ARCH/BLADERF/README diff --git a/configuration/bladeRF/enb-band7-5mhz.conf b/configuration/bladeRF/enb-band7-5mhz.conf new file mode 100644 index 0000000000..6e07b8d949 --- /dev/null +++ b/configuration/bladeRF/enb-band7-5mhz.conf @@ -0,0 +1,274 @@ +Active_eNBs = ( "eNB-Eurecom-LTEBox"); +# Asn1_verbosity, choice in: none, info, annoying +Asn1_verbosity = "none"; + +eNBs = +( + { + # real_time choice in {hard, rt-preempt, no} + real_time = "no"; + ////////// Identification parameters: + eNB_ID = 0xe00; + + cell_type = "CELL_MACRO_ENB"; + + eNB_name = "eNB-Eurecom-LTEBox"; + + // Tracking area code, 0x0000 and 0xfffe are reserved values + tracking_area_code = 1; + plmn_list = ( + { mcc = 208; mnc = 92; mnc_length = 2; } + ); + + tr_s_preference = "local_mac" + + ////////// Physical parameters: + + component_carriers = ( + { + node_function = "eNodeB_3GPP"; + node_timing = "synch_to_ext_device"; + node_synch_ref = 0; + nb_antenna_ports = 1; + ue_TransmissionMode = 1; + frame_type = "FDD"; + tdd_config = 3; + tdd_config_s = 0; + prefix_type = "NORMAL"; + eutra_band = 7; + downlink_frequency = 2680000000L; + uplink_frequency_offset = -120000000; + + Nid_cell = 0; + N_RB_DL = 25; + Nid_cell_mbsfn = 0; + nb_antennas_tx = 1; + nb_antennas_rx = 1; + prach_root = 0; + tx_gain = 90; + rx_gain = 115; + pbch_repetition = "FALSE"; + prach_config_index = 0; + prach_high_speed = "DISABLE"; + prach_zero_correlation = 1; + prach_freq_offset = 2; + pucch_delta_shift = 1; + pucch_nRB_CQI = 0; + pucch_nCS_AN = 0; + pucch_n1_AN = 0; + pdsch_referenceSignalPower = -29; + pdsch_p_b = 0; + pusch_n_SB = 1; + pusch_enable64QAM = "DISABLE"; + pusch_hoppingMode = "interSubFrame"; + pusch_hoppingOffset = 0; + pusch_groupHoppingEnabled = "ENABLE"; + pusch_groupAssignment = 0; + pusch_sequenceHoppingEnabled = "DISABLE"; + pusch_nDMRS1 = 1; + phich_duration = "NORMAL"; + phich_resource = "ONESIXTH"; + srs_enable = "DISABLE"; + /* srs_BandwidthConfig =; + srs_SubframeConfig =; + srs_ackNackST =; + srs_MaxUpPts =;*/ + + pusch_p0_Nominal = -96; + pusch_alpha = "AL1"; + pucch_p0_Nominal = -108; + msg3_delta_Preamble = 6; + pucch_deltaF_Format1 = "deltaF2"; + pucch_deltaF_Format1b = "deltaF3"; + pucch_deltaF_Format2 = "deltaF0"; + pucch_deltaF_Format2a = "deltaF0"; + pucch_deltaF_Format2b = "deltaF0"; + + rach_numberOfRA_Preambles = 64; + rach_preamblesGroupAConfig = "DISABLE"; +/* + rach_sizeOfRA_PreamblesGroupA = ; + rach_messageSizeGroupA = ; + rach_messagePowerOffsetGroupB = ; +*/ + rach_powerRampingStep = 4; + rach_preambleInitialReceivedTargetPower = -108; + rach_preambleTransMax = 10; + rach_raResponseWindowSize = 10; + rach_macContentionResolutionTimer = 48; + rach_maxHARQ_Msg3Tx = 4; + + pcch_default_PagingCycle = 128; + pcch_nB = "oneT"; + bcch_modificationPeriodCoeff = 2; + ue_TimersAndConstants_t300 = 1000; + ue_TimersAndConstants_t301 = 1000; + ue_TimersAndConstants_t310 = 1000; + ue_TimersAndConstants_t311 = 10000; + ue_TimersAndConstants_n310 = 20; + ue_TimersAndConstants_n311 = 1; + + //Parameters for SIB18 + rxPool_sc_CP_Len = "normal"; + rxPool_sc_Period = "sf40"; + rxPool_data_CP_Len = "normal"; + rxPool_ResourceConfig_prb_Num = 20; + rxPool_ResourceConfig_prb_Start = 5; + rxPool_ResourceConfig_prb_End = 44; + rxPool_ResourceConfig_offsetIndicator_present = "prSmall"; + rxPool_ResourceConfig_offsetIndicator_choice = 0; + rxPool_ResourceConfig_subframeBitmap_present = "prBs40"; + rxPool_ResourceConfig_subframeBitmap_choice_bs_buf = "00000000000000000000"; + rxPool_ResourceConfig_subframeBitmap_choice_bs_size = 5; + rxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused = 0; +/* rxPool_dataHoppingConfig_hoppingParameter = 0; + rxPool_dataHoppingConfig_numSubbands = "ns1"; + rxPool_dataHoppingConfig_rbOffset = 0; + rxPool_commTxResourceUC-ReqAllowed = "TRUE"; +*/ + // Parameters for SIB19 + discRxPool_cp_Len = "normal" + discRxPool_discPeriod = "rf32" + discRxPool_numRetx = 1; + discRxPool_numRepetition = 2; + discRxPool_ResourceConfig_prb_Num = 5; + discRxPool_ResourceConfig_prb_Start = 3; + discRxPool_ResourceConfig_prb_End = 21; + discRxPool_ResourceConfig_offsetIndicator_present = "prSmall"; + discRxPool_ResourceConfig_offsetIndicator_choice = 0; + discRxPool_ResourceConfig_subframeBitmap_present = "prBs40"; + discRxPool_ResourceConfig_subframeBitmap_choice_bs_buf = "f0ffffffff"; + discRxPool_ResourceConfig_subframeBitmap_choice_bs_size = 5; + discRxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused = 0; + + } + ); + + srb1_parameters : + { + # timer_poll_retransmit = (ms) [5, 10, 15, 20,... 250, 300, 350, ... 500] + timer_poll_retransmit = 80; + + # timer_reordering = (ms) [0,5, ... 100, 110, 120, ... ,200] + timer_reordering = 35; + + # timer_reordering = (ms) [0,5, ... 250, 300, 350, ... ,500] + timer_status_prohibit = 0; + + # poll_pdu = [4, 8, 16, 32 , 64, 128, 256, infinity(>10000)] + poll_pdu = 4; + + # poll_byte = (kB) [25,50,75,100,125,250,375,500,750,1000,1250,1500,2000,3000,infinity(>10000)] + poll_byte = 99999; + + # max_retx_threshold = [1, 2, 3, 4 , 6, 8, 16, 32] + max_retx_threshold = 4; + } + + # ------- SCTP definitions + SCTP : + { + # Number of streams to use in input/output + SCTP_INSTREAMS = 2; + SCTP_OUTSTREAMS = 2; + }; + + ////////// MME parameters: + mme_ip_address = ( { ipv4 = "192.168.12.148"; + ipv6 = "192:168:30::17"; + active = "yes"; + preference = "ipv4"; + } + ); + + NETWORK_INTERFACES : + { + ENB_INTERFACE_NAME_FOR_S1_MME = "eth1"; + ENB_IPV4_ADDRESS_FOR_S1_MME = "192.168.12.196/24"; + + ENB_INTERFACE_NAME_FOR_S1U = "eth1"; + ENB_IPV4_ADDRESS_FOR_S1U = "192.168.12.196/24"; + ENB_PORT_FOR_S1U = 2152; # Spec 2152 + + ENB_IPV4_ADDRESS_FOR_X2C = "192.168.12.196/24"; + ENB_PORT_FOR_X2C = 36422; # Spec 36422 + }; + + log_config : + { + global_log_level ="info"; + global_log_verbosity ="high"; + hw_log_level ="info"; + hw_log_verbosity ="medium"; + phy_log_level ="info"; + phy_log_verbosity ="medium"; + mac_log_level ="info"; + mac_log_verbosity ="high"; + rlc_log_level ="debug"; + rlc_log_verbosity ="high"; + pdcp_log_level ="info"; + pdcp_log_verbosity ="high"; + rrc_log_level ="info"; + rrc_log_verbosity ="medium"; + }; + + } +); + +MACRLCs = ( + { + num_cc = 1; + tr_s_preference = "local_L1"; + tr_n_preference = "local_RRC"; + phy_test_mode = 0; + puSch10xSnr = 210; + puCch10xSnr = 210; + } +); + +THREAD_STRUCT = ( + { + parallel_config = "PARALLEL_RU_L1_TRX_SPLITaaaaaa"; + worker_config = "ENABLE"; + } +); + +L1s = ( + { + num_cc = 1; + tr_n_preference = "local_mac"; + } +); + +RUs = ( + { + local_rf = "yes" + nb_tx = 1 + nb_rx = 1 + att_tx = 73 + att_rx = 0; + bands = [7]; + max_pdschReferenceSignalPower = -28; + max_rxgain = 96; + eNB_instances = [0]; + + } +); + + log_config : + { + global_log_level ="info"; + global_log_verbosity ="high"; + hw_log_level ="info"; + hw_log_verbosity ="medium"; + phy_log_level ="info"; + phy_log_verbosity ="medium"; + mac_log_level ="info"; + mac_log_verbosity ="high"; + rlc_log_level ="info"; + rlc_log_verbosity ="high"; + pdcp_log_level ="info"; + pdcp_log_verbosity ="high"; + rrc_log_level ="info"; + rrc_log_verbosity ="medium"; + }; diff --git a/targets/ARCH/BLADERF/README b/targets/ARCH/BLADERF/README new file mode 100644 index 0000000000..c93c938baf --- /dev/null +++ b/targets/ARCH/BLADERF/README @@ -0,0 +1,138 @@ +BladeRF documentation +===================== + +As of 2018-11-06, the bladeRF support is not fully automatic and requires +some manual settings before use. This documentation is the ultimate source +of information. If something described in this file does not work or does +not correspond to the reality, then contact us so we can fix the problems +and update this documentation. + +1. Install bladeRF 2.0 libraries. + + As of now, it's better to install from source. + So, do not run: ./build_oai -I -w BLADERF + (That is: do not include '-w BLADERF'.) + + Instead, follow the instructions at: https://github.com/Nuand/bladeRF + + If you already had some bladeRF software installed using automatic + methods, first remove it by hand ('apt-get purge bladeRF' or something + similar, you can get the list of installed bladeRF packages by running + 'dpkg -l|grep -i blade', remove them all). + +2. Update the device. + + Download the latest FX3 firmware and FPGA images from Nuand's website. + As of writing, this is: + + https://github.com/Nuand/bladeRF/wiki + + That points to the following pages. + For FX3: + + http://www.nuand.com/fx3_images/ + + For FPGA: + + http://www.nuand.com/fpga_images/ + + Install FX3 firmware: + + sudo bladeRF-cli -f bladeRF_fw_latest.img + + Install FPGA image (this is for BladeRF x40): + + sudo bladeRF-cli -L hostedx40-latest.rbf + + Retrieve calibration information: + + sudo bladeRF-cli -i + info + + That outputs the serial number of your device. + + Go to: + + https://www.nuand.com/calibration + + And enter your serial number. + The website tells you to run something like: + + sudo bladeRF-cli -i + flash_init_cal 40 0x9271 + + Actual values depend on your device and serial number. + +3. Calibrate the bladeRF device. + + We will work with band 7 on 2.68GHz with a bandwidth of 5 MHz (25 RBs). + + Plug the bladeRF device, then run: + + sudo bladeRF-cli -i + set frequency tx 2680000000 + set frequency rx 2560000000 + set gain rx 60 + set gain tx 60 + set bandwidth 5000000 + set samplerate 7680000 + cal lms + cal lms + cal lms + cal dc rxtx + cal dc rxtx + cal dc rxtx + +4. Tune the RX gain using the enb tracer. + + Run the softmodem and the 'enb' tracer. For instructions, see: + + https://gitlab.eurecom.fr/oai/openairinterface5g/wikis/T/basic + + In the enb window, check the 'input signal'. You should see some blue + signal as seen at: + + https://gitlab.eurecom.fr/oai/openairinterface5g/wikis/T/enb + + (the 'Time signal power' plot). + + The level should be around 30. + + If it's not around 30 then edit your configuration file and modify + the value 'max_rxgain' in the section 'RUs'. + + The configuration file to use is: + + configuration/bladeRF/enb-band7-5mhz.conf + + In the configuration file, you also need to set the correct values for: + + - tracking_area_code + - plmn_list: mcc, mnc, mnc_length + - mme_ip_address: this is the IP address used by the computer running + the softmodem to connect to the EPC + - NETWORK_INTERFACES: all the ENB*ADDRESS* variables have to point + to the IP address of the EPC machine + +5. You're good to go. + + You can now connect a UE and pass some traffic. If everything is well + configured you can expect more than 16 Mb/s of throughput in the downlink + using iperf and more than 8 Mb/s in the uplink. Looking at the logs, you + should find lines containing 'PHR 40' and 'CQI 15'. If your values are + lower then your setup may need some adjustments. + +6. In case of problems. + + If the performance of the softmodem is very bad, you can stop it and + run the calibration again, without setting the parameters (frequencies, + gains, etc.). Just run: + + sudo bladeRF-cli -i + cal lms + cal dc rxtx + + That may help. + + Be sure to use proper radio equipment (duplexer, antennas, clean + environment without interferences). diff --git a/targets/ARCH/BLADERF/USERSPACE/LIB/bladerf_lib.c b/targets/ARCH/BLADERF/USERSPACE/LIB/bladerf_lib.c index 75a7825669..e5966af267 100644 --- a/targets/ARCH/BLADERF/USERSPACE/LIB/bladerf_lib.c +++ b/targets/ARCH/BLADERF/USERSPACE/LIB/bladerf_lib.c @@ -116,15 +116,6 @@ int trx_brf_start(openair0_device *device) { abort(); } - if ((status=bladerf_calibrate_dc(brf->dev, BLADERF_MODULE_TX)) != 0) { - fprintf(stderr,"Failed to calibrate TX DC: %s\n", bladerf_strerror(status)); - abort(); - } - if ((status=bladerf_calibrate_dc(brf->dev, BLADERF_MODULE_RX)) != 0) { - fprintf(stderr,"Failed to calibrate RX DC: %s\n", bladerf_strerror(status)); - abort(); - } - return 0; } @@ -235,8 +226,6 @@ static int trx_brf_read(openair0_device *device, openair0_timestamp *ptimestamp, * \param device the hardware to use */ void trx_brf_end(openair0_device *device) { -abort(); - int status; brf_state_t *brf = (brf_state_t*)device->priv; // Disable RX module, shutting down our underlying RX stream @@ -247,6 +236,7 @@ abort(); fprintf(stderr, "Failed to disable TX module: %s\n", bladerf_strerror(status)); } bladerf_close(brf->dev); + exit(1); } /*! \brief print the BladeRF statistics @@ -362,6 +352,8 @@ void set_rx_gain_offset(openair0_config_t *openair0_cfg, int chain_index) { */ void calibrate_rf(openair0_device *device) { + /* TODO: this function does not seem to work. Disabled until fixed. */ + return; brf_state_t *brf = (brf_state_t *)device->priv; openair0_timestamp ptimestamp; @@ -1005,6 +997,12 @@ int device_init(openair0_device *device, openair0_config_t *openair0_cfg) { // RX // Example of CLI output: RX Frequency: 2539999999Hz + + if ((status=bladerf_set_gain_mode(brf->dev, BLADERF_MODULE_RX, BLADERF_GAIN_MGC))) { + fprintf(stderr, "[BRF] Failed to disable AGC\n"); + brf_error(status); + } + if ((status=bladerf_set_frequency(brf->dev, BLADERF_MODULE_RX, (unsigned int) openair0_cfg->rx_freq[0])) != 0){ fprintf(stderr,"Failed to set RX frequency: %s\n",bladerf_strerror(status)); brf_error(status); @@ -1096,17 +1094,14 @@ int device_init(openair0_device *device, openair0_config_t *openair0_cfg) { // calibrate - if ((status=bladerf_calibrate_dc(brf->dev, BLADERF_MODULE_TX)) != 0) { - fprintf(stderr,"Failed to calibrate TX DC: %s\n", bladerf_strerror(status)); + if ((status=bladerf_calibrate_dc(brf->dev, BLADERF_DC_CAL_LPF_TUNING)) != 0 || + (status=bladerf_calibrate_dc(brf->dev, BLADERF_DC_CAL_TX_LPF)) != 0 || + (status=bladerf_calibrate_dc(brf->dev, BLADERF_DC_CAL_RX_LPF)) != 0 || + (status=bladerf_calibrate_dc(brf->dev, BLADERF_DC_CAL_RXVGA2)) != 0) { + fprintf(stderr, "[BRF] error calibrating\n"); brf_error(status); - } else - printf("[BRF] TX module calibrated DC \n"); - - if ((status=bladerf_calibrate_dc(brf->dev, BLADERF_MODULE_RX)) != 0) { - fprintf(stderr,"Failed to calibrate RX DC: %s\n", bladerf_strerror(status)); - brf_error(status); - }else - printf("[BRF] RX module calibrated DC \n"); + } else + printf("[BRF] calibration OK\n"); bladerf_log_set_verbosity(get_brf_log_level(openair0_cfg->log_level)); @@ -1146,8 +1141,8 @@ int device_init(openair0_device *device, openair0_config_t *openair0_cfg) { * \returns 0 on success */ int brf_error(int status) { - - //exit(-1); + fprintf(stderr, "[BRF] brf_error: %s\n", bladerf_strerror(status)); + exit(-1); return status; // or status error code } @@ -1190,7 +1185,7 @@ struct bladerf * open_bladerf_from_serial(const char *serial) { int get_brf_log_level(int log_level){ int level=BLADERF_LOG_LEVEL_INFO; - return BLADERF_LOG_LEVEL_DEBUG; // BLADERF_LOG_LEVEL_VERBOSE;// BLADERF_LOG_LEVEL_DEBUG; // + return BLADERF_LOG_LEVEL_INFO; switch(log_level) { case LOG_DEBUG: level=BLADERF_LOG_LEVEL_DEBUG; From 2a48796406c2355eb2a6ec432f026742481c71d7 Mon Sep 17 00:00:00 2001 From: Raphael Defosseux Date: Wed, 7 Nov 2018 10:16:48 +0100 Subject: [PATCH 099/233] CI: removing obsolete options from CI scenarios Signed-off-by: Raphael Defosseux --- ci-scripts/xml_files/enb_usrp210_band7.xml | 6 +++--- ci-scripts/xml_files/enb_usrpb210_band40.xml | 6 +++--- ci-scripts/xml_files/if4p5_usrp210_band40.xml | 12 ++++++------ ci-scripts/xml_files/if4p5_usrp210_band7.xml | 12 ++++++------ 4 files changed, 18 insertions(+), 18 deletions(-) diff --git a/ci-scripts/xml_files/enb_usrp210_band7.xml b/ci-scripts/xml_files/enb_usrp210_band7.xml index 0785ad815d..c408dc7882 100644 --- a/ci-scripts/xml_files/enb_usrp210_band7.xml +++ b/ci-scripts/xml_files/enb_usrp210_band7.xml @@ -40,19 +40,19 @@ Initialize_eNB Initialize eNB (FDD/Band7/5MHz) - -O ci-scripts/conf_files/enb.band7.tm1.25PRB.usrpb210.conf --codingw --fepw + -O ci-scripts/conf_files/enb.band7.tm1.25PRB.usrpb210.conf Initialize_eNB Initialize eNB (FDD/Band7/10MHz) - -O ci-scripts/conf_files/enb.band7.tm1.50PRB.usrpb210.conf --codingw --fepw + -O ci-scripts/conf_files/enb.band7.tm1.50PRB.usrpb210.conf Initialize_eNB Initialize eNB (FDD/Band7/20MHz) - -O ci-scripts/conf_files/enb.band7.tm1.100PRB.usrpb210.conf --codingw --fepw + -O ci-scripts/conf_files/enb.band7.tm1.100PRB.usrpb210.conf diff --git a/ci-scripts/xml_files/enb_usrpb210_band40.xml b/ci-scripts/xml_files/enb_usrpb210_band40.xml index 1af1c319cf..53a0dc9380 100644 --- a/ci-scripts/xml_files/enb_usrpb210_band40.xml +++ b/ci-scripts/xml_files/enb_usrpb210_band40.xml @@ -43,19 +43,19 @@ Initialize_eNB Initialize eNB (TDD/Band40/5MHz) - -O ci-scripts/conf_files/enb.band40.tm1.25PRB.FairScheduler.usrpb210.conf --codingw --fepw + -O ci-scripts/conf_files/enb.band40.tm1.25PRB.FairScheduler.usrpb210.conf Initialize_eNB Initialize eNB (TDD/Band40/10MHz/info) - -O ci-scripts/conf_files/enb.band40.tm1.50PRB.FairScheduler.usrpb210.conf --codingw --fepw + -O ci-scripts/conf_files/enb.band40.tm1.50PRB.FairScheduler.usrpb210.conf Initialize_eNB Initialize eNB (TDD/Band40/20MHz/info) - -O ci-scripts/conf_files/enb.band40.tm1.100PRB.FairScheduler.usrpb210.conf --codingw --fepw + -O ci-scripts/conf_files/enb.band40.tm1.100PRB.FairScheduler.usrpb210.conf diff --git a/ci-scripts/xml_files/if4p5_usrp210_band40.xml b/ci-scripts/xml_files/if4p5_usrp210_band40.xml index 9c1b721bef..b7877009fd 100644 --- a/ci-scripts/xml_files/if4p5_usrp210_band40.xml +++ b/ci-scripts/xml_files/if4p5_usrp210_band40.xml @@ -46,42 +46,42 @@ Initialize_eNB Initialize RRU (TDD/Band40) - -O ci-scripts/conf_files/rru.tdd.band40.conf --codingw --fepw + -O ci-scripts/conf_files/rru.tdd.band40.conf 0 Initialize_eNB Initialize RCC (TDD/Band40/5MHz) - -O ci-scripts/conf_files/rcc.band40.tm1.25PRB.FairScheduler.usrpb210.conf --codingw --fepw + -O ci-scripts/conf_files/rcc.band40.tm1.25PRB.FairScheduler.usrpb210.conf 1 Initialize_eNB Initialize RRU (TDD/Band40) - -O ci-scripts/conf_files/rru.tdd.band40.conf --codingw --fepw + -O ci-scripts/conf_files/rru.tdd.band40.conf 0 Initialize_eNB Initialize RCC (TDD/Band40/10MHz/info) - -O ci-scripts/conf_files/rcc.band40.tm1.50PRB.FairScheduler.usrpb210.conf --codingw --fepw + -O ci-scripts/conf_files/rcc.band40.tm1.50PRB.FairScheduler.usrpb210.conf 1 Initialize_eNB Initialize RRU (TDD/Band40) - -O ci-scripts/conf_files/rru.tdd.band40.conf --codingw --fepw + -O ci-scripts/conf_files/rru.tdd.band40.conf 0 Initialize_eNB Initialize RCC (TDD/Band40/20MHz/info) - -O ci-scripts/conf_files/rcc.band40.tm1.100PRB.FairScheduler.usrpb210.conf --codingw --fepw + -O ci-scripts/conf_files/rcc.band40.tm1.100PRB.FairScheduler.usrpb210.conf 1 diff --git a/ci-scripts/xml_files/if4p5_usrp210_band7.xml b/ci-scripts/xml_files/if4p5_usrp210_band7.xml index a3e5ecd72c..9ca3a113bf 100644 --- a/ci-scripts/xml_files/if4p5_usrp210_band7.xml +++ b/ci-scripts/xml_files/if4p5_usrp210_band7.xml @@ -44,42 +44,42 @@ Initialize_eNB Initialize RRU (FDD/Band7) - -O ci-scripts/conf_files/rru.fdd.band7.conf --codingw --fepw + -O ci-scripts/conf_files/rru.fdd.band7.conf 1 Initialize_eNB Initialize RCC (FDD/Band7/5MHz) - -O ci-scripts/conf_files/rcc.band7.tm1.if4p5.lo.25PRB.usrpb210.conf --codingw --fepw + -O ci-scripts/conf_files/rcc.band7.tm1.if4p5.lo.25PRB.usrpb210.conf 0 Initialize_eNB Initialize RRU (FDD/Band7) - -O ci-scripts/conf_files/rru.fdd.band7.conf --codingw --fepw + -O ci-scripts/conf_files/rru.fdd.band7.conf 1 Initialize_eNB Initialize RCC (FDD/Band7/10MHz) - -O ci-scripts/conf_files/rcc.band7.tm1.if4p5.lo.50PRB.usrpb210.conf --codingw --fepw + -O ci-scripts/conf_files/rcc.band7.tm1.if4p5.lo.50PRB.usrpb210.conf 0 Initialize_eNB Initialize RRU (FDD/Band7) - -O ci-scripts/conf_files/rru.fdd.band7.conf --codingw --fepw + -O ci-scripts/conf_files/rru.fdd.band7.conf 1 Initialize_eNB Initialize RCC (FDD/Band7/20MHz) - -O ci-scripts/conf_files/rcc.band7.tm1.if4p5.lo.100PRB.usrpb210.conf --codingw --fepw + -O ci-scripts/conf_files/rcc.band7.tm1.if4p5.lo.100PRB.usrpb210.conf 0 From 11df1684b7c1c2f04b881d17da623f4aa5f6cbb0 Mon Sep 17 00:00:00 2001 From: "yoshio.inoue" Date: Wed, 7 Nov 2018 21:04:12 +0900 Subject: [PATCH 100/233] cleanup warnings --- nfapi/open-nFAPI/pnf/src/pnf.c | 2 +- nfapi/open-nFAPI/pnf/src/pnf_p7.c | 2 +- nfapi/open-nFAPI/vnf/src/vnf_p7.c | 4 ++-- openair3/NAS/UE/ESM/esm_ebr_context.c | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/nfapi/open-nFAPI/pnf/src/pnf.c b/nfapi/open-nFAPI/pnf/src/pnf.c index 362162cd9d..d0a7fa6fd1 100755 --- a/nfapi/open-nFAPI/pnf/src/pnf.c +++ b/nfapi/open-nFAPI/pnf/src/pnf.c @@ -1260,7 +1260,7 @@ int pnf_connect(pnf_t* pnf) address = inet_ntoa(addr->sin_addr); } -// NFAPI_TRACE(NFAPI_TRACE_NOTE, "Host address info %d Family:%s Address:%s\n", i++, family, address); + NFAPI_TRACE(NFAPI_TRACE_NOTE, "Host address info %d Family:%s Address:%s\n", i++, family, address); if (pnf->sctp) { diff --git a/nfapi/open-nFAPI/pnf/src/pnf_p7.c b/nfapi/open-nFAPI/pnf/src/pnf_p7.c index f7152cc077..8d94c23476 100755 --- a/nfapi/open-nFAPI/pnf/src/pnf_p7.c +++ b/nfapi/open-nFAPI/pnf/src/pnf_p7.c @@ -379,7 +379,7 @@ static uint32_t get_sf_time(uint32_t now_hr, uint32_t sf_start_hr) { if(now_hr < sf_start_hr) { -// NFAPI_TRACE(NFAPI_TRACE_INFO, "now is earlier than start of subframe now_hr:%u sf_start_hr:%u\n", now_hr, sf_start_hr); + NFAPI_TRACE(NFAPI_TRACE_INFO, "now is earlier than start of subframe now_hr:%u sf_start_hr:%u\n", now_hr, sf_start_hr); return 0; } else diff --git a/nfapi/open-nFAPI/vnf/src/vnf_p7.c b/nfapi/open-nFAPI/vnf/src/vnf_p7.c index 6c17fb2a99..cea259c35b 100755 --- a/nfapi/open-nFAPI/vnf/src/vnf_p7.c +++ b/nfapi/open-nFAPI/vnf/src/vnf_p7.c @@ -1203,13 +1203,13 @@ void vnf_handle_ul_node_sync(void *pRecvMsg, int recvMsgLen, vnf_p7_t* vnf_p7) if(phy->in_sync == 0) { -/* NFAPI_TRACE(NFAPI_TRACE_NOTE, "***** Adjusting VNF phy_id:%d SFN/SF (%s) from %d to %d (%d) mode:%s zeroCount:%u sync:%s\n", + NFAPI_TRACE(NFAPI_TRACE_NOTE, "***** Adjusting VNF phy_id:%d SFN/SF (%s) from %d to %d (%d) mode:%s zeroCount:%u sync:%s\n", ind.header.phy_id, (phy->in_sync ? "via sfn" : "now"), NFAPI_SFNSF2DEC(curr_sfn_sf), NFAPI_SFNSF2DEC(new_sfn_sf), phy->adjustment, phy->filtered_adjust ? "FILTERED" : "ABSOLUTE", phy->zero_count, phy->in_sync ? "IN_SYNC" : "OUT_OF_SYNC"); -*/ + phy->sfn_sf = new_sfn_sf; } } diff --git a/openair3/NAS/UE/ESM/esm_ebr_context.c b/openair3/NAS/UE/ESM/esm_ebr_context.c index 7cf1d8abbd..7404cd8b8a 100755 --- a/openair3/NAS/UE/ESM/esm_ebr_context.c +++ b/openair3/NAS/UE/ESM/esm_ebr_context.c @@ -214,7 +214,7 @@ int esm_ebr_context_create( char broadcast[INET_ADDRSTRLEN]; struct in_addr in_addr; char command_line[500]; - int res; + int res = -1; switch (pdn->type) { case NET_PDN_TYPE_IPV4V6: From 94bf32b0d462f340cfc881fe7dd88018ac433e18 Mon Sep 17 00:00:00 2001 From: Louis Adrien Dufrene Date: Thu, 8 Nov 2018 08:31:23 +0100 Subject: [PATCH 101/233] Bug fix: S1 id unknown after Detach Request (need to test) --- openair2/RRC/LTE/rrc_defs.h | 2 +- openair2/RRC/LTE/rrc_eNB_S1AP.c | 286 ++++++++++++++++++------ openair3/S1AP/s1ap_eNB_nas_procedures.c | 3 - 3 files changed, 214 insertions(+), 77 deletions(-) diff --git a/openair2/RRC/LTE/rrc_defs.h b/openair2/RRC/LTE/rrc_defs.h index 3756acc457..c5ca527b44 100644 --- a/openair2/RRC/LTE/rrc_defs.h +++ b/openair2/RRC/LTE/rrc_defs.h @@ -573,7 +573,7 @@ typedef struct eNB_RRC_UE_s { security_capabilities_t security_capabilities; /* Total number of e_rab already setup in the list */ - uint8_t setup_e_rabs; + uint8_t setup_e_rabs; /* Number of e_rab to be setup in the list */ uint8_t nb_of_e_rabs; /* Number of e_rab to be modified in the list */ diff --git a/openair2/RRC/LTE/rrc_eNB_S1AP.c b/openair2/RRC/LTE/rrc_eNB_S1AP.c index bb3f5a3851..81d5a6ae2b 100644 --- a/openair2/RRC/LTE/rrc_eNB_S1AP.c +++ b/openair2/RRC/LTE/rrc_eNB_S1AP.c @@ -36,6 +36,11 @@ # include "rrc_eNB_S1AP.h" # include "enb_config.h" # include "common/ran_context.h" +/****************************************/ +//# include "../../S1AP/s1ap_eNB_defs.h" +//# include "s1ap_eNB_management_procedures.h" +# include "s1ap_eNB_ue_context.h" +/****************************************/ # if defined(ENABLE_ITTI) # include "asn1_conversions.h" @@ -161,6 +166,9 @@ void extract_imsi(uint8_t *pdu_buf, uint32_t pdu_len, rrc_eNB_ue_context_t *ue_c # if defined(ENABLE_ITTI) //------------------------------------------------------------------------------ +/* +* TODO +*/ struct rrc_ue_s1ap_ids_s* rrc_eNB_S1AP_get_ue_ids( eNB_RRC_INST* const rrc_instance_pP, @@ -171,48 +179,169 @@ rrc_eNB_S1AP_get_ue_ids( { rrc_ue_s1ap_ids_t *result = NULL; rrc_ue_s1ap_ids_t *result2 = NULL; + /*****************************/ + instance_t instance = 0; + s1ap_eNB_instance_t *s1ap_eNB_instance_p = NULL; + s1ap_eNB_ue_context_t *ue_desc_p = NULL; + /*****************************/ hashtable_rc_t h_rc; - // we assume that a rrc_ue_s1ap_ids_s is initially inserted in initial_id2_s1ap_ids - if (eNB_ue_s1ap_id > 0) { - h_rc = hashtable_get(rrc_instance_pP->s1ap_id2_s1ap_ids, (hash_key_t)eNB_ue_s1ap_id, (void**)&result); - } if (ue_initial_id != UE_INITIAL_ID_INVALID) { h_rc = hashtable_get(rrc_instance_pP->initial_id2_s1ap_ids, (hash_key_t)ue_initial_id, (void**)&result); - if (h_rc == HASH_TABLE_OK) { - if (eNB_ue_s1ap_id > 0) { - h_rc = hashtable_get(rrc_instance_pP->s1ap_id2_s1ap_ids, (hash_key_t)eNB_ue_s1ap_id, (void**)&result2); - if (h_rc != HASH_TABLE_OK) { - result2 = malloc(sizeof(*result2)); - if (NULL != result2) { - *result2 = *result; - result2->eNB_ue_s1ap_id = eNB_ue_s1ap_id; - result->eNB_ue_s1ap_id = eNB_ue_s1ap_id; - h_rc = hashtable_insert(rrc_instance_pP->s1ap_id2_s1ap_ids, - (hash_key_t)eNB_ue_s1ap_id, - result2); + + if (h_rc == HASH_TABLE_OK) { + + if (eNB_ue_s1ap_id > 0) { + h_rc = hashtable_get(rrc_instance_pP->s1ap_id2_s1ap_ids, (hash_key_t)eNB_ue_s1ap_id, (void**)&result2); + + if (h_rc != HASH_TABLE_OK) { // this case is equivalent to associate eNB_ue_s1ap_id and ue_initial_id + result2 = malloc(sizeof(*result2)); + + if (NULL != result2) { + *result2 = *result; + + result2->eNB_ue_s1ap_id = eNB_ue_s1ap_id; + result->eNB_ue_s1ap_id = eNB_ue_s1ap_id; + + h_rc = hashtable_insert(rrc_instance_pP->s1ap_id2_s1ap_ids, (hash_key_t)eNB_ue_s1ap_id, result2); + if (h_rc != HASH_TABLE_OK) { - LOG_E(S1AP, "[eNB %ld] Error while hashtable_insert in s1ap_id2_s1ap_ids eNB_ue_s1ap_id %"PRIu32"\n", - rrc_instance_pP - RC.rrc[0], eNB_ue_s1ap_id); + LOG_E(S1AP, "[eNB %ld] Error while hashtable_insert in s1ap_id2_s1ap_ids eNB_ue_s1ap_id %"PRIu32"\n", + rrc_instance_pP - RC.rrc[0], + eNB_ue_s1ap_id); } - } - } - } - } + } + + } else { // here we should check that the association was done correctly + + if ((result->ue_initial_id != result2->ue_initial_id) || (result->eNB_ue_s1ap_id != result2->eNB_ue_s1ap_id)) { + + LOG_E(S1AP, "[eNB %ld] Error while hashtable_get, two rrc_ue_s1ap_ids_t that should be equal, are not: \ + ue_initial_id 1 = %"PRIu16", \ + ue_initial_id 2 = %"PRIu16", \ + eNB_ue_s1ap_id 1 = %"PRIu32", \ + eNB_ue_s1ap_id 2 = %"PRIu32"\n", + rrc_instance_pP - RC.rrc[0], + result->ue_initial_id, + result2->ue_initial_id, + result->eNB_ue_s1ap_id, + result2->eNB_ue_s1ap_id); + + } + + } + } // end if if (eNB_ue_s1ap_id > 0) + + } else { // end if (h_rc == HASH_TABLE_OK) + + LOG_E(S1AP, "[eNB %ld] In hashtable_get, couldn't find in initial_id2_s1ap_ids ue_initial_id %"PRIu16"\n", + rrc_instance_pP - RC.rrc[0], + ue_initial_id); + /* + * At the moment this is written, this case shouldn't (cannot) happen and is equivalent to an error. + * One could try to find the struct instance based on s1ap_id2_s1ap_ids and eNB_ue_s1ap_id (if > 0), + * but this behavior is not expected at the moment. + */ + + } // end else (h_rc != HASH_TABLE_OK) + + } else { // end if (ue_initial_id != UE_INITIAL_ID_INVALID) + + if (eNB_ue_s1ap_id > 0) { + h_rc = hashtable_get(rrc_instance_pP->s1ap_id2_s1ap_ids, (hash_key_t)eNB_ue_s1ap_id, (void**)&result); + + if (h_rc != HASH_TABLE_OK) { + /* + * This case is uncommon, but can happen when: + * -> if the first NAS message was a Detach Request (non exhaustiv), the UE RRC context exist + * but is not associated with eNB_ue_s1ap_id + * -> if the UE is in IDLE, hence no S1 context exist (in this case [h_rc != HASH_TABLE_OK] is normal) + * -> ... (?) + */ + LOG_E(S1AP, "[eNB %ld] In hashtable_get, couldn't find in s1ap_id2_s1ap_ids eNB_ue_s1ap_id %"PRIu32", trying \ + to find it through S1AP context\n", + rrc_instance_pP - RC.rrc[0], + eNB_ue_s1ap_id); + + instance = ENB_MODULE_ID_TO_INSTANCE(rrc_instance_pP - RC.rrc[0]); // get eNB instance + + s1ap_eNB_instance_p = s1ap_eNB_get_instance(instance); // get s1ap_eNB_instance + + ue_desc_p = s1ap_eNB_get_ue_context(s1ap_eNB_instance_p, eNB_ue_s1ap_id); // get s1ap_eNB_ue_context + + if (ue_desc_p != NULL) { + result = rrc_eNB_S1AP_get_ue_ids(rrc_instance_pP, ue_desc_p->ue_initial_id, eNB_ue_s1ap_id); + + } else { + + LOG_E(S1AP, "[eNB %ld] In hashtable_get, couldn't find in s1ap_id2_s1ap_ids eNB_ue_s1ap_id %"PRIu32", even \ + when looking at S1AP context\n", + rrc_instance_pP - RC.rrc[0], + eNB_ue_s1ap_id); + + } + + } // end if (h_rc != HASH_TABLE_OK) + } // end if (eNB_ue_s1ap_id > 0) + } // end else (ue_initial_id == UE_INITIAL_ID_INVALID) + + return result; + + // we assume that a rrc_ue_s1ap_ids_s is initially inserted in initial_id2_s1ap_ids + /* + if (eNB_ue_s1ap_id > 0) { + h_rc = hashtable_get(rrc_instance_pP->s1ap_id2_s1ap_ids, (hash_key_t)eNB_ue_s1ap_id, (void**)&result); + } + + if (ue_initial_id != UE_INITIAL_ID_INVALID) { + h_rc = hashtable_get(rrc_instance_pP->initial_id2_s1ap_ids, (hash_key_t)ue_initial_id, (void**)&result); + + if (h_rc == HASH_TABLE_OK) { + + if (eNB_ue_s1ap_id > 0) { + h_rc = hashtable_get(rrc_instance_pP->s1ap_id2_s1ap_ids, (hash_key_t)eNB_ue_s1ap_id, (void**)&result2); + + if (h_rc != HASH_TABLE_OK) { + result2 = malloc(sizeof(*result2)); + + if (NULL != result2) { + *result2 = *result; + + result2->eNB_ue_s1ap_id = eNB_ue_s1ap_id; + result->eNB_ue_s1ap_id = eNB_ue_s1ap_id; + + h_rc = hashtable_insert(rrc_instance_pP->s1ap_id2_s1ap_ids, (hash_key_t)eNB_ue_s1ap_id, result2); + + if (h_rc != HASH_TABLE_OK) { + LOG_E(S1AP, "[eNB %ld] Error while hashtable_insert in s1ap_id2_s1ap_ids eNB_ue_s1ap_id %"PRIu32"\n", + rrc_instance_pP - RC.rrc[0], + eNB_ue_s1ap_id); + } + } + } + } + } } return result; + */ } + //------------------------------------------------------------------------------ +/* +* TODO +*/ void rrc_eNB_S1AP_remove_ue_ids( - eNB_RRC_INST* const rrc_instance_pP, - struct rrc_ue_s1ap_ids_s* const ue_ids_pP + eNB_RRC_INST *const rrc_instance_pP, + struct rrc_ue_s1ap_ids_s *const ue_ids_pP ) //------------------------------------------------------------------------------ { const uint16_t ue_initial_id = ue_ids_pP->ue_initial_id; const uint32_t eNB_ue_s1ap_id = ue_ids_pP->eNB_ue_s1ap_id; + hashtable_rc_t h_rc; + if (rrc_instance_pP == NULL) { LOG_E(RRC, "Bad RRC instance\n"); return; @@ -224,21 +353,23 @@ rrc_eNB_S1AP_remove_ue_ids( } if (eNB_ue_s1ap_id > 0) { - h_rc = hashtable_remove(rrc_instance_pP->s1ap_id2_s1ap_ids, (hash_key_t)eNB_ue_s1ap_id); - if (h_rc != HASH_TABLE_OK) { - LOG_W(RRC, "S1AP Did not find entry in hashtable s1ap_id2_s1ap_ids for eNB_ue_s1ap_id %u\n", eNB_ue_s1ap_id); - } else { - LOG_W(RRC, "S1AP removed entry in hashtable s1ap_id2_s1ap_ids for eNB_ue_s1ap_id %u\n", eNB_ue_s1ap_id); - } + h_rc = hashtable_remove(rrc_instance_pP->s1ap_id2_s1ap_ids, (hash_key_t)eNB_ue_s1ap_id); + + if (h_rc != HASH_TABLE_OK) { + LOG_W(RRC, "S1AP Did not find entry in hashtable s1ap_id2_s1ap_ids for eNB_ue_s1ap_id %u\n", eNB_ue_s1ap_id); + } else { + LOG_W(RRC, "S1AP removed entry in hashtable s1ap_id2_s1ap_ids for eNB_ue_s1ap_id %u\n", eNB_ue_s1ap_id); + } } if (ue_initial_id != UE_INITIAL_ID_INVALID) { h_rc = hashtable_remove(rrc_instance_pP->initial_id2_s1ap_ids, (hash_key_t)ue_initial_id); - if (h_rc != HASH_TABLE_OK) { - LOG_W(RRC, "S1AP Did not find entry in hashtable initial_id2_s1ap_ids for ue_initial_id %u\n", ue_initial_id); - } else { - LOG_W(RRC, "S1AP removed entry in hashtable initial_id2_s1ap_ids for ue_initial_id %u\n", ue_initial_id); - } + + if (h_rc != HASH_TABLE_OK) { + LOG_W(RRC, "S1AP Did not find entry in hashtable initial_id2_s1ap_ids for ue_initial_id %u\n", ue_initial_id); + } else { + LOG_W(RRC, "S1AP removed entry in hashtable initial_id2_s1ap_ids for ue_initial_id %u\n", ue_initial_id); + } } } @@ -284,17 +415,11 @@ rrc_eNB_get_ue_context_from_s1ap_ids( ) { rrc_ue_s1ap_ids_t* temp = NULL; - temp = - rrc_eNB_S1AP_get_ue_ids( - RC.rrc[ENB_INSTANCE_TO_MODULE_ID(instanceP)], - ue_initial_idP, - eNB_ue_s1ap_idP); - if (temp) { + temp = rrc_eNB_S1AP_get_ue_ids(RC.rrc[ENB_INSTANCE_TO_MODULE_ID(instanceP)], ue_initial_idP, eNB_ue_s1ap_idP); - return rrc_eNB_get_ue_context( - RC.rrc[ENB_INSTANCE_TO_MODULE_ID(instanceP)], - temp->ue_rnti); + if (temp != NULL) { + return rrc_eNB_get_ue_context(RC.rrc[ENB_INSTANCE_TO_MODULE_ID(instanceP)], temp->ue_rnti); } return NULL; @@ -686,28 +811,31 @@ void rrc_eNB_send_S1AP_UE_CAPABILITIES_IND( } //------------------------------------------------------------------------------ +/* +* TODO +*/ void rrc_eNB_send_S1AP_NAS_FIRST_REQ( const protocol_ctxt_t* const ctxt_pP, - rrc_eNB_ue_context_t* const ue_context_pP, + rrc_eNB_ue_context_t* const ue_context_pP, RRCConnectionSetupComplete_r8_IEs_t* rrcConnectionSetupComplete ) //------------------------------------------------------------------------------ - - { - eNB_RRC_INST *rrc=RC.rrc[ctxt_pP->module_id]; + eNB_RRC_INST *rrc = RC.rrc[ctxt_pP->module_id]; + #if defined(ENABLE_ITTI) { MessageDef* message_p = NULL; rrc_ue_s1ap_ids_t* rrc_ue_s1ap_ids_p = NULL; hashtable_rc_t h_rc; - message_p = itti_alloc_new_message (TASK_RRC_ENB, S1AP_NAS_FIRST_REQ); + message_p = itti_alloc_new_message(TASK_RRC_ENB, S1AP_NAS_FIRST_REQ); memset(&message_p->ittiMsg.s1ap_nas_first_req, 0, sizeof(s1ap_nas_first_req_t)); - ue_context_pP->ue_context.ue_initial_id = get_next_ue_initial_id (ctxt_pP->module_id); - S1AP_NAS_FIRST_REQ (message_p).ue_initial_id = ue_context_pP->ue_context.ue_initial_id; + ue_context_pP->ue_context.ue_initial_id = get_next_ue_initial_id(ctxt_pP->module_id); + + S1AP_NAS_FIRST_REQ(message_p).ue_initial_id = ue_context_pP->ue_context.ue_initial_id; rrc_ue_s1ap_ids_p = malloc(sizeof(*rrc_ue_s1ap_ids_p)); rrc_ue_s1ap_ids_p->ue_initial_id = ue_context_pP->ue_context.ue_initial_id; @@ -715,22 +843,26 @@ rrc_eNB_send_S1AP_NAS_FIRST_REQ( rrc_ue_s1ap_ids_p->ue_rnti = ctxt_pP->rnti; h_rc = hashtable_insert(RC.rrc[ctxt_pP->module_id]->initial_id2_s1ap_ids, - (hash_key_t)ue_context_pP->ue_context.ue_initial_id, - rrc_ue_s1ap_ids_p); + (hash_key_t)ue_context_pP->ue_context.ue_initial_id, + rrc_ue_s1ap_ids_p); + if (h_rc != HASH_TABLE_OK) { LOG_E(S1AP, "[eNB %d] Error while hashtable_insert in initial_id2_s1ap_ids ue_initial_id %u\n", - ctxt_pP->module_id, ue_context_pP->ue_context.ue_initial_id); + ctxt_pP->module_id, + ue_context_pP->ue_context.ue_initial_id); } /* Assume that cause is coded in the same way in RRC and S1ap, just check that the value is in S1ap range */ AssertFatal(ue_context_pP->ue_context.establishment_cause < RRC_CAUSE_LAST, - "Establishment cause invalid (%jd/%d) for eNB %d!", - ue_context_pP->ue_context.establishment_cause, RRC_CAUSE_LAST, ctxt_pP->module_id); + "Establishment cause invalid (%jd/%d) for eNB %d!", + ue_context_pP->ue_context.establishment_cause, + RRC_CAUSE_LAST, + ctxt_pP->module_id); S1AP_NAS_FIRST_REQ (message_p).establishment_cause = ue_context_pP->ue_context.establishment_cause; - /* Forward NAS message */S1AP_NAS_FIRST_REQ (message_p).nas_pdu.buffer = - rrcConnectionSetupComplete->dedicatedInfoNAS.buf; + /* Forward NAS message */ + S1AP_NAS_FIRST_REQ (message_p).nas_pdu.buffer = rrcConnectionSetupComplete->dedicatedInfoNAS.buf; S1AP_NAS_FIRST_REQ (message_p).nas_pdu.length = rrcConnectionSetupComplete->dedicatedInfoNAS.size; extract_imsi(S1AP_NAS_FIRST_REQ (message_p).nas_pdu.buffer, @@ -748,12 +880,13 @@ rrc_eNB_send_S1AP_NAS_FIRST_REQ( S1AP_NAS_FIRST_REQ (message_p).ue_identity.presenceMask |= UE_IDENTITIES_s_tmsi; S1AP_NAS_FIRST_REQ (message_p).ue_identity.s_tmsi.mme_code = s_TMSI->mme_code; S1AP_NAS_FIRST_REQ (message_p).ue_identity.s_tmsi.m_tmsi = s_TMSI->m_tmsi; + LOG_I(S1AP, "[eNB %d] Build S1AP_NAS_FIRST_REQ with s_TMSI: MME code %u M-TMSI %u ue %x\n", ctxt_pP->module_id, S1AP_NAS_FIRST_REQ (message_p).ue_identity.s_tmsi.mme_code, S1AP_NAS_FIRST_REQ (message_p).ue_identity.s_tmsi.m_tmsi, ue_context_pP->ue_context.rnti); - } + } // end if S-TMSI presence /* selected_plmn_identity: IE is 1-based, convert to 0-based (C array) */ int selected_plmn_identity = rrcConnectionSetupComplete->selectedPLMN_Identity - 1; @@ -769,31 +902,33 @@ rrc_eNB_send_S1AP_NAS_FIRST_REQ( if ((r_mme->plmn_Identity->mcc != NULL) && (r_mme->plmn_Identity->mcc->list.count > 0)) { /* Use first indicated PLMN MCC if it is defined */ S1AP_NAS_FIRST_REQ (message_p).ue_identity.gummei.mcc = *r_mme->plmn_Identity->mcc->list.array[selected_plmn_identity]; + LOG_I(S1AP, "[eNB %d] Build S1AP_NAS_FIRST_REQ adding in s_TMSI: GUMMEI MCC %u ue %x\n", - ctxt_pP->module_id, - S1AP_NAS_FIRST_REQ (message_p).ue_identity.gummei.mcc, - ue_context_pP->ue_context.rnti); + ctxt_pP->module_id, + S1AP_NAS_FIRST_REQ (message_p).ue_identity.gummei.mcc, + ue_context_pP->ue_context.rnti); } if (r_mme->plmn_Identity->mnc.list.count > 0) { /* Use first indicated PLMN MNC if it is defined */ S1AP_NAS_FIRST_REQ (message_p).ue_identity.gummei.mnc = *r_mme->plmn_Identity->mnc.list.array[selected_plmn_identity]; + LOG_I(S1AP, "[eNB %d] Build S1AP_NAS_FIRST_REQ adding in s_TMSI: GUMMEI MNC %u ue %x\n", - ctxt_pP->module_id, - S1AP_NAS_FIRST_REQ (message_p).ue_identity.gummei.mnc, - ue_context_pP->ue_context.rnti); + ctxt_pP->module_id, + S1AP_NAS_FIRST_REQ (message_p).ue_identity.gummei.mnc, + ue_context_pP->ue_context.rnti); } - } else { + + } else { // end if plmn_Identity != NULL S1AP_NAS_FIRST_REQ(message_p).ue_identity.gummei.mcc = rrc->configuration.mcc[selected_plmn_identity]; S1AP_NAS_FIRST_REQ(message_p).ue_identity.gummei.mnc = rrc->configuration.mnc[selected_plmn_identity]; S1AP_NAS_FIRST_REQ(message_p).ue_identity.gummei.mnc_len = rrc->configuration.mnc_digit_length[selected_plmn_identity]; - } + } // end else (plmn_Identity == NULL) S1AP_NAS_FIRST_REQ (message_p).ue_identity.gummei.mme_code = BIT_STRING_to_uint8 (&r_mme->mmec); S1AP_NAS_FIRST_REQ (message_p).ue_identity.gummei.mme_group_id = BIT_STRING_to_uint16 (&r_mme->mmegi); - MSC_LOG_TX_MESSAGE( - MSC_S1AP_ENB, + MSC_LOG_TX_MESSAGE(MSC_S1AP_ENB, MSC_S1AP_MME, (const char *)&message_p->ittiMsg.s1ap_nas_first_req, sizeof(s1ap_nas_first_req_t), @@ -807,11 +942,15 @@ rrc_eNB_send_S1AP_NAS_FIRST_REQ( S1AP_NAS_FIRST_REQ (message_p).ue_identity.gummei.mme_code, S1AP_NAS_FIRST_REQ (message_p).ue_identity.gummei.mme_group_id, ue_context_pP->ue_context.rnti); - } - } + + } // end if MME info present + } // end "Fill UE identities with available information" sub-part + itti_send_msg_to_task (TASK_S1AP, ctxt_pP->instance, message_p); } + #else + { s1ap_eNB_new_data_request ( ctxt_pP->module_id, @@ -821,6 +960,7 @@ rrc_eNB_send_S1AP_NAS_FIRST_REQ( rrcConnectionSetupComplete->dedicatedInfoNAS. size); } + #endif } @@ -847,7 +987,6 @@ rrc_eNB_process_S1AP_DOWNLINK_NAS( eNB_ue_s1ap_id = S1AP_DOWNLINK_NAS (msg_p).eNB_ue_s1ap_id; ue_context_p = rrc_eNB_get_ue_context_from_s1ap_ids(instance, ue_initial_id, eNB_ue_s1ap_id); - LOG_I(RRC, "[eNB %d] Received %s: ue_initial_id %d, eNB_ue_s1ap_id %d\n", instance, msg_name, @@ -1250,11 +1389,12 @@ rrc_eNB_process_S1AP_UE_CONTEXT_RELEASE_COMMAND( rrc_ue_s1ap_ids = rrc_eNB_S1AP_get_ue_ids(RC.rrc[instance], UE_INITIAL_ID_INVALID, eNB_ue_s1ap_id); - if (NULL != rrc_ue_s1ap_ids) { + if (rrc_ue_s1ap_ids != NULL) { rrc_eNB_S1AP_remove_ue_ids(RC.rrc[instance], rrc_ue_s1ap_ids); } return -1; + } else { ue_context_p->ue_context.ue_release_timer_s1 = 0; diff --git a/openair3/S1AP/s1ap_eNB_nas_procedures.c b/openair3/S1AP/s1ap_eNB_nas_procedures.c index 80266a4d9c..0e2b809189 100644 --- a/openair3/S1AP/s1ap_eNB_nas_procedures.c +++ b/openair3/S1AP/s1ap_eNB_nas_procedures.c @@ -573,9 +573,6 @@ int s1ap_eNB_handle_nas_downlink(uint32_t assoc_id, ie->value.choice.NAS_PDU.buf, ie->value.choice.NAS_PDU.size); - // LG: Why set to 0 ?? - //ue_desc_p->ue_initial_id = 0; - return 0; } From 045f2bfd314a08a1764064fc9baa071de28bde99 Mon Sep 17 00:00:00 2001 From: Wang Tsu-Han Date: Thu, 8 Nov 2018 11:42:44 +0100 Subject: [PATCH 102/233] unused veriable remove --- openair1/PHY/defs_eNB.h | 3 --- targets/RT/USER/lte-enb.c | 25 ------------------------- targets/RT/USER/lte-ru.c | 3 --- 3 files changed, 31 deletions(-) diff --git a/openair1/PHY/defs_eNB.h b/openair1/PHY/defs_eNB.h index 44d8b6ab9b..fe93b8b6e5 100644 --- a/openair1/PHY/defs_eNB.h +++ b/openair1/PHY/defs_eNB.h @@ -257,9 +257,6 @@ typedef struct RU_proc_t_s { pthread_mutex_t mutex_pre_scd; int instance_pre_scd; #endif - /// pipeline ready state - int ru_rx_ready; - int ru_tx_ready; int emulate_rf_busy; } RU_proc_t; diff --git a/targets/RT/USER/lte-enb.c b/targets/RT/USER/lte-enb.c index f2b01dbc8b..5578fb6e76 100644 --- a/targets/RT/USER/lte-enb.c +++ b/targets/RT/USER/lte-enb.c @@ -223,31 +223,6 @@ static inline int rxtx(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc, char *thread_name } VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ULSCH_SCHEDULER , 1 ); -/*//#TODO - if(get_thread_parallel_conf() == PARALLEL_RU_L1_TRX_SPLIT) - { - if (pthread_mutex_lock(mutex) != 0) { - LOG_E(PHY, "[SCHED][eNB] ERROR locking mutex for eNB L1_thread_tx\n"); - exit_fun("ERROR pthread_lock"); - return(-1); - } - while(L1_proc_tx->instance_cnt == 0){ - pthread_cond_wait(L1_proc_tx->cond,L1_proc_tx->mutex); - } - L1_proc_tx->instance_cnt = 0; - if (pthread_cond_signal(&L1_proc_tx->cond) != 0) { - LOG_E( PHY, "[eNB] ERROR pthread_cond_signal for eNB L1_thread_tx\n"); - exit_fun( "ERROR pthread_cond_signal" ); - return(-1); - } - if (pthread_mutex_unlock(mutex) != 0) { - LOG_E(PHY,"[SCHED][eNB] error unlocking mutex for %s\n",name); - exit_fun("ERROR pthread_unlock"); - return(-1); - } - }*/ - - pthread_mutex_lock(&eNB->UL_INFO_mutex); eNB->UL_INFO.frame = proc->frame_rx; diff --git a/targets/RT/USER/lte-ru.c b/targets/RT/USER/lte-ru.c index 3fbb1e983d..06b019055a 100644 --- a/targets/RT/USER/lte-ru.c +++ b/targets/RT/USER/lte-ru.c @@ -2150,8 +2150,6 @@ void init_RU_proc(RU_t *ru) { proc->frame_offset = 0; proc->num_slaves = 0; proc->frame_tx_unwrap = 0; - proc->ru_rx_ready = 0; - proc->ru_tx_ready = 0; for (i=0;i<10;i++) proc->symbol_mask[i]=0; @@ -2326,7 +2324,6 @@ void kill_RU_proc(RU_t *ru) pthread_mutex_unlock(&proc->mutex_synch); pthread_mutex_lock(&proc->mutex_eNBs); - proc->ru_tx_ready = 0; proc->instance_cnt_eNBs = 1; // cond_eNBs is used by both ru_thread and ru_thread_tx, so we need to send // a broadcast to wake up both threads From d2b9f0f4f843a453e4d79812c847ecd41ba086b2 Mon Sep 17 00:00:00 2001 From: Raphael Defosseux Date: Thu, 8 Nov 2018 10:17:35 +0100 Subject: [PATCH 103/233] CI: added support for MR target branch other than 'develop' Signed-off-by: Raphael Defosseux --- ci-scripts/Jenkinsfile-tmp-ran | 11 ++++++++++- ci-scripts/main.py | 19 ++++++++++++++++--- 2 files changed, 26 insertions(+), 4 deletions(-) diff --git a/ci-scripts/Jenkinsfile-tmp-ran b/ci-scripts/Jenkinsfile-tmp-ran index 6795eab9b8..938110b458 100644 --- a/ci-scripts/Jenkinsfile-tmp-ran +++ b/ci-scripts/Jenkinsfile-tmp-ran @@ -53,6 +53,7 @@ def eNB_Repository def eNB_Branch def eNB_CommitID def eNB_AllowMergeRequestProcess = false +def eNB_TargetBranch pipeline { agent { @@ -150,6 +151,14 @@ pipeline { echo "eNB_CommitID : ${eNB_CommitID}" if (params.eNB_mergeRequest != null) { eNB_AllowMergeRequestProcess = params.eNB_mergeRequest + if (eNB_AllowMergeRequestProcess) { + if (params.eNB_TargetBranch != null) { + eNB_TargetBranch = params.eNB_TargetBranch + } else { + eNB_TargetBranch = 'develop' + } + echo "eNB_TargetBranch : ${eNB_TargetBranch}" + } } if (params.EPC_IPAddress == null) { @@ -192,7 +201,7 @@ pipeline { [$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.EPC_Credentials}", usernameVariable: 'EPC_Username', passwordVariable: 'EPC_Password'], [$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.ADB_Credentials}", usernameVariable: 'ADB_Username', passwordVariable: 'ADB_Password'] ]) { - sh "python3 main.py --mode=TesteNB --eNBIPAddress=${params.eNB_IPAddress} --eNBRepository=${eNB_Repository} --eNBBranch=${eNB_Branch} --eNBCommitID=${eNB_CommitID} --eNB_AllowMerge=${eNB_AllowMergeRequestProcess} --eNBUserName=${eNB_Username} --eNBPassword=${eNB_Password} --eNBSourceCodePath=${params.eNB_SourceCodePath} --EPCIPAddress=${params.EPC_IPAddress} --EPCType=${params.EPC_Type} --EPCUserName=${EPC_Username} --EPCPassword=${EPC_Password} --EPCSourceCodePath=${params.EPC_SourceCodePath} --ADBIPAddress=${params.ADB_IPAddress} --ADBUserName=${ADB_Username} --ADBPassword=${ADB_Password} --XMLTestFile=${testXMLFile}" + sh "python3 main.py --mode=TesteNB --eNBIPAddress=${params.eNB_IPAddress} --eNBRepository=${eNB_Repository} --eNBBranch=${eNB_Branch} --eNBCommitID=${eNB_CommitID} --eNB_AllowMerge=${eNB_AllowMergeRequestProcess} --eNBTargetBranch=${eNB_TargetBranch} --eNBUserName=${eNB_Username} --eNBPassword=${eNB_Password} --eNBSourceCodePath=${params.eNB_SourceCodePath} --EPCIPAddress=${params.EPC_IPAddress} --EPCType=${params.EPC_Type} --EPCUserName=${EPC_Username} --EPCPassword=${EPC_Password} --EPCSourceCodePath=${params.EPC_SourceCodePath} --ADBIPAddress=${params.ADB_IPAddress} --ADBUserName=${ADB_Username} --ADBPassword=${ADB_Password} --XMLTestFile=${testXMLFile}" } } catch (Exception e) { currentBuild.result = 'FAILURE' diff --git a/ci-scripts/main.py b/ci-scripts/main.py index b54c6f3fab..e4675e46c3 100644 --- a/ci-scripts/main.py +++ b/ci-scripts/main.py @@ -78,6 +78,7 @@ class SSHConnection(): self.eNBBranch = '' self.eNB_AllowMerge = False self.eNBCommitID = '' + self.eNBTargetBranch = '' self.eNBUserName = '' self.eNBPassword = '' self.eNBSourceCodePath = '' @@ -264,8 +265,12 @@ class SSHConnection(): # if the branch is not develop, then it is a merge request and we need to do # the potential merge. Note that merge conflicts should already been checked earlier if (self.eNB_AllowMerge): - if (self.eNBBranch != 'develop') and (self.eNBBranch != 'origin/develop'): - self.command('git merge --ff origin/develop -m "Temporary merge for CI"', '\$', 5) + if self.eNBTargetBranch == '': + if (self.eNBBranch != 'develop') and (self.eNBBranch != 'origin/develop'): + self.command('git merge --ff origin/develop -m "Temporary merge for CI"', '\$', 5) + else: + logging.debug('Merging with the target branch: ' + self.eNBTargetBranch) + self.command('git merge --ff origin/' + self.eNBTargetBranch + ' -m "Temporary merge for CI"', '\$', 5) self.command('source oaienv', '\$', 5) self.command('cd cmake_targets', '\$', 5) self.command('mkdir -p log', '\$', 5) @@ -1759,7 +1764,10 @@ class SSHConnection(): if (SSH.eNB_AllowMerge): self.htmlFile.write(' \n') self.htmlFile.write(' Target Branch\n') - self.htmlFile.write(' develop\n') + if (self.eNBTargetBranch == ''): + self.htmlFile.write(' develop\n') + else: + self.htmlFile.write(' ' + self.eNBTargetBranch + '\n') self.htmlFile.write(' \n') self.htmlFile.write(' \n') @@ -1906,6 +1914,8 @@ def Usage(): print(' --eNBRepository=[eNB\'s Repository URL]') print(' --eNBBranch=[eNB\'s Branch Name]') print(' --eNBCommitID=[eNB\'s Commit Number]') + print(' --eNB_AllowMerge=[eNB\'s Allow Merge Request (with target branch)]') + print(' --eNBTargetBranch=[eNB\'s Target Branch in case of a Merge Request]') print(' --eNBUserName=[eNB\'s Login User Name]') print(' --eNBPassword=[eNB\'s Login Password]') print(' --eNBSourceCodePath=[eNB\'s Source Code Path]') @@ -2002,6 +2012,9 @@ while len(argvs) > 1: elif re.match('^\-\-eNBCommitID=(.*)$', myArgv, re.IGNORECASE): matchReg = re.match('^\-\-eNBCommitID=(.*)$', myArgv, re.IGNORECASE) SSH.eNBCommitID = matchReg.group(1) + elif re.match('^\-\-eNBTargetBranch=(.*)$', myArgv, re.IGNORECASE): + matchReg = re.match('^\-\-eNBTargetBranch=(.*)$', myArgv, re.IGNORECASE) + SSH.eNBTargetBranch = matchReg.group(1) elif re.match('^\-\-eNBUserName=(.+)$', myArgv, re.IGNORECASE): matchReg = re.match('^\-\-eNBUserName=(.+)$', myArgv, re.IGNORECASE) SSH.eNBUserName = matchReg.group(1) From 3a294a246a5685e3fdb8dfb3996f6d8c77f6d218 Mon Sep 17 00:00:00 2001 From: Raphael Defosseux Date: Thu, 8 Nov 2018 11:28:27 +0100 Subject: [PATCH 104/233] CI: normalize IPv4 addresses for scripts Signed-off-by: Raphael Defosseux --- .../enb.band40.tm1.100PRB.FairScheduler.usrpb210.conf | 10 ++++------ .../enb.band40.tm1.25PRB.FairScheduler.usrpb210.conf | 10 ++++------ .../enb.band40.tm1.50PRB.FairScheduler.usrpb210.conf | 10 ++++------ .../conf_files/enb.band7.tm1.100PRB.usrpb210.conf | 9 ++++----- .../conf_files/enb.band7.tm1.25PRB.usrpb210.conf | 9 ++++----- .../conf_files/enb.band7.tm1.50PRB.usrpb210.conf | 9 ++++----- ci-scripts/conf_files/lte-fdd-basic-sim.conf | 1 - ci-scripts/conf_files/lte-tdd-basic-sim.conf | 2 -- .../rcc.band40.tm1.100PRB.FairScheduler.usrpb210.conf | 10 ++++------ .../rcc.band40.tm1.25PRB.FairScheduler.usrpb210.conf | 10 ++++------ .../rcc.band40.tm1.50PRB.FairScheduler.usrpb210.conf | 10 ++++------ .../rcc.band7.tm1.if4p5.lo.100PRB.usrpb210.conf | 9 ++++----- .../rcc.band7.tm1.if4p5.lo.25PRB.usrpb210.conf | 9 ++++----- .../rcc.band7.tm1.if4p5.lo.50PRB.usrpb210.conf | 9 ++++----- ci-scripts/main.py | 6 ++---- 15 files changed, 50 insertions(+), 73 deletions(-) diff --git a/ci-scripts/conf_files/enb.band40.tm1.100PRB.FairScheduler.usrpb210.conf b/ci-scripts/conf_files/enb.band40.tm1.100PRB.FairScheduler.usrpb210.conf index ec968e8cef..b6028a8152 100644 --- a/ci-scripts/conf_files/enb.band40.tm1.100PRB.FairScheduler.usrpb210.conf +++ b/ci-scripts/conf_files/enb.band40.tm1.100PRB.FairScheduler.usrpb210.conf @@ -134,7 +134,7 @@ eNBs = }; ////////// MME parameters: - mme_ip_address = ( { ipv4 = "10.0.0.2"; + mme_ip_address = ( { ipv4 = "CI_MME_IP_ADDR"; ipv6 = "192:168:30::17"; active = "yes"; preference = "ipv4"; @@ -144,13 +144,11 @@ eNBs = NETWORK_INTERFACES : { ENB_INTERFACE_NAME_FOR_S1_MME = "eth0"; - ENB_IPV4_ADDRESS_FOR_S1_MME = "10.0.0.1/24"; - + ENB_IPV4_ADDRESS_FOR_S1_MME = "CI_ENB_IP_ADDR"; ENB_INTERFACE_NAME_FOR_S1U = "eth0"; - ENB_IPV4_ADDRESS_FOR_S1U = "10.0.0.1/24"; + ENB_IPV4_ADDRESS_FOR_S1U = "CI_ENB_IP_ADDR"; ENB_PORT_FOR_S1U = 2152; # Spec 2152 - - ENB_IPV4_ADDRESS_FOR_X2C = "192.168.12.111/24"; + ENB_IPV4_ADDRESS_FOR_X2C = "CI_ENB_IP_ADDR"; ENB_PORT_FOR_X2C = 36422; # Spec 36422 }; diff --git a/ci-scripts/conf_files/enb.band40.tm1.25PRB.FairScheduler.usrpb210.conf b/ci-scripts/conf_files/enb.band40.tm1.25PRB.FairScheduler.usrpb210.conf index c2f69cb1b9..10cbd04e9a 100644 --- a/ci-scripts/conf_files/enb.band40.tm1.25PRB.FairScheduler.usrpb210.conf +++ b/ci-scripts/conf_files/enb.band40.tm1.25PRB.FairScheduler.usrpb210.conf @@ -134,7 +134,7 @@ eNBs = }; ////////// MME parameters: - mme_ip_address = ( { ipv4 = "10.0.0.2"; + mme_ip_address = ( { ipv4 = "CI_MME_IP_ADDR"; ipv6 = "192:168:30::17"; active = "yes"; preference = "ipv4"; @@ -144,13 +144,11 @@ eNBs = NETWORK_INTERFACES : { ENB_INTERFACE_NAME_FOR_S1_MME = "eth0"; - ENB_IPV4_ADDRESS_FOR_S1_MME = "10.0.0.1/24"; - + ENB_IPV4_ADDRESS_FOR_S1_MME = "CI_ENB_IP_ADDR"; ENB_INTERFACE_NAME_FOR_S1U = "eth0"; - ENB_IPV4_ADDRESS_FOR_S1U = "10.0.0.1/24"; + ENB_IPV4_ADDRESS_FOR_S1U = "CI_ENB_IP_ADDR"; ENB_PORT_FOR_S1U = 2152; # Spec 2152 - - ENB_IPV4_ADDRESS_FOR_X2C = "192.168.12.111/24"; + ENB_IPV4_ADDRESS_FOR_X2C = "CI_ENB_IP_ADDR"; ENB_PORT_FOR_X2C = 36422; # Spec 36422 }; diff --git a/ci-scripts/conf_files/enb.band40.tm1.50PRB.FairScheduler.usrpb210.conf b/ci-scripts/conf_files/enb.band40.tm1.50PRB.FairScheduler.usrpb210.conf index 6bdbd4e39b..c79dbf1ac0 100644 --- a/ci-scripts/conf_files/enb.band40.tm1.50PRB.FairScheduler.usrpb210.conf +++ b/ci-scripts/conf_files/enb.band40.tm1.50PRB.FairScheduler.usrpb210.conf @@ -134,7 +134,7 @@ eNBs = }; ////////// MME parameters: - mme_ip_address = ( { ipv4 = "10.0.0.2"; + mme_ip_address = ( { ipv4 = "CI_MME_IP_ADDR"; ipv6 = "192:168:30::17"; active = "yes"; preference = "ipv4"; @@ -144,13 +144,11 @@ eNBs = NETWORK_INTERFACES : { ENB_INTERFACE_NAME_FOR_S1_MME = "eth0"; - ENB_IPV4_ADDRESS_FOR_S1_MME = "10.0.0.1/24"; - + ENB_IPV4_ADDRESS_FOR_S1_MME = "CI_ENB_IP_ADDR"; ENB_INTERFACE_NAME_FOR_S1U = "eth0"; - ENB_IPV4_ADDRESS_FOR_S1U = "10.0.0.1/24"; + ENB_IPV4_ADDRESS_FOR_S1U = "CI_ENB_IP_ADDR"; ENB_PORT_FOR_S1U = 2152; # Spec 2152 - - ENB_IPV4_ADDRESS_FOR_X2C = "192.168.12.111/24"; + ENB_IPV4_ADDRESS_FOR_X2C = "CI_ENB_IP_ADDR"; ENB_PORT_FOR_X2C = 36422; # Spec 36422 }; diff --git a/ci-scripts/conf_files/enb.band7.tm1.100PRB.usrpb210.conf b/ci-scripts/conf_files/enb.band7.tm1.100PRB.usrpb210.conf index 1a566e9579..f3cb31f449 100644 --- a/ci-scripts/conf_files/enb.band7.tm1.100PRB.usrpb210.conf +++ b/ci-scripts/conf_files/enb.band7.tm1.100PRB.usrpb210.conf @@ -171,7 +171,7 @@ eNBs = ////////// MME parameters: - mme_ip_address = ( { ipv4 = "192.168.12.26"; + mme_ip_address = ( { ipv4 = "CI_MME_IP_ADDR"; ipv6 = "192:168:30::17"; active = "yes"; preference = "ipv4"; @@ -181,12 +181,11 @@ eNBs = NETWORK_INTERFACES : { ENB_INTERFACE_NAME_FOR_S1_MME = "eth0"; - ENB_IPV4_ADDRESS_FOR_S1_MME = "192.168.12.111/24"; + ENB_IPV4_ADDRESS_FOR_S1_MME = "CI_ENB_IP_ADDR"; ENB_INTERFACE_NAME_FOR_S1U = "eth0"; - ENB_IPV4_ADDRESS_FOR_S1U = "192.168.12.111/24"; + ENB_IPV4_ADDRESS_FOR_S1U = "CI_ENB_IP_ADDR"; ENB_PORT_FOR_S1U = 2152; # Spec 2152 - - ENB_IPV4_ADDRESS_FOR_X2C = "192.168.12.111/24"; + ENB_IPV4_ADDRESS_FOR_X2C = "CI_ENB_IP_ADDR"; ENB_PORT_FOR_X2C = 36422; # Spec 36422 }; } diff --git a/ci-scripts/conf_files/enb.band7.tm1.25PRB.usrpb210.conf b/ci-scripts/conf_files/enb.band7.tm1.25PRB.usrpb210.conf index fd49fe9d83..e33daa7a8a 100644 --- a/ci-scripts/conf_files/enb.band7.tm1.25PRB.usrpb210.conf +++ b/ci-scripts/conf_files/enb.band7.tm1.25PRB.usrpb210.conf @@ -171,7 +171,7 @@ eNBs = ////////// MME parameters: - mme_ip_address = ( { ipv4 = "192.168.12.26"; + mme_ip_address = ( { ipv4 = "CI_MME_IP_ADDR"; ipv6 = "192:168:30::17"; active = "yes"; preference = "ipv4"; @@ -181,12 +181,11 @@ eNBs = NETWORK_INTERFACES : { ENB_INTERFACE_NAME_FOR_S1_MME = "eth0"; - ENB_IPV4_ADDRESS_FOR_S1_MME = "192.168.12.111/24"; + ENB_IPV4_ADDRESS_FOR_S1_MME = "CI_ENB_IP_ADDR"; ENB_INTERFACE_NAME_FOR_S1U = "eth0"; - ENB_IPV4_ADDRESS_FOR_S1U = "192.168.12.111/24"; + ENB_IPV4_ADDRESS_FOR_S1U = "CI_ENB_IP_ADDR"; ENB_PORT_FOR_S1U = 2152; # Spec 2152 - - ENB_IPV4_ADDRESS_FOR_X2C = "192.168.12.111/24"; + ENB_IPV4_ADDRESS_FOR_X2C = "CI_ENB_IP_ADDR"; ENB_PORT_FOR_X2C = 36422; # Spec 36422 }; } diff --git a/ci-scripts/conf_files/enb.band7.tm1.50PRB.usrpb210.conf b/ci-scripts/conf_files/enb.band7.tm1.50PRB.usrpb210.conf index 1613dd4c32..32e8bb9931 100644 --- a/ci-scripts/conf_files/enb.band7.tm1.50PRB.usrpb210.conf +++ b/ci-scripts/conf_files/enb.band7.tm1.50PRB.usrpb210.conf @@ -171,7 +171,7 @@ eNBs = ////////// MME parameters: - mme_ip_address = ( { ipv4 = "192.168.12.26"; + mme_ip_address = ( { ipv4 = "CI_MME_IP_ADDR"; ipv6 = "192:168:30::17"; active = "yes"; preference = "ipv4"; @@ -181,12 +181,11 @@ eNBs = NETWORK_INTERFACES : { ENB_INTERFACE_NAME_FOR_S1_MME = "eth0"; - ENB_IPV4_ADDRESS_FOR_S1_MME = "192.168.12.111/24"; + ENB_IPV4_ADDRESS_FOR_S1_MME = "CI_ENB_IP_ADDR"; ENB_INTERFACE_NAME_FOR_S1U = "eth0"; - ENB_IPV4_ADDRESS_FOR_S1U = "192.168.12.111/24"; + ENB_IPV4_ADDRESS_FOR_S1U = "CI_ENB_IP_ADDR"; ENB_PORT_FOR_S1U = 2152; # Spec 2152 - - ENB_IPV4_ADDRESS_FOR_X2C = "192.168.12.111/24"; + ENB_IPV4_ADDRESS_FOR_X2C = "CI_ENB_IP_ADDR"; ENB_PORT_FOR_X2C = 36422; # Spec 36422 }; } diff --git a/ci-scripts/conf_files/lte-fdd-basic-sim.conf b/ci-scripts/conf_files/lte-fdd-basic-sim.conf index 0211e126a1..1d1395cf6d 100644 --- a/ci-scripts/conf_files/lte-fdd-basic-sim.conf +++ b/ci-scripts/conf_files/lte-fdd-basic-sim.conf @@ -186,7 +186,6 @@ eNBs = ENB_INTERFACE_NAME_FOR_S1U = "eth0"; ENB_IPV4_ADDRESS_FOR_S1U = "CI_ENB_IP_ADDR"; ENB_PORT_FOR_S1U = 2152; # Spec 2152 - ENB_IPV4_ADDRESS_FOR_X2C = "CI_ENB_IP_ADDR"; ENB_PORT_FOR_X2C = 36422; # Spec 36422 }; diff --git a/ci-scripts/conf_files/lte-tdd-basic-sim.conf b/ci-scripts/conf_files/lte-tdd-basic-sim.conf index a7bc31eed8..32a84fd206 100644 --- a/ci-scripts/conf_files/lte-tdd-basic-sim.conf +++ b/ci-scripts/conf_files/lte-tdd-basic-sim.conf @@ -145,11 +145,9 @@ eNBs = { ENB_INTERFACE_NAME_FOR_S1_MME = "eth0"; ENB_IPV4_ADDRESS_FOR_S1_MME = "CI_ENB_IP_ADDR"; - ENB_INTERFACE_NAME_FOR_S1U = "eth0"; ENB_IPV4_ADDRESS_FOR_S1U = "CI_ENB_IP_ADDR"; ENB_PORT_FOR_S1U = 2152; # Spec 2152 - ENB_IPV4_ADDRESS_FOR_X2C = "CI_ENB_IP_ADDR"; ENB_PORT_FOR_X2C = 36422; # Spec 36422 }; diff --git a/ci-scripts/conf_files/rcc.band40.tm1.100PRB.FairScheduler.usrpb210.conf b/ci-scripts/conf_files/rcc.band40.tm1.100PRB.FairScheduler.usrpb210.conf index 217991f69f..285b7eaf9f 100644 --- a/ci-scripts/conf_files/rcc.band40.tm1.100PRB.FairScheduler.usrpb210.conf +++ b/ci-scripts/conf_files/rcc.band40.tm1.100PRB.FairScheduler.usrpb210.conf @@ -137,7 +137,7 @@ eNBs = }; ////////// MME parameters: - mme_ip_address = ( { ipv4 = "10.0.0.2"; + mme_ip_address = ( { ipv4 = "CI_MME_IP_ADDR"; ipv6 = "192:168:30::17"; active = "yes"; preference = "ipv4"; @@ -147,13 +147,11 @@ eNBs = NETWORK_INTERFACES : { ENB_INTERFACE_NAME_FOR_S1_MME = "eth0"; - ENB_IPV4_ADDRESS_FOR_S1_MME = "10.0.0.1/24"; - + ENB_IPV4_ADDRESS_FOR_S1_MME = "CI_ENB_IP_ADDR"; ENB_INTERFACE_NAME_FOR_S1U = "eth0"; - ENB_IPV4_ADDRESS_FOR_S1U = "10.0.0.1/24"; + ENB_IPV4_ADDRESS_FOR_S1U = "CI_ENB_IP_ADDR"; ENB_PORT_FOR_S1U = 2152; # Spec 2152 - - ENB_IPV4_ADDRESS_FOR_X2C = "192.168.12.111/24"; + ENB_IPV4_ADDRESS_FOR_X2C = "CI_ENB_IP_ADDR"; ENB_PORT_FOR_X2C = 36422; # Spec 36422 }; diff --git a/ci-scripts/conf_files/rcc.band40.tm1.25PRB.FairScheduler.usrpb210.conf b/ci-scripts/conf_files/rcc.band40.tm1.25PRB.FairScheduler.usrpb210.conf index 21f4f34ba9..62e7fb48a4 100644 --- a/ci-scripts/conf_files/rcc.band40.tm1.25PRB.FairScheduler.usrpb210.conf +++ b/ci-scripts/conf_files/rcc.band40.tm1.25PRB.FairScheduler.usrpb210.conf @@ -137,7 +137,7 @@ eNBs = }; ////////// MME parameters: - mme_ip_address = ( { ipv4 = "10.0.0.2"; + mme_ip_address = ( { ipv4 = "CI_MME_IP_ADDR"; ipv6 = "192:168:30::17"; active = "yes"; preference = "ipv4"; @@ -147,13 +147,11 @@ eNBs = NETWORK_INTERFACES : { ENB_INTERFACE_NAME_FOR_S1_MME = "eth0"; - ENB_IPV4_ADDRESS_FOR_S1_MME = "10.0.0.1/24"; - + ENB_IPV4_ADDRESS_FOR_S1_MME = "CI_ENB_IP_ADDR"; ENB_INTERFACE_NAME_FOR_S1U = "eth0"; - ENB_IPV4_ADDRESS_FOR_S1U = "10.0.0.1/24"; + ENB_IPV4_ADDRESS_FOR_S1U = "CI_ENB_IP_ADDR"; ENB_PORT_FOR_S1U = 2152; # Spec 2152 - - ENB_IPV4_ADDRESS_FOR_X2C = "192.168.12.111/24"; + ENB_IPV4_ADDRESS_FOR_X2C = "CI_ENB_IP_ADDR"; ENB_PORT_FOR_X2C = 36422; # Spec 36422 }; diff --git a/ci-scripts/conf_files/rcc.band40.tm1.50PRB.FairScheduler.usrpb210.conf b/ci-scripts/conf_files/rcc.band40.tm1.50PRB.FairScheduler.usrpb210.conf index 2fdfa3c4e7..f99b701b8e 100644 --- a/ci-scripts/conf_files/rcc.band40.tm1.50PRB.FairScheduler.usrpb210.conf +++ b/ci-scripts/conf_files/rcc.band40.tm1.50PRB.FairScheduler.usrpb210.conf @@ -137,7 +137,7 @@ eNBs = }; ////////// MME parameters: - mme_ip_address = ( { ipv4 = "10.0.0.2"; + mme_ip_address = ( { ipv4 = "CI_MME_IP_ADDR"; ipv6 = "192:168:30::17"; active = "yes"; preference = "ipv4"; @@ -147,13 +147,11 @@ eNBs = NETWORK_INTERFACES : { ENB_INTERFACE_NAME_FOR_S1_MME = "eth0"; - ENB_IPV4_ADDRESS_FOR_S1_MME = "10.0.0.1/24"; - + ENB_IPV4_ADDRESS_FOR_S1_MME = "CI_ENB_IP_ADDR"; ENB_INTERFACE_NAME_FOR_S1U = "eth0"; - ENB_IPV4_ADDRESS_FOR_S1U = "10.0.0.1/24"; + ENB_IPV4_ADDRESS_FOR_S1U = "CI_ENB_IP_ADDR"; ENB_PORT_FOR_S1U = 2152; # Spec 2152 - - ENB_IPV4_ADDRESS_FOR_X2C = "192.168.12.111/24"; + ENB_IPV4_ADDRESS_FOR_X2C = "CI_ENB_IP_ADDR"; ENB_PORT_FOR_X2C = 36422; # Spec 36422 }; diff --git a/ci-scripts/conf_files/rcc.band7.tm1.if4p5.lo.100PRB.usrpb210.conf b/ci-scripts/conf_files/rcc.band7.tm1.if4p5.lo.100PRB.usrpb210.conf index 28ffc43b23..fc2f24b8a1 100644 --- a/ci-scripts/conf_files/rcc.band7.tm1.if4p5.lo.100PRB.usrpb210.conf +++ b/ci-scripts/conf_files/rcc.band7.tm1.if4p5.lo.100PRB.usrpb210.conf @@ -174,7 +174,7 @@ eNBs = ////////// MME parameters: - mme_ip_address = ( { ipv4 = "192.168.12.26"; + mme_ip_address = ( { ipv4 = "CI_MME_IP_ADDR"; ipv6 = "192:168:30::17"; active = "yes"; preference = "ipv4"; @@ -184,12 +184,11 @@ eNBs = NETWORK_INTERFACES : { ENB_INTERFACE_NAME_FOR_S1_MME = "eth0"; - ENB_IPV4_ADDRESS_FOR_S1_MME = "192.168.12.111/24"; + ENB_IPV4_ADDRESS_FOR_S1_MME = "CI_ENB_IP_ADDR"; ENB_INTERFACE_NAME_FOR_S1U = "eth0"; - ENB_IPV4_ADDRESS_FOR_S1U = "192.168.12.111/24"; + ENB_IPV4_ADDRESS_FOR_S1U = "CI_ENB_IP_ADDR"; ENB_PORT_FOR_S1U = 2152; # Spec 2152 - - ENB_IPV4_ADDRESS_FOR_X2C = "192.168.12.111/24"; + ENB_IPV4_ADDRESS_FOR_X2C = "CI_ENB_IP_ADDR"; ENB_PORT_FOR_X2C = 36422; # Spec 36422 }; } diff --git a/ci-scripts/conf_files/rcc.band7.tm1.if4p5.lo.25PRB.usrpb210.conf b/ci-scripts/conf_files/rcc.band7.tm1.if4p5.lo.25PRB.usrpb210.conf index 4d064ecc0e..010ef28061 100644 --- a/ci-scripts/conf_files/rcc.band7.tm1.if4p5.lo.25PRB.usrpb210.conf +++ b/ci-scripts/conf_files/rcc.band7.tm1.if4p5.lo.25PRB.usrpb210.conf @@ -174,7 +174,7 @@ eNBs = ////////// MME parameters: - mme_ip_address = ( { ipv4 = "192.168.12.26"; + mme_ip_address = ( { ipv4 = "CI_MME_IP_ADDR"; ipv6 = "192:168:30::17"; active = "yes"; preference = "ipv4"; @@ -184,12 +184,11 @@ eNBs = NETWORK_INTERFACES : { ENB_INTERFACE_NAME_FOR_S1_MME = "eth0"; - ENB_IPV4_ADDRESS_FOR_S1_MME = "192.168.12.111/24"; + ENB_IPV4_ADDRESS_FOR_S1_MME = "CI_ENB_IP_ADDR"; ENB_INTERFACE_NAME_FOR_S1U = "eth0"; - ENB_IPV4_ADDRESS_FOR_S1U = "192.168.12.111/24"; + ENB_IPV4_ADDRESS_FOR_S1U = "CI_ENB_IP_ADDR"; ENB_PORT_FOR_S1U = 2152; # Spec 2152 - - ENB_IPV4_ADDRESS_FOR_X2C = "192.168.12.111/24"; + ENB_IPV4_ADDRESS_FOR_X2C = "CI_ENB_IP_ADDR"; ENB_PORT_FOR_X2C = 36422; # Spec 36422 }; } diff --git a/ci-scripts/conf_files/rcc.band7.tm1.if4p5.lo.50PRB.usrpb210.conf b/ci-scripts/conf_files/rcc.band7.tm1.if4p5.lo.50PRB.usrpb210.conf index efb1e823ad..ddf01096cd 100644 --- a/ci-scripts/conf_files/rcc.band7.tm1.if4p5.lo.50PRB.usrpb210.conf +++ b/ci-scripts/conf_files/rcc.band7.tm1.if4p5.lo.50PRB.usrpb210.conf @@ -174,7 +174,7 @@ eNBs = ////////// MME parameters: - mme_ip_address = ( { ipv4 = "192.168.12.26"; + mme_ip_address = ( { ipv4 = "CI_MME_IP_ADDR"; ipv6 = "192:168:30::17"; active = "yes"; preference = "ipv4"; @@ -184,12 +184,11 @@ eNBs = NETWORK_INTERFACES : { ENB_INTERFACE_NAME_FOR_S1_MME = "eth0"; - ENB_IPV4_ADDRESS_FOR_S1_MME = "192.168.12.111/24"; + ENB_IPV4_ADDRESS_FOR_S1_MME = "CI_ENB_IP_ADDR"; ENB_INTERFACE_NAME_FOR_S1U = "eth0"; - ENB_IPV4_ADDRESS_FOR_S1U = "192.168.12.111/24"; + ENB_IPV4_ADDRESS_FOR_S1U = "CI_ENB_IP_ADDR"; ENB_PORT_FOR_S1U = 2152; # Spec 2152 - - ENB_IPV4_ADDRESS_FOR_X2C = "192.168.12.111/24"; + ENB_IPV4_ADDRESS_FOR_X2C = "CI_ENB_IP_ADDR"; ENB_PORT_FOR_X2C = 36422; # Spec 36422 }; } diff --git a/ci-scripts/main.py b/ci-scripts/main.py index e4675e46c3..f617d6f40a 100644 --- a/ci-scripts/main.py +++ b/ci-scripts/main.py @@ -372,10 +372,8 @@ class SSHConnection(): rruCheck = True # Make a copy and adapt to EPC / eNB IP addresses self.command('cp ' + full_config_file + ' ' + ci_full_config_file, '\$', 5) - self.command('sed -i -e \'s/mme_ip_address.*$/mme_ip_address = ( { ipv4 = "' + self.EPCIPAddress + '";/\' ' + ci_full_config_file, '\$', 2); - self.command('sed -i -e \'s/ENB_IPV4_ADDRESS_FOR_S1_MME.*$/ENB_IPV4_ADDRESS_FOR_S1_MME = "' + self.eNBIPAddress + '";/\' ' + ci_full_config_file, '\$', 2); - self.command('sed -i -e \'s/ENB_IPV4_ADDRESS_FOR_S1U.*$/ENB_IPV4_ADDRESS_FOR_S1U = "' + self.eNBIPAddress + '";/\' ' + ci_full_config_file, '\$', 2); - self.command('sed -i -e \'s/ENB_IPV4_ADDRESS_FOR_X2C.*$/ENB_IPV4_ADDRESS_FOR_X2C = "' + self.eNBIPAddress + '";/\' ' + ci_full_config_file, '\$', 2); + self.command('sed -i -e \'s/CI_MME_IP_ADDR/' + self.EPCIPAddress + '/\' ' + ci_full_config_file, '\$', 2); + self.command('sed -i -e \'s/CI_ENB_IP_ADDR/' + self.eNBIPAddress + '/\' ' + ci_full_config_file, '\$', 2); # Launch eNB with the modified config file self.command('source oaienv', '\$', 5) self.command('cd cmake_targets', '\$', 5) From 03217fbad28ed33ed65bcd8f0480e1384e1b363d Mon Sep 17 00:00:00 2001 From: Raphael Defosseux Date: Thu, 8 Nov 2018 12:40:59 +0100 Subject: [PATCH 105/233] CI: fix HTML reporting for CentOS build Signed-off-by: Raphael Defosseux --- ci-scripts/reportBuildLocally.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-scripts/reportBuildLocally.sh b/ci-scripts/reportBuildLocally.sh index a499fa3b66..1a02d72ad2 100755 --- a/ci-scripts/reportBuildLocally.sh +++ b/ci-scripts/reportBuildLocally.sh @@ -103,7 +103,7 @@ function details_table { COMPLETE_MESSAGE="start" for MESSAGE in $LIST_MESSAGES do - if [[ $MESSAGE == *"/home/ubuntu/tmp"* ]] + if [[ $MESSAGE == *"/home/ubuntu/tmp"* ]] || [[ $MESSAGE == *"/tmp/CI-eNB"* ]] then FILENAME=`echo $MESSAGE | sed -e "s#^/home/ubuntu/tmp/##" -e "s#^.*/tmp/CI-eNB/##" | awk -F ":" '{print $1}'` LINENB=`echo $MESSAGE | awk -F ":" '{print $2}'` From 7c6a5ef288ed1d01bf8ec2b0a22212e72f229bbb Mon Sep 17 00:00:00 2001 From: Raphael Defosseux Date: Thu, 8 Nov 2018 13:03:29 +0100 Subject: [PATCH 106/233] CI: adding a TM2 - FDD configuration file for testing Signed-off-by: Raphael Defosseux --- .../enb.band7.tm2.25PRB.usrpb210.conf | 265 ++++++++++++++++++ 1 file changed, 265 insertions(+) create mode 100644 ci-scripts/conf_files/enb.band7.tm2.25PRB.usrpb210.conf diff --git a/ci-scripts/conf_files/enb.band7.tm2.25PRB.usrpb210.conf b/ci-scripts/conf_files/enb.band7.tm2.25PRB.usrpb210.conf new file mode 100644 index 0000000000..4e5510b0d4 --- /dev/null +++ b/ci-scripts/conf_files/enb.band7.tm2.25PRB.usrpb210.conf @@ -0,0 +1,265 @@ +Active_eNBs = ( "eNB-Eurecom-LTEBox"); +# Asn1_verbosity, choice in: none, info, annoying +Asn1_verbosity = "none"; + +eNBs = +( + { + ////////// Identification parameters: + eNB_ID = 0xe00; + + cell_type = "CELL_MACRO_ENB"; + + eNB_name = "eNB-Eurecom-LTEBox"; + + // Tracking area code, 0x0000 and 0xfffe are reserved values + tracking_area_code = 1; + plmn_list = ( { mcc = 208; mnc = 92; mnc_length = 2; } ); + + tr_s_preference = "local_mac" + + ////////// Physical parameters: + + component_carriers = ( + { + node_function = "3GPP_eNODEB"; + node_timing = "synch_to_ext_device"; + node_synch_ref = 0; + frame_type = "FDD"; + tdd_config = 3; + tdd_config_s = 0; + prefix_type = "NORMAL"; + eutra_band = 7; + downlink_frequency = 2680000000L; + uplink_frequency_offset = -120000000; + Nid_cell = 0; + N_RB_DL = 25; + Nid_cell_mbsfn = 0; + nb_antenna_ports = 2; + nb_antennas_tx = 2; + nb_antennas_rx = 2; + tx_gain = 90; + rx_gain = 125; + pbch_repetition = "FALSE"; + prach_root = 0; + prach_config_index = 0; + prach_high_speed = "DISABLE"; + prach_zero_correlation = 1; + prach_freq_offset = 2; + pucch_delta_shift = 1; + pucch_nRB_CQI = 0; + pucch_nCS_AN = 0; + pucch_n1_AN = 0; + pdsch_referenceSignalPower = -25; + pdsch_p_b = 0; + pusch_n_SB = 1; + pusch_enable64QAM = "DISABLE"; + pusch_hoppingMode = "interSubFrame"; + pusch_hoppingOffset = 0; + pusch_groupHoppingEnabled = "ENABLE"; + pusch_groupAssignment = 0; + pusch_sequenceHoppingEnabled = "DISABLE"; + pusch_nDMRS1 = 1; + phich_duration = "NORMAL"; + phich_resource = "ONESIXTH"; + srs_enable = "DISABLE"; + /* + srs_BandwidthConfig =; + srs_SubframeConfig =; + srs_ackNackST =; + srs_MaxUpPts =; + */ + + pusch_p0_Nominal = -96; + pusch_alpha = "AL1"; + pucch_p0_Nominal = -104; + msg3_delta_Preamble = 6; + pucch_deltaF_Format1 = "deltaF2"; + pucch_deltaF_Format1b = "deltaF3"; + pucch_deltaF_Format2 = "deltaF0"; + pucch_deltaF_Format2a = "deltaF0"; + pucch_deltaF_Format2b = "deltaF0"; + + rach_numberOfRA_Preambles = 64; + rach_preamblesGroupAConfig = "DISABLE"; + /* + rach_sizeOfRA_PreamblesGroupA = ; + rach_messageSizeGroupA = ; + rach_messagePowerOffsetGroupB = ; + */ + rach_powerRampingStep = 4; + rach_preambleInitialReceivedTargetPower = -108; + rach_preambleTransMax = 10; + rach_raResponseWindowSize = 10; + rach_macContentionResolutionTimer = 48; + rach_maxHARQ_Msg3Tx = 4; + + pcch_default_PagingCycle = 128; + pcch_nB = "oneT"; + bcch_modificationPeriodCoeff = 2; + ue_TimersAndConstants_t300 = 1000; + ue_TimersAndConstants_t301 = 1000; + ue_TimersAndConstants_t310 = 1000; + ue_TimersAndConstants_t311 = 10000; + ue_TimersAndConstants_n310 = 20; + ue_TimersAndConstants_n311 = 1; + ue_TransmissionMode = 2; + + //Parameters for SIB18 + rxPool_sc_CP_Len = "normal"; + rxPool_sc_Period = "sf40"; + rxPool_data_CP_Len = "normal"; + rxPool_ResourceConfig_prb_Num = 20; + rxPool_ResourceConfig_prb_Start = 5; + rxPool_ResourceConfig_prb_End = 44; + rxPool_ResourceConfig_offsetIndicator_present = "prSmall"; + rxPool_ResourceConfig_offsetIndicator_choice = 0; + rxPool_ResourceConfig_subframeBitmap_present = "prBs40"; + rxPool_ResourceConfig_subframeBitmap_choice_bs_buf = "00000000000000000000"; + rxPool_ResourceConfig_subframeBitmap_choice_bs_size = 5; + rxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused = 0; +/* + rxPool_dataHoppingConfig_hoppingParameter = 0; + rxPool_dataHoppingConfig_numSubbands = "ns1"; + rxPool_dataHoppingConfig_rbOffset = 0; + rxPool_commTxResourceUC-ReqAllowed = "TRUE"; +*/ + // Parameters for SIB19 + discRxPool_cp_Len = "normal" + discRxPool_discPeriod = "rf32" + discRxPool_numRetx = 1; + discRxPool_numRepetition = 2; + discRxPool_ResourceConfig_prb_Num = 5; + discRxPool_ResourceConfig_prb_Start = 3; + discRxPool_ResourceConfig_prb_End = 21; + discRxPool_ResourceConfig_offsetIndicator_present = "prSmall"; + discRxPool_ResourceConfig_offsetIndicator_choice = 0; + discRxPool_ResourceConfig_subframeBitmap_present = "prBs40"; + discRxPool_ResourceConfig_subframeBitmap_choice_bs_buf = "f0ffffffff"; + discRxPool_ResourceConfig_subframeBitmap_choice_bs_size = 5; + discRxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused = 0; + + } + ); + + + srb1_parameters : + { + # timer_poll_retransmit = (ms) [5, 10, 15, 20,... 250, 300, 350, ... 500] + timer_poll_retransmit = 80; + + # timer_reordering = (ms) [0,5, ... 100, 110, 120, ... ,200] + timer_reordering = 35; + + # timer_reordering = (ms) [0,5, ... 250, 300, 350, ... ,500] + timer_status_prohibit = 0; + + # poll_pdu = [4, 8, 16, 32 , 64, 128, 256, infinity(>10000)] + poll_pdu = 4; + + # poll_byte = (kB) [25,50,75,100,125,250,375,500,750,1000,1250,1500,2000,3000,infinity(>10000)] + poll_byte = 99999; + + # max_retx_threshold = [1, 2, 3, 4 , 6, 8, 16, 32] + max_retx_threshold = 4; + } + + # ------- SCTP definitions + SCTP : + { + # Number of streams to use in input/output + SCTP_INSTREAMS = 2; + SCTP_OUTSTREAMS = 2; + }; + + + ////////// MME parameters: + mme_ip_address = ( { ipv4 = "CI_MME_IP_ADDR"; + ipv6 = "192:168:30::17"; + active = "yes"; + preference = "ipv4"; + } + ); + + NETWORK_INTERFACES : + { + ENB_INTERFACE_NAME_FOR_S1_MME = "eth0"; + ENB_IPV4_ADDRESS_FOR_S1_MME = "CI_ENB_IP_ADDR"; + ENB_INTERFACE_NAME_FOR_S1U = "eth0"; + ENB_IPV4_ADDRESS_FOR_S1U = "CI_ENB_IP_ADDR"; + ENB_PORT_FOR_S1U = 2152; # Spec 2152 + ENB_IPV4_ADDRESS_FOR_X2C = "CI_ENB_IP_ADDR"; + ENB_PORT_FOR_X2C = 36422; # Spec 36422 + }; + } +); + +MACRLCs = ( + { + num_cc = 1; + tr_s_preference = "local_L1"; + tr_n_preference = "local_RRC"; + phy_test_mode = 0; + puSch10xSnr = 200; + puCch10xSnr = 200; + } +); + +L1s = ( + { + num_cc = 1; + tr_n_preference = "local_mac"; + } +); + +RUs = ( + { + local_rf = "yes" + nb_tx = 2 + nb_rx = 2 + att_tx = 0 + att_rx = 0; + bands = [7]; + max_pdschReferenceSignalPower = -27; + max_rxgain = 115; + eNB_instances = [0]; + } +); + +THREAD_STRUCT = ( + { + #three config for level of parallelism "PARALLEL_SINGLE_THREAD", "PARALLEL_RU_L1_SPLIT", or "PARALLEL_RU_L1_TRX_SPLIT" + parallel_config = "PARALLEL_RU_L1_TRX_SPLIT"; + #two option for worker "WORKER_DISABLE" or "WORKER_ENABLE" + worker_config = "WORKER_ENABLE"; + } +); + +NETWORK_CONTROLLER : +{ + FLEXRAN_ENABLED = "no"; + FLEXRAN_INTERFACE_NAME = "lo"; + FLEXRAN_IPV4_ADDRESS = "127.0.0.1"; + FLEXRAN_PORT = 2210; + FLEXRAN_CACHE = "/mnt/oai_agent_cache"; + FLEXRAN_AWAIT_RECONF = "no"; +}; + +log_config : + { + global_log_level ="info"; + global_log_verbosity ="medium"; + hw_log_level ="info"; + hw_log_verbosity ="medium"; + phy_log_level ="info"; + phy_log_verbosity ="medium"; + mac_log_level ="info"; + mac_log_verbosity ="high"; + rlc_log_level ="info"; + rlc_log_verbosity ="medium"; + pdcp_log_level ="info"; + pdcp_log_verbosity ="medium"; + rrc_log_level ="info"; + rrc_log_verbosity ="medium"; + }; + From 3515d4316f18417412012bc9264a8c661a1192ae Mon Sep 17 00:00:00 2001 From: frtabu Date: Thu, 8 Nov 2018 19:10:49 +0100 Subject: [PATCH 107/233] doc for config module moved from wiki --- common/config/DOC/config.md | 11 ++ common/config/DOC/config/arch.md | 7 + common/config/DOC/config/devusage.md | 20 +++ .../config/DOC/config/devusage/addaparam.md | 86 ++++++++++++ .../config/DOC/config/devusage/addparamset.md | 131 ++++++++++++++++++ common/config/DOC/config/devusage/api.md | 48 +++++++ common/config/DOC/config/devusage/struct.md | 85 ++++++++++++ common/config/DOC/config/rtusage.md | 52 +++++++ common/utils/DOC/loader.md | 17 +++ common/utils/DOC/loader/arch.md | 7 + common/utils/DOC/loader/devusage.md | 17 +++ common/utils/DOC/loader/devusage/api.md | 20 +++ common/utils/DOC/loader/devusage/loading.md | 56 ++++++++ common/utils/DOC/loader/devusage/struct.md | 10 ++ common/utils/DOC/loader/rtusage.md | 50 +++++++ common/utils/telnetsrv/DOC/telnetaddcmd.md | 116 ++++++++++++++++ common/utils/telnetsrv/DOC/telnetarch.md | 21 +++ common/utils/telnetsrv/DOC/telnetgetset.md | 21 +++ common/utils/telnetsrv/DOC/telnethelp.md | 57 ++++++++ common/utils/telnetsrv/DOC/telnethist.md | 44 ++++++ common/utils/telnetsrv/DOC/telnetloader.md | 47 +++++++ common/utils/telnetsrv/DOC/telnetlog.md | 95 +++++++++++++ common/utils/telnetsrv/DOC/telnetloop.md | 40 ++++++ common/utils/telnetsrv/DOC/telnetsrv.md | 7 + common/utils/telnetsrv/DOC/telnetusage.md | 39 ++++++ 25 files changed, 1104 insertions(+) create mode 100644 common/config/DOC/config.md create mode 100644 common/config/DOC/config/arch.md create mode 100644 common/config/DOC/config/devusage.md create mode 100644 common/config/DOC/config/devusage/addaparam.md create mode 100644 common/config/DOC/config/devusage/addparamset.md create mode 100644 common/config/DOC/config/devusage/api.md create mode 100644 common/config/DOC/config/devusage/struct.md create mode 100644 common/config/DOC/config/rtusage.md create mode 100644 common/utils/DOC/loader.md create mode 100644 common/utils/DOC/loader/arch.md create mode 100644 common/utils/DOC/loader/devusage.md create mode 100644 common/utils/DOC/loader/devusage/api.md create mode 100644 common/utils/DOC/loader/devusage/loading.md create mode 100644 common/utils/DOC/loader/devusage/struct.md create mode 100644 common/utils/DOC/loader/rtusage.md create mode 100644 common/utils/telnetsrv/DOC/telnetaddcmd.md create mode 100644 common/utils/telnetsrv/DOC/telnetarch.md create mode 100644 common/utils/telnetsrv/DOC/telnetgetset.md create mode 100644 common/utils/telnetsrv/DOC/telnethelp.md create mode 100644 common/utils/telnetsrv/DOC/telnethist.md create mode 100644 common/utils/telnetsrv/DOC/telnetloader.md create mode 100644 common/utils/telnetsrv/DOC/telnetlog.md create mode 100644 common/utils/telnetsrv/DOC/telnetloop.md create mode 100644 common/utils/telnetsrv/DOC/telnetsrv.md create mode 100644 common/utils/telnetsrv/DOC/telnetusage.md diff --git a/common/config/DOC/config.md b/common/config/DOC/config.md new file mode 100644 index 0000000000..682780cd3b --- /dev/null +++ b/common/config/DOC/config.md @@ -0,0 +1,11 @@ +# OAI configuration module + +The configuration module provides an api that other oai components can use to get parameters at init time. It defines a parameter structure, used to describe parameters attributes (for example name and type). The same structure includes a pointer to the variable where the configuration module writes the parameter value, at run time, when calling config_get or config_getlist functions. For each parameter a function to check the value can be specified and pre-defined functions are provided for some common parameter validations (integer in a range or in a list, string in a list). The module also include a mechanism to check that no unknown options have been entered on the command line + +## Documentation + +* [runtime usage](config/rtusage) +* [developer usage](config/devusage) +* [module architecture](config/arch) + +[oai Wikis home](https://gitlab.eurecom.fr/oai/openairinterface5g/wikis/home) diff --git a/common/config/DOC/config/arch.md b/common/config/DOC/config/arch.md new file mode 100644 index 0000000000..efe4d9eef7 --- /dev/null +++ b/common/config/DOC/config/arch.md @@ -0,0 +1,7 @@ +# config module source files +![configmodule_srcdir](/uploads/fdc3e96011fd5592440900dfa05b4701/configmodule_srcdir.png) +# config module components +![configmodule_components](/uploads/54f8a3953d5ee53717cd9a3b71f85c68/configmodule_components.png) + + +[Configuration module home](config) \ No newline at end of file diff --git a/common/config/DOC/config/devusage.md b/common/config/DOC/config/devusage.md new file mode 100644 index 0000000000..88abc96f42 --- /dev/null +++ b/common/config/DOC/config/devusage.md @@ -0,0 +1,20 @@ +The configuration module objectives are +1. Allow easy parameters management in oai, helping the development of a flexible, modularized and fully configurable softmodem. +1. Use a common configuration API in all oai modules +1. Allow development of alternative configuration sources without modifying the oai code. Today the only delivered configuration source is the libconfig format configuration file. + +As a developer you may need to look at these sections: + +* [add parameters in an existing section](config/devusage/addaparam) +* [add a parameter set, in a new section](config/devusage/addparamset) +* [configuration module API](config/devusage/api) +* [configuration module public structures](config/devusage/struct) + +Whatever your need is, configuration module usage examples can be found in oai sources: +* complex example, using all the configuration module functionalities, including parameter checking: +[NB-IoT configuration code](https://gitlab.eurecom.fr/oai/openairinterface5g/blob/develop/openair2/ENB_APP/NB_IoT_config.c) and [NB-IoT configuration include file](https://gitlab.eurecom.fr/oai/openairinterface5g/blob/develop/openair2/ENB_APP/NB_IoT_paramdef.h) +* very simple example, just reading a parameter set corresponding to a dedicated section: the telnetsrv_autoinit function in [common/utils/telnetsrv/telnetsrv.c, around line 726](https://gitlab.eurecom.fr/oai/openairinterface5g/blob/develop/common/utils/telnetsrv/telnetsrv.c#L726) +* an example with run-time definition of parameters, in the logging sub-system: the log_getconfig function at the top of [openair2/UTIL/LOG/log.c](https://gitlab.eurecom.fr/oai/openairinterface5g/blob/develop/openair2/UTIL/LOG/log.c) + + +[Configuration module home](config) diff --git a/common/config/DOC/config/devusage/addaparam.md b/common/config/DOC/config/devusage/addaparam.md new file mode 100644 index 0000000000..28bd3ee142 --- /dev/null +++ b/common/config/DOC/config/devusage/addaparam.md @@ -0,0 +1,86 @@ +To add a new parameter in an existing section you insert an item in a `paramdef_t` array, which describes the parameters to be read in the existing `config_get` call. You also need to increment the numparams argument. + +existing code: +```c +unsigned int varopt1; +paramdef_t someoptions[] = { +/*---------------------------------------------------------------------------------*/ +/* configuration parameters for some module */ +/* optname helpstr paramflags XXXptr defXXXval type numelt */ +/*---------------------------------------------------------------------------------*/ + {"opt1", "", 0, uptr:&varopt1, defuintval:0, TYPE_UINT, 0 }, +}; + +config_get( someoptions,sizeof(someoptions)/sizeof(paramdef_t),"somesection"); + +``` +new code: +```c +unsigned int varopt1; + + +/* varopt2 will be allocated by the config module and free at end_configmodule call + except if PARAMFLAG_NOFREE bit is set in paramflags field*/ +char *varopt2; +paramdef_t someoptions[] = { +/*---------------------------------------------------------------------------------*/ +/* configuration parameters for some module */ +/* optname helpstr paramflags XXXptr defXXXval type numelt */ +/*---------------------------------------------------------------------------------*/ + {"opt1", "", 0, uptr:&varopt1, defuintval:0,TYPE_UINT, 0 }, + {"opt2", "", 0, strptr:&varopt2,defstrval:"",TYPE_STRING,0 }, +}; + +config_get( someoptions,sizeof(someoptions)/sizeof(paramdef_t),"somesection"); + +``` + +The corresponding configuration file may now include opt2 parameter in the somesection section: + +```c +somesection = +{ +opt1 = 3; +opt2 = "abcd"; +}; +``` + +In these examples the variables used to retrieve the parameters values are pointed by the `uptr` or `strptr` fields of the `paramdef_t` structure. After the `config_get` call `varopt1` and `varopt2` have been set to the value specified in the config file. It is also possible to specify a `NULL` value to the `< XXX >ptr` fields, which are then allocated by the config module and possibly free when calling `config_end()`, if the `PARAMFLAG_NOFREE` bit has not been set in the `paramflags` field. + +The configuration module provides a mechanism to check the parameter value read from the configuration source. The following functions are implemented: +1. Check an integer parameter against a list of authorized values +1. Check an integer parameter against a list of authorized values and set the parameter to a new value +1. Check an integer parameter against a range +1. Check a C string parameter against a list of authorized values +1. Check a C string parameter against a list of authorized values and set the parameter to a new integer value + + A `checkedparam_t` structure array provides the parameter verification procedures: + +```c +/* + definition of the verification to be done on param opt1 and opt2. + opt1 is an integer option we must be set to 0,2,3,4 or 7 in the + config source. + if opt1 is set to 0 in the config file, it will be set to 1, etc + opt2 is C string option with the authorize values "zero","oneThird","twoThird","one" + */ +#define OPT1_OKVALUES {0,2,3,4,7} +#define OPT1_NEWVALUES {1,1,0,6,9} +#define OPT2_OKVALUES {"zero","oneThird","twoThird","one"} + +#define OPT_CHECK_DESC { \ + { .s1a= { config_check_modify_integer, OPT1_OKVALUE, OPT1_NEWVALUES ,5 }}, \ + { .s3= { config_check_strval, OPT2_OKVALUES,4 }}, \ +} +checkedparam_t checkopt[] = OPT_CHECK_DESC; +..... +/* assign the verification procedures to the parameters definitions */ +for(int i=0 ; i < sizeof(someoptions)/sizeof(paramdesc_t) ; i ++) { + someoptions[i].chkPptr = &(checkopt[i]); +} +.... +``` +When you need a specific verification algorithm, you can provide your own verification function and use it in place of the available ones, in the `checkedparam_t` union. If no existing structure definition match your need, you can enhance the configuration module. You then have to add a new verification function in https://gitlab.eurecom.fr/oai/openairinterface5g/blob/develop/common/config/config_userapi.c and add a new structure definition in the `checkedparam_t` type defined in https://gitlab.eurecom.fr/oai/openairinterface5g/blob/develop/common/config/config_paramdesc.h + +[Configuration module developer main page](config/devusage) +[Configuration module home](config) diff --git a/common/config/DOC/config/devusage/addparamset.md b/common/config/DOC/config/devusage/addparamset.md new file mode 100644 index 0000000000..9b90fcc81f --- /dev/null +++ b/common/config/DOC/config/devusage/addparamset.md @@ -0,0 +1,131 @@ +The configuration module maps a configuration file section to a `paramdef_t` structure array. One `config_get` call can be used to return the values of all the parameters described in the `paramdef_t` array. +Retrieving a single occurence of a parameter set ( a group in the libconfig terminology) is just a two steps task: +1. describe the parameters in a `paramdef_t` array +1. call the `config_get` function + + +[config_get example](https://gitlab.eurecom.fr/oai/openairinterface5g/wikis/config/devusage/addaparam) + + +In oai some parameters set may be instantiated a variable number of occurrences. In a configuration file this is mapped to lists of group of parameters, with this syntax: +```c +NB-IoT_MACRLCs = +/* start list element 1 */ +( + /* start a group of parameters */ + { + num_cc = 2; + ..... + remote_s_portd = 55001; + } +), +/* start list element 2 */ +( + /* start a group of parameters */ + { + num_cc = 1; + ...... + remote_s_portd = 65001; + } +); + +``` +The configuration module provides the `config_getlist` call to support lists of group of parameters. Below is a commented code example, using the config_getlist call. + +```c +/* name of section containing the list */ +#define NBIOT_MACRLCLIST_CONFIG_STRING "NB-IoT_MACRLCs" + +/* +The following macro define the parameters names, as used in the +configuration file +*/ +#define CONFIG_STRING_MACRLC_CC "num_cc" +..... +#define CONFIG_MACRLC_S_PORTD "remote_s_portd" + +/* + now define a macro which will be used to initialize the NbIoT_MacRLC_Params + variable. NbIoT_MacRLC_Params is an array of paramdef_t structure, each item + describing a parameter. When using the config_getlist call you must let the config + module allocate the memory for the parameters values. +*/ +/*------------------------------------------------------------------------------------------------------------*/ +/* optname helpstr paramflags XXXptr defXXXval type numelt */ +/*------------------------------------------------------------------------------------------------------------*/ + +#define MACRLCPARAMS_DESC { \ +{CONFIG_STRING_MACRLC_CC, NULL, 0, uptr:NULL, defintval:1, TYPE_UINT, 0}, \ +............. \ +{CONFIG_MACRLC_S_PORTD, NULL, 0, uptr:NULL, defintval:50021, TYPE_UINT, 0}, \ +} + +/* +the following macros define the indexes used to access the NbIoT_MacRLC_Params array +items. They must be maintained consistent with the previous MACRLCPARAMS_DESC macro +which is used to initialize the NbIoT_MacRLC_Params variable +*/ +#define MACRLC_CC_IDX 0 +......... +#define MACRLC_REMOTE_S_PORTD_IDX 16 + + + +void RCconfig_NbIoTmacrlc(void) { + + +/* + define and initialize the array of paramdef_t structures describing the groups of + parameters we want to read. It will be passed as the second argument of the + config_getlist call, which will use it as an input only argument. +*/ + paramdef_t NbIoT_MacRLC_Params[] = MACRLCPARAMS_DESC; + +/* + now define and initialize a paramlist_def_t structure which will be passed + to the config_getlist call. The first field is the only one to be initialized + it contains the name of the section to be read. + that section contains the list of group of parameters. + The two other fields are output parameters used to return respectively + a pointer to a two dimensional array of paramdef_t structures pointers, and the + number of items in the list of groups (size of first dimension, the second one + being the number of parameters in each group. +*/ + paramlist_def_t NbIoT_MacRLC_ParamList = {NBIOT_MACRLCLIST_CONFIG_STRING,NULL,0}; + + + /* + the config_getlist will allocate the second field of the paramlist_def_t structure, a +two dimensional array of paramdef_t pointers. In each param_def item it will allocate +the value pointer and set the value to what it will get from the config source. The +numelt field of the paramlist_def_t structure will be set to the number of groups of +parameters in the list. + in this example the last argument of config_getlist is unused, it may contain a +character string, used as a prefix for the section name. It has to be specified when the +list to be read is under another section. +*/ + config_getlist( &NbIoT_MacRLC_ParamList,NbIoT_MacRLC_Params, + sizeof(NbIoT_MacRLC_Params)/sizeof(paramdef_t), + NULL); + +/* + start a loop in the nuber of groups in the list, the numelt field of the + paramlist_def_t structure has been set in the config_getlist call +*/ + for (j=0 ; jeth_params_s.remote_portd = + *(NbIoT_MacRLC_ParamList.paramarray[j][MACRLC_REMOTE_S_PORTD_IDX].iptr); +............ + + } // MacRLC_ParamList.numelt > 0 +} + + +``` + +[Configuration module developer main page](config/devusage) +[Configuration module home](config) diff --git a/common/config/DOC/config/devusage/api.md b/common/config/DOC/config/devusage/api.md new file mode 100644 index 0000000000..c9d562ced0 --- /dev/null +++ b/common/config/DOC/config/devusage/api.md @@ -0,0 +1,48 @@ +```c +configmodule_interface_t *load_configmodule(int argc, char **argv) +``` +* Parses the command line options, looking for the –O argument +* Loads the `libparams_.so` (today `libparams_libconfig.so`) shared library +* Looks for `config__init` symbol and calls it , passing it an array of string corresponding to the « : » separated strings used in the –O option +* Looks for `config__get`, `config__getlist` and `config__end` symbols which are the three functions a configuration library should implement. Get and getlist are mandatory, end is optional. +* Stores all the necessary information in a `configmodule_interface_t structure`, which is of no use for caller as long as we only use one configuration source. + +```c +void End_configmodule(void) +``` +* Free memory which has been allocated by the configuration module since its initialization. +* Possibly calls the `config__end` function + +```c +int config_get(paramdef_t *params,int numparams, char *prefix) +``` +* Reads as many parameters as described in params, they must all be in the same configuration file section +* Calls the `config__get` function +* Calls the `config_process_cmdline` function +* `params` points to an array of `paramdef_t` structures which describes the parameters to be read, possibly including a pointer to a checking function. The following bits can possibly be set in the `paramflags` mask before calling + - `PARAMFLAG_MANDATORY`: -1 is returned if the parameter is not explicitly defined in the config source. + - `PARAMFLAG_DISABLECMDLINE`: parameter cannot be modified via the command line + - `PARAMFLAG_DONOTREAD`: ignore the parameter, can be used at run-time, to alter a pre-defined `paramdef_t` array which is used in several `config_get` or/and `config_getlist` calls. + - `PARAMFLAG_NOFREE`: do not free the memory possibly allocated by the config module to store the value of the parameter. Default behavior is for the config module to free the memory it has allocated when the `config_end` function is called. + - `PARAMFLAG_BOOL`: Only relevant for integer types. tell the config module that when processing the command line, the corresponding option can be specified without any arggument and that in this case it must set the value to 1. + +* `params` is also used as an output parameter, `< XXX >ptr >` field is used by the config module to store the value it has read. The following bits can possibly be set in the `paramflags` mask after the call: + - `PARAMFLAG_MALLOCINCONFIG`: memory has been allocated for the ` < XXX >ptr > ` field + - `PARAMFLAG_PARAMSET`: parameter has been found in the config source, it is not set to default value. + - `PARAMFLAG_PARAMSET`: parameter has been set to its default value +* `numparams` is the number of entries in the params array +* `prefix` is a character string to be appended to the parameters name, it defines the parameters position in the configuration file hierarchy (the section name in libconfig terminology). +* The returned value is the number of parameters which have been assigned a value or -1 if a severe error occured + +```c +int config_libconfig_getlist(paramlist_def_t *ParamList, paramdef_t *params, int numparams, char *prefix) +``` +* Reads multiple occurrences of a parameters array +* Calls the `config__get` function for each list occurrence +* `params` points to an array of `paramdef_t` structures which describes the parameters in each occurrence of the list +* `ParamList` points to a structure, where `paramarray` field points to an array of `paramdef_t` structure, allocated by the function. It is used to return the values of the parameters. +* The returned value is the number of occurrences in the list or -1 in case of severe error + + +[Configuration module developer main page](config/devusage) +[Configuration module home](config) diff --git a/common/config/DOC/config/devusage/struct.md b/common/config/DOC/config/devusage/struct.md new file mode 100644 index 0000000000..17a9c36455 --- /dev/null +++ b/common/config/DOC/config/devusage/struct.md @@ -0,0 +1,85 @@ +# `paramdef_t`structure +It is defined in include file [ common/config/config_paramdesc.h ](https://gitlab.eurecom.fr/oai/openairinterface5g/blob/develop/common/config/config_paramdesc.h#L103). This structure is used by developers to describe parameters and by the configuration module to return parameters value. A pointer to a `paramdef_t` array is passed to `config_get` and `config_getlist` calls to instruct the configuration module what parameters it should read. + +| Fields | Description | I/O | +|:-----------|:------------------------------------------------------------------|----:| +| `optname` | parameter name, as used when looking for it in the config source, 63 bytes max (64 with trailing \0) | I | +| `helstr` | pointer to a C string printed when using --help on the command line | I | +| `strptr` `strlistptr` `u8ptr` `i8ptr` `u16ptr` `i16ptr` `uptr` `iptr` `u64ptr` `i64ptr` `dblptr` `voidptr` | a pointer to a variable where the parameter value(s) will be returned. This field is an anonymous union, the supported pointer types have been built to avoid type mismatch warnings at compile time. | O | +| `defstrval` `defstrlistval` `defuintval` `defintval` `defint64val` `defintarrayval` `defdblval` | this field is an anonymous union, it can be used to define the default value for the parameter. It is ignored if `PARAMFLAG_MANDATORY` is set in the `paramflags` field.| I | +| `type` | Supported parameter types are defined as integer macros. Supported simple types are `TYPE_STRING`, parameter value is returned in `strptr` field, `TYPE_INT8` `TYPE_UINT8` `TYPE_INT16` `TYPE_UINT16` `TYPE_INT32` `TYPE_UINT32` `TYPE_INT64` `TYPE_UINT64`, parameter value is returned in the corresponding uXptr or iXptr, `TYPE_MASK`, value is returned in `u32ptr`, `TYPE_DOUBLE` value is returned in `dblptr`, `TYPE_IPV4ADDR` value is returned in binary, network bytes order in `u32ptr` field. `TYPE_STRINGLIST`, `TYPE_INTARRAY` and `TYPE_UINTARRAY` are multiple values types. Multiple values are returned in respectively, `strlistptr`, `iptr` and `uptr` fields which then point to arrays. The `numelt` field gives the number of item in the array. | I | +| `numelt` | For `TYPE_STRING` where `strptr` points to a preallocated string, this field must contain the size in bytes of the available memory. For all multiple values types, this field contains the number of values in the value field.| I/O | +| `chkPptr` | possible pointer to the structure containing the info used to check parameter values | I | +| `processedvalue` | When `chkPptr` is not `ǸULL`, is used to return a value, computed from the original parameter, as read from the configuration source. | O | + +# `paramlist_def_t`structure +It is defined in include file [ common/config/config_paramdesc.h ](https://gitlab.eurecom.fr/oai/openairinterface5g/blob/develop/common/config/config_paramdesc.h#L160). +It is used as an argument to `config_getlist` calls, to get values of multiple occurrences of group of parameters. + +| Fields | Description | I/O | +|:-----------|:------------------------------------------------------------------|----:| +| `listname` | Name of the section containing the list, 63 bytes max (64 with trailing \0). It is used to prefix each paramater name when looking for its value. In the libconfig syntax, the parameter name full path build by the configuration module is: listname.[occurence index].optname. | I | +| `paramarray` | Pointer to an array of `ǹumelt` `paramdef_t` pointers. It is allocated by the configuration module and is used to return the parameters values. All input fields of each `paramdef_t` occurence are a copy of the `paramdef_t` argument passed to the `config_getlist` call. | O | +| `numelt` | Number of items in the `paramarray` field | O | + +# `checkedparam_t` union +It is defined in include file [ common/config/config_paramdesc.h ](https://gitlab.eurecom.fr/oai/openairinterface5g/blob/develop/common/config/config_paramdesc.h#L62). +This union of structures is used to provide a parameter checking mechanism. Each `paramdef_t` instance may include a pointer to a `checkedparam_t`structure which is then used by the configuration module to check the value it got from the config source. +Each structure in the union provides one parameter verification method, which returns `-1` when the verification fails. Currently the following structures are defined in the `checkedparam_t` union: + +| structure name | Description | +|:-----------|:------------------------------------------------------------------|----:| +| `s1` | check an integer against a list of authorized values | +| `s1a` | check an integer against a list of authorized values and set the parameter value to another integer depending on the read value| +| `s2` | check an integer against an authorized range, defined by its min and max value| +| `s3` | check a string against a list of authorized values | +| `s3a` | check a string against a list of authorized values and set the parameter value to an integer depending on the read value| +| `s4` | generic structure, to be used to provide a specific, not defined in the configuration module, verification algorithm | + +each of these structures provide the required fields to perform the specified parameter check. The first field is a pointer to a function, taking one argument, the `paramdef_t` structure describing the parameter to be checked. This function is called by the configuration module, in the `config_get` call , after the parameter value has been set, it then uses the other fields of the structure to perform the check. +The configuration module provides an implementation of the functions to be used to check parameters, qs described below. + +## `s1` structure +| field | Description | +|:-----------|:------------------------------------------------------------------| +| `f1` | pointer to the checking function. Initialize to `config_check_intval` to use the config module implementation | +| `okintval` | array of `CONFIG_MAX_NUMCHECKVAL` integers containing the authorized values | +| `num_okintval` | number of used values in `okintval` | + +## `s1a` structure +| field | Description | +|:-----------|:------------------------------------------------------------------| +| `f1a` | pointer to the checking function. Initialize to `config_check_modify_integer` to use the config module implementation | +| `okintval` | array of `CONFIG_MAX_NUMCHECKVAL` integers containing the authorized values | +| `setintval` | array of `CONFIG_MAX_NUMCHECKVAL` integers containing the values to be used for the parameter. The configuration module implementation set the parameter value to `setintval[i]` when the configured value is `okintval[i]` | +| `num_okintval` | number of used values in `okintval` and `setintval` | + +## `s2` structure +| field | Description | +|:-----------|:------------------------------------------------------------------| +| `f2` | pointer to the checking function. Initialize to `config_check_intrange` to use the config module implementation | +| `okintrange` | array of 2 integers containing the min and max values for the parameter | + +## `s3` structure +| field | Description | +|:-----------|:------------------------------------------------------------------| +| `f3` | pointer to the checking function. Initialize to `config_check_strval` to use the config module implementation | +| `okstrval` | array of `CONFIG_MAX_NUMCHECKVAL` C string pointers containing the authorized values | +| `num_okstrval` | number of used values in `okstrtval` | + + +## `s3a` structure +| field | Description | +|:-----------|:------------------------------------------------------------------| +| `f3a` | pointer to the checking function. Initialize to `config_checkstr_assign_integer` to use the config module implementation | +| `okstrval` | array of `CONFIG_MAX_NUMCHECKVAL` C string pointers containing the authorized values | +| `setintval` | array of `CONFIG_MAX_NUMCHECKVAL` integers containing the values to be used for the parameter. The configuration module implementation set the parameter value to `setintval[i]` when the configured value is `okstrval[i]` | +| `num_okstrval` | number of used values in `okintval` and `setintval` | + +## `s4` and `s5` structures +| field | Description | +|:-----------|:------------------------------------------------------------------| +| `f4` or `f5` | pointer to the checking function. they are generic structures to be used when no existing structure provides the required parameter verification. `f4` takes one argument, the `paramdef_t` structure corresponding to the parameter to be checked (`int (*f4)(paramdef_t *param)`), `f5` taxes no argument (`void (*checkfunc)(void)`) | + +[Configuration module developer main page](config/devusage) +[Configuration module home](config) diff --git a/common/config/DOC/config/rtusage.md b/common/config/DOC/config/rtusage.md new file mode 100644 index 0000000000..828f6a959d --- /dev/null +++ b/common/config/DOC/config/rtusage.md @@ -0,0 +1,52 @@ + + -O is the only mandatory command line option to start the eNodeb softmodem (lte-softmodem executable), it is used to specify the configuration source with the associated parameters: +```bash +$ ./lte-softmodem -O :::... +``` + The configuration module can also be used without a configuration source, ie to only parse the command line. In this case the -O switch is optional. This mode is used in the ue-softmodem executable and by the phy_simulators executables (ulsim, dlsim) + +Currently the available config sources are: + +- **libconfig**: libconfig file. [libconfig file format](http://www.hyperrealm.com/libconfig/libconfig_manual.html#Configuration-Files) Parameter1 is the file path and parameter 2 can be used to specify the level of console messages printed by the configuration module. +```bash +$ ./lte-softmodem -O libconfig::dbgl +``` +- **cmdlineonly**: command line only, the default mode for lte-uesoftmodem and the phy simiulators. In this case -O may be used to specify the config module debug level. + +The debug level is a mask: +* bit 1: print parameters values +* bit 2: print memory allocation/free performed by the config module +* bit 3: print command line processing messages +* bit 4: disable execution abort when parameters checking fails + +As a oai user, you may have to use bit 1 (dbgl1) , to check your configuration and get the full name of a parameter you would like to modify on the command line. Other bits are for developers usage, (dbgl7 will print all debug messages). + +```bash +$ ./lte-softmodem -O libconfig::dbgl1 +``` +```bash +$ ./lte-uesoftmodem -O cmdlineonly:dbgl1 +``` +For the lte-softmodem (the eNodeB) The config source parameter defaults to libconfig, preserving the initial -O option format. In this case you cannot specify the debug level. + +```bash +$ ./lte-softmodem -O +``` + +Configuration file parameters, except for the configuration file path, can be specified in a **config** section in the configuration file: + +``` +config: +{ + debugflags = 1; +} +``` +Configuration files examples can be found in the targets/PROJECTS/GENERIC-LTE-EPC/CONF sub-directory of the oai source tree. To minimize the number of configuration file to maintain, any parameter can also be specified on the command line. For example to modify the lte bandwidth to 20 MHz where the configuration file specifies 10MHz you can enter: + +```bash +$ ./lte-softmodem -O --eNBs.[0].component_carriers.[0].N_RB_DL 100 +``` + +As specified earlier, use the dbgl1 debug level to get the full name of a parameter you would like to modify on the command line. + +[Configuration module home](config) \ No newline at end of file diff --git a/common/utils/DOC/loader.md b/common/utils/DOC/loader.md new file mode 100644 index 0000000000..7ed23952aa --- /dev/null +++ b/common/utils/DOC/loader.md @@ -0,0 +1,17 @@ +# OAI shared library loader + +Shared libraries usage is modularization mechanism which provides the following advantages: +1. Prevents including in the main executable code which is not used in a given configuration +1. Provides flexibility, several implementation of a given functionality can be chosen at run-time, without any compilation step. For example you can build several devices (USRP, BladeFR, LimeSDR) and choose which one you want to use on the command line or via the configuration. +1. Makes code evolution easier: as soon as the shared library interface is clearly defined, you can work on the functionality implemented in a shared library while regularly updating the other components of the code. You can decide to develop your own version of a functionality, decide to deliver it or not, letting the user decide wwhat version he wants to use. + +The main drawback is a performance cost at init time, when loading libraries. + + +## Documentation + +* [runtime usage](loader/rtusage) +* [developer usage](loader/devusage) +* [module architecture](loader/arch) + +[oai Wikis home](home) \ No newline at end of file diff --git a/common/utils/DOC/loader/arch.md b/common/utils/DOC/loader/arch.md new file mode 100644 index 0000000000..53a1cc7ea2 --- /dev/null +++ b/common/utils/DOC/loader/arch.md @@ -0,0 +1,7 @@ +# loader source files + +The oai shared library loader is implemented in two source files, located in [common/utils](https://gitlab.eurecom.fr/oai/openairinterface5g/tree/develop/common/utils) +1. [load_module_shlib.c](https://gitlab.eurecom.fr/oai/openairinterface5g/tree/develop/common/utils/load_module_shlib.c) contains the loader implementation +1. [load_module_shlib.h](https://gitlab.eurecom.fr/oai/openairinterface5g/tree/develop/common/utils/load_module_shlib.h) is the loader include file containing both private and public data type definitions. It also contain API prototypes. + +[loader home page](loader) \ No newline at end of file diff --git a/common/utils/DOC/loader/devusage.md b/common/utils/DOC/loader/devusage.md new file mode 100644 index 0000000000..89d15aa75e --- /dev/null +++ b/common/utils/DOC/loader/devusage.md @@ -0,0 +1,17 @@ +The configuration module objectives are +1. Allow easy parameters management in oai, helping the development of a flexible, modularized and fully configurable softmodem. +1. Use a common configuration API in all oai modules +1. Allow development of alternative configuration sources without modifying the oai code. Today the only delivered configuration source is the libconfig format configuration file. + +As a developer you may need to look at these sections: + +* [loading a shared library](loader/devusage/loading) +* [loader API](loader/devusage/api) +* [loader public structures](loader/devusage/struct) + +Loader usage examples can be found in oai sources: + +* device and transport initialization code: [function `load_lib` in *targets/ARCH/COMMON/__common_lib.c__* ](https://gitlab.eurecom.fr/oai/openairinterface5g/blob/develop/targets/ARCH/COMMON/common_lib.c#L91) +* turbo encoder and decoder initialization: [function `load_codinglib`in *openair1/PHY/CODING/__coding_load.c__*](https://gitlab.eurecom.fr/oai/openairinterface5g/blob/develop/openair1/PHY/CODING/coding_load.c#L113) + +[loader home page](loader) diff --git a/common/utils/DOC/loader/devusage/api.md b/common/utils/DOC/loader/devusage/api.md new file mode 100644 index 0000000000..e01d69e9d4 --- /dev/null +++ b/common/utils/DOC/loader/devusage/api.md @@ -0,0 +1,20 @@ + Loader API is defined in the [common/utils/load_module_shlib.h](https://gitlab.eurecom.fr/oai/openairinterface5g/blob/develop/common/utils/load_module_shlib.h) include file. +```c +int load_module_shlib(char *modname,loader_shlibfunc_t *farray, int numf) +``` +* possibly initializes the loader, if it has not been already initialized +* Formats the full shared library path, using the `modname` argument and the loader `shlibpath` and `shlibversion`configuration parameters. +* loads the shared library, using the dlopen system call +* looks for `< modname >_autoinit` symbol, using the `dlsym` system call and possibly call the corresponding function. +* looks for `< modname >_checkbuildver` symbol, using the `dlsym` system call and possibly calls the corresponding function. If the return value of this call is `-1`, program execution is stopped. It is the responsibility of the shared library developer to implement or not a `< modname >_checkbuildver` function and to decide if a version mismatch is a fatal condition. The `< modname >_checkbuildver` function must match the `checkverfunc_t` function type. The first argument is the main executable version, as set in the `PACKAGE_VERSION` macro defined in the [oai CMakeLists](https://gitlab.eurecom.fr/oai/openairinterface5g/blob/develop/cmake_targets/CMakeLists.txt#L218), around line 218. The second argument points to the shared library version which should be set by the `< modname >_checkbuildver` function. +* If the farray pointer is null, looks for `< modname >_getfarray` symbol, calls the corresponding function when the symbol is found. `< modname >_getfarray` takes one argument, a pointer to a `loader_shlibfunc_t` array, and returns the number of items in this array, as defined by the `getfarrayfunc_t` type. The `loader_shlibfunc_t` array returned by the shared library must be fully filled (both `fname` and `fptr` fields). +* looks for the `numf` function symbols listed in the `farray[i].fname` arguments and set the corresponding `farray[i].fptr`function pointers + + +```c +void * get_shlibmodule_fptr(char *modname, char *fname) +``` +Returns a pointer to the symbol `fname`, defined in module `modname`, or `NULL` if the symbol is not found. + +[loader home page](loader) +[loader developer home page](loader/devusage) \ No newline at end of file diff --git a/common/utils/DOC/loader/devusage/loading.md b/common/utils/DOC/loader/devusage/loading.md new file mode 100644 index 0000000000..e544830c03 --- /dev/null +++ b/common/utils/DOC/loader/devusage/loading.md @@ -0,0 +1,56 @@ +Implementing a shared library dynamic load using the oai loader is a two steps task: +1. define the `loader_shlibfunc_t` array, describing the list of externally available functions implemented in the library. This is the interface of the module. +1. Call the `load_module_shlib` function, passing it the previously defined array and the number of items in this array. The first argument to `load_module_shlib` is the name identifying the module, which is also used to format the corresponding library name, as described [here](loader/rtusage#shared-library-names) + +After a successful `load__module_shlib` call, the function pointer of each `loader_shlibfunc_t` array item has been set and can be used to call the corresponding function. + +Typical loader usage looks like: + +```c +/* shared library loader include file */ +#include "common/utils/load_module_shlib.h" +............. +/* + define and initialize the array, describing the list of functions + implemented in "mymodule" +*/ + loader_shlibfunc_t mymodule_fdesc[2]; + mymodule_fdesc[0].fname="mymodule_f1"; + mymodule_fdesc[1].fname="mymodule_f2"; + +/* + load the library, it's name must be libmymod.so. Configuration can be + used to specify a specific path to look for libmymod.so. Configuration + can also specify a version, for example "V1", in this case the loader + will look for libmymodV1.so +*/ + ret=load_module_shlib("mymod",mymodule_fdesc, sizeof(mymodule_fdesc)/sizeof(loader_shlibfunc_t)); + if (ret < 0) { + fprintf(stderr,"Library couldn't be loaded\n"); + } else { +/* +library has been loaded, we probably want to call some functions... +*/ + ret=((funcf1_t)mymodule_fdesc[0].fptr)(); + +.................. +/* +later and/or somewhere else in the code you may want to call function "mymodule_f2" +You can use the loader get_shlibmodule_fptr(char *modname, char *fname) function +to retrieve the pointer to that function +*/ +funcf2_t *f2; +int ret; +int intarg1; +char *strarg; +........................ +f2 = (funcf2_t)get_shlibmodule_fptr("mymodule", "mymodule_f2") +if (f2 != NULL) { + ret = f2(intarg1,strarg); +} +............... +``` +When loading a shared library the loader looks for a symbol named `< module name > _autoinit` and, if it finds it, calls it. The `autoinit` function is called without any argument and the returned value, if any, is not tested. + +[loader home page](loader) +[loader developer home page](loader/devusage) \ No newline at end of file diff --git a/common/utils/DOC/loader/devusage/struct.md b/common/utils/DOC/loader/devusage/struct.md new file mode 100644 index 0000000000..b771f136d7 --- /dev/null +++ b/common/utils/DOC/loader/devusage/struct.md @@ -0,0 +1,10 @@ +# `loader_shlibfunc_t`structure +It is defined in include file [ common/util/load_module_shlib.h ](https://gitlab.eurecom.fr/oai/openairinterface5g/blob/develop/common/utils/load_module_shlib.h#L38). This structure is used to list the symbols that should be searched by the loader when calling the `load_module_shlib` function. + +| Fields | Description | I/O | +|:-----------|:------------------------------------------------------------------|----:| +| `fname` | symbol name, is passed to the [`dlsym`](http://man7.org/linux/man-pages/man3/dlsym.3.html) system call performed by the loader to get a pointer to the symbol | I | +| `fptr` | pointer to the symbol name, set by the loader. `fptr` is defined as a `int (*fptr)(void)` function type | O | + +[loader home page](loader) +[loader developer home page](loader/devusage) \ No newline at end of file diff --git a/common/utils/DOC/loader/rtusage.md b/common/utils/DOC/loader/rtusage.md new file mode 100644 index 0000000000..cdd2883153 --- /dev/null +++ b/common/utils/DOC/loader/rtusage.md @@ -0,0 +1,50 @@ +## shared library names +Shared library full names are built by the loader using the format: +> < *path* >/lib< *module name* >< *module version* >.so + +1. the < *module name* > is defined at development time, it comes from the `modname` argument of the `load_module_shlib` call. +1. the < *module version* > and < *path* > optional parameters, are defined at run-time, depending on the configuration. + +## loader parameters +The loader is using the [configuration module](config), and defines global and per library parameters. Global parameters must be specified under the **loader** section and library specific parameters under a **loader.<*module name*>** section. Module specific parameters override the global parameters. +### Global loader parameters +| name | type | default | description | +|:---:|:---:|:---:|:----| +| `shlibpath` | `string of char` | `""` | directory path used to look for shared libraries, may be superseded by the library specific `shlibpath`.| +| `maxshlibs` | `integer` | 10 | Maximum number of shared libraries the loader can manage. | + +### library specific loader parameters +| name | type | default | description | +|:---:|:---:|:---:|:----| +| `shlibpath` | `string of char` | `""` | directory path used to look for this shared library.| +| `shlibversion` | `string of char` | `""` | version to be used to load this shared library.| + +### loader configuration examples + +The following configuration file example just reproduce the default loader parameters: +```c +loader : +{ + shlibpath = "./"; + maxshlibs = 10; + liboai_device : + { + shlibpath = "./"; + shlibversion = ""; + } +}; +``` +If you want to load a device called *liboai_device_USRP.so* without writting a specific configuration, you can start the softmodem using the following command: +> ./lte-softmodem -O libconfig:/usr/local/oai/openairinterface5g/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.nbiot.band7.tm1.50PRB.usrpb210.conf:dbgl5 --loader.oai_device.shlibversion _USRP + +With this latest example, nn the softmodem logs, you can check that the right device library has been loaded: +```bash +[LIBCONFIG] loader.oai_device.shlibpath not found in /usr/local/oai/develop-nb-iot-merge/openairinterface5g/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.nbiot.band7.tm1.50PRB.usrpb210.conf +[LIBCONFIG] loader.oai_device.shlibversion set to default value "" +[LIBCONFIG] loader.oai_device: 1/2 parameters successfully set, (1 to default value) +[CONFIG] shlibversion set to _USRP from command line +[CONFIG] loader.oai_device 1 options set from command line + +``` + +[loader home page](loader) \ No newline at end of file diff --git a/common/utils/telnetsrv/DOC/telnetaddcmd.md b/common/utils/telnetsrv/DOC/telnetaddcmd.md new file mode 100644 index 0000000000..9d23b6917f --- /dev/null +++ b/common/utils/telnetsrv/DOC/telnetaddcmd.md @@ -0,0 +1,116 @@ +# code example of adding a command to the telnet server + +The following example is extracted from [the oai `openair1/PHY/CODING/coding_load.c` file](https://gitlab.eurecom.fr/oai/openairinterface5g/blob/develop/openair1/PHY/CODING/coding_load.c). + +```c +/* +include the telnet server data structures and API definitions +*/ +#include "common/utils/telnetsrv/telnetsrv.h" + + +/* +define the null terminated array of telnetshell_cmddef_t structures +which map each sub-command string to a function implementing it. +you may also provide a help string which will be printed when +the global help command is used. The prototype for the function +implementing sub commands must match the `cmdfunc_t` type defined +in `telnetsrv.h` +*/ +static int coding_setmod_cmd(char *buff, int debug, telnet_printfunc_t prnt); +static telnetshell_cmddef_t coding_cmdarray[] = { + {"mode","[sse,avx2,stdc,none]",coding_setmod_cmd}, + {"","",NULL}, +}; + +/* +define the null terminated list of telnetshell_vardef_t structures defining the +variables that can be set and get using the pre-defined get and set command +of the telnet server +*/ +telnetshell_vardef_t coding_vardef[] = { +{"maxiter",TELNET_VARTYPE_INT32,&max_turbo_iterations}, +{"",0,NULL} +}; +................. +/* + look for telnet server, if it is loaded, add the coding commands to it + we use the shared library loader API to check the telnet server availibility +The telnet server TELNET_ADDCMD_FNAME function takes three arguments: +1. The name of the telnet command to be added, here "coding" +1. The `coding_cmdarray` list of "coding" sub-commands we defined earlier +1. The `coding_varde f`list of variables we defined earlier +*/ + add_telnetcmd_func_t addcmd = (add_telnetcmd_func_t)get_shlibmodule_fptr("telnetsrv", TELNET_ADDCMD_FNAME); + if (addcmd != NULL) { + addcmd("coding",coding_vardef,coding_cmdarray); +....... +/* + functions implementing the "coding mode" sub command, as defined in + the `coding_cmdarray` passed earlier to the TELNET_ADDCMD_FNAME function. + This function will be called by the telnet server, when the `coding_cmdarray` + command is received from the telnet client +*/ +int coding_setmod_cmd(char *buff, int debug, telnet_printfunc_t prnt) +{ + /* + 1. buff argument is an input argument, pointer to the string received + from the telnet client, the command and sub-command parts are removed + In this case it points after "coding setmod" and is of no use as + we don't have second level sub-commands. + 1. debug argument is an input argument set by the telnet server + 1. prnt arguments is also an input argument, a function pointer, to be used + in place of printf to print messages on the telnet client interface. As this function + is called by the telnet server stdout points to the main executable console, + */ + if (debug > 0) + prnt( "coding_setmod_cmd received %s\n",buff); + + if (strcasestr(buff,"sse") != NULL) { + decoding_setmode(MODE_DECODE_SSE); + } else if (strcasestr(buff,"avx2") != NULL) { + decoding_setmode(MODE_DECODE_AVX2); + } else if (strcasestr(buff,"stdc") != NULL) { + decoding_setmode(MODE_DECODE_C); + } else if (strcasestr(buff,"none") != NULL) { + decoding_setmode(MODE_DECODE_NONE); + } else { + prnt("%s: wrong setmod parameter...\n",buff); + } + prnt("Coding and decoding current mode: %s\n",modedesc[curmode]); + return 0; +} + +.............. + +``` +# telnet server API + +```c +int add_telnetcmd(char *modulename, telnetshell_vardef_t *var, telnetshell_cmddef_t *cmd) +``` +Add a command and the `cmd` list of sub-commands to the telnet server. After a successful call to `add_telnetcmd` function, the telnet server calls the function defined for each sub-commands in the null terminated `cmd` array, when the character string received from the telnet client matches the command and sub-command strings. +Also adds the list of variables described in the `var` array to the list of variable which can be set and read. +The function returns -1 if one argument is NULL. +The telnet server is dynamically loaded, to use the `add_telnetcmd` function, the shared library loader API should be used to check the availability of the telnet server and retrieve it's address, as shown in [the example at the top of this page](telnetaddcmd#code-example-of-adding-a-command-to-the-telnet-server). + +# telnet server public data types +## `telnetshell_vardef_t`structure + This structure is used by developers to describe the variables that can be set or read using the get,set and getall sub-commands. + +| Fields | type |Description | +|:-----------|:------:|:-----------------------| +| `varname` | `char[TELNET_CMD_MAXSIZE]` | variable name, as specified when using the get and set commands. | +| `vartype` | `char` | Defines the type of the variable pointed by the `varvalptr`field. Supported values: TELNET_VARTYPE_INT32 TELNET_VARTYPE_INT16 TELNET_VARTYPE_INT64 TELNET_VARTYPE_STRING TELNET_VARTYPE_DOUBLE | +| `varvalptr` | `void*` | Defines the type of the variable pointed by the `varvalptr`field | + +## `telnetshell_cmddef_t`structure + This structure is used by developers to describe the first level sub-commands to be added to the telnet server. + +| Fields | type |Description | +|:-----------|:------:|:-----------------------| +| `cmdname` | `char[TELNET_CMD_MAXSIZE]` | command name, as tested by the telnet server to check it should call the `cmdfunc` function | +| `helpstr` | `char[TELNET_HELPSTR_SIZE]` | character string to print when the elp`command is received from the telnet client | +| `cmdfunc` | `cmdfunc_t` | pointer to the function implementing the `cmdname` sub command. | + +[oai telnet server home](telnetsrv) \ No newline at end of file diff --git a/common/utils/telnetsrv/DOC/telnetarch.md b/common/utils/telnetsrv/DOC/telnetarch.md new file mode 100644 index 0000000000..579a7de967 --- /dev/null +++ b/common/utils/telnetsrv/DOC/telnetarch.md @@ -0,0 +1,21 @@ +# telnet server principles + +The oai telnet server is implemented in a shared library to be loaded by the [oai shared library loader](loader). The implementation includes a `telnetsrv_autoinit` function which is automatically called at load time, starts the telnet server and registers a first set of commands, which are delivered with the server (telnet, softmodem, loader). + +Currently the telnet server only supports one user connection. The same dedicated thread is used to wait for a user connection and process the input received from this connection. + +The telnet server provides an API which can be used by any oai component to add new CLI commands to the server. A pre-defined command can be used to get or set a list of variables. + + + +# telnet server source files + +telnet server source files are located in [common/utils/telnetsrv](https://gitlab.eurecom.fr/oai/openairinterface5g/tree/develop/common/utils/telnetsrv) + +1. [telnetsrv.c](https://gitlab.eurecom.fr/oai/openairinterface5g/tree/develop/common/utils/telnetsrv/telnetsrv.c) contains the telnet server implementation, including the implementation of the telnet CLI command. +1. [telnetsrv.h](https://gitlab.eurecom.fr/oai/openairinterface5g/tree/develop/common/utils/telnetsrv/telnetsrv.h) is the telnet server include file containing both private and public data type definitions. It also contains API prototypes for functions that are used to register a new command in the server. +1. `telnetsrv\_\.c`: implementation of \ CLI command which are delivered with the telnet server. +1. `telnetsrv\_\.h`: include file for the implementation of XXX CLI command. Usually included only in the corresponding `.c`file +1. [telnetsrv_CMakeLists.txt](https://gitlab.eurecom.fr/oai/openairinterface5g/blob/develop/common/utils/telnetsrv/telnetsrv_CMakeLists.txt): CMakelists file containing the cmake instructions to build the telnet server. this file is included in the [global oai CMakelists](https://gitlab.eurecom.fr/oai/openairinterface5g/blob/develop/cmake_targets/CMakeLists.txt). + +[oai telnet server home](telnetsrv) \ No newline at end of file diff --git a/common/utils/telnetsrv/DOC/telnetgetset.md b/common/utils/telnetsrv/DOC/telnetgetset.md new file mode 100644 index 0000000000..ccf774a752 --- /dev/null +++ b/common/utils/telnetsrv/DOC/telnetgetset.md @@ -0,0 +1,21 @@ +getall command can be used to get the list of variables that can bet set or get from the telnet shell. Knowing the names of the variables they can then be set or read. Setting a variable is not always relevant, the telnet server doesn't provide a mechanism to restrict the set command. + +```bash +softmodem> telnet getall +telnet, debug = 0 +telnet, prio = 0 +telnet, loopc = 10 +telnet, loopd = 5000 +telnet, phypb = 65000 +telnet, hsize = 50 +telnet, hfile = "oaitelnet.history" +softmodem> telnet set loopc 100 +telnet, loopc set to +100 +softmodem> telnet get loopc +telnet, loopc = 100 +softmodem> + +``` +[oai telnetserver home](telnetsrv) +[oai telnetserver usage home](telnetusage) \ No newline at end of file diff --git a/common/utils/telnetsrv/DOC/telnethelp.md b/common/utils/telnetsrv/DOC/telnethelp.md new file mode 100644 index 0000000000..ef614cae1c --- /dev/null +++ b/common/utils/telnetsrv/DOC/telnethelp.md @@ -0,0 +1,57 @@ +# oai telnet server global help + +``` bash +alblf@at8020-a:~$ telnet 10.133.10.77 9090 +Trying 10.133.10.77... +Connected to 10.133.10.77. +Escape character is '^]'. + +softmodem> help + module 0 = telnet: + telnet [get set] debug + telnet [get set] prio + telnet [get set] loopc + telnet [get set] loopd + telnet [get set] phypb + telnet [get set] hsize + telnet [get set] hfile + telnet redirlog [here,file,off] + telnet param [prio] + telnet history [list,reset] + module 1 = softmodem: + softmodem show loglvl|thread|config + softmodem log (enter help for details) + softmodem thread (enter help for details) + softmodem exit + module 2 = phy: + phy disp [phycnt,uedump,uestat UE] + module 3 = loader: + loader [get set] mainversion + loader [get set] defpath + loader [get set] maxshlibs + loader [get set] numshlibs + loader show [params,modules] + module 4 = coding: + coding [get set] maxiter + coding mode [sse,avx2,stdc,none] +softmodem> +``` + +# oai telnet server, specific commands help + +``` bash +softmodem> softmodem log help + log sub commands: + show: display current log configuration + online, noonline: enable or disable console logs + enable, disable id1-id2: enable or disable logs for components index id1 to id2 + level_ id1-id2: set log level to for components index id1 to id2 + level_ id1-id2: set log verbosity to for components index id1 to id2 +use the show command to get the values for , and the list of component indexes that can be used for id1 and id2 +softmodem> + + +``` + +[oai telnetserver home](telnetsrv) +[oai telnetserver usage home](telnetusage) \ No newline at end of file diff --git a/common/utils/telnetsrv/DOC/telnethist.md b/common/utils/telnetsrv/DOC/telnethist.md new file mode 100644 index 0000000000..10682b8a85 --- /dev/null +++ b/common/utils/telnetsrv/DOC/telnethist.md @@ -0,0 +1,44 @@ +The telnet server implements a simple history system +```bash +softmodem> telnet history list +1: telnet history list +2: telnet history list +3: help +4: loader show modules +5: softmodem show loglvl +6: help +7: telnet history +8: help +9: telnet history list +10: help +11: loader show modules +12: softmodem show loglvl +13: softmodem log help +14: softmodem log disable 0-35 +15: softmodem log show +16: help +17: telnet history list +18: loader show modules +19: softmodem thread show +20: help +21: softmodem thread help +22: softmodem log show +23: softmodem log help +24: softmodem log level_error 0-4 +25: loader show modules +26: loader show config +27: help +28: loader show params +29: loader show modules +softmodem> !28 +softmodem> loader show params +loader parameters: + Main executable build version: "Branch: develop-telnet-loader-fixes Abrev. Hash: e56ae69 Date: Fri Mar 9 16:47:08 2018 +0100" + Default shared lib path: "" + Max number of shared lib : 10 +softmodem> + +``` + +[oai telnetserver home](telnetsrv) +[oai telnetserver usage home](telnetusage) \ No newline at end of file diff --git a/common/utils/telnetsrv/DOC/telnetloader.md b/common/utils/telnetsrv/DOC/telnetloader.md new file mode 100644 index 0000000000..d64f0c6cdb --- /dev/null +++ b/common/utils/telnetsrv/DOC/telnetloader.md @@ -0,0 +1,47 @@ +loader command can be used to check loader configuration parameters and the list of loaded shared libraries and for each library the list of available functions. + +```bash +softmodem> loader show params +loader parameters: + Main executable build version: "Branch: develop-telnet-loader-fixes Abrev. Hash: e56ae69 Date: Fri Mar 9 16:47:08 2018 +0100" + Default shared lib path: "" + Max number of shared lib : 10 +softmodem> loader show modules +4 shared lib have been dynamicaly loaded by the oai loader + Module 0: telnetsrv + Shared library build version: "Branch: develop-telnet-loader-fixes Abrev. Hash: e56ae69 Date: Fri Mar 9 16:47:08 2018 +0100" + Shared library path: "libtelnetsrv.so" + 1 function pointers registered: + function 0 add_telnetcmd at 0x7ff8b772a2b0 + Module 1: NB_IoT + Shared library build version: "" + Shared library path: "libNB_IoT.so" + 1 function pointers registered: + function 0 RCConfig_NbIoT at 0x7ff8b6b1b390 + Module 2: coding + Shared library build version: "Branch: develop-telnet-loader-fixes Abrev. Hash: e56ae69 Date: Fri Mar 9 16:47:08 2018 +0100" + Shared library path: "libcoding.so" + 13 function pointers registered: + function 0 init_td8 at 0x7ff8adde63a0 + function 1 init_td16 at 0x7ff8adde9760 + function 2 init_td16avx2 at 0x7ff8addec050 + function 3 phy_threegpplte_turbo_decoder8 at 0x7ff8adde6780 + function 4 phy_threegpplte_turbo_decoder16 at 0x7ff8adde9a90 + function 5 phy_threegpplte_turbo_decoder_scalar at 0x7ff8addef4a0 + function 6 phy_threegpplte_turbo_decoder16avx2 at 0x7ff8addec530 + function 7 free_td8 at 0x7ff8adde61d0 + function 8 free_td16 at 0x7ff8adde9590 + function 9 free_td16avx2 at 0x7ff8addebe80 + function 10 threegpplte_turbo_encoder_sse at 0x7ff8adde45b0 + function 11 threegpplte_turbo_encoder at 0x7ff8adde4a30 + function 12 init_encoder_sse at 0x7ff8adde49d0 + Module 3: oai_device + Shared library build version: "" + Shared library path: "liboai_device_usrp.so" + 1 function pointers registered: + function 0 device_init at 0x7ff8ac16a7a0 +softmodem> +``` + +[oai telnetserver home](telnetsrv) +[oai telnetserver usage home](telnetusage) \ No newline at end of file diff --git a/common/utils/telnetsrv/DOC/telnetlog.md b/common/utils/telnetsrv/DOC/telnetlog.md new file mode 100644 index 0000000000..00f09a3a6f --- /dev/null +++ b/common/utils/telnetsrv/DOC/telnetlog.md @@ -0,0 +1,95 @@ +The log command can be used to get the status of the log parameters and to dynamically modify these parameters. The log command has its own [help](telnethelp#oai-telnet-server-specific-commands-help) +```bash +softmodem> softmodem log disable 0-35 +log level/verbosity comp 0 PHY set to info / medium (disabled) +log level/verbosity comp 1 MAC set to info / medium (disabled) +log level/verbosity comp 2 EMU set to info / medium (disabled) +log level/verbosity comp 3 OCG set to info / medium (disabled) +log level/verbosity comp 4 OMG set to info / medium (disabled) +log level/verbosity comp 5 OPT set to info / medium (disabled) +log level/verbosity comp 6 OTG set to info / medium (disabled) +log level/verbosity comp 7 OTG_LATENCY set to info / medium (disabled) +log level/verbosity comp 8 OTG_LATENCY_BG set to info / medium (disabled) +log level/verbosity comp 9 OTG_GP set to info / medium (disabled) +log level/verbosity comp 10 OTG_GP_BG set to info / medium (disabled) +log level/verbosity comp 11 OTG_JITTER set to info / medium (disabled) +log level/verbosity comp 12 RLC set to info / medium (disabled) +log level/verbosity comp 13 PDCP set to info / medium (disabled) +log level/verbosity comp 14 RRC set to info / medium (disabled) +log level/verbosity comp 15 NAS set to info / medium (disabled) +log level/verbosity comp 16 PERF set to info / medium (disabled) +log level/verbosity comp 17 OIP set to info / medium (disabled) +log level/verbosity comp 18 CLI set to info / medium (disabled) +log level/verbosity comp 19 MSC set to info / medium (disabled) +log level/verbosity comp 20 OCM set to info / medium (disabled) +log level/verbosity comp 21 UDP set to info / medium (disabled) +log level/verbosity comp 22 GTPV1U set to info / medium (disabled) +log level/verbosity comp 23 comp23? set to info / medium (disabled) +log level/verbosity comp 24 S1AP set to info / medium (disabled) +log level/verbosity comp 25 SCTP set to info / medium (disabled) +log level/verbosity comp 26 HW set to info / medium (disabled) +log level/verbosity comp 27 OSA set to info / medium (disabled) +log level/verbosity comp 28 eRAL set to info / medium (disabled) +log level/verbosity comp 29 mRAL set to info / medium (disabled) +log level/verbosity comp 30 ENB_APP set to info / medium (disabled) +log level/verbosity comp 31 FLEXRAN_AGENT set to info / medium (disabled) +log level/verbosity comp 32 TMR set to info / medium (disabled) +log level/verbosity comp 33 USIM set to info / medium (disabled) +log level/verbosity comp 34 LOCALIZE set to info / medium (disabled) +log level/verbosity comp 35 RRH set to info / medium (disabled) +softmodem> softmodem log show +Available log levels: + emerg alert crit error warn notice info debug file trace +Available verbosity: + none low medium high full +component verbosity level enabled +00 PHY: medium info N +01 MAC: medium info N +02 EMU: medium info N +03 OCG: medium info N +04 OMG: medium info N +05 OPT: medium info N +06 OTG: medium info N +07 OTG_LATENCY: medium info N +08 OTG_LATENCY_BG: medium info N +09 OTG_GP: medium info N +10 OTG_GP_BG: medium info N +11 OTG_JITTER: medium info N +12 RLC: medium info N +13 PDCP: medium info N +14 RRC: medium info N +15 NAS: medium info N +16 PERF: medium info N +17 OIP: medium info N +18 CLI: medium info N +19 MSC: medium info N +20 OCM: medium info N +21 UDP: medium info N +22 GTPV1U: medium info N +23 comp23?: medium info N +24 S1AP: medium info N +25 SCTP: medium info N +26 HW: medium info N +27 OSA: medium info N +28 eRAL: medium info N +29 mRAL: medium info N +30 ENB_APP: medium info N +31 FLEXRAN_AGENT: medium info N +32 TMR: medium info N +33 USIM: medium info N +34 LOCALIZE: medium info N +35 RRH: medium info N +36 comp36?: medium info Y +37 LOADER: medium alert Y +softmodem> softmodem log level_error 0-4 +log level/verbosity comp 0 PHY set to error / medium (enabled) +log level/verbosity comp 1 MAC set to error / medium (enabled) +log level/verbosity comp 2 EMU set to error / medium (enabled) +log level/verbosity comp 3 OCG set to error / medium (enabled) +log level/verbosity comp 4 OMG set to error / medium (enabled) +softmodem> exit +Connection closed by foreign host. +``` + +[oai telnetserver home](telnetsrv) +[oai telnetserver usage home](telnetusage) \ No newline at end of file diff --git a/common/utils/telnetsrv/DOC/telnetloop.md b/common/utils/telnetsrv/DOC/telnetloop.md new file mode 100644 index 0000000000..437481da68 --- /dev/null +++ b/common/utils/telnetsrv/DOC/telnetloop.md @@ -0,0 +1,40 @@ +The telnet server includes a **_loop_** command that can be used to iterate a given command. The number of iterations and the delay, in ms between two iterations can be modified, as shown in the following example: + +```bash +softmodem> telnet get loopc +telnet, loopc = 10 +softmodem> telnet get loopd +telnet, loopd = 2000 +softmodem> telnet set loopd 1000 +telnet, loopd set to +1000 +softmodem> loop softmodem show thread + 2018-03-27 17:58:49.000 2/10 + id name state USRmod KRNmod prio nice vsize proc pol + + 3946 lte-softmodem S 20005 9440 20 0 236560384 2 0 other + + 3946 lte-softmodem S 7 95 20 0 236560384 2 0 other + 3948 telnet R 0 0 20 0 236560384 2 0 other + 3949 ITTI acceptor S 2 9 20 0 236560384 2 0 other + 3951 ITTI 12 S 2 2 20 0 236560384 7 0 other + 3952 ITTI 11 S 0 0 20 0 236560384 0 0 other + 3953 ITTI 9 S 0 0 20 0 236560384 1 0 other + 3954 ITTI 7 S 0 0 20 0 236560384 7 0 other + 3955 ITTI 8 S 0 0 20 0 236560384 7 0 other + 3956 ITTI 4 S 35 0 20 0 236560384 2 0 other + 3957 ru_thread S 15366 3072 -10 0 236560384 0 2 rt: rr + 3958 ru_thread_prach S 0 0 -10 0 236560384 7 1 rt: fifo + 3959 fep_thread S 1874 123 -10 0 236560384 5 1 rt: fifo + 3960 feptx_thread S 1554 101 -10 0 236560384 7 1 rt: fifo + 3969 ru_thread S 0 0 -10 0 236560384 0 2 rt: rr + 3970 ru_thread S 1313 5522 -10 0 236560384 5 2 rt: rr + 3971 ru_thread S 4 6 -10 0 236560384 1 2 rt: rr + 3972 lte-softmodem S 318 9 -10 0 236560384 7 1 rt: fifo + 3973 lte-softmodem S 6 13 -10 0 236560384 4 1 rt: fifo + +``` +A **_loop_** command can be interrupted by pressing the **_enter_** key till getting the prompt. + +[oai telnetserver home](telnetsrv) +[oai telnetserver usage home](telnetusage) \ No newline at end of file diff --git a/common/utils/telnetsrv/DOC/telnetsrv.md b/common/utils/telnetsrv/DOC/telnetsrv.md new file mode 100644 index 0000000000..c621e7f6e5 --- /dev/null +++ b/common/utils/telnetsrv/DOC/telnetsrv.md @@ -0,0 +1,7 @@ +The oai embedded telnet server is an optional monitoring and debugging tool. It provides a simple Command Line Interface to the oai softmem. New commands can easily be added by developers to the telnet server. + +* [Using the telnet server](telnetusage) +* [Adding commands to the oai telnet server](telnetaddcmd) +* [telnet server architecture ](telnetarch) + +[oai Wikis home](home) \ No newline at end of file diff --git a/common/utils/telnetsrv/DOC/telnetusage.md b/common/utils/telnetsrv/DOC/telnetusage.md new file mode 100644 index 0000000000..2b5aaf405f --- /dev/null +++ b/common/utils/telnetsrv/DOC/telnetusage.md @@ -0,0 +1,39 @@ +# starting the softmodem with the telnet server +By default the embedded telnet server, which is implemented in a shared library, is not built. It can be built after compiling the softmodem executable using the `build_oai` script: + +```bash + cd \/openairinterface5g + source oaienv + cd cmake_targets + ./build_oai --build-telnetsrv +``` + +This will create the `libtelnetsrv.so` file in the `targets/bin` and `cmake_targets/lte_build_oai/build` sub directories of the oai repository. + +When starting the softmodem, you must specify the **_\-\-telnetsrv_** option to load and start the telnet server. The telnet server is loaded via the [oai shared library loader](loader). + +# using the Command Line Interface +By default the telnet server listen on all the ip addresses configured on the system and on port 9090. This behavior can be changed using the `listenaddr` and `listenport` parameters. +The telnet server includes a basic help, listing available commands and some commands also provide a specific detailed help sub-command. +Below are examples of telnet sessions: + +* [getting help](telnethelp) +* [using the history](telnethist) +* [using the get and set commands](telnetgetset) +* [using the loop command](telnetloop) +* [loader command](telnetloader) +* [log command](telnetlog) + +# telnet server parameters +The telnet server is using the [oai configuration module](Config/Rtusage). Telnet parameters must be specified in the `telnetsrv` section. Some parameters can be modified via the telnet telnet server command, as specified in the last column of the following table. + +| name | type | default | description | dynamic | +|:---:|:---:|:---:|:----|:----:| +| `listenaddr` | `ipV4 address, ascii format` | "0.0.0.0" | local address the server is listening on| N | +| `listenport` | `integer` | 9090 | port number the server is listening on | N | +| `loopcount` | `integer` | 10 | number of iterations for the loop command | Y | +| `loopdelay` | `integer` | 5000 | delay (in ms) between 2 loop command iterations | Y | +| `histfile` | `character string` | "oaitelnet.history" | file used for command history persistency | Y | +| `histfsize` | `integer` | 50 | maximum number of commands saved in the history | Y | + +[oai telnet server home](telnetsrv) \ No newline at end of file From c570ad63fe61e563d0d75735a820ebdd40600ff4 Mon Sep 17 00:00:00 2001 From: Francois TABURET Date: Thu, 8 Nov 2018 19:21:33 +0100 Subject: [PATCH 108/233] fix config DOC broken links --- common/config/DOC/config.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/common/config/DOC/config.md b/common/config/DOC/config.md index 682780cd3b..580ac5476f 100644 --- a/common/config/DOC/config.md +++ b/common/config/DOC/config.md @@ -4,8 +4,8 @@ The configuration module provides an api that other oai components can use to ge ## Documentation -* [runtime usage](config/rtusage) -* [developer usage](config/devusage) -* [module architecture](config/arch) +* [runtime usage](config/rtusage.md) +* [developer usage](config/devusage.md) +* [module architecture](config/arch.md) [oai Wikis home](https://gitlab.eurecom.fr/oai/openairinterface5g/wikis/home) From 7df76dfbfc31c2cdc420a9b4808a3fb0f8a3b988 Mon Sep 17 00:00:00 2001 From: Francois TABURET Date: Thu, 8 Nov 2018 19:24:01 +0100 Subject: [PATCH 109/233] fix config doc broken link --- common/config/DOC/config/rtusage.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/config/DOC/config/rtusage.md b/common/config/DOC/config/rtusage.md index 828f6a959d..ba362d011e 100644 --- a/common/config/DOC/config/rtusage.md +++ b/common/config/DOC/config/rtusage.md @@ -49,4 +49,4 @@ $ ./lte-softmodem -O --eNBs.[0].component_carriers.[0].N_RB_DL 100 As specified earlier, use the dbgl1 debug level to get the full name of a parameter you would like to modify on the command line. -[Configuration module home](config) \ No newline at end of file +[Configuration module home](../config) \ No newline at end of file From 736febd06470a20f31aacfcc584ec6109b494fca Mon Sep 17 00:00:00 2001 From: Francois TABURET Date: Thu, 8 Nov 2018 19:26:24 +0100 Subject: [PATCH 110/233] fix broken link --- common/config/DOC/config/rtusage.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/config/DOC/config/rtusage.md b/common/config/DOC/config/rtusage.md index ba362d011e..19519ef058 100644 --- a/common/config/DOC/config/rtusage.md +++ b/common/config/DOC/config/rtusage.md @@ -49,4 +49,4 @@ $ ./lte-softmodem -O --eNBs.[0].component_carriers.[0].N_RB_DL 100 As specified earlier, use the dbgl1 debug level to get the full name of a parameter you would like to modify on the command line. -[Configuration module home](../config) \ No newline at end of file +[Configuration module home](../config.md) \ No newline at end of file From 65fd02b1b6ac3a7f93c2da56e8ce10846f091284 Mon Sep 17 00:00:00 2001 From: Francois TABURET Date: Thu, 8 Nov 2018 19:29:37 +0100 Subject: [PATCH 111/233] fix config doc broken links --- common/config/DOC/config/devusage.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/common/config/DOC/config/devusage.md b/common/config/DOC/config/devusage.md index 88abc96f42..9e4c7013e7 100644 --- a/common/config/DOC/config/devusage.md +++ b/common/config/DOC/config/devusage.md @@ -5,10 +5,10 @@ The configuration module objectives are As a developer you may need to look at these sections: -* [add parameters in an existing section](config/devusage/addaparam) -* [add a parameter set, in a new section](config/devusage/addparamset) -* [configuration module API](config/devusage/api) -* [configuration module public structures](config/devusage/struct) +* [add parameters in an existing section](devusage/addaparam) +* [add a parameter set, in a new section](devusage/addparamset) +* [configuration module API](devusage/api) +* [configuration module public structures](devusage/struct) Whatever your need is, configuration module usage examples can be found in oai sources: * complex example, using all the configuration module functionalities, including parameter checking: @@ -17,4 +17,4 @@ Whatever your need is, configuration module usage examples can be found in oai s * an example with run-time definition of parameters, in the logging sub-system: the log_getconfig function at the top of [openair2/UTIL/LOG/log.c](https://gitlab.eurecom.fr/oai/openairinterface5g/blob/develop/openair2/UTIL/LOG/log.c) -[Configuration module home](config) +[Configuration module home](../config.md) From ef2088166422845077107a18df5d0ff331a02035 Mon Sep 17 00:00:00 2001 From: Francois TABURET Date: Thu, 8 Nov 2018 19:32:32 +0100 Subject: [PATCH 112/233] fix config doc broken links --- common/config/DOC/config/devusage.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/common/config/DOC/config/devusage.md b/common/config/DOC/config/devusage.md index 9e4c7013e7..bfc1180ab8 100644 --- a/common/config/DOC/config/devusage.md +++ b/common/config/DOC/config/devusage.md @@ -5,10 +5,10 @@ The configuration module objectives are As a developer you may need to look at these sections: -* [add parameters in an existing section](devusage/addaparam) -* [add a parameter set, in a new section](devusage/addparamset) -* [configuration module API](devusage/api) -* [configuration module public structures](devusage/struct) +* [add parameters in an existing section](devusage/addaparam.md) +* [add a parameter set, in a new section](devusage/addparamset.md) +* [configuration module API](devusage/api.md) +* [configuration module public structures](devusage/struct.md) Whatever your need is, configuration module usage examples can be found in oai sources: * complex example, using all the configuration module functionalities, including parameter checking: From a149d1cbfd9e0451c6cf7886cb76e342c3de25d4 Mon Sep 17 00:00:00 2001 From: Francois TABURET Date: Thu, 8 Nov 2018 19:34:07 +0100 Subject: [PATCH 113/233] fix broken links in api.md --- common/config/DOC/config/devusage/api.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/common/config/DOC/config/devusage/api.md b/common/config/DOC/config/devusage/api.md index c9d562ced0..56b444a447 100644 --- a/common/config/DOC/config/devusage/api.md +++ b/common/config/DOC/config/devusage/api.md @@ -44,5 +44,5 @@ int config_libconfig_getlist(paramlist_def_t *ParamList, paramdef_t *params, int * The returned value is the number of occurrences in the list or -1 in case of severe error -[Configuration module developer main page](config/devusage) -[Configuration module home](config) +[Configuration module developer main page](../../config/devusage.md) +[Configuration module home](../../config.md) From a9de514b7cbff03b2531023ea5fbaad93f162d23 Mon Sep 17 00:00:00 2001 From: Francois TABURET Date: Thu, 8 Nov 2018 19:36:06 +0100 Subject: [PATCH 114/233] fix broken links in addaparam.md --- common/config/DOC/config/devusage/addaparam.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/common/config/DOC/config/devusage/addaparam.md b/common/config/DOC/config/devusage/addaparam.md index 28bd3ee142..b7bb8a73b9 100644 --- a/common/config/DOC/config/devusage/addaparam.md +++ b/common/config/DOC/config/devusage/addaparam.md @@ -82,5 +82,5 @@ for(int i=0 ; i < sizeof(someoptions)/sizeof(paramdesc_t) ; i ++) { ``` When you need a specific verification algorithm, you can provide your own verification function and use it in place of the available ones, in the `checkedparam_t` union. If no existing structure definition match your need, you can enhance the configuration module. You then have to add a new verification function in https://gitlab.eurecom.fr/oai/openairinterface5g/blob/develop/common/config/config_userapi.c and add a new structure definition in the `checkedparam_t` type defined in https://gitlab.eurecom.fr/oai/openairinterface5g/blob/develop/common/config/config_paramdesc.h -[Configuration module developer main page](config/devusage) -[Configuration module home](config) +[Configuration module developer main page](../../config/devusage.md) +[Configuration module home](../../config.md) From 59a690bb4b97082da233cb88a26412282827a98e Mon Sep 17 00:00:00 2001 From: Francois TABURET Date: Thu, 8 Nov 2018 19:38:38 +0100 Subject: [PATCH 115/233] fix broken link in addparamset.md --- common/config/DOC/config/devusage/addparamset.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/common/config/DOC/config/devusage/addparamset.md b/common/config/DOC/config/devusage/addparamset.md index 9b90fcc81f..130e7c690e 100644 --- a/common/config/DOC/config/devusage/addparamset.md +++ b/common/config/DOC/config/devusage/addparamset.md @@ -4,7 +4,7 @@ Retrieving a single occurence of a parameter set ( a group in the libconfig term 1. call the `config_get` function -[config_get example](https://gitlab.eurecom.fr/oai/openairinterface5g/wikis/config/devusage/addaparam) +[config_get example](../../config/devusage/addaparam.md) In oai some parameters set may be instantiated a variable number of occurrences. In a configuration file this is mapped to lists of group of parameters, with this syntax: @@ -127,5 +127,5 @@ list to be read is under another section. ``` -[Configuration module developer main page](config/devusage) -[Configuration module home](config) +[Configuration module developer main page](../../config/devusage.md) +[Configuration module home](../..config.md) From d4092a32f980a5429c5844231d5e15e3c1f5d088 Mon Sep 17 00:00:00 2001 From: Francois TABURET Date: Thu, 8 Nov 2018 19:40:17 +0100 Subject: [PATCH 116/233] fix typo.... --- common/config/DOC/config/devusage/addparamset.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/config/DOC/config/devusage/addparamset.md b/common/config/DOC/config/devusage/addparamset.md index 130e7c690e..130a7eda74 100644 --- a/common/config/DOC/config/devusage/addparamset.md +++ b/common/config/DOC/config/devusage/addparamset.md @@ -128,4 +128,4 @@ list to be read is under another section. ``` [Configuration module developer main page](../../config/devusage.md) -[Configuration module home](../..config.md) +[Configuration module home](../../config.md) From 95dc47cc0775c124375fe2fc8b58e4deab274e27 Mon Sep 17 00:00:00 2001 From: Francois TABURET Date: Thu, 8 Nov 2018 19:41:36 +0100 Subject: [PATCH 117/233] fix broken link in struct.md --- common/config/DOC/config/devusage/struct.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/common/config/DOC/config/devusage/struct.md b/common/config/DOC/config/devusage/struct.md index 17a9c36455..236c1b4e03 100644 --- a/common/config/DOC/config/devusage/struct.md +++ b/common/config/DOC/config/devusage/struct.md @@ -81,5 +81,5 @@ The configuration module provides an implementation of the functions to be used |:-----------|:------------------------------------------------------------------| | `f4` or `f5` | pointer to the checking function. they are generic structures to be used when no existing structure provides the required parameter verification. `f4` takes one argument, the `paramdef_t` structure corresponding to the parameter to be checked (`int (*f4)(paramdef_t *param)`), `f5` taxes no argument (`void (*checkfunc)(void)`) | -[Configuration module developer main page](config/devusage) -[Configuration module home](config) +[Configuration module developer main page](../../config/devusage.md) +[Configuration module home](../../config.md) From 337c068d220846ad2abbfa8b02e260fa2e9d4fec Mon Sep 17 00:00:00 2001 From: Francois TABURET Date: Thu, 8 Nov 2018 19:49:41 +0100 Subject: [PATCH 118/233] fix broken links in telnetsrv.md --- common/utils/telnetsrv/DOC/telnetsrv.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/common/utils/telnetsrv/DOC/telnetsrv.md b/common/utils/telnetsrv/DOC/telnetsrv.md index c621e7f6e5..ab89da3f85 100644 --- a/common/utils/telnetsrv/DOC/telnetsrv.md +++ b/common/utils/telnetsrv/DOC/telnetsrv.md @@ -1,7 +1,7 @@ The oai embedded telnet server is an optional monitoring and debugging tool. It provides a simple Command Line Interface to the oai softmem. New commands can easily be added by developers to the telnet server. -* [Using the telnet server](telnetusage) -* [Adding commands to the oai telnet server](telnetaddcmd) -* [telnet server architecture ](telnetarch) +* [Using the telnet server](telnetusage.md) +* [Adding commands to the oai telnet server](telnetaddcmd.md) +* [telnet server architecture ](telnetarch.md) [oai Wikis home](home) \ No newline at end of file From f08ef335b4166318aa90ed5b2e49aceedc5b6f7c Mon Sep 17 00:00:00 2001 From: Francois TABURET Date: Thu, 8 Nov 2018 19:51:27 +0100 Subject: [PATCH 119/233] fix broken links in telnetusage.md --- common/utils/telnetsrv/DOC/telnetusage.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/common/utils/telnetsrv/DOC/telnetusage.md b/common/utils/telnetsrv/DOC/telnetusage.md index 2b5aaf405f..f8319d5ef2 100644 --- a/common/utils/telnetsrv/DOC/telnetusage.md +++ b/common/utils/telnetsrv/DOC/telnetusage.md @@ -17,12 +17,12 @@ By default the telnet server listen on all the ip addresses configured on the sy The telnet server includes a basic help, listing available commands and some commands also provide a specific detailed help sub-command. Below are examples of telnet sessions: -* [getting help](telnethelp) -* [using the history](telnethist) -* [using the get and set commands](telnetgetset) -* [using the loop command](telnetloop) -* [loader command](telnetloader) -* [log command](telnetlog) +* [getting help](telnethelp.md) +* [using the history](telnethist.md) +* [using the get and set commands](telnetgetset.md) +* [using the loop command](telnetloop.md) +* [loader command](telnetloader.md) +* [log command](telnetlog.md) # telnet server parameters The telnet server is using the [oai configuration module](Config/Rtusage). Telnet parameters must be specified in the `telnetsrv` section. Some parameters can be modified via the telnet telnet server command, as specified in the last column of the following table. @@ -36,4 +36,4 @@ The telnet server is using the [oai configuration module](Config/Rtusage). Telne | `histfile` | `character string` | "oaitelnet.history" | file used for command history persistency | Y | | `histfsize` | `integer` | 50 | maximum number of commands saved in the history | Y | -[oai telnet server home](telnetsrv) \ No newline at end of file +[oai telnet server home](telnetsrv.md) \ No newline at end of file From 83dde269141a00c778be8146d111325642525325 Mon Sep 17 00:00:00 2001 From: frtabu Date: Thu, 8 Nov 2018 20:16:14 +0100 Subject: [PATCH 120/233] fix broken links --- common/utils/DOC/loader/arch.md | 2 +- common/utils/DOC/loader/devusage.md | 8 ++++---- common/utils/DOC/loader/devusage/api.md | 4 ++-- common/utils/DOC/loader/devusage/loading.md | 4 ++-- common/utils/DOC/loader/devusage/struct.md | 4 ++-- common/utils/DOC/loader/rtusage.md | 4 ++-- common/utils/telnetsrv/DOC/telnetaddcmd.md | 4 ++-- common/utils/telnetsrv/DOC/telnetarch.md | 2 +- common/utils/telnetsrv/DOC/telnetgetset.md | 4 ++-- common/utils/telnetsrv/DOC/telnethelp.md | 4 ++-- common/utils/telnetsrv/DOC/telnethist.md | 4 ++-- common/utils/telnetsrv/DOC/telnetloader.md | 4 ++-- common/utils/telnetsrv/DOC/telnetlog.md | 6 +++--- common/utils/telnetsrv/DOC/telnetloop.md | 4 ++-- common/utils/telnetsrv/DOC/telnetsrv.md | 2 +- 15 files changed, 30 insertions(+), 30 deletions(-) diff --git a/common/utils/DOC/loader/arch.md b/common/utils/DOC/loader/arch.md index 53a1cc7ea2..c37aedb4ef 100644 --- a/common/utils/DOC/loader/arch.md +++ b/common/utils/DOC/loader/arch.md @@ -4,4 +4,4 @@ The oai shared library loader is implemented in two source files, located in [co 1. [load_module_shlib.c](https://gitlab.eurecom.fr/oai/openairinterface5g/tree/develop/common/utils/load_module_shlib.c) contains the loader implementation 1. [load_module_shlib.h](https://gitlab.eurecom.fr/oai/openairinterface5g/tree/develop/common/utils/load_module_shlib.h) is the loader include file containing both private and public data type definitions. It also contain API prototypes. -[loader home page](loader) \ No newline at end of file +[loader home page](..loader.md) \ No newline at end of file diff --git a/common/utils/DOC/loader/devusage.md b/common/utils/DOC/loader/devusage.md index 89d15aa75e..4b82e18362 100644 --- a/common/utils/DOC/loader/devusage.md +++ b/common/utils/DOC/loader/devusage.md @@ -5,13 +5,13 @@ The configuration module objectives are As a developer you may need to look at these sections: -* [loading a shared library](loader/devusage/loading) -* [loader API](loader/devusage/api) -* [loader public structures](loader/devusage/struct) +* [loading a shared library](devusage/loading.md) +* [loader API](devusage/api.md) +* [loader public structures](devusage/struct.md) Loader usage examples can be found in oai sources: * device and transport initialization code: [function `load_lib` in *targets/ARCH/COMMON/__common_lib.c__* ](https://gitlab.eurecom.fr/oai/openairinterface5g/blob/develop/targets/ARCH/COMMON/common_lib.c#L91) * turbo encoder and decoder initialization: [function `load_codinglib`in *openair1/PHY/CODING/__coding_load.c__*](https://gitlab.eurecom.fr/oai/openairinterface5g/blob/develop/openair1/PHY/CODING/coding_load.c#L113) -[loader home page](loader) +[loader home page](../loader.md) diff --git a/common/utils/DOC/loader/devusage/api.md b/common/utils/DOC/loader/devusage/api.md index e01d69e9d4..eabfe677e9 100644 --- a/common/utils/DOC/loader/devusage/api.md +++ b/common/utils/DOC/loader/devusage/api.md @@ -16,5 +16,5 @@ void * get_shlibmodule_fptr(char *modname, char *fname) ``` Returns a pointer to the symbol `fname`, defined in module `modname`, or `NULL` if the symbol is not found. -[loader home page](loader) -[loader developer home page](loader/devusage) \ No newline at end of file +[loader home page](../loader.md) +[loader developer home page](../devusage.md) \ No newline at end of file diff --git a/common/utils/DOC/loader/devusage/loading.md b/common/utils/DOC/loader/devusage/loading.md index e544830c03..766bf85462 100644 --- a/common/utils/DOC/loader/devusage/loading.md +++ b/common/utils/DOC/loader/devusage/loading.md @@ -52,5 +52,5 @@ if (f2 != NULL) { ``` When loading a shared library the loader looks for a symbol named `< module name > _autoinit` and, if it finds it, calls it. The `autoinit` function is called without any argument and the returned value, if any, is not tested. -[loader home page](loader) -[loader developer home page](loader/devusage) \ No newline at end of file +[loader home page](../loader.md) +[loader developer home page](../../loader/devusage.md) \ No newline at end of file diff --git a/common/utils/DOC/loader/devusage/struct.md b/common/utils/DOC/loader/devusage/struct.md index b771f136d7..e3cfc74993 100644 --- a/common/utils/DOC/loader/devusage/struct.md +++ b/common/utils/DOC/loader/devusage/struct.md @@ -6,5 +6,5 @@ It is defined in include file [ common/util/load_module_shlib.h ](https://gitlab | `fname` | symbol name, is passed to the [`dlsym`](http://man7.org/linux/man-pages/man3/dlsym.3.html) system call performed by the loader to get a pointer to the symbol | I | | `fptr` | pointer to the symbol name, set by the loader. `fptr` is defined as a `int (*fptr)(void)` function type | O | -[loader home page](loader) -[loader developer home page](loader/devusage) \ No newline at end of file +[loader home page](../..loader.md) +[loader developer home page](../devusage.md) \ No newline at end of file diff --git a/common/utils/DOC/loader/rtusage.md b/common/utils/DOC/loader/rtusage.md index cdd2883153..e6b69f5e80 100644 --- a/common/utils/DOC/loader/rtusage.md +++ b/common/utils/DOC/loader/rtusage.md @@ -6,7 +6,7 @@ Shared library full names are built by the loader using the format: 1. the < *module version* > and < *path* > optional parameters, are defined at run-time, depending on the configuration. ## loader parameters -The loader is using the [configuration module](config), and defines global and per library parameters. Global parameters must be specified under the **loader** section and library specific parameters under a **loader.<*module name*>** section. Module specific parameters override the global parameters. +The loader is using the [configuration module](../../../config/DOCconfig.md), and defines global and per library parameters. Global parameters must be specified under the **loader** section and library specific parameters under a **loader.<*module name*>** section. Module specific parameters override the global parameters. ### Global loader parameters | name | type | default | description | |:---:|:---:|:---:|:----| @@ -47,4 +47,4 @@ With this latest example, nn the softmodem logs, you can check that the right de ``` -[loader home page](loader) \ No newline at end of file +[loader home page](..loader.md) \ No newline at end of file diff --git a/common/utils/telnetsrv/DOC/telnetaddcmd.md b/common/utils/telnetsrv/DOC/telnetaddcmd.md index 9d23b6917f..ef5af3fb7e 100644 --- a/common/utils/telnetsrv/DOC/telnetaddcmd.md +++ b/common/utils/telnetsrv/DOC/telnetaddcmd.md @@ -92,7 +92,7 @@ int add_telnetcmd(char *modulename, telnetshell_vardef_t *var, telnetshell_cmdde Add a command and the `cmd` list of sub-commands to the telnet server. After a successful call to `add_telnetcmd` function, the telnet server calls the function defined for each sub-commands in the null terminated `cmd` array, when the character string received from the telnet client matches the command and sub-command strings. Also adds the list of variables described in the `var` array to the list of variable which can be set and read. The function returns -1 if one argument is NULL. -The telnet server is dynamically loaded, to use the `add_telnetcmd` function, the shared library loader API should be used to check the availability of the telnet server and retrieve it's address, as shown in [the example at the top of this page](telnetaddcmd#code-example-of-adding-a-command-to-the-telnet-server). +The telnet server is dynamically loaded, to use the `add_telnetcmd` function, the shared library loader API should be used to check the availability of the telnet server and retrieve it's address, as shown in [the example at the top of this page](telnetaddcmd.md#code-example-of-adding-a-command-to-the-telnet-server). # telnet server public data types ## `telnetshell_vardef_t`structure @@ -113,4 +113,4 @@ The telnet server is dynamically loaded, to use the `add_telnetcmd` function, t | `helpstr` | `char[TELNET_HELPSTR_SIZE]` | character string to print when the elp`command is received from the telnet client | | `cmdfunc` | `cmdfunc_t` | pointer to the function implementing the `cmdname` sub command. | -[oai telnet server home](telnetsrv) \ No newline at end of file +[oai telnet server home](telnetsrv.md) \ No newline at end of file diff --git a/common/utils/telnetsrv/DOC/telnetarch.md b/common/utils/telnetsrv/DOC/telnetarch.md index 579a7de967..f31a51b352 100644 --- a/common/utils/telnetsrv/DOC/telnetarch.md +++ b/common/utils/telnetsrv/DOC/telnetarch.md @@ -18,4 +18,4 @@ telnet server source files are located in [common/utils/telnetsrv](https://gitla 1. `telnetsrv\_\.h`: include file for the implementation of XXX CLI command. Usually included only in the corresponding `.c`file 1. [telnetsrv_CMakeLists.txt](https://gitlab.eurecom.fr/oai/openairinterface5g/blob/develop/common/utils/telnetsrv/telnetsrv_CMakeLists.txt): CMakelists file containing the cmake instructions to build the telnet server. this file is included in the [global oai CMakelists](https://gitlab.eurecom.fr/oai/openairinterface5g/blob/develop/cmake_targets/CMakeLists.txt). -[oai telnet server home](telnetsrv) \ No newline at end of file +[oai telnet server home](telnetsrv.md) \ No newline at end of file diff --git a/common/utils/telnetsrv/DOC/telnetgetset.md b/common/utils/telnetsrv/DOC/telnetgetset.md index ccf774a752..e0b2c90d79 100644 --- a/common/utils/telnetsrv/DOC/telnetgetset.md +++ b/common/utils/telnetsrv/DOC/telnetgetset.md @@ -17,5 +17,5 @@ telnet, loopc = 100 softmodem> ``` -[oai telnetserver home](telnetsrv) -[oai telnetserver usage home](telnetusage) \ No newline at end of file +[oai telnetserver home](telnetsrv.md) +[oai telnetserver usage home](telnetusage.md) \ No newline at end of file diff --git a/common/utils/telnetsrv/DOC/telnethelp.md b/common/utils/telnetsrv/DOC/telnethelp.md index ef614cae1c..63183fb611 100644 --- a/common/utils/telnetsrv/DOC/telnethelp.md +++ b/common/utils/telnetsrv/DOC/telnethelp.md @@ -53,5 +53,5 @@ softmodem> ``` -[oai telnetserver home](telnetsrv) -[oai telnetserver usage home](telnetusage) \ No newline at end of file +[oai telnetserver home](telnetsrv.md) +[oai telnetserver usage home](telnetusage.md) \ No newline at end of file diff --git a/common/utils/telnetsrv/DOC/telnethist.md b/common/utils/telnetsrv/DOC/telnethist.md index 10682b8a85..d938435a24 100644 --- a/common/utils/telnetsrv/DOC/telnethist.md +++ b/common/utils/telnetsrv/DOC/telnethist.md @@ -40,5 +40,5 @@ softmodem> ``` -[oai telnetserver home](telnetsrv) -[oai telnetserver usage home](telnetusage) \ No newline at end of file +[oai telnetserver home](telnetsrv.md) +[oai telnetserver usage home](telnetusage.md) \ No newline at end of file diff --git a/common/utils/telnetsrv/DOC/telnetloader.md b/common/utils/telnetsrv/DOC/telnetloader.md index d64f0c6cdb..9250524989 100644 --- a/common/utils/telnetsrv/DOC/telnetloader.md +++ b/common/utils/telnetsrv/DOC/telnetloader.md @@ -43,5 +43,5 @@ softmodem> loader show modules softmodem> ``` -[oai telnetserver home](telnetsrv) -[oai telnetserver usage home](telnetusage) \ No newline at end of file +[oai telnetserver home](telnetsrv.md) +[oai telnetserver usage home](telnetusage.md) \ No newline at end of file diff --git a/common/utils/telnetsrv/DOC/telnetlog.md b/common/utils/telnetsrv/DOC/telnetlog.md index 00f09a3a6f..7c1d4f0384 100644 --- a/common/utils/telnetsrv/DOC/telnetlog.md +++ b/common/utils/telnetsrv/DOC/telnetlog.md @@ -1,4 +1,4 @@ -The log command can be used to get the status of the log parameters and to dynamically modify these parameters. The log command has its own [help](telnethelp#oai-telnet-server-specific-commands-help) +The log command can be used to get the status of the log parameters and to dynamically modify these parameters. The log command has its own [help](telnethelp.md#oai-telnet-server-specific-commands-help) ```bash softmodem> softmodem log disable 0-35 log level/verbosity comp 0 PHY set to info / medium (disabled) @@ -91,5 +91,5 @@ softmodem> exit Connection closed by foreign host. ``` -[oai telnetserver home](telnetsrv) -[oai telnetserver usage home](telnetusage) \ No newline at end of file +[oai telnetserver home](telnetsrv.md) +[oai telnetserver usage home](telnetusage.md) \ No newline at end of file diff --git a/common/utils/telnetsrv/DOC/telnetloop.md b/common/utils/telnetsrv/DOC/telnetloop.md index 437481da68..f045e8a716 100644 --- a/common/utils/telnetsrv/DOC/telnetloop.md +++ b/common/utils/telnetsrv/DOC/telnetloop.md @@ -36,5 +36,5 @@ softmodem> loop softmodem show thread ``` A **_loop_** command can be interrupted by pressing the **_enter_** key till getting the prompt. -[oai telnetserver home](telnetsrv) -[oai telnetserver usage home](telnetusage) \ No newline at end of file +[oai telnetserver home](telnetsrv.md) +[oai telnetserver usage home](telnetusage.md) \ No newline at end of file diff --git a/common/utils/telnetsrv/DOC/telnetsrv.md b/common/utils/telnetsrv/DOC/telnetsrv.md index ab89da3f85..e8909595d9 100644 --- a/common/utils/telnetsrv/DOC/telnetsrv.md +++ b/common/utils/telnetsrv/DOC/telnetsrv.md @@ -4,4 +4,4 @@ The oai embedded telnet server is an optional monitoring and debugging tool. It * [Adding commands to the oai telnet server](telnetaddcmd.md) * [telnet server architecture ](telnetarch.md) -[oai Wikis home](home) \ No newline at end of file +[oai Wikis home](https://gitlab.eurecom.fr/oai/openairinterface5g/wikis/home) \ No newline at end of file From 6ce4b9ad667e1f3d0b64d5a872740ac5f6c9b6c4 Mon Sep 17 00:00:00 2001 From: Francois TABURET Date: Thu, 8 Nov 2018 20:18:13 +0100 Subject: [PATCH 121/233] Update arch.md --- common/config/DOC/config/arch.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/config/DOC/config/arch.md b/common/config/DOC/config/arch.md index efe4d9eef7..170241500b 100644 --- a/common/config/DOC/config/arch.md +++ b/common/config/DOC/config/arch.md @@ -4,4 +4,4 @@ ![configmodule_components](/uploads/54f8a3953d5ee53717cd9a3b71f85c68/configmodule_components.png) -[Configuration module home](config) \ No newline at end of file +[Configuration module home](../config.md) \ No newline at end of file From 91ba760a029f6d3eaea4a7b87a3a1817fa73dd99 Mon Sep 17 00:00:00 2001 From: Francois TABURET Date: Thu, 8 Nov 2018 20:21:17 +0100 Subject: [PATCH 122/233] Update loader.md --- common/utils/DOC/loader.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/common/utils/DOC/loader.md b/common/utils/DOC/loader.md index 7ed23952aa..91ff0c02f0 100644 --- a/common/utils/DOC/loader.md +++ b/common/utils/DOC/loader.md @@ -10,8 +10,8 @@ The main drawback is a performance cost at init time, when loading libraries. ## Documentation -* [runtime usage](loader/rtusage) -* [developer usage](loader/devusage) -* [module architecture](loader/arch) +* [runtime usage](loader/rtusage.md) +* [developer usage](loader/devusage.md) +* [module architecture](loader/arch.md) -[oai Wikis home](home) \ No newline at end of file +[oai Wikis home](https://gitlab.eurecom.fr/oai/openairinterface5g/wikis/home) \ No newline at end of file From 894fc6072cb9e663b3a5793fe64f7a39e552af04 Mon Sep 17 00:00:00 2001 From: Francois TABURET Date: Thu, 8 Nov 2018 20:24:27 +0100 Subject: [PATCH 123/233] Update rtusage.md --- common/utils/DOC/loader/rtusage.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/utils/DOC/loader/rtusage.md b/common/utils/DOC/loader/rtusage.md index e6b69f5e80..903d249d65 100644 --- a/common/utils/DOC/loader/rtusage.md +++ b/common/utils/DOC/loader/rtusage.md @@ -47,4 +47,4 @@ With this latest example, nn the softmodem logs, you can check that the right de ``` -[loader home page](..loader.md) \ No newline at end of file +[loader home page](../loader.md) \ No newline at end of file From eb6afba80966361170a0e75bf149d0d10e1f0406 Mon Sep 17 00:00:00 2001 From: Francois TABURET Date: Thu, 8 Nov 2018 20:25:54 +0100 Subject: [PATCH 124/233] Update api.md --- common/utils/DOC/loader/devusage/api.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/utils/DOC/loader/devusage/api.md b/common/utils/DOC/loader/devusage/api.md index eabfe677e9..ffbc9d7d4b 100644 --- a/common/utils/DOC/loader/devusage/api.md +++ b/common/utils/DOC/loader/devusage/api.md @@ -16,5 +16,5 @@ void * get_shlibmodule_fptr(char *modname, char *fname) ``` Returns a pointer to the symbol `fname`, defined in module `modname`, or `NULL` if the symbol is not found. -[loader home page](../loader.md) +[loader home page](../../../loader.md) [loader developer home page](../devusage.md) \ No newline at end of file From d49d0b10a6b20a1ca96882ba959c5ea11efc709a Mon Sep 17 00:00:00 2001 From: Francois TABURET Date: Thu, 8 Nov 2018 20:26:44 +0100 Subject: [PATCH 125/233] Update api.md --- common/utils/DOC/loader/devusage/api.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/utils/DOC/loader/devusage/api.md b/common/utils/DOC/loader/devusage/api.md index ffbc9d7d4b..21c2a1d253 100644 --- a/common/utils/DOC/loader/devusage/api.md +++ b/common/utils/DOC/loader/devusage/api.md @@ -16,5 +16,5 @@ void * get_shlibmodule_fptr(char *modname, char *fname) ``` Returns a pointer to the symbol `fname`, defined in module `modname`, or `NULL` if the symbol is not found. -[loader home page](../../../loader.md) +[loader home page](../../loader.md) [loader developer home page](../devusage.md) \ No newline at end of file From 36612d8c5d2ed8daadd9271438289b0b6c0dd284 Mon Sep 17 00:00:00 2001 From: Francois TABURET Date: Thu, 8 Nov 2018 20:27:10 +0100 Subject: [PATCH 126/233] Update arch.md --- common/utils/DOC/loader/arch.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/utils/DOC/loader/arch.md b/common/utils/DOC/loader/arch.md index c37aedb4ef..6fd1f47e7b 100644 --- a/common/utils/DOC/loader/arch.md +++ b/common/utils/DOC/loader/arch.md @@ -4,4 +4,4 @@ The oai shared library loader is implemented in two source files, located in [co 1. [load_module_shlib.c](https://gitlab.eurecom.fr/oai/openairinterface5g/tree/develop/common/utils/load_module_shlib.c) contains the loader implementation 1. [load_module_shlib.h](https://gitlab.eurecom.fr/oai/openairinterface5g/tree/develop/common/utils/load_module_shlib.h) is the loader include file containing both private and public data type definitions. It also contain API prototypes. -[loader home page](..loader.md) \ No newline at end of file +[loader home page](../loader.md) \ No newline at end of file From 9db199269dee4cd6036498a543ffab345afbe495 Mon Sep 17 00:00:00 2001 From: Francois TABURET Date: Fri, 9 Nov 2018 08:40:48 +0100 Subject: [PATCH 127/233] Update struct.md --- common/utils/DOC/loader/devusage/struct.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/utils/DOC/loader/devusage/struct.md b/common/utils/DOC/loader/devusage/struct.md index e3cfc74993..17504f3866 100644 --- a/common/utils/DOC/loader/devusage/struct.md +++ b/common/utils/DOC/loader/devusage/struct.md @@ -6,5 +6,5 @@ It is defined in include file [ common/util/load_module_shlib.h ](https://gitlab | `fname` | symbol name, is passed to the [`dlsym`](http://man7.org/linux/man-pages/man3/dlsym.3.html) system call performed by the loader to get a pointer to the symbol | I | | `fptr` | pointer to the symbol name, set by the loader. `fptr` is defined as a `int (*fptr)(void)` function type | O | -[loader home page](../..loader.md) +[loader home page](../../loader.md) [loader developer home page](../devusage.md) \ No newline at end of file From 9b4d01f48ff8d1c59b84b57b7aae29b0410b51cb Mon Sep 17 00:00:00 2001 From: Francois TABURET Date: Fri, 9 Nov 2018 08:42:16 +0100 Subject: [PATCH 128/233] Update rtusage.md --- common/utils/DOC/loader/rtusage.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/utils/DOC/loader/rtusage.md b/common/utils/DOC/loader/rtusage.md index 903d249d65..bf87316e13 100644 --- a/common/utils/DOC/loader/rtusage.md +++ b/common/utils/DOC/loader/rtusage.md @@ -6,7 +6,7 @@ Shared library full names are built by the loader using the format: 1. the < *module version* > and < *path* > optional parameters, are defined at run-time, depending on the configuration. ## loader parameters -The loader is using the [configuration module](../../../config/DOCconfig.md), and defines global and per library parameters. Global parameters must be specified under the **loader** section and library specific parameters under a **loader.<*module name*>** section. Module specific parameters override the global parameters. +The loader is using the [configuration module](../../../config/DOC/config.md), and defines global and per library parameters. Global parameters must be specified under the **loader** section and library specific parameters under a **loader.<*module name*>** section. Module specific parameters override the global parameters. ### Global loader parameters | name | type | default | description | |:---:|:---:|:---:|:----| From 4edc42a4b70c0680f74ce02934179ef2354237f3 Mon Sep 17 00:00:00 2001 From: Raphael Defosseux Date: Fri, 9 Nov 2018 13:45:26 +0100 Subject: [PATCH 129/233] CI: unified VM scripting for option management Signed-off-by: Raphael Defosseux --- ci-scripts/Jenkinsfile-gitlab | 56 +- ci-scripts/buildOnVM.sh | 483 +++-------- ci-scripts/createVM.sh | 172 +--- ci-scripts/destroyAllRunningVM.sh | 82 +- ci-scripts/oai-ci-vm-tool | 537 +++++++++++++ ci-scripts/reportBuildLocally.sh | 541 +++++-------- ci-scripts/reportTestLocally.sh | 820 ++++++++----------- ci-scripts/runTestOnVM.sh | 1234 +++++++++++++---------------- ci-scripts/waitBuildOnVM.sh | 422 +++------- 9 files changed, 1939 insertions(+), 2408 deletions(-) create mode 100755 ci-scripts/oai-ci-vm-tool diff --git a/ci-scripts/Jenkinsfile-gitlab b/ci-scripts/Jenkinsfile-gitlab index 0def0c916a..423e07be92 100644 --- a/ci-scripts/Jenkinsfile-gitlab +++ b/ci-scripts/Jenkinsfile-gitlab @@ -118,7 +118,7 @@ pipeline { stage ("Start VM -- basic-sim") { steps { timeout (time: 5, unit: 'MINUTES') { - sh "./ci-scripts/buildOnVM.sh --workspace $WORKSPACE --variant basic-sim --job-name ${JOB_NAME} --build-id ${BUILD_ID} --daemon" + sh "./ci-scripts/oai-ci-vm-tool build --workspace $WORKSPACE --variant basic-sim --job-name ${JOB_NAME} --build-id ${BUILD_ID} --daemon" } } } @@ -126,7 +126,7 @@ pipeline { stage ("Start VM -- enb-usrp") { steps { timeout (time: 5, unit: 'MINUTES') { - sh "./ci-scripts/buildOnVM.sh --workspace $WORKSPACE --variant enb-usrp --job-name ${JOB_NAME} --build-id ${BUILD_ID} --daemon" + sh "./ci-scripts/oai-ci-vm-tool build --workspace $WORKSPACE --variant enb-usrp --job-name ${JOB_NAME} --build-id ${BUILD_ID} --daemon" } } } @@ -134,7 +134,7 @@ pipeline { stage ("Start VM -- enb-ethernet") { steps { timeout (time: 5, unit: 'MINUTES') { - sh "./ci-scripts/buildOnVM.sh --workspace $WORKSPACE --variant enb-ethernet --job-name ${JOB_NAME} --build-id ${BUILD_ID} --daemon" + sh "./ci-scripts/oai-ci-vm-tool build --workspace $WORKSPACE --variant enb-ethernet --job-name ${JOB_NAME} --build-id ${BUILD_ID} --daemon" } } } @@ -142,7 +142,7 @@ pipeline { stage ("Start VM -- ue-ethernet") { steps { timeout (time: 5, unit: 'MINUTES') { - sh "./ci-scripts/buildOnVM.sh --workspace $WORKSPACE --variant ue-ethernet --job-name ${JOB_NAME} --build-id ${BUILD_ID} --daemon" + sh "./ci-scripts/oai-ci-vm-tool build --workspace $WORKSPACE --variant ue-ethernet --job-name ${JOB_NAME} --build-id ${BUILD_ID} --daemon" } } } @@ -150,7 +150,7 @@ pipeline { stage ("Start VM -- phy-sim") { steps { timeout (time: 5, unit: 'MINUTES') { - sh "./ci-scripts/buildOnVM.sh --workspace $WORKSPACE --variant phy-sim --job-name ${JOB_NAME} --build-id ${BUILD_ID} --daemon" + sh "./ci-scripts/oai-ci-vm-tool build --workspace $WORKSPACE --variant phy-sim --job-name ${JOB_NAME} --build-id ${BUILD_ID} --daemon" } } } @@ -158,7 +158,7 @@ pipeline { stage ("Start VM -- cppcheck") { steps { timeout (time: 5, unit: 'MINUTES') { - sh "./ci-scripts/buildOnVM.sh --workspace $WORKSPACE --variant cppcheck --job-name ${JOB_NAME} --build-id ${BUILD_ID} --daemon" + sh "./ci-scripts/oai-ci-vm-tool build --workspace $WORKSPACE --variant cppcheck --job-name ${JOB_NAME} --build-id ${BUILD_ID} --daemon" } } } @@ -169,7 +169,7 @@ pipeline { steps { gitlabCommitStatus(name: "Analysis with cppcheck") { timeout (time: 20, unit: 'MINUTES') { - sh "./ci-scripts/waitBuildOnVM.sh --workspace $WORKSPACE --variant cppcheck --job-name ${JOB_NAME} --build-id ${BUILD_ID}" + sh "./ci-scripts/oai-ci-vm-tool wait --workspace $WORKSPACE --variant cppcheck --job-name ${JOB_NAME} --build-id ${BUILD_ID}" } } } @@ -178,7 +178,7 @@ pipeline { steps { gitlabCommitStatus(name: "Build eNb-USRP") { timeout (time: 20, unit: 'MINUTES') { - sh "./ci-scripts/waitBuildOnVM.sh --workspace $WORKSPACE --variant enb-usrp --job-name ${JOB_NAME} --build-id ${BUILD_ID}" + sh "./ci-scripts/oai-ci-vm-tool wait --workspace $WORKSPACE --variant enb-usrp --job-name ${JOB_NAME} --build-id ${BUILD_ID}" } } } @@ -187,16 +187,7 @@ pipeline { steps { gitlabCommitStatus(name: "Build basic-sim") { timeout (time: 20, unit: 'MINUTES') { - sh "./ci-scripts/waitBuildOnVM.sh --workspace $WORKSPACE --variant basic-sim --job-name ${JOB_NAME} --build-id ${BUILD_ID} --keep-vm-alive" - } - } - } - } - stage ("Build physical simulators") { - steps { - gitlabCommitStatus(name: "Build phy-sim") { - timeout (time: 20, unit: 'MINUTES') { - sh "./ci-scripts/waitBuildOnVM.sh --workspace $WORKSPACE --variant phy-sim --job-name ${JOB_NAME} --build-id ${BUILD_ID} --keep-vm-alive" + sh "./ci-scripts/oai-ci-vm-tool wait --workspace $WORKSPACE --variant basic-sim --job-name ${JOB_NAME} --build-id ${BUILD_ID} --keep-vm-alive" } } } @@ -205,7 +196,7 @@ pipeline { steps { gitlabCommitStatus(name: "Build eNb-ethernet") { timeout (time: 20, unit: 'MINUTES') { - sh "./ci-scripts/waitBuildOnVM.sh --workspace $WORKSPACE --variant enb-ethernet --job-name ${JOB_NAME} --build-id ${BUILD_ID} --keep-vm-alive" + sh "./ci-scripts/oai-ci-vm-tool wait --workspace $WORKSPACE --variant enb-ethernet --job-name ${JOB_NAME} --build-id ${BUILD_ID} --keep-vm-alive" } } } @@ -214,7 +205,16 @@ pipeline { steps { gitlabCommitStatus(name: "Build UE-ethernet") { timeout (time: 20, unit: 'MINUTES') { - sh "./ci-scripts/waitBuildOnVM.sh --workspace $WORKSPACE --variant ue-ethernet --job-name ${JOB_NAME} --build-id ${BUILD_ID} --keep-vm-alive" + sh "./ci-scripts/oai-ci-vm-tool wait --workspace $WORKSPACE --variant ue-ethernet --job-name ${JOB_NAME} --build-id ${BUILD_ID} --keep-vm-alive" + } + } + } + } + stage ("Build physical simulators") { + steps { + gitlabCommitStatus(name: "Build phy-sim") { + timeout (time: 20, unit: 'MINUTES') { + sh "./ci-scripts/oai-ci-vm-tool wait --workspace $WORKSPACE --variant phy-sim --job-name ${JOB_NAME} --build-id ${BUILD_ID} --keep-vm-alive" } } } @@ -252,7 +252,7 @@ pipeline { archiveArtifacts artifacts: 'archives/vm_build_logs.zip' } if ("MERGE".equals(env.gitlabActionType)) { - sh "./ci-scripts/reportBuildLocally.sh --git-url ${GIT_URL} --job-name ${JOB_NAME} --build-id ${BUILD_ID} --trigger merge-request --src-branch ${env.gitlabSourceBranch} --src-commit ${env.gitlabMergeRequestLastCommit} --target-branch ${env.gitlabTargetBranch} --target-commit ${GIT_COMMIT}" + sh "./ci-scripts/oai-ci-vm-tool report-build --workspace $WORKSPACE --git-url ${GIT_URL} --job-name ${JOB_NAME} --build-id ${BUILD_ID} --trigger merge-request --src-branch ${env.gitlabSourceBranch} --src-commit ${env.gitlabMergeRequestLastCommit} --target-branch ${env.gitlabTargetBranch} --target-commit ${GIT_COMMIT}" sh "./ci-scripts/checkAddedWarnings.sh --src-branch ${env.gitlabSourceBranch} --target-branch ${env.gitlabTargetBranch}" def res=readFile('./oai_warning_files.txt').trim(); if ("0".equals(res)) { @@ -263,7 +263,7 @@ pipeline { addGitLabMRComment comment: message } } else { - sh "./ci-scripts/reportBuildLocally.sh --git-url ${GIT_URL} --job-name ${JOB_NAME} --build-id ${BUILD_ID} --trigger push --branch ${GIT_BRANCH} --commit ${GIT_COMMIT}" + sh "./ci-scripts/oai-ci-vm-tool report-build --workspace $WORKSPACE --git-url ${GIT_URL} --job-name ${JOB_NAME} --build-id ${BUILD_ID} --trigger push --branch ${GIT_BRANCH} --commit ${GIT_COMMIT}" } if(fileExists('build_results.html')) { sh "sed -i -e 's#Build-ID: ${BUILD_ID}#Build-ID: ${BUILD_ID}#' -e 's#TEMPLATE_BUILD_TIME#${JOB_TIMESTAMP}#' build_results.html" @@ -280,7 +280,7 @@ pipeline { steps { gitlabCommitStatus(name: "Test phy-sim") { timeout (time: 20, unit: 'MINUTES') { - sh "./ci-scripts/runTestOnVM.sh --workspace $WORKSPACE --variant phy-sim --job-name ${JOB_NAME} --build-id ${BUILD_ID}" + sh "./ci-scripts/oai-ci-vm-tool test --workspace $WORKSPACE --variant phy-sim --job-name ${JOB_NAME} --build-id ${BUILD_ID}" } } } @@ -289,7 +289,7 @@ pipeline { steps { gitlabCommitStatus(name: "Test basic-sim") { timeout (time: 20, unit: 'MINUTES') { - sh "./ci-scripts/runTestOnVM.sh --workspace $WORKSPACE --variant basic-sim --job-name ${JOB_NAME} --build-id ${BUILD_ID} --keep-vm-alive" + sh "./ci-scripts/oai-ci-vm-tool test --workspace $WORKSPACE --variant basic-sim --job-name ${JOB_NAME} --build-id ${BUILD_ID}" } } } @@ -484,9 +484,9 @@ pipeline { if(fileExists('archives/vm_tests_logs.zip')) { archiveArtifacts artifacts: 'archives/vm_tests_logs.zip' if ("MERGE".equals(env.gitlabActionType)) { - sh "./ci-scripts/reportTestLocally.sh --git-url ${GIT_URL} --job-name ${JOB_NAME} --build-id ${BUILD_ID} --trigger merge-request --src-branch ${env.gitlabSourceBranch} --src-commit ${env.gitlabMergeRequestLastCommit} --target-branch ${env.gitlabTargetBranch} --target-commit ${GIT_COMMIT}" + sh "./ci-scripts/oai-ci-vm-tool report-test --workspace $WORKSPACE --git-url ${GIT_URL} --job-name ${JOB_NAME} --build-id ${BUILD_ID} --trigger merge-request --src-branch ${env.gitlabSourceBranch} --src-commit ${env.gitlabMergeRequestLastCommit} --target-branch ${env.gitlabTargetBranch} --target-commit ${GIT_COMMIT}" } else { - sh "./ci-scripts/reportTestLocally.sh --git-url ${GIT_URL} --job-name ${JOB_NAME} --build-id ${BUILD_ID} --trigger push --branch ${GIT_BRANCH} --commit ${GIT_COMMIT}" + sh "./ci-scripts/oai-ci-vm-tool report-test --workspace $WORKSPACE --git-url ${GIT_URL} --job-name ${JOB_NAME} --build-id ${BUILD_ID} --trigger push --branch ${GIT_BRANCH} --commit ${GIT_COMMIT}" } if(fileExists('test_simulator_results.html')) { sh "sed -i -e 's#Build-ID: ${BUILD_ID}#Build-ID: ${BUILD_ID}#' -e 's#TEMPLATE_BUILD_TIME#${JOB_TIMESTAMP}#' test_simulator_results.html" @@ -499,7 +499,7 @@ pipeline { } stage ("Destroy all Virtual Machines") { steps { - sh "./ci-scripts/destroyAllRunningVM.sh --job-name ${JOB_NAME} --build-id ${BUILD_ID}" + sh "./ci-scripts/oai-ci-vm-tool destroy --job-name ${JOB_NAME} --build-id ${BUILD_ID}" } } } @@ -507,7 +507,7 @@ pipeline { always { script { // Stage destroy may not be run if error in previous stage - sh "./ci-scripts/destroyAllRunningVM.sh --job-name ${JOB_NAME} --build-id ${BUILD_ID}" + sh "./ci-scripts/oai-ci-vm-tool destroy --job-name ${JOB_NAME} --build-id ${BUILD_ID}" emailext attachmentsPattern: '*results*.html', body: '''Hi, Here are attached HTML report files for $PROJECT_NAME - Build # $BUILD_NUMBER - $BUILD_STATUS! diff --git a/ci-scripts/buildOnVM.sh b/ci-scripts/buildOnVM.sh index c1f554093d..aed449f180 100755 --- a/ci-scripts/buildOnVM.sh +++ b/ci-scripts/buildOnVM.sh @@ -20,8 +20,8 @@ # * contact@openairinterface.org # */ -function usage { - echo "OAI VM Build Check script" +function build_usage { + echo "OAI CI VM script" echo " Original Author: Raphael Defosseux" echo " Requirements:" echo " -- uvtool uvtool-libvirt apt-cacher" @@ -31,9 +31,9 @@ function usage { echo "" echo "Usage:" echo "------" - echo " buildOnVM.sh [OPTIONS]" + echo " oai-ci-vm-tool build [OPTIONS]" echo "" - echo "Options:" + echo "Mandatory Options:" echo "--------" echo " --job-name #### OR -jn ####" echo " Specify the name of the Jenkins job." @@ -44,12 +44,9 @@ function usage { echo " --workspace #### OR -ws ####" echo " Specify the workspace." echo "" - echo " --variant enb-usrp OR -v1" - echo " --variant basic-sim OR -v2" - echo " --variant phy-sim OR -v3" - echo " --variant cppcheck OR -v4" - echo " --variant enb-ethernet OR -v7" - echo " --variant ue-ethernet OR -v8" + echo "Options:" + echo "--------" + variant_usage echo " Specify the variant to build." echo "" echo " --keep-vm-alive OR -k" @@ -63,382 +60,120 @@ function usage { echo "" } -function variant_usage { - echo "OAI VM Build Check script" - echo " Original Author: Raphael Defosseux" - echo "" - echo " --variant enb-usrp OR -v1" - echo " --variant basic-sim OR -v2" - echo " --variant phy-sim OR -v3" - echo " --variant cppcheck OR -v4" - echo " --variant enb-ethernet OR -v7" - echo " --variant ue-ethernet OR -v8" - echo "" -} - -if [ $# -lt 1 ] || [ $# -gt 9 ] -then - echo "Syntax Error: not the correct number of arguments" - echo "" - usage - exit 1 -fi - -VM_TEMPLATE=ci- -JOB_NAME=XX -BUILD_ID=XX -VM_NAME=ci-enb-usrp -VM_MEMORY=2048 -VM_CPU=4 -ARCHIVES_LOC=enb_usrp -LOG_PATTERN=.Rel14.txt -NB_PATTERN_FILES=4 -BUILD_OPTIONS="--eNB -w USRP" -KEEP_VM_ALIVE=0 -DAEMON=0 - -while [[ $# -gt 0 ]] -do -key="$1" - -case $key in - -h|--help) - shift - usage - exit 0 - ;; - -jn|--job-name) - JOB_NAME="$2" - shift - shift - ;; - -id|--build-id) - BUILD_ID="$2" - shift - shift - ;; - -ws|--workspace) - JENKINS_WKSP="$2" - shift - shift - ;; - -k|--keep-vm-alive) - KEEP_VM_ALIVE=1 - shift - ;; - -D|--daemon) - DAEMON=1 - shift - ;; - -v1) - VM_NAME=ci-enb-usrp - ARCHIVES_LOC=enb_usrp - LOG_PATTERN=.Rel14.txt - NB_PATTERN_FILES=4 - BUILD_OPTIONS="--eNB -w USRP --mu" - shift - ;; - -v2) - VM_NAME=ci-basic-sim - ARCHIVES_LOC=basic_sim - LOG_PATTERN=basic_simulator - NB_PATTERN_FILES=2 - BUILD_OPTIONS="--basic-simulator" - VM_MEMORY=8192 - VM_CPU=4 - shift - ;; - -v3) - VM_NAME=ci-phy-sim - ARCHIVES_LOC=phy_sim - LOG_PATTERN=.Rel14.txt - NB_PATTERN_FILES=3 - BUILD_OPTIONS="--phy_simulators" - shift - ;; - -v4) - VM_NAME=ci-cppcheck - VM_MEMORY=4096 - ARCHIVES_LOC=cppcheck - LOG_PATTERN=cppcheck.xml - NB_PATTERN_FILES=1 - BUILD_OPTIONS="--enable=warning --force --xml --xml-version=2" - shift - ;; - -v7) - VM_NAME=ci-enb-ethernet - ARCHIVES_LOC=enb_eth - LOG_PATTERN=.Rel14.txt - NB_PATTERN_FILES=6 - BUILD_OPTIONS="--eNB -t ETHERNET --noS1" - shift - ;; - -v8) - VM_NAME=ci-ue-ethernet - ARCHIVES_LOC=ue_eth - LOG_PATTERN=.Rel14.txt - NB_PATTERN_FILES=6 - BUILD_OPTIONS="--UE -t ETHERNET --noS1" - shift - ;; - --variant) - variant="$2" - case $variant in - enb-usrp) - VM_NAME=ci-enb-usrp - ARCHIVES_LOC=enb_usrp - LOG_PATTERN=.Rel14.txt - NB_PATTERN_FILES=4 - BUILD_OPTIONS="--eNB -w USRP --mu" - ;; - basic-sim) - VM_NAME=ci-basic-sim - ARCHIVES_LOC=basic_sim - LOG_PATTERN=basic_simulator - NB_PATTERN_FILES=2 - BUILD_OPTIONS="--basic-simulator" - VM_MEMORY=8192 - VM_CPU=4 - ;; - phy-sim) - VM_NAME=ci-phy-sim - ARCHIVES_LOC=phy_sim - LOG_PATTERN=.Rel14.txt - NB_PATTERN_FILES=3 - BUILD_OPTIONS="--phy_simulators" - ;; - cppcheck) - VM_NAME=ci-cppcheck - VM_MEMORY=4096 - ARCHIVES_LOC=cppcheck - LOG_PATTERN=cppcheck.xml - NB_PATTERN_FILES=1 - BUILD_OPTIONS="--enable=warning --force --xml --xml-version=2" - ;; - enb-ethernet) - VM_NAME=ci-enb-ethernet - ARCHIVES_LOC=enb_eth - LOG_PATTERN=.Rel14.txt - NB_PATTERN_FILES=6 - BUILD_OPTIONS="--eNB -t ETHERNET --noS1" - ;; - ue-ethernet) - VM_NAME=ci-ue-ethernet - ARCHIVES_LOC=ue_eth - LOG_PATTERN=.Rel14.txt - NB_PATTERN_FILES=6 - BUILD_OPTIONS="--UE -t ETHERNET --noS1" - ;; - *) - echo "" - echo "Syntax Error: Invalid Variant option -> $variant" - echo "" - variant_usage - exit 1 - esac - shift - shift - ;; - *) - echo "Syntax Error: unknown option: $key" - echo "" - usage - exit 1 -esac -done - -if [ ! -f $JENKINS_WKSP/localZip.zip ] -then - echo "Missing localZip.zip file!" - exit 1 -fi -if [ ! -f /etc/apt/apt.conf.d/01proxy ] -then - echo "Missing /etc/apt/apt.conf.d/01proxy file!" - echo "Is apt-cacher installed and configured?" - exit 1 -fi - -if [ "$JOB_NAME" == "XX" ] || [ "$BUILD_ID" == "XX" ] -then - VM_TEMPLATE=ci- -else - VM_TEMPLATE=${JOB_NAME}-b${BUILD_ID}- -fi - -VM_NAME=`echo $VM_NAME | sed -e "s#ci-#$VM_TEMPLATE#"` -VM_CMDS=${VM_NAME}_cmds.txt -ARCHIVES_LOC=${JENKINS_WKSP}/archives/${ARCHIVES_LOC} - -echo "VM_NAME = $VM_NAME" -echo "VM_CMD_FILE = $VM_CMDS" -echo "JENKINS_WKSP = $JENKINS_WKSP" -echo "ARCHIVES_LOC = $ARCHIVES_LOC" -echo "BUILD_OPTIONS = $BUILD_OPTIONS" - -IS_VM_ALIVE=`uvt-kvm list | grep -c $VM_NAME` - -if [ $IS_VM_ALIVE -eq 0 ] -then - echo "############################################################" - echo "Creating VM ($VM_NAME) on Ubuntu Cloud Image base" - echo "############################################################" - uvt-kvm create $VM_NAME release=xenial --memory $VM_MEMORY --cpu $VM_CPU --unsafe-caching --template ci-scripts/template-host.xml -fi - -echo "Waiting for VM to be started" -uvt-kvm wait $VM_NAME --insecure - -VM_IP_ADDR=`uvt-kvm ip $VM_NAME` -echo "$VM_NAME has for IP addr = $VM_IP_ADDR" - -echo "############################################################" -echo "Copying GIT repo into VM ($VM_NAME)" -echo "############################################################" -scp -o StrictHostKeyChecking=no localZip.zip ubuntu@$VM_IP_ADDR:/home/ubuntu -scp -o StrictHostKeyChecking=no /etc/apt/apt.conf.d/01proxy ubuntu@$VM_IP_ADDR:/home/ubuntu - -echo "############################################################" -echo "Running install and build script on VM ($VM_NAME)" -echo "############################################################" -echo "sudo cp 01proxy /etc/apt/apt.conf.d/" > $VM_CMDS -echo "touch /home/ubuntu/.hushlogin" >> $VM_CMDS -if [[ "$VM_NAME" == *"-cppcheck"* ]] -then - if [ $DAEMON -eq 0 ] +function build_on_vm { + if [ ! -f $JENKINS_WKSP/localZip.zip ] then - echo "echo \"sudo apt-get --yes --quiet install zip cppcheck \"" >> $VM_CMDS - echo "sudo apt-get update > zip-install.txt 2>&1" >> $VM_CMDS - echo "sudo apt-get --yes install zip cppcheck >> zip-install.txt 2>&1" >> $VM_CMDS - else - echo "echo \"sudo apt-get --yes --quiet install zip daemon cppcheck \"" >> $VM_CMDS - echo "sudo apt-get update > zip-install.txt 2>&1" >> $VM_CMDS - echo "sudo apt-get --yes install zip daemon cppcheck >> zip-install.txt 2>&1" >> $VM_CMDS + echo "Missing localZip.zip file!" + STATUS=1 + return fi -else - if [ $DAEMON -eq 0 ] + if [ ! -f /etc/apt/apt.conf.d/01proxy ] then - echo "echo \"sudo apt-get --yes --quiet install zip subversion libboost-dev \"" >> $VM_CMDS - echo "sudo apt-get update > zip-install.txt 2>&1" >> $VM_CMDS - echo "sudo apt-get --yes install zip subversion libboost-dev >> zip-install.txt 2>&1" >> $VM_CMDS - else - echo "echo \"sudo apt-get --yes --quiet install zip daemon subversion libboost-dev \"" >> $VM_CMDS - echo "sudo apt-get update > zip-install.txt 2>&1" >> $VM_CMDS - echo "sudo apt-get --yes install zip daemon subversion libboost-dev >> zip-install.txt 2>&1" >> $VM_CMDS + echo "Missing /etc/apt/apt.conf.d/01proxy file!" + echo "Is apt-cacher installed and configured?" + STATUS=1 + return fi -fi -echo "mkdir tmp" >> $VM_CMDS -echo "cd tmp" >> $VM_CMDS -echo "echo \"unzip -qq -DD ../localZip.zip\"" >> $VM_CMDS -echo "unzip -qq -DD ../localZip.zip" >> $VM_CMDS -if [[ "$VM_NAME" == *"-cppcheck"* ]] -then - echo "mkdir cmake_targets/log" >> $VM_CMDS - echo "chmod 777 cmake_targets/log" >> $VM_CMDS - echo "cp /home/ubuntu/zip-install.txt cmake_targets/log" >> $VM_CMDS - echo "echo \"cppcheck $BUILD_OPTIONS . \"" >> $VM_CMDS - if [ $DAEMON -eq 0 ] - then - echo "cppcheck $BUILD_OPTIONS . 2> cmake_targets/log/cppcheck.xml 1> cmake_targets/log/cppcheck_build.txt" >> $VM_CMDS - else - echo "echo \"cppcheck $BUILD_OPTIONS .\" > ./my-vm-build.sh" >> $VM_CMDS - echo "chmod 775 ./my-vm-build.sh " >> $VM_CMDS - echo "sudo -E daemon --inherit --unsafe --name=build_daemon --chdir=/home/ubuntu/tmp -O /home/ubuntu/tmp/cmake_targets/log/cppcheck_build.txt -E /home/ubuntu/tmp/cmake_targets/log/cppcheck.xml ./my-vm-build.sh" >> $VM_CMDS - fi -else - echo "echo \"source oaienv\"" >> $VM_CMDS - echo "source oaienv" >> $VM_CMDS - echo "cd cmake_targets/" >> $VM_CMDS - echo "mkdir log" >> $VM_CMDS - echo "chmod 777 log" >> $VM_CMDS - echo "cp /home/ubuntu/zip-install.txt log" >> $VM_CMDS - if [ $DAEMON -eq 0 ] - then - echo "echo \"./build_oai -I $BUILD_OPTIONS \"" >> $VM_CMDS - echo "./build_oai -I $BUILD_OPTIONS > log/install-build.txt 2>&1" >> $VM_CMDS - else - echo "echo \"./build_oai -I $BUILD_OPTIONS\" > ./my-vm-build.sh" >> $VM_CMDS - echo "chmod 775 ./my-vm-build.sh " >> $VM_CMDS - echo "echo \"sudo -E daemon --inherit --unsafe --name=build_daemon --chdir=/home/ubuntu/tmp/cmake_targets -o /home/ubuntu/tmp/cmake_targets/log/install-build.txt ./my-vm-build.sh\"" >> $VM_CMDS - echo "sudo -E daemon --inherit --unsafe --name=build_daemon --chdir=/home/ubuntu/tmp/cmake_targets -o /home/ubuntu/tmp/cmake_targets/log/install-build.txt ./my-vm-build.sh" >> $VM_CMDS - fi -fi -ssh -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR < $VM_CMDS -if [ $DAEMON -eq 1 ] -then - rm -f $VM_CMDS - echo "STATUS is OK" - exit 0 -fi -echo "############################################################" -echo "Creating a tmp folder to store results and artifacts" -echo "############################################################" -if [ ! -d $JENKINS_WKSP/archives ] -then - mkdir $JENKINS_WKSP/archives -fi - -if [ ! -d $ARCHIVES_LOC ] -then - mkdir $ARCHIVES_LOC -fi - -scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/*.txt $ARCHIVES_LOC -if [[ "$VM_NAME" == *"-cppcheck"* ]] -then - scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/*.xml $ARCHIVES_LOC -fi - -if [ $KEEP_VM_ALIVE -eq 0 ] -then echo "############################################################" - echo "Destroying VM" + echo "OAI CI VM script" echo "############################################################" - uvt-kvm destroy $VM_NAME - ssh-keygen -R $VM_IP_ADDR -fi -rm -f $VM_CMDS -echo "############################################################" -echo "Checking build status" -echo "############################################################" + echo "VM_NAME = $VM_NAME" + echo "VM_CMD_FILE = $VM_CMDS" + echo "JENKINS_WKSP = $JENKINS_WKSP" + echo "ARCHIVES_LOC = $ARCHIVES_LOC" + echo "BUILD_OPTIONS = $BUILD_OPTIONS" -LOG_FILES=`ls $ARCHIVES_LOC/*.txt $ARCHIVES_LOC/*.xml` -STATUS=0 -NB_FOUND_FILES=0 + IS_VM_ALIVE=`uvt-kvm list | grep -c $VM_NAME` -for FULLFILE in $LOG_FILES -do - if [[ $FULLFILE == *"$LOG_PATTERN"* ]] + if [ $IS_VM_ALIVE -eq 0 ] then - filename=$(basename -- "$FULLFILE") - if [ "$LOG_PATTERN" == ".Rel14.txt" ] + echo "VM_MEMORY = $VM_MEMORY MBytes" + echo "VM_CPU = $VM_CPU" + echo "############################################################" + echo "Creating VM ($VM_NAME) on Ubuntu Cloud Image base" + echo "############################################################" + uvt-kvm create $VM_NAME release=xenial --memory $VM_MEMORY --cpu $VM_CPU --unsafe-caching --template ci-scripts/template-host.xml + fi + + echo "Waiting for VM to be started" + uvt-kvm wait $VM_NAME --insecure + + VM_IP_ADDR=`uvt-kvm ip $VM_NAME` + echo "$VM_NAME has for IP addr = $VM_IP_ADDR" + + echo "############################################################" + echo "Copying GIT repo into VM ($VM_NAME)" + echo "############################################################" + scp -o StrictHostKeyChecking=no $JENKINS_WKSP/localZip.zip ubuntu@$VM_IP_ADDR:/home/ubuntu + scp -o StrictHostKeyChecking=no /etc/apt/apt.conf.d/01proxy ubuntu@$VM_IP_ADDR:/home/ubuntu + + echo "############################################################" + echo "Running install and build script on VM ($VM_NAME)" + echo "############################################################" + echo "sudo cp 01proxy /etc/apt/apt.conf.d/" > $VM_CMDS + echo "touch /home/ubuntu/.hushlogin" >> $VM_CMDS + if [[ "$VM_NAME" == *"-cppcheck"* ]] + then + if [ $DAEMON -eq 0 ] then - PASS_PATTERN=`echo $filename | sed -e "s#$LOG_PATTERN##"` - fi - if [ "$LOG_PATTERN" == "basic_simulator" ] - then - PASS_PATTERN="lte-" - fi - if [ "$LOG_PATTERN" == "cppcheck.xml" ] - then - PASS_PATTERN="results version" - LOCAL_STAT=`egrep -c "$PASS_PATTERN" $FULLFILE` + echo "echo \"sudo apt-get --yes --quiet install zip cppcheck \"" >> $VM_CMDS + echo "sudo apt-get update > zip-install.txt 2>&1" >> $VM_CMDS + echo "sudo apt-get --yes install zip cppcheck >> zip-install.txt 2>&1" >> $VM_CMDS else - LOCAL_STAT=`egrep -c "Built target $PASS_PATTERN" $FULLFILE` + echo "echo \"sudo apt-get --yes --quiet install zip daemon cppcheck \"" >> $VM_CMDS + echo "sudo apt-get update > zip-install.txt 2>&1" >> $VM_CMDS + echo "sudo apt-get --yes install zip daemon cppcheck >> zip-install.txt 2>&1" >> $VM_CMDS + fi + else + if [ $DAEMON -eq 0 ] + then + echo "echo \"sudo apt-get --yes --quiet install zip subversion libboost-dev \"" >> $VM_CMDS + echo "sudo apt-get update > zip-install.txt 2>&1" >> $VM_CMDS + echo "sudo apt-get --yes install zip subversion libboost-dev >> zip-install.txt 2>&1" >> $VM_CMDS + else + echo "echo \"sudo apt-get --yes --quiet install zip daemon subversion libboost-dev \"" >> $VM_CMDS + echo "sudo apt-get update > zip-install.txt 2>&1" >> $VM_CMDS + echo "sudo apt-get --yes install zip daemon subversion libboost-dev >> zip-install.txt 2>&1" >> $VM_CMDS fi - if [ $LOCAL_STAT -eq 0 ]; then STATUS=-1; fi - NB_FOUND_FILES=$((NB_FOUND_FILES + 1)) fi -done - -if [ $NB_PATTERN_FILES -ne $NB_FOUND_FILES ]; then STATUS=-1; fi - -if [ $STATUS -eq 0 ] -then - echo "STATUS seems OK" -else - echo "STATUS failed?" -fi -exit $STATUS + echo "mkdir tmp" >> $VM_CMDS + echo "cd tmp" >> $VM_CMDS + echo "echo \"unzip -qq -DD ../localZip.zip\"" >> $VM_CMDS + echo "unzip -qq -DD ../localZip.zip" >> $VM_CMDS + if [[ "$VM_NAME" == *"-cppcheck"* ]] + then + echo "mkdir cmake_targets/log" >> $VM_CMDS + echo "chmod 777 cmake_targets/log" >> $VM_CMDS + echo "cp /home/ubuntu/zip-install.txt cmake_targets/log" >> $VM_CMDS + echo "echo \"cppcheck $BUILD_OPTIONS . \"" >> $VM_CMDS + if [ $DAEMON -eq 0 ] + then + echo "cppcheck $BUILD_OPTIONS . 2> cmake_targets/log/cppcheck.xml 1> cmake_targets/log/cppcheck_build.txt" >> $VM_CMDS + else + echo "echo \"cppcheck $BUILD_OPTIONS .\" > ./my-vm-build.sh" >> $VM_CMDS + echo "chmod 775 ./my-vm-build.sh " >> $VM_CMDS + echo "sudo -E daemon --inherit --unsafe --name=build_daemon --chdir=/home/ubuntu/tmp -O /home/ubuntu/tmp/cmake_targets/log/cppcheck_build.txt -E /home/ubuntu/tmp/cmake_targets/log/cppcheck.xml ./my-vm-build.sh" >> $VM_CMDS + fi + else + echo "echo \"source oaienv\"" >> $VM_CMDS + echo "source oaienv" >> $VM_CMDS + echo "cd cmake_targets/" >> $VM_CMDS + echo "mkdir log" >> $VM_CMDS + echo "chmod 777 log" >> $VM_CMDS + echo "cp /home/ubuntu/zip-install.txt log" >> $VM_CMDS + if [ $DAEMON -eq 0 ] + then + echo "echo \"./build_oai -I $BUILD_OPTIONS \"" >> $VM_CMDS + echo "./build_oai -I $BUILD_OPTIONS > log/install-build.txt 2>&1" >> $VM_CMDS + else + echo "echo \"./build_oai -I $BUILD_OPTIONS\" > ./my-vm-build.sh" >> $VM_CMDS + echo "chmod 775 ./my-vm-build.sh " >> $VM_CMDS + echo "echo \"sudo -E daemon --inherit --unsafe --name=build_daemon --chdir=/home/ubuntu/tmp/cmake_targets -o /home/ubuntu/tmp/cmake_targets/log/install-build.txt ./my-vm-build.sh\"" >> $VM_CMDS + echo "sudo -E daemon --inherit --unsafe --name=build_daemon --chdir=/home/ubuntu/tmp/cmake_targets -o /home/ubuntu/tmp/cmake_targets/log/install-build.txt ./my-vm-build.sh" >> $VM_CMDS + fi + fi + ssh -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR < $VM_CMDS + rm -f $VM_CMDS +} diff --git a/ci-scripts/createVM.sh b/ci-scripts/createVM.sh index f972a921ac..192008d867 100755 --- a/ci-scripts/createVM.sh +++ b/ci-scripts/createVM.sh @@ -20,8 +20,8 @@ # * contact@openairinterface.org # */ -function usage { - echo "OAI VM Creation script" +function create_usage { + echo "OAI CI VM script" echo " Original Author: Raphael Defosseux" echo " Requirements:" echo " -- uvtool uvtool-libvirt apt-cacher" @@ -31,9 +31,9 @@ function usage { echo "" echo "Usage:" echo "------" - echo " createVM.sh [OPTIONS]" + echo " oai-ci-vm-tool create [OPTIONS]" echo "" - echo "Options:" + echo "Mandatory Options:" echo "--------" echo " --job-name #### OR -jn ####" echo " Specify the name of the Jenkins job." @@ -41,12 +41,7 @@ function usage { echo " --build-id #### OR -id ####" echo " Specify the build ID of the Jenkins job." echo "" - echo " --variant enb-usrp OR -v1" - echo " --variant basic-sim OR -v2" - echo " --variant phy-sim OR -v3" - echo " --variant cppcheck OR -v4" - echo " --variant enb-ethernet OR -v7" - echo " --variant ue-ethernet OR -v8" + variant_usage echo " Specify the variant to build." echo "" echo " --help OR -h" @@ -54,144 +49,21 @@ function usage { echo "" } -function variant_usage { - echo "OAI VM Build Check script" - echo " Original Author: Raphael Defosseux" - echo "" - echo " --variant enb-usrp OR -v1" - echo " --variant basic-sim OR -v2" - echo " --variant phy-sim OR -v3" - echo " --variant cppcheck OR -v4" - echo " --variant enb-ethernet OR -v7" - echo " --variant ue-ethernet OR -v8" - echo "" +function create_vm { + echo "############################################################" + echo "OAI CI VM script" + echo "############################################################" + echo "VM_NAME = $VM_NAME" + echo "VM_MEMORY = $VM_MEMORY MBytes" + echo "VM_CPU = $VM_CPU" + + echo "############################################################" + echo "Creating VM ($VM_NAME) on Ubuntu Cloud Image base" + echo "############################################################" + uvt-kvm create $VM_NAME release=xenial --memory $VM_MEMORY --cpu $VM_CPU --unsafe-caching --template ci-scripts/template-host.xml + echo "Waiting for VM to be started" + uvt-kvm wait $VM_NAME --insecure + + VM_IP_ADDR=`uvt-kvm ip $VM_NAME` + echo "$VM_NAME has for IP addr = $VM_IP_ADDR" } - -if [ $# -lt 1 ] || [ $# -gt 6 ] -then - echo "Syntax Error: not the correct number of arguments" - echo "" - usage - exit 1 -fi - -VM_TEMPLATE=ci- -JOB_NAME=XX -BUILD_ID=XX -VM_NAME=ci-enb-usrp -VM_MEMORY=2048 -VM_CPU=4 - -while [[ $# -gt 0 ]] -do -key="$1" - -case $key in - -h|--help) - shift - usage - exit 0 - ;; - -jn|--job-name) - JOB_NAME="$2" - shift - shift - ;; - -id|--build-id) - BUILD_ID="$2" - shift - shift - ;; - -v1) - VM_NAME=ci-enb-usrp - shift - ;; - -v2) - VM_NAME=ci-basic-sim - VM_MEMORY=8192 - shift - ;; - -v3) - VM_NAME=ci-phy-sim - shift - ;; - -v4) - VM_NAME=ci-cppcheck - VM_MEMORY=4096 - VM_CPU=4 - shift - ;; - -v7) - VM_NAME=ci-enb-ethernet - shift - ;; - -v8) - VM_NAME=ci-ue-ethernet - shift - ;; - --variant) - variant="$2" - case $variant in - enb-usrp) - VM_NAME=ci-enb-usrp - ;; - basic-sim) - VM_NAME=ci-basic-sim - VM_MEMORY=8192 - ;; - phy-sim) - VM_NAME=ci-phy-sim - ;; - cppcheck) - VM_NAME=ci-cppcheck - VM_MEMORY=4096 - VM_CPU=4 - ;; - enb-ethernet) - VM_NAME=ci-enb-ethernet - ;; - ue-ethernet) - VM_NAME=ci-ue-ethernet - ;; - *) - echo "" - echo "Syntax Error: Invalid Variant option -> $variant" - echo "" - variant_usage - exit 1 - esac - shift - shift - ;; - *) - echo "Syntax Error: unknown option: $key" - echo "" - usage - exit 1 -esac -done - -if [ "$JOB_NAME" == "XX" ] || [ "$BUILD_ID" == "XX" ] -then - VM_TEMPLATE=ci- -else - VM_TEMPLATE=${JOB_NAME}-b${BUILD_ID}- -fi - -VM_NAME=`echo $VM_NAME | sed -e "s#ci-#$VM_TEMPLATE#"` -VM_CMDS=${VM_NAME}_cmds.txt - -echo "VM_NAME = $VM_NAME" -echo "VM_MEMORY = $VM_MEMORY MBytes" -echo "VM_CPU = $VM_CPU" - -echo "############################################################" -echo "Creating VM ($VM_NAME) on Ubuntu Cloud Image base" -echo "############################################################" -uvt-kvm create $VM_NAME release=xenial --memory $VM_MEMORY --cpu $VM_CPU --unsafe-caching --template ci-scripts/template-host.xml -echo "Waiting for VM to be started" -uvt-kvm wait $VM_NAME --insecure - -VM_IP_ADDR=`uvt-kvm ip $VM_NAME` -echo "$VM_NAME has for IP addr = $VM_IP_ADDR" -exit 0 diff --git a/ci-scripts/destroyAllRunningVM.sh b/ci-scripts/destroyAllRunningVM.sh index 5e152bc590..76a7fd0b50 100755 --- a/ci-scripts/destroyAllRunningVM.sh +++ b/ci-scripts/destroyAllRunningVM.sh @@ -20,15 +20,17 @@ # * contact@openairinterface.org # */ -function usage { - echo "OAI VM Destroy script" +function destroy_usage { + echo "OAI CI VM script" echo " Original Author: Raphael Defosseux" + echo " Requirements:" + echo " -- uvtool uvtool-libvirt apt-cacher" echo "" echo "Usage:" echo "------" - echo " destroyAllRunningVM.sh [OPTIONS]" + echo " oai-ci-vm-tool destroy [OPTIONS]" echo "" - echo "Options:" + echo "Mandatory Options:" echo "--------" echo " --job-name #### OR -jn ####" echo " Specify the name of the Jenkins job." @@ -36,66 +38,26 @@ function usage { echo " --build-id #### OR -id ####" echo " Specify the build ID of the Jenkins job." echo "" + echo "Options:" + echo "--------" echo " --help OR -h" echo " Print this help message." echo "" } -if [ $# -gt 4 ] -then - echo "Syntax Error: not the correct number of arguments" - echo "" - usage - exit 1 -fi +function destroy_vm { + echo "############################################################" + echo "OAI CI VM script" + echo "############################################################" + echo "VM_TEMPLATE = $VM_TEMPLATE" -VM_TEMPLATE=ci- -JOB_NAME=XX -BUILD_ID=XX - -while [[ $# -gt 0 ]] -do -key="$1" -case $key in - -h|--help) - shift - usage - exit 0 - ;; - -jn|--job-name) - JOB_NAME="$2" - shift - shift - ;; - -id|--build-id) - BUILD_ID="$2" - shift - shift - ;; - *) - echo "Syntax Error: unknown option: $key" - echo "" - usage - exit 1 -esac -done - -if [ "$JOB_NAME" == "XX" ] || [ "$BUILD_ID" == "XX" ] -then - VM_TEMPLATE=ci- -else - VM_TEMPLATE=${JOB_NAME}-b${BUILD_ID}- -fi - -LIST_CI_VM=`uvt-kvm list | grep $VM_TEMPLATE` - -for CI_VM in $LIST_CI_VM -do - VM_IP_ADDR=`uvt-kvm ip $CI_VM` - echo "VM to destroy: $CI_VM -- IP $VM_IP_ADDR" - uvt-kvm destroy $CI_VM - ssh-keygen -R $VM_IP_ADDR -done - -exit 0 + LIST_CI_VM=`uvt-kvm list | grep $VM_TEMPLATE` + for CI_VM in $LIST_CI_VM + do + VM_IP_ADDR=`uvt-kvm ip $CI_VM` + echo "VM to destroy: $CI_VM -- IP $VM_IP_ADDR" + uvt-kvm destroy $CI_VM + ssh-keygen -R $VM_IP_ADDR + done +} diff --git a/ci-scripts/oai-ci-vm-tool b/ci-scripts/oai-ci-vm-tool new file mode 100755 index 0000000000..cfa18ece2e --- /dev/null +++ b/ci-scripts/oai-ci-vm-tool @@ -0,0 +1,537 @@ +#!/bin/bash +#/* +# * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more +# * contributor license agreements. See the NOTICE file distributed with +# * this work for additional information regarding copyright ownership. +# * The OpenAirInterface Software Alliance licenses this file to You under +# * the OAI Public License, Version 1.1 (the "License"); you may not use this file +# * except in compliance with the License. +# * You may obtain a copy of the License at +# * +# * http://www.openairinterface.org/?page_id=698 +# * +# * Unless required by applicable law or agreed to in writing, software +# * distributed under the License is distributed on an "AS IS" BASIS, +# * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# * See the License for the specific language governing permissions and +# * limitations under the License. +# *------------------------------------------------------------------------------- +# * For more information about the OpenAirInterface (OAI) Software Alliance: +# * contact@openairinterface.org +# */ + +function top_usage { + echo "OAI CI VM script" + echo " Original Author: Raphael Defosseux" + echo " Requirements:" + echo " -- uvtool uvtool-libvirt apt-cacher" + echo " -- xenial image already synced" + echo "" + echo "Usage:" + echo "------" + echo " oai-ci-vm-tool (-h|--help) {create,destroy,build,wait,test,report-build,report-test} ..." + echo "" +} + +function variant_usage { + echo " --variant enb-usrp OR -v1" + echo " --variant basic-sim OR -v2" + echo " --variant phy-sim OR -v3" + echo " --variant cppcheck OR -v4" + echo " --variant enb-ethernet OR -v7" + echo " --variant ue-ethernet OR -v8" +} + +MY_DIR=$(dirname $(readlink -f $0)) +. $MY_DIR/createVM.sh +. $MY_DIR/buildOnVM.sh +. $MY_DIR/waitBuildOnVM.sh +. $MY_DIR/destroyAllRunningVM.sh +. $MY_DIR/runTestOnVM.sh +. $MY_DIR/reportBuildLocally.sh +. $MY_DIR/reportTestLocally.sh + +if [ $# -lt 1 ] +then + echo "Syntax Error: too few arguments" + echo "" + top_usage + exit 1 +fi + +VM_TEMPLATE=ci- +JOB_NAME=XX +BUILD_ID=XX +VM_NAME=ci-enb-usrp +VM_MEMORY=2048 +VM_CPU=4 +ARCHIVES_LOC=enb_usrp +LOG_PATTERN=.Rel14.txt +NB_PATTERN_FILES=4 +BUILD_OPTIONS="--eNB -w USRP" +KEEP_VM_ALIVE=0 +RUN_OPTIONS="none" +DAEMON=0 +MR_TRIG=0 +PU_TRIG=0 + +HELP_CMD=0 +CREATE_CMD=0 +BUILD_CMD=0 +WAIT_CMD=0 +DESTROY_CMD=0 +TEST_CMD=0 +REPORT_BUILD_CMD=0 +REPORT_TEST_CMD=0 +NBARGS=0 + +while [[ $# -gt 0 ]] +do +key="$1" + +case $key in + -h|--help) + HELP_CMD=1 + shift + ;; + create) + CREATE_CMD=1 + # It is implied to keep the VM when creating it + KEEP_VM_ALIVE=1 + shift + ;; + build) + BUILD_CMD=1 + shift + ;; + wait) + WAIT_CMD=1 + shift + ;; + test) + TEST_CMD=1 + shift + ;; + destroy) + DESTROY_CMD=1 + shift + ;; + report-build) + REPORT_BUILD_CMD=1 + shift + ;; + report-test) + REPORT_TEST_CMD=1 + shift + ;; + -jn|--job-name) + JOB_NAME="$2" + NBARGS=$[$NBARGS+1] + shift + shift + ;; + -id|--build-id) + BUILD_ID="$2" + NBARGS=$[$NBARGS+2] + shift + shift + ;; + -ws|--workspace) + JENKINS_WKSP="$2" + NBARGS=$[$NBARGS+4] + shift + shift + ;; + -k|--keep-vm-alive) + KEEP_VM_ALIVE=1 + NBARGS=$[$NBARGS+8] + shift + ;; + -D|--daemon) + DAEMON=1 + NBARGS=$[$NBARGS+16] + shift + ;; + -gu|--git-url) + GIT_URL="$2" + NBARGS=$[$NBARGS+32] + shift + shift + ;; + --trigger) + TRIG="$2" + case $TRIG in + merge-request) + MR_TRIG=1 + ;; + push) + PU_TRIG=1 + ;; + *) + echo "" + echo "Syntax Error: Invalid Trigger option -> $TRIG" + echo "" + trigger_usage + exit + ;; + esac + NBARGS=$[$NBARGS+64] + shift + shift + ;; + -mr) + MR_TRIG=1 + NBARGS=$[$NBARGS+64] + shift + ;; + -pu) + PU_TRIG=1 + NBARGS=$[$NBARGS+64] + shift + ;; + -sb|--src-branch) + SOURCE_BRANCH="$2" + NBARGS=$[$NBARGS+1024] + shift + shift + ;; + -sc|--src-commit) + SOURCE_COMMIT_ID="$2" + NBARGS=$[$NBARGS+2048] + shift + shift + ;; + -tb|--target-branch) + TARGET_BRANCH="$2" + NBARGS=$[$NBARGS+4096] + shift + shift + ;; + -tc|--target-commit) + TARGET_COMMIT_ID="$2" + NBARGS=$[$NBARGS+8192] + shift + shift + ;; + -br|--branch) + SOURCE_BRANCH="$2" + NBARGS=$[$NBARGS+16384] + shift + shift + ;; + -co|--commit) + SOURCE_COMMIT_ID="$2" + NBARGS=$[$NBARGS+32768] + shift + shift + ;; + -v1) + VM_NAME=ci-enb-usrp + ARCHIVES_LOC=enb_usrp + LOG_PATTERN=.Rel14.txt + NB_PATTERN_FILES=4 + BUILD_OPTIONS="--eNB -w USRP --mu" + NBARGS=$[$NBARGS+256] + shift + ;; + -v2) + VM_NAME=ci-basic-sim + ARCHIVES_LOC=basic_sim + LOG_PATTERN=basic_simulator + NB_PATTERN_FILES=2 + BUILD_OPTIONS="--basic-simulator" + VM_MEMORY=8192 + VM_CPU=4 + RUN_OPTIONS="complex" + NBARGS=$[$NBARGS+256] + shift + ;; + -v3) + VM_NAME=ci-phy-sim + ARCHIVES_LOC=phy_sim + LOG_PATTERN=.Rel14.txt + NB_PATTERN_FILES=3 + BUILD_OPTIONS="--phy_simulators" + RUN_OPTIONS="./run_exec_autotests.bash -g \"01510*\" -q -np -b" + NBARGS=$[$NBARGS+256] + shift + ;; + -v4) + VM_NAME=ci-cppcheck + VM_MEMORY=4096 + ARCHIVES_LOC=cppcheck + LOG_PATTERN=cppcheck.xml + NB_PATTERN_FILES=1 + BUILD_OPTIONS="--enable=warning --force --xml --xml-version=2" + NBARGS=$[$NBARGS+256] + shift + ;; + -v7) + VM_NAME=ci-enb-ethernet + ARCHIVES_LOC=enb_eth + LOG_PATTERN=.Rel14.txt + NB_PATTERN_FILES=6 + BUILD_OPTIONS="--eNB -t ETHERNET --noS1" + NBARGS=$[$NBARGS+256] + shift + ;; + -v8) + VM_NAME=ci-ue-ethernet + ARCHIVES_LOC=ue_eth + LOG_PATTERN=.Rel14.txt + NB_PATTERN_FILES=6 + BUILD_OPTIONS="--UE -t ETHERNET --noS1" + NBARGS=$[$NBARGS+256] + shift + ;; + --variant) + variant="$2" + case $variant in + enb-usrp) + VM_NAME=ci-enb-usrp + ARCHIVES_LOC=enb_usrp + LOG_PATTERN=.Rel14.txt + NB_PATTERN_FILES=4 + BUILD_OPTIONS="--eNB -w USRP --mu" + NBARGS=$[$NBARGS+256] + ;; + basic-sim) + VM_NAME=ci-basic-sim + ARCHIVES_LOC=basic_sim + LOG_PATTERN=basic_simulator + NB_PATTERN_FILES=2 + BUILD_OPTIONS="--basic-simulator" + VM_MEMORY=8192 + VM_CPU=4 + RUN_OPTIONS="complex" + NBARGS=$[$NBARGS+256] + ;; + phy-sim) + VM_NAME=ci-phy-sim + ARCHIVES_LOC=phy_sim + LOG_PATTERN=.Rel14.txt + NB_PATTERN_FILES=3 + BUILD_OPTIONS="--phy_simulators" + RUN_OPTIONS="./run_exec_autotests.bash -g \"01510*\" -q -np -b" + NBARGS=$[$NBARGS+256] + ;; + cppcheck) + VM_NAME=ci-cppcheck + VM_MEMORY=8192 + ARCHIVES_LOC=cppcheck + LOG_PATTERN=cppcheck.xml + NB_PATTERN_FILES=1 + BUILD_OPTIONS="--enable=warning --force --xml --xml-version=2" + NBARGS=$[$NBARGS+256] + ;; + enb-ethernet) + VM_NAME=ci-enb-ethernet + ARCHIVES_LOC=enb_eth + LOG_PATTERN=.Rel14.txt + NB_PATTERN_FILES=6 + BUILD_OPTIONS="--eNB -t ETHERNET --noS1" + NBARGS=$[$NBARGS+256] + ;; + ue-ethernet) + VM_NAME=ci-ue-ethernet + ARCHIVES_LOC=ue_eth + LOG_PATTERN=.Rel14.txt + NB_PATTERN_FILES=6 + BUILD_OPTIONS="--UE -t ETHERNET --noS1" + NBARGS=$[$NBARGS+256] + ;; + *) + echo "" + echo "Syntax Error: Invalid Variant option -> $variant" + echo "" + variant_usage + exit 1 + esac + shift + shift + ;; + *) + echo "Syntax Error: unknown option: $key" + echo "" + top_usage + exit 1 +esac +done + +MANY_CMDS=$[$CREATE_CMD+$BUILD_CMD+$WAIT_CMD+$DESTROY_CMD+$TEST_CMD+$REPORT_BUILD_CMD+$REPORT_TEST_CMD] +if [ $MANY_CMDS -gt 1 ] +then + echo "Syntax Error: too many commands" + top_usage + exit 1 +fi + +if [ $HELP_CMD -eq 1 ] +then + if [ $MANY_CMDS -eq 0 ] + then + top_usage + exit 0 + fi + if [ $CREATE_CMD -eq 1 ] + then + create_usage + exit 0 + fi + if [ $BUILD_CMD -eq 1 ] + then + build_usage + exit 0 + fi + if [ $WAIT_CMD -eq 1 ] + then + wait_usage + exit 0 + fi + if [ $TEST_CMD -eq 1 ] + then + run_test_usage + exit 0 + fi + if [ $DESTROY_CMD -eq 1 ] + then + destroy_usage + exit 0 + fi + if [ $REPORT_BUILD_CMD -eq 1 ] + then + report_build_usage + exit 0 + fi + if [ $REPORT_TEST_CMD -eq 1 ] + then + report_test_usage + exit 0 + fi +else + if [ $MANY_CMDS -eq 0 ] + then + echo "Syntax Error: no command" + top_usage + exit 1 + fi + # For create, mandatory options: jn, id. Optional: variant + if [ $CREATE_CMD -eq 1 ] && [ $NBARGS -ne 3 ] && [ $NBARGS -ne 259 ] + then + echo "Syntax Error: unsupported option(s) for create command" + create_usage + exit 1 + fi + # For build, mandatory options: jn, id, ws. Optional: variant, k, D + if [ $BUILD_CMD -eq 1 ] && [ $NBARGS -ne 7 ] && [ $NBARGS -ne 263 ] && [ $NBARGS -ne 15 ] && [ $NBARGS -ne 271 ] && [ $NBARGS -ne 23 ] && [ $NBARGS -ne 279 ] && [ $NBARGS -ne 31 ] && [ $NBARGS -ne 287 ] + then + echo "Syntax Error: unsupported option(s) for build command" + build_usage + exit 1 + fi + # For wait, mandatory options: jn, id, ws. Optional: variant, k + if [ $WAIT_CMD -eq 1 ] && [ $NBARGS -ne 7 ] && [ $NBARGS -ne 263 ] && [ $NBARGS -ne 15 ] && [ $NBARGS -ne 271 ] + then + echo "Syntax Error: unsupported option(s) for wait command" + wait_usage + exit 1 + fi + # For test, mandatory options: jn, id, ws. Optional: variant, k + if [ $TEST_CMD -eq 1 ] && [ $NBARGS -ne 7 ] && [ $NBARGS -ne 263 ] && [ $NBARGS -ne 15 ] && [ $NBARGS -ne 271 ] + then + echo "Syntax Error: unsupported option(s) for test command" + run_test_usage + exit 1 + fi + # For destroy, mandatory options: jn, id. + if [ $DESTROY_CMD -eq 1 ] && [ $NBARGS -ne 3 ] + then + echo "Syntax Error: unsupported option(s) for destroy command" + destroy_usage + exit 1 + fi + # For report-build, mandatory options: jn, id, ws, gu, pu, br,co. + # or: jn, id, ws, gu, mr, sb, sc, tb, tc. + if [ $REPORT_BUILD_CMD -eq 1 ] && [ $NBARGS -ne 15463 ] && [ $NBARGS -ne 49255 ] + then + echo "Syntax Error: unsupported option(s) for report-build command" + report_build_usage + exit 1 + fi + # For report-test, mandatory options: jn, id, ws, gu, pu, br,co. + # or: jn, id, ws, gu, mr, sb, sc, tb, tc. + if [ $REPORT_TEST_CMD -eq 1 ] && [ $NBARGS -ne 15463 ] && [ $NBARGS -ne 49255 ] + then + echo "Syntax Error: unsupported option(s) for report-test command" + report_test_usage + exit 1 + fi +fi + +# Checking uvt-kvm is installed +UVT_KVM_PATH=`which uvt-kvm | grep -c uvt-kvm` +if [ $UVT_KVM_PATH -eq 0 ] +then + echo "Error: uvt-kvm is not installed" + top_usage + exit 1 +fi + +if [ "$JOB_NAME" == "XX" ] || [ "$BUILD_ID" == "XX" ] +then + VM_TEMPLATE=ci- +else + VM_TEMPLATE=${JOB_NAME}-b${BUILD_ID}- +fi + +VM_NAME=`echo $VM_NAME | sed -e "s#ci-#$VM_TEMPLATE#"` +VM_CMDS=${VM_NAME}_cmds.txt +ARCHIVES_LOC=${JENKINS_WKSP}/archives/${ARCHIVES_LOC} + +STATUS=0 +if [ $CREATE_CMD -eq 1 ] +then + create_vm +fi +if [ $BUILD_CMD -eq 1 ] +then + build_on_vm + if [ $DAEMON -eq 0 ] && [ $STATUS -eq 0 ] + then + check_on_vm_build + fi +fi +if [ $WAIT_CMD -eq 1 ] +then + wait_on_vm_build + if [ $STATUS -eq 0 ] + then + check_on_vm_build + fi +fi +if [ $TEST_CMD -eq 1 ] +then + ARCHIVES_LOC=${ARCHIVES_LOC}/test + run_test_on_vm +fi +if [ $DESTROY_CMD -eq 1 ] +then + destroy_vm +fi +if [ $REPORT_BUILD_CMD -eq 1 ] +then + report_build +fi +if [ $REPORT_TEST_CMD -eq 1 ] +then + report_test +fi + +# Did command pass or fail? +if [ $STATUS -eq 0 ] +then + echo "STATUS seems OK" +else + echo "STATUS failed?" +fi +exit $STATUS diff --git a/ci-scripts/reportBuildLocally.sh b/ci-scripts/reportBuildLocally.sh index 1a02d72ad2..1b97841e69 100755 --- a/ci-scripts/reportBuildLocally.sh +++ b/ci-scripts/reportBuildLocally.sh @@ -20,14 +20,13 @@ # * contact@openairinterface.org # */ -function usage { - echo "OAI Local Build Report script" +function report_build_usage { + echo "OAI CI VM script" echo " Original Author: Raphael Defosseux" echo "" echo "Usage:" echo "------" - echo "" - echo " reportBuildLocally.sh [OPTIONS]" + echo " oai-ci-vm-tool report-build [OPTIONS]" echo "" echo "Options:" echo "--------" @@ -47,6 +46,9 @@ function usage { echo " --build-id #### OR -id ####" echo " Specify the build ID of the Jenkins job." echo "" + echo " --workspace #### OR -ws ####" + echo " Specify the workspace." + echo "" echo " --trigger merge-request OR -mr" echo " --trigger push OR -pu" echo " Specify trigger action of the Jenkins job. Either a merge-request event or a push event." @@ -79,7 +81,7 @@ function usage { } function trigger_usage { - echo "OAI Local Build Report script" + echo "OAI CI VM script" echo " Original Author: Raphael Defosseux" echo "" echo " --trigger merge-request OR -mr" @@ -153,8 +155,8 @@ function summary_table_row { echo " $1" >> ./build_results.html if [ -f $2 ] then - STATUS=`egrep -c "$3" $2` - if [ $STATUS -eq 1 ] + BUILD_STATUS=`egrep -c "$3" $2` + if [ $BUILD_STATUS -eq 1 ] then echo " OK" >> ./build_results.html else @@ -263,342 +265,233 @@ function sca_summary_table_footer { echo "

Graphical Interface tool : cppcheck-gui -l cppcheck/cppcheck.xml

" >> ./build_results.html } -jb_checker=0 -mr_checker=0 -pu_checker=0 -MR_TRIG=0 -PU_TRIG=0 -while [[ $# -gt 0 ]] -do -key="$1" +function report_build { + echo "############################################################" + echo "OAI CI VM script" + echo "############################################################" -case $key in - -h|--help) - shift - usage - exit 0 - ;; - -gu|--git-url) - GIT_URL="$2" - let "jb_checker|=0x1" - shift - shift - ;; - -jn|--job-name) - JOB_NAME="$2" - let "jb_checker|=0x2" - shift - shift - ;; - -id|--build-id) - BUILD_ID="$2" - let "jb_checker|=0x4" - shift - shift - ;; - --trigger) - TRIG="$2" - case $TRIG in - merge-request) - MR_TRIG=1 - ;; - push) - PU_TRIG=1 - ;; - *) - echo "" - echo "Syntax Error: Invalid Trigger option -> $TRIG" - echo "" - trigger_usage - exit - ;; - esac - let "jb_checker|=0x8" - shift - shift - ;; - -mr) - MR_TRIG=1 - let "jb_checker|=0x8" - shift - ;; - -pu) - PU_TRIG=1 - let "jb_checker|=0x8" - shift - ;; - -sb|--src-branch) - SOURCE_BRANCH="$2" - let "mr_checker|=0x1" - shift - shift - ;; - -sc|--src-commit) - SOURCE_COMMIT_ID="$2" - let "mr_checker|=0x2" - shift - shift - ;; - -tb|--target-branch) - TARGET_BRANCH="$2" - let "mr_checker|=0x4" - shift - shift - ;; - -tc|--target-commit) - TARGET_COMMIT_ID="$2" - let "mr_checker|=0x8" - shift - shift - ;; - -br|--branch) - SOURCE_BRANCH="$2" - let "pu_checker|=0x1" - shift - shift - ;; - -co|--commit) - SOURCE_COMMIT_ID="$2" - let "pu_checker|=0x2" - shift - shift - ;; - *) - echo "Syntax Error: unknown option: $key" - echo "" - usage - exit 1 - ;; -esac + echo "JENKINS_WKSP = $JENKINS_WKSP" -done - -if [ $jb_checker -ne 15 ] -then - echo "" - echo "Syntax Error: missing job information." - # TODO : list missing info - echo "" - exit 1 -fi - -if [ $PU_TRIG -eq 1 ] && [ $MR_TRIG -eq 1 ] -then - echo "" - echo "Syntax Error: trigger action incoherent." - echo "" - trigger_usage - exit 1 -fi - -if [ $PU_TRIG -eq 1 ] -then - if [ $pu_checker -ne 3 ] + cd ${JENKINS_WKSP} + echo "" > ./build_results.html + echo "" >> ./build_results.html + echo "" >> ./build_results.html + echo " Build Results for $JOB_NAME job build #$BUILD_ID" >> ./build_results.html + echo " " >> ./build_results.html + echo "" >> ./build_results.html + echo "" >> ./build_results.html + echo " " >> ./build_results.html + echo " " >> ./build_results.html + echo " " >> ./build_results.html + echo " " >> ./build_results.html + echo " " >> ./build_results.html + echo "
" >> ./build_results.html + echo " " >> ./build_results.html + echo " \"\"" >> ./build_results.html + echo " " >> ./build_results.html + echo " " >> ./build_results.html + echo " " >> ./build_results.html + echo " Job Summary -- Job: $JOB_NAME -- Build-ID: $BUILD_ID" >> ./build_results.html + echo "
" >> ./build_results.html + echo "
" >> ./build_results.html + echo " " >> ./build_results.html + echo " " >> ./build_results.html + echo " " >> ./build_results.html + echo " " >> ./build_results.html + echo " " >> ./build_results.html + echo " " >> ./build_results.html + echo " " >> ./build_results.html + echo " " >> ./build_results.html + echo " " >> ./build_results.html + echo " " >> ./build_results.html + echo " " >> ./build_results.html + if [ $PU_TRIG -eq 1 ]; then echo " " >> ./build_results.html; fi + if [ $MR_TRIG -eq 1 ]; then echo " " >> ./build_results.html; fi + echo " " >> ./build_results.html + if [ $PU_TRIG -eq 1 ] then - echo "" - echo "Syntax Error: missing push information." - # TODO : list missing info - echo "" - exit 1 + echo " " >> ./build_results.html + echo " " >> ./build_results.html + echo " " >> ./build_results.html + echo " " >> ./build_results.html + echo " " >> ./build_results.html + echo " " >> ./build_results.html + echo " " >> ./build_results.html + echo " " >> ./build_results.html fi -fi - -if [ $MR_TRIG -eq 1 ] -then - if [ $mr_checker -ne 15 ] + if [ $MR_TRIG -eq 1 ] then - echo "" - echo "Syntax Error: missing merge-request information." - # TODO : list missing info - echo "" - exit 1 + echo " " >> ./build_results.html + echo " " >> ./build_results.html + echo " " >> ./build_results.html + echo " " >> ./build_results.html + echo " " >> ./build_results.html + echo " " >> ./build_results.html + echo " " >> ./build_results.html + echo " " >> ./build_results.html + echo " " >> ./build_results.html + echo " " >> ./build_results.html + echo " " >> ./build_results.html + echo " " >> ./build_results.html + echo " " >> ./build_results.html + echo " " >> ./build_results.html + echo " " >> ./build_results.html + echo " " >> ./build_results.html fi -fi + echo "
Build Start Time (UTC)TEMPLATE_BUILD_TIME
GIT Repository$GIT_URL
Job TriggerPush EventMerge-Request
Branch$SOURCE_BRANCH
Commit ID$SOURCE_COMMIT_ID
Source Branch$SOURCE_BRANCH
Source Commit ID$SOURCE_COMMIT_ID
Target Branch$TARGET_BRANCH
Target Commit ID$TARGET_COMMIT_ID
" >> ./build_results.html + echo "

Build Summary

" >> ./build_results.html -echo "" > ./build_results.html -echo "" >> ./build_results.html -echo "" >> ./build_results.html -echo " Build Results for $JOB_NAME job build #$BUILD_ID" >> ./build_results.html -echo " " >> ./build_results.html -echo "" >> ./build_results.html -echo "" >> ./build_results.html -echo " " >> ./build_results.html -echo " " >> ./build_results.html -echo " " >> ./build_results.html -echo " " >> ./build_results.html -echo " " >> ./build_results.html -echo "
" >> ./build_results.html -echo " " >> ./build_results.html -echo " \"\"" >> ./build_results.html -echo " " >> ./build_results.html -echo " " >> ./build_results.html -echo " " >> ./build_results.html -echo " Job Summary -- Job: $JOB_NAME -- Build-ID: $BUILD_ID" >> ./build_results.html -echo "
" >> ./build_results.html -echo "
" >> ./build_results.html -echo " " >> ./build_results.html -echo " " >> ./build_results.html -echo " " >> ./build_results.html -echo " " >> ./build_results.html -echo " " >> ./build_results.html -echo " " >> ./build_results.html -echo " " >> ./build_results.html -echo " " >> ./build_results.html -echo " " >> ./build_results.html -echo " " >> ./build_results.html -echo " " >> ./build_results.html -if [ $PU_TRIG -eq 1 ]; then echo " " >> ./build_results.html; fi -if [ $MR_TRIG -eq 1 ]; then echo " " >> ./build_results.html; fi -echo " " >> ./build_results.html -if [ $PU_TRIG -eq 1 ] -then - echo " " >> ./build_results.html - echo " " >> ./build_results.html - echo " " >> ./build_results.html - echo " " >> ./build_results.html - echo " " >> ./build_results.html - echo " " >> ./build_results.html - echo " " >> ./build_results.html - echo " " >> ./build_results.html -fi -if [ $MR_TRIG -eq 1 ] -then - echo " " >> ./build_results.html - echo " " >> ./build_results.html - echo " " >> ./build_results.html - echo " " >> ./build_results.html - echo " " >> ./build_results.html - echo " " >> ./build_results.html - echo " " >> ./build_results.html - echo " " >> ./build_results.html - echo " " >> ./build_results.html - echo " " >> ./build_results.html - echo " " >> ./build_results.html - echo " " >> ./build_results.html - echo " " >> ./build_results.html - echo " " >> ./build_results.html - echo " " >> ./build_results.html - echo " " >> ./build_results.html -fi -echo "
Build Start Time (UTC)TEMPLATE_BUILD_TIME
GIT Repository$GIT_URL
Job TriggerPush EventMerge-Request
Branch$SOURCE_BRANCH
Commit ID$SOURCE_COMMIT_ID
Source Branch$SOURCE_BRANCH
Source Commit ID$SOURCE_COMMIT_ID
Target Branch$TARGET_BRANCH
Target Commit ID$TARGET_COMMIT_ID
" >> ./build_results.html -echo "

Build Summary

" >> ./build_results.html - -if [ -f ./oai_rules_result.txt ] -then - echo "

OAI Coding / Formatting Guidelines Check

" >> ./build_results.html - echo " " >> ./build_results.html - echo " " >> ./build_results.html - echo " " >> ./build_results.html - NB_FILES=`cat ./oai_rules_result.txt` - if [ $NB_FILES = "0" ] - then - if [ $PU_TRIG -eq 1 ]; then echo " " >> ./build_results.html; fi - if [ $MR_TRIG -eq 1 ]; then echo " " >> ./build_results.html; fi - echo " " >> ./build_results.html - echo "
Result:All files in repository follow OAI rules. All modified files in Merge-Request follow OAI rules.
" >> ./build_results.html - else - if [ $PU_TRIG -eq 1 ]; then echo " $NB_FILES files in repository DO NOT follow OAI rules. " >> ./build_results.html; fi - if [ $MR_TRIG -eq 1 ]; then echo " $NB_FILES modified files in Merge-Request DO NOT follow OAI rules." >> ./build_results.html; fi - echo " " >> ./build_results.html - if [ -f ./oai_rules_result_list.txt ] - then - awk '{print " "$1""}' ./oai_rules_result_list.txt >> ./build_results.html + if [ -f ./oai_rules_result.txt ] + then + echo "

OAI Coding / Formatting Guidelines Check

" >> ./build_results.html + echo " " >> ./build_results.html + echo " " >> ./build_results.html + echo " " >> ./build_results.html + NB_FILES=`cat ./oai_rules_result.txt` + if [ $NB_FILES = "0" ] + then + if [ $PU_TRIG -eq 1 ]; then echo " " >> ./build_results.html; fi + if [ $MR_TRIG -eq 1 ]; then echo " " >> ./build_results.html; fi + echo " " >> ./build_results.html + echo "
Result:All files in repository follow OAI rules. All modified files in Merge-Request follow OAI rules.
" >> ./build_results.html + else + if [ $PU_TRIG -eq 1 ]; then echo " $NB_FILES files in repository DO NOT follow OAI rules. " >> ./build_results.html; fi + if [ $MR_TRIG -eq 1 ]; then echo " $NB_FILES modified files in Merge-Request DO NOT follow OAI rules." >> ./build_results.html; fi + echo " " >> ./build_results.html + if [ -f ./oai_rules_result_list.txt ] + then + awk '{print " "$1""}' ./oai_rules_result_list.txt >> ./build_results.html + fi + echo " " >> ./build_results.html + echo "

Please apply the following command to this(ese) file(s):

" >> ./build_results.html + echo "

astyle --options=ci-scripts/astyle-options.txt filename(s)

" >> ./build_results.html fi - echo " " >> ./build_results.html - echo "

Please apply the following command to this(ese) file(s):

" >> ./build_results.html - echo "

astyle --options=ci-scripts/astyle-options.txt filename(s)

" >> ./build_results.html fi -fi -echo "

Ubuntu 16.04 LTS -- Summary

" >> ./build_results.html + echo "

Ubuntu 16.04 LTS -- Summary

" >> ./build_results.html -sca_summary_table_header "OAI Static Code Analysis with CPPCHECK" -sca_summary_table_row ./archives/cppcheck/cppcheck.xml "Uninitialized variable" uninitvar -sca_summary_table_row ./archives/cppcheck/cppcheck.xml "Uninitialized struct member" uninitStructMember -sca_summary_table_row ./archives/cppcheck/cppcheck.xml "Memory leak" memleak -sca_summary_table_row ./archives/cppcheck/cppcheck.xml "Memory is freed twice" doubleFree -sca_summary_table_row ./archives/cppcheck/cppcheck.xml "Resource leak" resourceLeak -sca_summary_table_row ./archives/cppcheck/cppcheck.xml "Possible null pointer dereference" nullPointer -sca_summary_table_row ./archives/cppcheck/cppcheck.xml "Array access out of bounds" arrayIndexOutOfBounds -sca_summary_table_row ./archives/cppcheck/cppcheck.xml "Buffer is accessed out of bounds" bufferAccessOutOfBounds -sca_summary_table_row ./archives/cppcheck/cppcheck.xml "Expression depends on order of evaluation of side effects" unknownEvaluationOrder -sca_summary_table_footer ./archives/cppcheck/cppcheck.xml + sca_summary_table_header "OAI Static Code Analysis with CPPCHECK" + sca_summary_table_row ./archives/cppcheck/cppcheck.xml "Uninitialized variable" uninitvar + sca_summary_table_row ./archives/cppcheck/cppcheck.xml "Uninitialized struct member" uninitStructMember + sca_summary_table_row ./archives/cppcheck/cppcheck.xml "Memory leak" memleak + sca_summary_table_row ./archives/cppcheck/cppcheck.xml "Memory is freed twice" doubleFree + sca_summary_table_row ./archives/cppcheck/cppcheck.xml "Resource leak" resourceLeak + sca_summary_table_row ./archives/cppcheck/cppcheck.xml "Possible null pointer dereference" nullPointer + sca_summary_table_row ./archives/cppcheck/cppcheck.xml "Array access out of bounds" arrayIndexOutOfBounds + sca_summary_table_row ./archives/cppcheck/cppcheck.xml "Buffer is accessed out of bounds" bufferAccessOutOfBounds + sca_summary_table_row ./archives/cppcheck/cppcheck.xml "Expression depends on order of evaluation of side effects" unknownEvaluationOrder + sca_summary_table_footer ./archives/cppcheck/cppcheck.xml -summary_table_header "OAI Build eNB -- USRP option" -summary_table_row "LTE SoftModem - Release 14" ./archives/enb_usrp/lte-softmodem.Rel14.txt "Built target lte-softmodem" ./enb_usrp_row1.html -summary_table_row "Coding - Release 14" ./archives/enb_usrp/coding.Rel14.txt "Built target coding" ./enb_usrp_row2.html -summary_table_row "OAI USRP device if - Release 14" ./archives/enb_usrp/oai_usrpdevif.Rel14.txt "Built target oai_usrpdevif" ./enb_usrp_row3.html -summary_table_row "Parameters Lib Config - Release 14" ./archives/enb_usrp/params_libconfig.Rel14.txt "Built target params_libconfig" ./enb_usrp_row4.html -summary_table_footer + summary_table_header "OAI Build eNB -- USRP option" + summary_table_row "LTE SoftModem - Release 14" ./archives/enb_usrp/lte-softmodem.Rel14.txt "Built target lte-softmodem" ./enb_usrp_row1.html + summary_table_row "Coding - Release 14" ./archives/enb_usrp/coding.Rel14.txt "Built target coding" ./enb_usrp_row2.html + summary_table_row "OAI USRP device if - Release 14" ./archives/enb_usrp/oai_usrpdevif.Rel14.txt "Built target oai_usrpdevif" ./enb_usrp_row3.html + summary_table_row "Parameters Lib Config - Release 14" ./archives/enb_usrp/params_libconfig.Rel14.txt "Built target params_libconfig" ./enb_usrp_row4.html + summary_table_footer -summary_table_header "OAI Build basic simulator option" -summary_table_row "Basic Simulator eNb - Release 14" ./archives/basic_sim/basic_simulator_enb.txt "Built target lte-softmodem" ./basic_sim_row1.html -summary_table_row "Basic Simulator UE - Release 14" ./archives/basic_sim/basic_simulator_ue.txt "Built target lte-uesoftmodem" ./basic_sim_row2.html -summary_table_row "Conf 2 UE data - Release 14" ./archives/basic_sim/conf2uedata.Rel14.txt "Built target conf2uedata" ./basic_sim_row3.html -summary_table_footer + summary_table_header "OAI Build basic simulator option" + summary_table_row "Basic Simulator eNb - Release 14" ./archives/basic_sim/basic_simulator_enb.txt "Built target lte-softmodem" ./basic_sim_row1.html + summary_table_row "Basic Simulator UE - Release 14" ./archives/basic_sim/basic_simulator_ue.txt "Built target lte-uesoftmodem" ./basic_sim_row2.html + summary_table_row "Conf 2 UE data - Release 14" ./archives/basic_sim/conf2uedata.Rel14.txt "Built target conf2uedata" ./basic_sim_row3.html + summary_table_footer -summary_table_header "OAI Build Physical simulators option" -summary_table_row "DL Simulator - Release 14" ./archives/phy_sim/dlsim.Rel14.txt "Built target dlsim" ./phy_sim_row1.html -summary_table_row "UL Simulator - Release 14" ./archives/phy_sim/ulsim.Rel14.txt "Built target ulsim" ./phy_sim_row2.html -summary_table_row "Coding - Release 14" ./archives/phy_sim/coding.Rel14.txt "Built target coding" ./phy_sim_row3.html -summary_table_footer + summary_table_header "OAI Build Physical simulators option" + summary_table_row "DL Simulator - Release 14" ./archives/phy_sim/dlsim.Rel14.txt "Built target dlsim" ./phy_sim_row1.html + summary_table_row "UL Simulator - Release 14" ./archives/phy_sim/ulsim.Rel14.txt "Built target ulsim" ./phy_sim_row2.html + summary_table_row "Coding - Release 14" ./archives/phy_sim/coding.Rel14.txt "Built target coding" ./phy_sim_row3.html + summary_table_footer -summary_table_header "OAI Build eNB -- ETHERNET transport option" -summary_table_row "LTE SoftModem w/o S1 - Release 14" ./archives/enb_eth/lte-softmodem-nos1.Rel14.txt "Built target lte-softmodem" ./enb_eth_row1.html -summary_table_row "Coding - Release 14" ./archives/enb_eth/coding.Rel14.txt "Built target coding" ./enb_eth_row2.html -summary_table_row "OAI ETHERNET transport - Release 14" ./archives/enb_eth/oai_eth_transpro.Rel14.txt "Built target oai_eth_transpro" ./enb_eth_row3.html -summary_table_row "Parameters Lib Config - Release 14" ./archives/enb_eth/params_libconfig.Rel14.txt "Built target params_libconfig" ./enb_eth_row4.html -summary_table_row "RB Tools - Release 14" ./archives/enb_eth/rb_tool.Rel14.txt "Built target rb_tool" ./enb_eth_row5.html -summary_table_row "NAS Mesh - Release 14" ./archives/enb_eth/nasmesh.Rel14.txt "Built target nasmesh" ./enb_eth_row6.html -summary_table_footer -summary_table_header "OAI Build UE -- ETHERNET transport option" -summary_table_row "LTE UE SoftModem w/o S1 - Release 14" ./archives/ue_eth/lte-uesoftmodem-nos1.Rel14.txt "Built target lte-uesoftmodem" ./ue_eth_row1.html -summary_table_row "Coding - Release 14" ./archives/ue_eth/coding.Rel14.txt "Built target coding" ./ue_eth_row2.html -summary_table_row "OAI ETHERNET transport - Release 14" ./archives/ue_eth/oai_eth_transpro.Rel14.txt "Built target oai_eth_transpro" ./ue_eth_row3.html -summary_table_row "Parameters Lib Config - Release 14" ./archives/ue_eth/params_libconfig.Rel14.txt "Built target params_libconfig" ./ue_eth_row4.html -summary_table_row "RB Tools - Release 14" ./archives/ue_eth/rb_tool.Rel14.txt "Built target rb_tool" ./ue_eth_row5.html -summary_table_row "NAS Mesh - Release 14" ./archives/ue_eth/nasmesh.Rel14.txt "Built target nasmesh" ./ue_eth_row6.html -summary_table_footer + if [ -f archives/gnb_usrp/nr-softmodem.Rel14.txt ] + then + summary_table_header "OAI Build gNB -- USRP option" + summary_table_row "LTE SoftModem - Release 14" ./archives/gnb_usrp/nr-softmodem.Rel14.txt "Built target nr-softmodem" ./gnb_usrp_row1.html + summary_table_row "Coding - Release 14" ./archives/gnb_usrp/coding.Rel14.txt "Built target coding" ./gnb_usrp_row2.html + summary_table_row "OAI USRP device if - Release 14" ./archives/gnb_usrp/oai_usrpdevif.Rel14.txt "Built target oai_usrpdevif" ./gnb_usrp_row3.html + summary_table_row "Parameters Lib Config - Release 14" ./archives/gnb_usrp/params_libconfig.Rel14.txt "Built target params_libconfig" ./gnb_usrp_row4.html + summary_table_footer + fi -echo "

Red Hat (CentOS Linux release 7.4.1708) -- Summary

" >> ./build_results.html + if [ -f archives/nrue_usrp/nr-uesoftmodem.Rel14.txt ] + then + summary_table_header "OAI Build 5G NR UE -- USRP option" + summary_table_row "UE SoftModem - Release 14" ./archives/nrue_usrp/nr-uesoftmodem.Rel14.txt "Built target nr-uesoftmodem" ./nrue_usrp_row1.html + summary_table_row "Coding - Release 14" ./archives/nrue_usrp/coding.Rel14.txt "Built target coding" ./nrue_usrp_row2.html + summary_table_row "OAI USRP device if - Release 14" ./archives/nrue_usrp/oai_usrpdevif.Rel14.txt "Built target oai_usrpdevif" ./nrue_usrp_row3.html + summary_table_row "Parameters Lib Config - Release 14" ./archives/nrue_usrp/params_libconfig.Rel14.txt "Built target params_libconfig" ./nrue_usrp_row4.html + summary_table_footer + fi -summary_table_header "Red Hat -- OAI Build eNB -- USRP option" -summary_table_row "LTE SoftModem - Release 14" ./archives/red_hat/lte-softmodem.Rel14.txt "Built target lte-softmodem" ./enb_usrp_rh_row1.html -summary_table_row "Coding - Release 14" ./archives/red_hat/coding.Rel14.txt "Built target coding" ./enb_usrp_rh_row2.html -summary_table_row "OAI USRP device if - Release 14" ./archives/red_hat/oai_usrpdevif.Rel14.txt "Built target oai_usrpdevif" ./enb_usrp_rh_row3.html -summary_table_row "Parameters Lib Config - Release 14" ./archives/red_hat/params_libconfig.Rel14.txt "Built target params_libconfig" ./enb_usrp_rh_row4.html -summary_table_footer + summary_table_header "OAI Build eNB -- ETHERNET transport option" + summary_table_row "LTE SoftModem w/o S1 - Release 14" ./archives/enb_eth/lte-softmodem-nos1.Rel14.txt "Built target lte-softmodem" ./enb_eth_row1.html + summary_table_row "Coding - Release 14" ./archives/enb_eth/coding.Rel14.txt "Built target coding" ./enb_eth_row2.html + summary_table_row "OAI ETHERNET transport - Release 14" ./archives/enb_eth/oai_eth_transpro.Rel14.txt "Built target oai_eth_transpro" ./enb_eth_row3.html + summary_table_row "Parameters Lib Config - Release 14" ./archives/enb_eth/params_libconfig.Rel14.txt "Built target params_libconfig" ./enb_eth_row4.html + summary_table_row "RB Tools - Release 14" ./archives/enb_eth/rb_tool.Rel14.txt "Built target rb_tool" ./enb_eth_row5.html + summary_table_row "NAS Mesh - Release 14" ./archives/enb_eth/nasmesh.Rel14.txt "Built target nasmesh" ./enb_eth_row6.html + summary_table_footer -echo "

Details

" >> ./build_results.html + summary_table_header "OAI Build UE -- ETHERNET transport option" + summary_table_row "LTE UE SoftModem w/o S1 - Release 14" ./archives/ue_eth/lte-uesoftmodem-nos1.Rel14.txt "Built target lte-uesoftmodem" ./ue_eth_row1.html + summary_table_row "Coding - Release 14" ./archives/ue_eth/coding.Rel14.txt "Built target coding" ./ue_eth_row2.html + summary_table_row "OAI ETHERNET transport - Release 14" ./archives/ue_eth/oai_eth_transpro.Rel14.txt "Built target oai_eth_transpro" ./ue_eth_row3.html + summary_table_row "Parameters Lib Config - Release 14" ./archives/ue_eth/params_libconfig.Rel14.txt "Built target params_libconfig" ./ue_eth_row4.html + summary_table_row "RB Tools - Release 14" ./archives/ue_eth/rb_tool.Rel14.txt "Built target rb_tool" ./ue_eth_row5.html + summary_table_row "NAS Mesh - Release 14" ./archives/ue_eth/nasmesh.Rel14.txt "Built target nasmesh" ./ue_eth_row6.html + summary_table_footer -for DETAILS_TABLE in `ls ./enb_usrp_row*.html` -do - cat $DETAILS_TABLE >> ./build_results.html -done -for DETAILS_TABLE in `ls ./basic_sim_row*.html` -do - cat $DETAILS_TABLE >> ./build_results.html -done -for DETAILS_TABLE in `ls ./phy_sim_row*.html` -do - cat $DETAILS_TABLE >> ./build_results.html -done -for DETAILS_TABLE in `ls ./enb_eth_row*.html` -do - cat $DETAILS_TABLE >> ./build_results.html -done -for DETAILS_TABLE in `ls ./ue_eth_row*.html` -do - cat $DETAILS_TABLE >> ./build_results.html -done -for DETAILS_TABLE in `ls ./enb_usrp_rh_row*.html` -do - cat $DETAILS_TABLE >> ./build_results.html -done -rm -f ./enb_usrp_row*.html ./basic_sim_row*.html ./phy_sim_row*.html ./enb_eth_row*.html ./ue_eth_row*.html ./enb_usrp_rh_row*.html + if [ -e ./archives/red_hat ] + then + echo "

Red Hat (CentOS Linux release 7.4.1708) -- Summary

" >> ./build_results.html -echo "" >> ./build_results.html -echo "" >> ./build_results.html + summary_table_header "Red Hat -- OAI Build eNB -- USRP option" + summary_table_row "LTE SoftModem - Release 14" ./archives/red_hat/lte-softmodem.Rel14.txt "Built target lte-softmodem" ./enb_usrp_rh_row1.html + summary_table_row "Coding - Release 14" ./archives/red_hat/coding.Rel14.txt "Built target coding" ./enb_usrp_rh_row2.html + summary_table_row "OAI USRP device if - Release 14" ./archives/red_hat/oai_usrpdevif.Rel14.txt "Built target oai_usrpdevif" ./enb_usrp_rh_row3.html + summary_table_row "Parameters Lib Config - Release 14" ./archives/red_hat/params_libconfig.Rel14.txt "Built target params_libconfig" ./enb_usrp_rh_row4.html + summary_table_footer + fi -exit 0 + echo "

Details

" >> ./build_results.html + + for DETAILS_TABLE in `ls ./enb_usrp_row*.html` + do + cat $DETAILS_TABLE >> ./build_results.html + done + for DETAILS_TABLE in `ls ./basic_sim_row*.html` + do + cat $DETAILS_TABLE >> ./build_results.html + done + for DETAILS_TABLE in `ls ./phy_sim_row*.html` + do + cat $DETAILS_TABLE >> ./build_results.html + done + + for DETAILS_TABLE in `ls ./gnb_usrp_row*.html` + do + cat $DETAILS_TABLE >> ./build_results.html + done + for DETAILS_TABLE in `ls ./nrue_usrp_row*.html` + do + cat $DETAILS_TABLE >> ./build_results.html + done + for DETAILS_TABLE in `ls ./enb_eth_row*.html` + do + cat $DETAILS_TABLE >> ./build_results.html + done + for DETAILS_TABLE in `ls ./ue_eth_row*.html` + do + cat $DETAILS_TABLE >> ./build_results.html + done + if [ -e ./archives/red_hat ] + then + for DETAILS_TABLE in `ls ./enb_usrp_rh_row*.html` + do + cat $DETAILS_TABLE >> ./build_results.html + done + fi + rm -f ./*_row*.html + + echo "" >> ./build_results.html + echo "" >> ./build_results.html +} diff --git a/ci-scripts/reportTestLocally.sh b/ci-scripts/reportTestLocally.sh index e00956199c..7bbf52ca2b 100755 --- a/ci-scripts/reportTestLocally.sh +++ b/ci-scripts/reportTestLocally.sh @@ -20,14 +20,13 @@ # * contact@openairinterface.org # */ -function usage { - echo "OAI Test Report script" +function report_test_usage { + echo "OAI CI VM script" echo " Original Author: Raphael Defosseux" echo "" echo "Usage:" echo "------" - echo "" - echo " reportTestLocally.sh [OPTIONS]" + echo " oai-ci-vm-tool report-test [OPTIONS]" echo "" echo "Options:" echo "--------" @@ -47,6 +46,9 @@ function usage { echo " --build-id #### OR -id ####" echo " Specify the build ID of the Jenkins job." echo "" + echo " --workspace #### OR -ws ####" + echo " Specify the workspace." + echo "" echo " --trigger merge-request OR -mr" echo " --trigger push OR -pu" echo " Specify trigger action of the Jenkins job. Either a merge-request event or a push event." @@ -78,513 +80,375 @@ function usage { echo "" } -function trigger_usage { - echo "OAI Test Report script" - echo " Original Author: Raphael Defosseux" - echo "" - echo " --trigger merge-request OR -mr" - echo " --trigger push OR -pu" - echo " Specify trigger action of the Jenkins job. Either a merge-request event or a push event." - echo "" -} +function report_test { + echo "############################################################" + echo "OAI CI VM script" + echo "############################################################" -jb_checker=0 -mr_checker=0 -pu_checker=0 -MR_TRIG=0 -PU_TRIG=0 -while [[ $# -gt 0 ]] -do -key="$1" + echo "JENKINS_WKSP = $JENKINS_WKSP" -case $key in - -h|--help) - shift - usage - exit 0 - ;; - -gu|--git-url) - GIT_URL="$2" - let "jb_checker|=0x1" - shift - shift - ;; - -jn|--job-name) - JOB_NAME="$2" - let "jb_checker|=0x2" - shift - shift - ;; - -id|--build-id) - BUILD_ID="$2" - let "jb_checker|=0x4" - shift - shift - ;; - --trigger) - TRIG="$2" - case $TRIG in - merge-request) - MR_TRIG=1 - ;; - push) - PU_TRIG=1 - ;; - *) - echo "" - echo "Syntax Error: Invalid Trigger option -> $TRIG" - echo "" - trigger_usage - exit - ;; - esac - let "jb_checker|=0x8" - shift - shift - ;; - -mr) - MR_TRIG=1 - let "jb_checker|=0x8" - shift - ;; - -pu) - PU_TRIG=1 - let "jb_checker|=0x8" - shift - ;; - -sb|--src-branch) - SOURCE_BRANCH="$2" - let "mr_checker|=0x1" - shift - shift - ;; - -sc|--src-commit) - SOURCE_COMMIT_ID="$2" - let "mr_checker|=0x2" - shift - shift - ;; - -tb|--target-branch) - TARGET_BRANCH="$2" - let "mr_checker|=0x4" - shift - shift - ;; - -tc|--target-commit) - TARGET_COMMIT_ID="$2" - let "mr_checker|=0x8" - shift - shift - ;; - -br|--branch) - SOURCE_BRANCH="$2" - let "pu_checker|=0x1" - shift - shift - ;; - -co|--commit) - SOURCE_COMMIT_ID="$2" - let "pu_checker|=0x2" - shift - shift - ;; - *) - echo "Syntax Error: unknown option: $key" - echo "" - usage - exit 1 - ;; -esac - -done - -if [ $jb_checker -ne 15 ] -then - echo "" - echo "Syntax Error: missing job information." - # TODO : list missing info - echo "" - exit 1 -fi - -if [ $PU_TRIG -eq 1 ] && [ $MR_TRIG -eq 1 ] -then - echo "" - echo "Syntax Error: trigger action incoherent." - echo "" - trigger_usage - exit 1 -fi - -if [ $PU_TRIG -eq 1 ] -then - if [ $pu_checker -ne 3 ] - then - echo "" - echo "Syntax Error: missing push information." - # TODO : list missing info - echo "" - exit 1 - fi -fi - -if [ $MR_TRIG -eq 1 ] -then - if [ $mr_checker -ne 15 ] - then - echo "" - echo "Syntax Error: missing merge-request information." - # TODO : list missing info - echo "" - exit 1 - fi -fi - -echo "" > ./test_simulator_results.html -echo "" >> ./test_simulator_results.html -echo "" >> ./test_simulator_results.html -echo " Simulator Results for $JOB_NAME job build #$BUILD_ID" >> ./test_simulator_results.html -echo " " >> ./test_simulator_results.html -echo "" >> ./test_simulator_results.html -echo "" >> ./test_simulator_results.html -echo " " >> ./test_simulator_results.html -echo " " >> ./test_simulator_results.html -echo " " >> ./test_simulator_results.html -echo " " >> ./test_simulator_results.html -echo " " >> ./test_simulator_results.html -echo "
" >> ./test_simulator_results.html -echo " " >> ./test_simulator_results.html -echo " \"\"" >> ./test_simulator_results.html -echo " " >> ./test_simulator_results.html -echo " " >> ./test_simulator_results.html -echo " " >> ./test_simulator_results.html -echo " Job Summary -- Job: $JOB_NAME -- Build-ID: $BUILD_ID" >> ./test_simulator_results.html -echo "
" >> ./test_simulator_results.html -echo "
" >> ./test_simulator_results.html -echo " " >> ./test_simulator_results.html -echo " " >> ./test_simulator_results.html -echo " " >> ./test_simulator_results.html -echo " " >> ./test_simulator_results.html -echo " " >> ./test_simulator_results.html -echo " " >> ./test_simulator_results.html -echo " " >> ./test_simulator_results.html -echo " " >> ./test_simulator_results.html -echo " " >> ./test_simulator_results.html -echo " " >> ./test_simulator_results.html -echo " " >> ./test_simulator_results.html -if [ $PU_TRIG -eq 1 ]; then echo " " >> ./test_simulator_results.html; fi -if [ $MR_TRIG -eq 1 ]; then echo " " >> ./test_simulator_results.html; fi -echo " " >> ./test_simulator_results.html -if [ $PU_TRIG -eq 1 ] -then - echo " " >> ./test_simulator_results.html - echo " " >> ./test_simulator_results.html - echo " " >> ./test_simulator_results.html - echo " " >> ./test_simulator_results.html - echo " " >> ./test_simulator_results.html - echo " " >> ./test_simulator_results.html - echo " " >> ./test_simulator_results.html - echo " " >> ./test_simulator_results.html -fi -if [ $MR_TRIG -eq 1 ] -then - echo " " >> ./test_simulator_results.html - echo " " >> ./test_simulator_results.html - echo " " >> ./test_simulator_results.html - echo " " >> ./test_simulator_results.html - echo " " >> ./test_simulator_results.html - echo " " >> ./test_simulator_results.html - echo " " >> ./test_simulator_results.html - echo " " >> ./test_simulator_results.html - echo " " >> ./test_simulator_results.html - echo " " >> ./test_simulator_results.html - echo " " >> ./test_simulator_results.html - echo " " >> ./test_simulator_results.html - echo " " >> ./test_simulator_results.html - echo " " >> ./test_simulator_results.html - echo " " >> ./test_simulator_results.html - echo " " >> ./test_simulator_results.html -fi -echo "
Build Start Time (UTC)TEMPLATE_BUILD_TIME
GIT Repository$GIT_URL
Job TriggerPush EventMerge-Request
Branch$SOURCE_BRANCH
Commit ID$SOURCE_COMMIT_ID
Source Branch$SOURCE_BRANCH
Source Commit ID$SOURCE_COMMIT_ID
Target Branch$TARGET_BRANCH
Target Commit ID$TARGET_COMMIT_ID
" >> ./test_simulator_results.html -echo "

Test Summary

" >> ./test_simulator_results.html - -ARCHIVES_LOC=archives/basic_sim/test -if [ -d $ARCHIVES_LOC ] -then - echo "

Basic Simulator Check

" >> ./test_simulator_results.html + cd ${JENKINS_WKSP} + echo "" > ./test_simulator_results.html + echo "" >> ./test_simulator_results.html + echo "" >> ./test_simulator_results.html + echo " Simulator Results for $JOB_NAME job build #$BUILD_ID" >> ./test_simulator_results.html + echo " " >> ./test_simulator_results.html + echo "" >> ./test_simulator_results.html + echo "" >> ./test_simulator_results.html + echo " " >> ./test_simulator_results.html + echo " " >> ./test_simulator_results.html + echo " " >> ./test_simulator_results.html + echo " " >> ./test_simulator_results.html + echo " " >> ./test_simulator_results.html + echo "
" >> ./test_simulator_results.html + echo " " >> ./test_simulator_results.html + echo " \"\"" >> ./test_simulator_results.html + echo " " >> ./test_simulator_results.html + echo " " >> ./test_simulator_results.html + echo " " >> ./test_simulator_results.html + echo " Job Summary -- Job: $JOB_NAME -- Build-ID: $BUILD_ID" >> ./test_simulator_results.html + echo "
" >> ./test_simulator_results.html + echo "
" >> ./test_simulator_results.html echo " " >> ./test_simulator_results.html - echo " " >> ./test_simulator_results.html - echo " " >> ./test_simulator_results.html - echo " " >> ./test_simulator_results.html - echo " " >> ./test_simulator_results.html - echo " " >> ./test_simulator_results.html + echo " " >> ./test_simulator_results.html + echo " " >> ./test_simulator_results.html + echo " " >> ./test_simulator_results.html echo " " >> ./test_simulator_results.html + echo " " >> ./test_simulator_results.html + echo " " >> ./test_simulator_results.html + echo " " >> ./test_simulator_results.html + echo " " >> ./test_simulator_results.html + echo " " >> ./test_simulator_results.html + echo " " >> ./test_simulator_results.html + if [ $PU_TRIG -eq 1 ]; then echo " " >> ./test_simulator_results.html; fi + if [ $MR_TRIG -eq 1 ]; then echo " " >> ./test_simulator_results.html; fi + echo " " >> ./test_simulator_results.html + if [ $PU_TRIG -eq 1 ] + then + echo " " >> ./test_simulator_results.html + echo " " >> ./test_simulator_results.html + echo " " >> ./test_simulator_results.html + echo " " >> ./test_simulator_results.html + echo " " >> ./test_simulator_results.html + echo " " >> ./test_simulator_results.html + echo " " >> ./test_simulator_results.html + echo " " >> ./test_simulator_results.html + fi + if [ $MR_TRIG -eq 1 ] + then + echo " " >> ./test_simulator_results.html + echo " " >> ./test_simulator_results.html + echo " " >> ./test_simulator_results.html + echo " " >> ./test_simulator_results.html + echo " " >> ./test_simulator_results.html + echo " " >> ./test_simulator_results.html + echo " " >> ./test_simulator_results.html + echo " " >> ./test_simulator_results.html + echo " " >> ./test_simulator_results.html + echo " " >> ./test_simulator_results.html + echo " " >> ./test_simulator_results.html + echo " " >> ./test_simulator_results.html + echo " " >> ./test_simulator_results.html + echo " " >> ./test_simulator_results.html + echo " " >> ./test_simulator_results.html + echo " " >> ./test_simulator_results.html + fi + echo "
Log File NameCommandStatusStatistics
Build Start Time (UTC)TEMPLATE_BUILD_TIME
GIT Repository$GIT_URL
Job TriggerPush EventMerge-Request
Branch$SOURCE_BRANCH
Commit ID$SOURCE_COMMIT_ID
Source Branch$SOURCE_BRANCH
Source Commit ID$SOURCE_COMMIT_ID
Target Branch$TARGET_BRANCH
Target Commit ID$TARGET_COMMIT_ID
" >> ./test_simulator_results.html + echo "

Test Summary

" >> ./test_simulator_results.html - TRANS_MODES=("fdd" "tdd") - BW_CASES=(05 10 20) - for TMODE in ${TRANS_MODES[@]} - do - for BW in ${BW_CASES[@]} + ARCHIVES_LOC=archives/basic_sim/test + if [ -d $ARCHIVES_LOC ] + then + echo "

Basic Simulator Check

" >> ./test_simulator_results.html + + echo " " >> ./test_simulator_results.html + echo " " >> ./test_simulator_results.html + echo " " >> ./test_simulator_results.html + echo " " >> ./test_simulator_results.html + echo " " >> ./test_simulator_results.html + echo " " >> ./test_simulator_results.html + echo " " >> ./test_simulator_results.html + + TRANS_MODES=("fdd" "tdd") + BW_CASES=(05 10 20) + for TMODE in ${TRANS_MODES[@]} do - ENB_LOG=$ARCHIVES_LOC/${TMODE}_${BW}MHz_enb.log - UE_LOG=`echo $ENB_LOG | sed -e "s#enb#ue#"` - if [ -f $ENB_LOG ] && [ -f $UE_LOG ] - then - NAME_ENB=`echo $ENB_LOG | sed -e "s#$ARCHIVES_LOC/##"` - NAME_UE=`echo $UE_LOG | sed -e "s#$ARCHIVES_LOC/##"` - echo " " >> ./test_simulator_results.html - echo " " >> ./test_simulator_results.html - echo " " >> ./test_simulator_results.html - NB_ENB_GOT_SYNC=`egrep -c "got sync" $ENB_LOG` - NB_UE_GOT_SYNC=`egrep -c "got sync" $UE_LOG` - NB_ENB_SYNCED_WITH_UE=`egrep -c "got UE capabilities for UE" $ENB_LOG` - if [ $NB_ENB_GOT_SYNC -eq 1 ] && [ $NB_UE_GOT_SYNC -eq 2 ] && [ $NB_ENB_SYNCED_WITH_UE -eq 1 ] + for BW in ${BW_CASES[@]} + do + ENB_LOG=$ARCHIVES_LOC/${TMODE}_${BW}MHz_enb.log + UE_LOG=`echo $ENB_LOG | sed -e "s#enb#ue#"` + if [ -f $ENB_LOG ] && [ -f $UE_LOG ] then - echo " " >> ./test_simulator_results.html - else - echo " " >> ./test_simulator_results.html - fi - echo " " >> ./test_simulator_results.html - echo " " >> ./test_simulator_results.html - fi - PING_CASE=$ARCHIVES_LOC/${TMODE}_${BW}MHz_ping_ue.txt - if [ -f $PING_CASE ] - then - echo " " >> ./test_simulator_results.html - NAME=`echo $PING_CASE | sed -e "s#$ARCHIVES_LOC/##"` - echo " " >> ./test_simulator_results.html - CMD=`egrep "COMMAND IS" $PING_CASE | sed -e "s#COMMAND IS: ##"` - echo " " >> ./test_simulator_results.html - FILE_COMPLETE=`egrep -c "ping statistics" $PING_CASE` - if [ $FILE_COMPLETE -eq 0 ] - then - echo " " >> ./test_simulator_results.html + NAME_ENB=`echo $ENB_LOG | sed -e "s#$ARCHIVES_LOC/##"` + NAME_UE=`echo $UE_LOG | sed -e "s#$ARCHIVES_LOC/##"` + echo " " >> ./test_simulator_results.html + echo " " >> ./test_simulator_results.html echo " " >> ./test_simulator_results.html - else - NB_TR_PACKETS=`egrep "packets transmitted" $PING_CASE | sed -e "s# packets transmitted.*##"` - NB_RC_PACKETS=`egrep "packets transmitted" $PING_CASE | sed -e "s#^.*packets transmitted, ##" -e "s# received,.*##"` - if [ $NB_TR_PACKETS -eq $NB_RC_PACKETS ] + NB_ENB_GOT_SYNC=`egrep -c "got sync" $ENB_LOG` + NB_UE_GOT_SYNC=`egrep -c "got sync" $UE_LOG` + NB_ENB_SYNCED_WITH_UE=`egrep -c "got UE capabilities for UE" $ENB_LOG` + if [ $NB_ENB_GOT_SYNC -eq 1 ] && [ $NB_UE_GOT_SYNC -eq 2 ] && [ $NB_ENB_SYNCED_WITH_UE -eq 1 ] then echo " " >> ./test_simulator_results.html else echo " " >> ./test_simulator_results.html fi + echo " " >> ./test_simulator_results.html + echo " " >> ./test_simulator_results.html + fi + PING_CASE=$ARCHIVES_LOC/${TMODE}_${BW}MHz_ping_ue.txt + if [ -f $PING_CASE ] + then + echo " " >> ./test_simulator_results.html + NAME=`echo $PING_CASE | sed -e "s#$ARCHIVES_LOC/##"` + echo " " >> ./test_simulator_results.html + CMD=`egrep "COMMAND IS" $PING_CASE | sed -e "s#COMMAND IS: ##"` + echo " " >> ./test_simulator_results.html + FILE_COMPLETE=`egrep -c "ping statistics" $PING_CASE` + if [ $FILE_COMPLETE -eq 0 ] + then + echo " " >> ./test_simulator_results.html + echo " " >> ./test_simulator_results.html + else + NB_TR_PACKETS=`egrep "packets transmitted" $PING_CASE | sed -e "s# packets transmitted.*##"` + NB_RC_PACKETS=`egrep "packets transmitted" $PING_CASE | sed -e "s#^.*packets transmitted, ##" -e "s# received,.*##"` + if [ $NB_TR_PACKETS -eq $NB_RC_PACKETS ] + then + echo " " >> ./test_simulator_results.html + else + echo " " >> ./test_simulator_results.html + fi + echo " " >> ./test_simulator_results.html + fi + echo " " >> ./test_simulator_results.html + fi + + if [ -f $ARCHIVES_LOC/${TMODE}_${BW}*iperf*dl*client*txt ] + then + IPERF_TESTS=`ls $ARCHIVES_LOC/${TMODE}_${BW}*iperf*client*txt` + else + echo "There are no iperf files" + IPERF_TESTS="" + fi + for IPERF_CASE in $IPERF_TESTS + do + echo " " >> ./test_simulator_results.html + NAME=`echo $IPERF_CASE | sed -e "s#$ARCHIVES_LOC/##"` + echo " " >> ./test_simulator_results.html + CMD=`egrep "COMMAND IS" $IPERF_CASE | sed -e "s#COMMAND IS: ##"` + echo " " >> ./test_simulator_results.html + REQ_BITRATE=`echo $CMD | sed -e "s#^.*-b ##" -e "s#-i 1.*##"` + if [[ $REQ_BITRATE =~ .*K.* ]] + then + REQ_BITRATE=`echo $REQ_BITRATE | sed -e "s#K##"` + FLOAT_REQ_BITRATE=`echo "$REQ_BITRATE * 1000.0" | bc -l` + fi + if [[ $REQ_BITRATE =~ .*M.* ]] + then + REQ_BITRATE=`echo $REQ_BITRATE | sed -e "s#M##"` + FLOAT_REQ_BITRATE=`echo "$REQ_BITRATE * 1000000.0" | bc -l` + fi + if [[ $REQ_BITRATE =~ .*G.* ]] + then + REQ_BITRATE=`echo $REQ_BITRATE | sed -e "s#G##"` + FLOAT_REQ_BITRATE=`echo "$REQ_BITRATE * 1000000000.0" | bc -l` + fi + FILE_COMPLETE=`egrep -c "Server Report" $IPERF_CASE` + if [ $FILE_COMPLETE -eq 0 ] + then + echo " " >> ./test_simulator_results.html + SERVER_FILE=`echo $IPERF_CASE | sed -e "s#client#server#"` + FLOAT_EFF_BITRATE=`grep --color=never sec $SERVER_FILE | sed -e "s#^.*Bytes *##" -e "s#sec *.*#sec#" | awk 'BEGIN{s=0;n=0}{n++;if ($2 ~/Mbits/){a = $1 * 1000000};if ($2 ~/Kbits/){a = $1 * 1000};s=s+a}END{br=s/n; printf "%.0f", br}'` + EFFECTIVE_BITRATE=`grep --color=never sec $SERVER_FILE | sed -e "s#^.*Bytes *##" -e "s#sec *.*#sec#" | awk 'BEGIN{s=0;n=0}{n++;if ($2 ~/Mbits/){a = $1 * 1000000};if ($2 ~/Kbits/){a = $1 * 1000};s=s+a}END{br=s/n; if(br>1000000){printf "%.2f MBits/sec", br/1000000}}'` + PERF=`echo "100 * $FLOAT_EFF_BITRATE / $FLOAT_REQ_BITRATE" | bc -l | awk '{printf "%.2f", $0}'` + JITTER=`grep --color=never sec $SERVER_FILE | sed -e "s#^.*/sec *##" -e "s# *ms.*##" | awk 'BEGIN{s=0;n=0}{n++;s+=$1}END{jitter=s/n; printf "%.3f ms", jitter}'` + PACKETLOSS_NOSIGN=`grep --color=never sec $SERVER_FILE | sed -e "s#^.*(##" -e "s#%.*##" | awk 'BEGIN{s=0;n=0}{n++;s+=$1}END{per=s/n; printf "%.1f", per}'` + PACKETLOSS=`echo "${PACKETLOSS_NOSIGN}%"` + else + EFFECTIVE_BITRATE=`tail -n3 $IPERF_CASE | egrep "Mbits/sec" | sed -e "s#^.*MBytes *##" -e "s#sec.*#sec#"` + if [[ $EFFECTIVE_BITRATE =~ .*Kbits/sec.* ]] + then + EFFECTIVE_BITRATE=`echo $EFFECTIVE_BITRATE | sed -e "s# *Kbits/sec.*##"` + FLOAT_EFF_BITRATE=`echo "$EFFECTIVE_BITRATE * 1000" | bc -l` + fi + if [[ $EFFECTIVE_BITRATE =~ .*Mbits/sec.* ]] + then + EFFECTIVE_BITRATE=`echo $EFFECTIVE_BITRATE | sed -e "s# *Mbits/sec.*##"` + FLOAT_EFF_BITRATE=`echo "$EFFECTIVE_BITRATE * 1000000" | bc -l` + fi + if [[ $EFFECTIVE_BITRATE =~ .*Gbits/sec.* ]] + then + EFFECTIVE_BITRATE=`echo $EFFECTIVE_BITRATE | sed -e "s# *Gbits/sec.*##"` + FLOAT_EFF_BITRATE=`echo "$EFFECTIVE_BITRATE * 1000000000" | bc -l` + fi + PERF=`echo "100 * $FLOAT_EFF_BITRATE / $FLOAT_REQ_BITRATE" | bc -l | awk '{printf "%.2f", $0}'` + PERF_INT=`echo "100 * $FLOAT_EFF_BITRATE / $FLOAT_REQ_BITRATE" | bc -l | awk '{printf "%.0f", $0}'` + if [[ $PERF_INT -lt 90 ]] + then + echo " " >> ./test_simulator_results.html + else + echo " " >> ./test_simulator_results.html + fi + EFFECTIVE_BITRATE=`tail -n3 $IPERF_CASE | egrep "Mbits/sec" | sed -e "s#^.*MBytes *##" -e "s#sec.*#sec#"` + JITTER=`tail -n3 $IPERF_CASE | egrep "Mbits/sec" | sed -e "s#^.*Mbits/sec *##" -e "s#ms.*#ms#"` + PACKETLOSS=`tail -n3 $IPERF_CASE | egrep "Mbits/sec" | sed -e "s#^.*(##" -e "s#).*##"` + fi echo " " >> ./test_simulator_results.html - fi - echo " " >> ./test_simulator_results.html - fi - - if [ -f $ARCHIVES_LOC/${TMODE}_${BW}*iperf*dl*client*txt ] - then - IPERF_TESTS=`ls $ARCHIVES_LOC/${TMODE}_${BW}*iperf*client*txt` - else - echo "There are no iperf files" - IPERF_TESTS="" - fi - for IPERF_CASE in $IPERF_TESTS - do - echo " " >> ./test_simulator_results.html - NAME=`echo $IPERF_CASE | sed -e "s#$ARCHIVES_LOC/##"` - echo " " >> ./test_simulator_results.html - CMD=`egrep "COMMAND IS" $IPERF_CASE | sed -e "s#COMMAND IS: ##"` - echo " " >> ./test_simulator_results.html - REQ_BITRATE=`echo $CMD | sed -e "s#^.*-b ##" -e "s#-i 1.*##"` - if [[ $REQ_BITRATE =~ .*K.* ]] - then - REQ_BITRATE=`echo $REQ_BITRATE | sed -e "s#K##"` - FLOAT_REQ_BITRATE=`echo "$REQ_BITRATE * 1000.0" | bc -l` - fi - if [[ $REQ_BITRATE =~ .*M.* ]] - then - REQ_BITRATE=`echo $REQ_BITRATE | sed -e "s#M##"` - FLOAT_REQ_BITRATE=`echo "$REQ_BITRATE * 1000000.0" | bc -l` - fi - if [[ $REQ_BITRATE =~ .*G.* ]] - then - REQ_BITRATE=`echo $REQ_BITRATE | sed -e "s#G##"` - FLOAT_REQ_BITRATE=`echo "$REQ_BITRATE * 1000000000.0" | bc -l` - fi - FILE_COMPLETE=`egrep -c "Server Report" $IPERF_CASE` - if [ $FILE_COMPLETE -eq 0 ] - then - echo " " >> ./test_simulator_results.html - SERVER_FILE=`echo $IPERF_CASE | sed -e "s#client#server#"` - FLOAT_EFF_BITRATE=`grep --color=never sec $SERVER_FILE | sed -e "s#^.*Bytes *##" -e "s#sec *.*#sec#" | awk 'BEGIN{s=0;n=0}{n++;if ($2 ~/Mbits/){a = $1 * 1000000};if ($2 ~/Kbits/){a = $1 * 1000};s=s+a}END{br=s/n; printf "%.0f", br}'` - EFFECTIVE_BITRATE=`grep --color=never sec $SERVER_FILE | sed -e "s#^.*Bytes *##" -e "s#sec *.*#sec#" | awk 'BEGIN{s=0;n=0}{n++;if ($2 ~/Mbits/){a = $1 * 1000000};if ($2 ~/Kbits/){a = $1 * 1000};s=s+a}END{br=s/n; if(br>1000000){printf "%.2f MBits/sec", br/1000000}}'` - PERF=`echo "100 * $FLOAT_EFF_BITRATE / $FLOAT_REQ_BITRATE" | bc -l | awk '{printf "%.2f", $0}'` - JITTER=`grep --color=never sec $SERVER_FILE | sed -e "s#^.*/sec *##" -e "s# *ms.*##" | awk 'BEGIN{s=0;n=0}{n++;s+=$1}END{jitter=s/n; printf "%.3f ms", jitter}'` - PACKETLOSS_NOSIGN=`grep --color=never sec $SERVER_FILE | sed -e "s#^.*(##" -e "s#%.*##" | awk 'BEGIN{s=0;n=0}{n++;s+=$1}END{per=s/n; printf "%.1f", per}'` - PACKETLOSS=`echo "${PACKETLOSS_NOSIGN}%"` - else - EFFECTIVE_BITRATE=`tail -n3 $IPERF_CASE | egrep "Mbits/sec" | sed -e "s#^.*MBytes *##" -e "s#sec.*#sec#"` - if [[ $EFFECTIVE_BITRATE =~ .*Kbits/sec.* ]] - then - EFFECTIVE_BITRATE=`echo $EFFECTIVE_BITRATE | sed -e "s# *Kbits/sec.*##"` - FLOAT_EFF_BITRATE=`echo "$EFFECTIVE_BITRATE * 1000" | bc -l` - fi - if [[ $EFFECTIVE_BITRATE =~ .*Mbits/sec.* ]] - then - EFFECTIVE_BITRATE=`echo $EFFECTIVE_BITRATE | sed -e "s# *Mbits/sec.*##"` - FLOAT_EFF_BITRATE=`echo "$EFFECTIVE_BITRATE * 1000000" | bc -l` - fi - if [[ $EFFECTIVE_BITRATE =~ .*Gbits/sec.* ]] - then - EFFECTIVE_BITRATE=`echo $EFFECTIVE_BITRATE | sed -e "s# *Gbits/sec.*##"` - FLOAT_EFF_BITRATE=`echo "$EFFECTIVE_BITRATE * 1000000000" | bc -l` - fi - PERF=`echo "100 * $FLOAT_EFF_BITRATE / $FLOAT_REQ_BITRATE" | bc -l | awk '{printf "%.2f", $0}'` - PERF_INT=`echo "100 * $FLOAT_EFF_BITRATE / $FLOAT_REQ_BITRATE" | bc -l | awk '{printf "%.0f", $0}'` - if [[ $PERF_INT -lt 90 ]] - then - echo " " >> ./test_simulator_results.html - else - echo " " >> ./test_simulator_results.html - fi - EFFECTIVE_BITRATE=`tail -n3 $IPERF_CASE | egrep "Mbits/sec" | sed -e "s#^.*MBytes *##" -e "s#sec.*#sec#"` - JITTER=`tail -n3 $IPERF_CASE | egrep "Mbits/sec" | sed -e "s#^.*Mbits/sec *##" -e "s#ms.*#ms#"` - PACKETLOSS=`tail -n3 $IPERF_CASE | egrep "Mbits/sec" | sed -e "s#^.*(##" -e "s#).*##"` - fi - echo " " >> ./test_simulator_results.html - echo " " >> ./test_simulator_results.html + echo " " >> ./test_simulator_results.html + done done done - done - echo "
Log File NameCommandStatusStatistics
$NAME_ENB --- $NAME_UEN/AOKKO
" >> ./test_simulator_results.html
-                if [ $NB_ENB_GOT_SYNC -eq 1 ]
-                then
-                    echo "- eNB --> got sync" >> ./test_simulator_results.html
-                else
-                    echo "- eNB NEVER got sync" >> ./test_simulator_results.html
-                fi
-                if [ $NB_UE_GOT_SYNC -eq 2 ]
-                then
-                    echo "- UE --> got sync" >> ./test_simulator_results.html
-                else
-                    echo "- UE NEVER got sync" >> ./test_simulator_results.html
-                fi
-                if [ $NB_ENB_SYNCED_WITH_UE -eq 1 ]
-                then
-                    echo "- UE attached to eNB" >> ./test_simulator_results.html
-                else
-                    echo "- UE NEVER attached to eNB" >> ./test_simulator_results.html
-                fi
-                NB_SEGFAULT_ENB=`egrep -i -c "Segmentation Fault" $ENB_LOG`
-                if [ $NB_SEGFAULT_ENB -ne 0 ]
-                then
-                    echo "- eNB --> Segmentation Fault" >> ./test_simulator_results.html
-                fi
-                NB_SEGFAULT_UE=`egrep -i -c "Segmentation Fault" $UE_LOG`
-                if [ $NB_SEGFAULT_UE -ne 0 ]
-                then
-                    echo "- UE --> Segmentation Fault" >> ./test_simulator_results.html
-                fi
-                NB_ASSERTION_ENB=`egrep -i -c "Assertion" $ENB_LOG`
-                if [ $NB_ASSERTION_ENB -ne 0 ]
-                then
-                    echo "- eNB --> Assertion" >> ./test_simulator_results.html
-                    awk 'BEGIN{assertion=10}{if(assertion < 3){print "    " $0; assertion++};if ($0 ~/Assertion/){print "    " $0;assertion=1}}END{}' $ENB_LOG >> ./test_simulator_results.html
-                fi
-                NB_ASSERTION_UE=`egrep -i -c "Assertion" $UE_LOG`
-                if [ $NB_ASSERTION_UE -ne 0 ]
-                then
-                    echo "- eNB --> Assertion" >> ./test_simulator_results.html
-                    awk 'BEGIN{assertion=10}{if(assertion < 3){print "    " $0; assertion++};if ($0 ~/Assertion/){print "    " $0;assertion=1}}END{}' $UE_LOG >> ./test_simulator_results.html
-                fi
-                echo "        
$NAME$CMDKO
$NAME_ENB --- $NAME_UEN/AOKKO
" >> ./test_simulator_results.html
+                    if [ $NB_ENB_GOT_SYNC -eq 1 ]
+                    then
+                        echo "- eNB --> got sync" >> ./test_simulator_results.html
+                    else
+                        echo "- eNB NEVER got sync" >> ./test_simulator_results.html
+                    fi
+                    if [ $NB_UE_GOT_SYNC -eq 2 ]
+                    then
+                        echo "- UE --> got sync" >> ./test_simulator_results.html
+                    else
+                        echo "- UE NEVER got sync" >> ./test_simulator_results.html
+                    fi
+                    if [ $NB_ENB_SYNCED_WITH_UE -eq 1 ]
+                    then
+                        echo "- UE attached to eNB" >> ./test_simulator_results.html
+                    else
+                        echo "- UE NEVER attached to eNB" >> ./test_simulator_results.html
+                    fi
+                    NB_SEGFAULT_ENB=`egrep -i -c "Segmentation Fault" $ENB_LOG`
+                    if [ $NB_SEGFAULT_ENB -ne 0 ]
+                    then
+                        echo "- eNB --> Segmentation Fault" >> ./test_simulator_results.html
+                    fi
+                    NB_SEGFAULT_UE=`egrep -i -c "Segmentation Fault" $UE_LOG`
+                    if [ $NB_SEGFAULT_UE -ne 0 ]
+                    then
+                        echo "- UE --> Segmentation Fault" >> ./test_simulator_results.html
+                    fi
+                    NB_ASSERTION_ENB=`egrep -i -c "Assertion" $ENB_LOG`
+                    if [ $NB_ASSERTION_ENB -ne 0 ]
+                    then
+                        echo "- eNB --> Assertion" >> ./test_simulator_results.html
+                        awk 'BEGIN{assertion=10}{if(assertion < 3){print "    " $0; assertion++};if ($0 ~/Assertion/){print "    " $0;assertion=1}}END{}' $ENB_LOG >> ./test_simulator_results.html
+                    fi
+                    NB_ASSERTION_UE=`egrep -i -c "Assertion" $UE_LOG`
+                    if [ $NB_ASSERTION_UE -ne 0 ]
+                    then
+                        echo "- eNB --> Assertion" >> ./test_simulator_results.html
+                        awk 'BEGIN{assertion=10}{if(assertion < 3){print "    " $0; assertion++};if ($0 ~/Assertion/){print "    " $0;assertion=1}}END{}' $UE_LOG >> ./test_simulator_results.html
+                    fi
+                    echo "        
$NAME$CMDKON/AOKKO" >> ./test_simulator_results.html + echo "
" >> ./test_simulator_results.html
+                        STATS=`egrep "packets transmitted" $PING_CASE | sed -e "s#^.*received, ##" -e "s#, time.*##" -e "s# packet loss##"`
+                        echo "Packet Loss : $STATS" >> ./test_simulator_results.html
+                        RTTMIN=`egrep "rtt min" $PING_CASE | awk '{split($4,a,"/"); print a[1] " " $5}'`
+                        echo "RTT Minimal : $RTTMIN" >> ./test_simulator_results.html
+                        RTTAVG=`egrep "rtt min" $PING_CASE | awk '{split($4,a,"/"); print a[2] " " $5}'`
+                        echo "RTT Average : $RTTAVG" >> ./test_simulator_results.html
+                        RTTMAX=`egrep "rtt min" $PING_CASE | awk '{split($4,a,"/"); print a[3] " " $5}'`
+                        echo "RTT Maximal : $RTTMAX" >> ./test_simulator_results.html
+                        echo "            
" >> ./test_simulator_results.html + echo "
$NAME$CMDKOKOOK" >> ./test_simulator_results.html echo "
" >> ./test_simulator_results.html
-                    STATS=`egrep "packets transmitted" $PING_CASE | sed -e "s#^.*received, ##" -e "s#, time.*##" -e "s# packet loss##"`
-                    echo "Packet Loss : $STATS" >> ./test_simulator_results.html
-                    RTTMIN=`egrep "rtt min" $PING_CASE | awk '{split($4,a,"/"); print a[1] " " $5}'`
-                    echo "RTT Minimal : $RTTMIN" >> ./test_simulator_results.html
-                    RTTAVG=`egrep "rtt min" $PING_CASE | awk '{split($4,a,"/"); print a[2] " " $5}'`
-                    echo "RTT Average : $RTTAVG" >> ./test_simulator_results.html
-                    RTTMAX=`egrep "rtt min" $PING_CASE | awk '{split($4,a,"/"); print a[3] " " $5}'`
-                    echo "RTT Maximal : $RTTMAX" >> ./test_simulator_results.html
+                    echo "Bitrate      : $EFFECTIVE_BITRATE" >> ./test_simulator_results.html
+                    echo "Bitrate Perf : $PERF %" >> ./test_simulator_results.html
+                    echo "Jitter       : $JITTER" >> ./test_simulator_results.html
+                    echo "Packet Loss  : $PACKETLOSS" >> ./test_simulator_results.html
                     echo "            
" >> ./test_simulator_results.html echo "
$NAME$CMDKOKOOK" >> ./test_simulator_results.html - echo "
" >> ./test_simulator_results.html
-                echo "Bitrate      : $EFFECTIVE_BITRATE" >> ./test_simulator_results.html
-                echo "Bitrate Perf : $PERF %" >> ./test_simulator_results.html
-                echo "Jitter       : $JITTER" >> ./test_simulator_results.html
-                echo "Packet Loss  : $PACKETLOSS" >> ./test_simulator_results.html
-                echo "            
" >> ./test_simulator_results.html - echo "
" >> ./test_simulator_results.html -fi + echo " " >> ./test_simulator_results.html + fi -ARCHIVES_LOC=archives/phy_sim/test -if [ -d $ARCHIVES_LOC ] -then - echo "

Physical Simulators Check

" >> ./test_simulator_results.html + ARCHIVES_LOC=archives/phy_sim/test + if [ -d $ARCHIVES_LOC ] + then + echo "

Physical Simulators Check

" >> ./test_simulator_results.html - echo " " >> ./test_simulator_results.html - echo " " >> ./test_simulator_results.html - echo " " >> ./test_simulator_results.html - echo " " >> ./test_simulator_results.html - echo " " >> ./test_simulator_results.html - echo " " >> ./test_simulator_results.html - echo " " >> ./test_simulator_results.html - echo " " >> ./test_simulator_results.html - - XML_TESTS=`ls $ARCHIVES_LOC/*xml` - for XML_FILE in $XML_TESTS - do - echo " " >> ./test_simulator_results.html - NAME=`echo $XML_FILE | sed -e "s#$ARCHIVES_LOC/##"` - NB_TESTS=`egrep "testsuite errors" $XML_FILE | sed -e "s#^.*tests='##" -e "s#' *time=.*##"` - NB_ERRORS=`egrep "testsuite errors" $XML_FILE | sed -e "s#^.*errors='##" -e "s#' *failures=.*##"` - NB_FAILURES=`egrep "testsuite errors" $XML_FILE | sed -e "s#^.*failures='##" -e "s#' *hostname=.*##"` - NB_SKIPPED=`egrep "testsuite errors" $XML_FILE | sed -e "s#^.*skipped='##" -e "s#' *tests=.*##"` - if [ $NB_ERRORS -eq 0 ] && [ $NB_FAILURES -eq 0 ] - then - echo " " >> ./test_simulator_results.html - else - echo " " >> ./test_simulator_results.html - fi - echo " " >> ./test_simulator_results.html - echo " " >> ./test_simulator_results.html - echo " " >> ./test_simulator_results.html - echo " " >> ./test_simulator_results.html - echo " " >> ./test_simulator_results.html - done - - echo "
Log File NameNb TestsNb ErrorsNb FailuresNb Failures
$NAME$NAME$NB_TESTS$NB_ERRORS$NB_FAILURES$NB_SKIPPED
" >> ./test_simulator_results.html - - echo "

Details

" >> ./test_simulator_results.html - for XML_FILE in $XML_TESTS - do echo " " >> ./test_simulator_results.html echo " " >> ./test_simulator_results.html - echo " " >> ./test_simulator_results.html - echo " " >> ./test_simulator_results.html - echo " " >> ./test_simulator_results.html - echo " " >> ./test_simulator_results.html + echo " " >> ./test_simulator_results.html + echo " " >> ./test_simulator_results.html + echo " " >> ./test_simulator_results.html + echo " " >> ./test_simulator_results.html + echo " " >> ./test_simulator_results.html echo " " >> ./test_simulator_results.html - TESTCASES_LIST=`sed -e "s# #@#g" $XML_FILE | grep testcase` - for TESTCASE in $TESTCASES_LIST + + XML_TESTS=`ls $ARCHIVES_LOC/*xml` + for XML_FILE in $XML_TESTS do echo " " >> ./test_simulator_results.html - NAME=`echo $TESTCASE | sed -e "s#^.*name='##" -e "s#'@description=.*##" | sed -e "s#@# #g"` - echo " " >> ./test_simulator_results.html - DESC=`echo $TESTCASE | sed -e "s#^.*description='##" -e "s#'@Run_result=.*##" | sed -e "s#@# #g"` - echo " " >> ./test_simulator_results.html - RESULT=`echo $TESTCASE | sed -e "s#^.*RESULT='##" -e "s#'.*##" | sed -e "s#@# #g"` - if [[ $RESULT =~ .*PASS.* ]] + NAME=`echo $XML_FILE | sed -e "s#$ARCHIVES_LOC/##"` + NB_TESTS=`egrep "testsuite errors" $XML_FILE | sed -e "s#^.*tests='##" -e "s#' *time=.*##"` + NB_ERRORS=`egrep "testsuite errors" $XML_FILE | sed -e "s#^.*errors='##" -e "s#' *failures=.*##"` + NB_FAILURES=`egrep "testsuite errors" $XML_FILE | sed -e "s#^.*failures='##" -e "s#' *hostname=.*##"` + NB_SKIPPED=`egrep "testsuite errors" $XML_FILE | sed -e "s#^.*skipped='##" -e "s#' *tests=.*##"` + if [ $NB_ERRORS -eq 0 ] && [ $NB_FAILURES -eq 0 ] then - echo " " >> ./test_simulator_results.html + echo " " >> ./test_simulator_results.html else - echo " " >> ./test_simulator_results.html + echo " " >> ./test_simulator_results.html fi - TIME=`echo $TESTCASE | sed -e "s#^.*time='##" -e "s#'@RESULT=.*##" | sed -e "s#@# #g"` - echo " " >> ./test_simulator_results.html + echo " " >> ./test_simulator_results.html + echo " " >> ./test_simulator_results.html + echo " " >> ./test_simulator_results.html + echo " " >> ./test_simulator_results.html echo " " >> ./test_simulator_results.html done + echo "
Test NameDescriptionResultTimeLog File NameNb TestsNb ErrorsNb FailuresNb Failures
$NAME$DESC$RESULT$NAME$RESULT$NAME$TIME$NB_TESTS$NB_ERRORS$NB_FAILURES$NB_SKIPPED
" >> ./test_simulator_results.html - done -fi -echo "" >> ./test_simulator_results.html -echo "" >> ./test_simulator_results.html + echo "

Details

" >> ./test_simulator_results.html + for XML_FILE in $XML_TESTS + do + echo " " >> ./test_simulator_results.html + echo " " >> ./test_simulator_results.html + echo " " >> ./test_simulator_results.html + echo " " >> ./test_simulator_results.html + echo " " >> ./test_simulator_results.html + echo " " >> ./test_simulator_results.html + echo " " >> ./test_simulator_results.html + PREV_SECTION=0 + PREV_TIME_IN_SECS=0 + TESTCASES_LIST=`sed -e "s# #@#g" $XML_FILE | grep testcase` + for TESTCASE in $TESTCASES_LIST + do + NAME=`echo $TESTCASE | sed -e "s#^.*name='##" -e "s#'@description=.*##" | sed -e "s#@# #g"` + SECTION=`echo $NAME | sed -e "s#\..*##"` + if [ $SECTION != $PREV_SECTION ] + then + echo " " >> ./test_simulator_results.html + echo " " >> ./test_simulator_results.html + echo " " >> ./test_simulator_results.html + PREV_SECTION=$SECTION + PREV_TIME_IN_SECS=0 + fi + DESC=`echo $TESTCASE | sed -e "s#^.*description='##" -e "s#'@Run_result=.*##" | sed -e "s#@# #g"` + RESULT=`echo $TESTCASE | sed -e "s#^.*RESULT='##" -e "s#'.*##" | sed -e "s#@# #g"` + TIME_IN_SECS=`echo $TESTCASE | sed -e "s#^.*time='##" -e "s#'@RESULT=.*##" | sed -e "s#@# #g" -e "s# s.*##"` + TIME=`echo "$TIME_IN_SECS - $PREV_TIME_IN_SECS" | bc -l | awk '{printf "%.2f s", $0}'` + PREV_TIME_IN_SECS=$TIME_IN_SECS + echo " " >> ./test_simulator_results.html + echo " " >> ./test_simulator_results.html + echo " " >> ./test_simulator_results.html + if [[ $RESULT =~ .*PASS.* ]] + then + echo " " >> ./test_simulator_results.html + else + SPLITTED_LINE=`echo -e $TESTCASE | sed -e "s#@#\n#g"` + NB_RUNS=`echo -e "${SPLITTED_LINE}" | grep -v Run_result | egrep -c "Run_"` + NB_FAILS=`echo -e "${SPLITTED_LINE}" | grep -v Run_result | egrep -c "=FAIL"` + echo " " >> ./test_simulator_results.html + fi + echo " " >> ./test_simulator_results.html + echo " " >> ./test_simulator_results.html + done + echo "
Test NameDescriptionResultTime
\"$SECTION\" series
$NAME$DESC$RESULT${RESULT} (${NB_FAILS}/${NB_RUNS})$TIME
" >> ./test_simulator_results.html + done + fi -exit 0 + echo "" >> ./test_simulator_results.html + echo "" >> ./test_simulator_results.html +} diff --git a/ci-scripts/runTestOnVM.sh b/ci-scripts/runTestOnVM.sh index 94af2d75ef..527fe48edb 100755 --- a/ci-scripts/runTestOnVM.sh +++ b/ci-scripts/runTestOnVM.sh @@ -20,15 +20,18 @@ # * contact@openairinterface.org # */ -function usage { - echo "OAI VM Test Run script" +function run_test_usage { + echo "OAI CI VM script" echo " Original Author: Raphael Defosseux" + echo " Requirements:" + echo " -- uvtool uvtool-libvirt apt-cacher" + echo " -- xenial image already synced" echo " Default:" echo " -- eNB with USRP" echo "" echo "Usage:" echo "------" - echo " runTestOnVM.sh [OPTIONS]" + echo " oai-ci-vm-tool test [OPTIONS]" echo "" echo "Options:" echo "--------" @@ -41,12 +44,7 @@ function usage { echo " --workspace #### OR -ws ####" echo " Specify the workspace." echo "" - echo " --variant enb-usrp OR -v1" - echo " --variant basic-sim OR -v2" - echo " --variant phy-sim OR -v3" - echo " --variant cppcheck OR -v4" - echo " --variant enb-ethernet OR -v7" - echo " --variant ue-ethernet OR -v8" + variant_usage echo " Specify the variant to build." echo "" echo " --keep-vm-alive OR -k" @@ -57,19 +55,6 @@ function usage { echo "" } -function variant_usage { - echo "OAI VM Test Run script" - echo " Original Author: Raphael Defosseux" - echo "" - echo " --variant enb-usrp OR -v1" - echo " --variant basic-sim OR -v2" - echo " --variant phy-sim OR -v3" - echo " --variant cppcheck OR -v4" - echo " --variant enb-ethernet OR -v7" - echo " --variant ue-ethernet OR -v8" - echo "" -} - function start_basic_sim_enb { local LOC_VM_IP_ADDR=$2 local LOC_EPC_IP_ADDR=$3 @@ -95,6 +80,7 @@ function start_basic_sim_enb { echo "echo \"ulimit -c unlimited && ./lte-softmodem -O /home/ubuntu/tmp/ci-scripts/conf_files/ci-$LOC_CONF_FILE\" > ./my-lte-softmodem-run.sh " >> $1 echo "chmod 775 ./my-lte-softmodem-run.sh" >> $1 echo "cat ./my-lte-softmodem-run.sh" >> $1 + echo "if [ -e /home/ubuntu/tmp/cmake_targets/log/$LOC_LOG_FILE ]; then sudo sudo rm -f /home/ubuntu/tmp/cmake_targets/log/$LOC_LOG_FILE; fi" >> $1 echo "sudo -E daemon --inherit --unsafe --name=enb_daemon --chdir=/home/ubuntu/tmp/cmake_targets/basic_simulator/enb -o /home/ubuntu/tmp/cmake_targets/log/$LOC_LOG_FILE ./my-lte-softmodem-run.sh" >> $1 ssh -o StrictHostKeyChecking=no ubuntu@$LOC_VM_IP_ADDR < $1 @@ -112,6 +98,7 @@ function start_basic_sim_ue { echo "echo \"./lte-uesoftmodem -C ${LOC_FREQUENCY}000000 -r $LOC_NB_RBS --ue-rxgain 140\" > ./my-lte-uesoftmodem-run.sh" >> $1 echo "chmod 775 ./my-lte-uesoftmodem-run.sh" >> $1 echo "cat ./my-lte-uesoftmodem-run.sh" >> $1 + echo "if [ -e /home/ubuntu/tmp/cmake_targets/log/$LOC_UE_LOG_FILE ]; then sudo sudo rm -f /home/ubuntu/tmp/cmake_targets/log/$LOC_UE_LOG_FILE; fi" >> $1 echo "sudo -E daemon --inherit --unsafe --name=ue_daemon --chdir=/home/ubuntu/tmp/cmake_targets/basic_simulator/ue -o /home/ubuntu/tmp/cmake_targets/log/$LOC_UE_LOG_FILE ./my-lte-uesoftmodem-run.sh" >> $1 ssh -o StrictHostKeyChecking=no ubuntu@$2 < $1 @@ -299,736 +286,619 @@ function terminate_ltebox_epc { rm $1 } -if [ $# -lt 1 ] || [ $# -gt 9 ] -then - echo "Syntax Error: not the correct number of arguments" - echo "" - usage - exit 1 -fi - -VM_TEMPLATE=ci- -JOB_NAME=XX -BUILD_ID=XX -VM_NAME=ci-enb-usrp -ARCHIVES_LOC=enb_usrp/test -KEEP_VM_ALIVE=0 -RUN_OPTIONS="none" -STATUS=0 - -while [[ $# -gt 0 ]] -do -key="$1" - -case $key in - -h|--help) - shift - usage - exit 0 - ;; - -jn|--job-name) - JOB_NAME="$2" - shift - shift - ;; - -id|--build-id) - BUILD_ID="$2" - shift - shift - ;; - -ws|--workspace) - JENKINS_WKSP="$2" - shift - shift - ;; - -k|--keep-vm-alive) - KEEP_VM_ALIVE=1 - shift - ;; - -v1) - VM_NAME=ci-enb-usrp - shift - ;; - -v2) - VM_NAME=ci-basic-sim - RUN_OPTIONS="complex" - ARCHIVES_LOC=basic_sim/test - shift - ;; - -v3) - VM_NAME=ci-phy-sim - RUN_OPTIONS="./run_exec_autotests.bash -g \"01510*\" -q -np -b" - ARCHIVES_LOC=phy_sim/test - shift - ;; - -v4) - VM_NAME=ci-cppcheck - shift - ;; - -v7) - VM_NAME=ci-enb-ethernet - shift - ;; - -v8) - VM_NAME=ci-ue-ethernet - shift - ;; - --variant) - variant="$2" - case $variant in - enb-usrp) - VM_NAME=ci-enb-usrp - ;; - basic-sim) - VM_NAME=ci-basic-sim - RUN_OPTIONS="complex" - ARCHIVES_LOC=basic_sim/test - ;; - phy-sim) - VM_NAME=ci-phy-sim - RUN_OPTIONS="./run_exec_autotests.bash -g \"01510*\" -q -np -b" - ARCHIVES_LOC=phy_sim/test - ;; - cppcheck) - VM_NAME=ci-cppcheck - ;; - enb-ethernet) - VM_NAME=ci-enb-ethernet - ;; - ue-ethernet) - VM_NAME=ci-ue-ethernet - ;; - *) - echo "" - echo "Syntax Error: Invalid Variant option -> $variant" - echo "" - variant_usage - exit 1 - esac - shift - shift - ;; - *) - echo "Syntax Error: unknown option: $key" - echo "" - usage - exit 1 -esac -done - -if [ "$JOB_NAME" == "XX" ] || [ "$BUILD_ID" == "XX" ] -then - VM_TEMPLATE=ci- -else - VM_TEMPLATE=${JOB_NAME}-b${BUILD_ID}- -fi - -VM_NAME=`echo $VM_NAME | sed -e "s#ci-#$VM_TEMPLATE#"` -VM_CMDS=${VM_NAME}_cmds.txt -ARCHIVES_LOC=${JENKINS_WKSP}/archives/${ARCHIVES_LOC} - -echo "VM_NAME = $VM_NAME" -echo "VM_CMD_FILE = $VM_CMDS" -echo "JENKINS_WKSP = $JENKINS_WKSP" -echo "ARCHIVES_LOC = $ARCHIVES_LOC" - -echo "############################################################" -echo "Waiting for VM to be started" -echo "############################################################" -uvt-kvm wait $VM_NAME --insecure - -VM_IP_ADDR=`uvt-kvm ip $VM_NAME` -echo "$VM_NAME has for IP addr = $VM_IP_ADDR" - -if [ "$RUN_OPTIONS" == "none" ] -then - echo "No run on VM testing for this variant currently" - exit $STATUS -fi - -if [[ $RUN_OPTIONS =~ .*run_exec_autotests.* ]] -then +function run_test_on_vm { echo "############################################################" - echo "Running test script on VM ($VM_NAME)" + echo "OAI CI VM script" echo "############################################################" - echo "echo \"sudo apt-get --yes --quiet install bc \"" > $VM_CMDS - echo "sudo apt-get update > bc-install.txt 2>&1" >> $VM_CMDS - echo "sudo apt-get --yes install bc >> bc-install.txt 2>&1" >> $VM_CMDS - echo "cd tmp" >> $VM_CMDS - echo "echo \"source oaienv\"" >> $VM_CMDS - echo "source oaienv" >> $VM_CMDS - echo "echo \"cd cmake_targets/autotests\"" >> $VM_CMDS - echo "cd cmake_targets/autotests" >> $VM_CMDS - echo "echo \"rm -Rf log\"" >> $VM_CMDS - echo "rm -Rf log" >> $VM_CMDS - echo "$RUN_OPTIONS" | sed -e 's@"@\\"@g' -e 's@^@echo "@' -e 's@$@"@' >> $VM_CMDS - echo "$RUN_OPTIONS" >> $VM_CMDS - echo "cp /home/ubuntu/bc-install.txt log" >> $VM_CMDS - echo "cd log" >> $VM_CMDS - echo "zip -r -qq tmp.zip *.* 0*" >> $VM_CMDS - - ssh -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR < $VM_CMDS + echo "VM_NAME = $VM_NAME" + echo "VM_CMD_FILE = $VM_CMDS" + echo "JENKINS_WKSP = $JENKINS_WKSP" + echo "ARCHIVES_LOC = $ARCHIVES_LOC" echo "############################################################" - echo "Creating a tmp folder to store results and artifacts" + echo "Waiting for VM to be started" echo "############################################################" + uvt-kvm wait $VM_NAME --insecure - if [ -d $ARCHIVES_LOC ] + VM_IP_ADDR=`uvt-kvm ip $VM_NAME` + echo "$VM_NAME has for IP addr = $VM_IP_ADDR" + + if [ "$RUN_OPTIONS" == "none" ] then - rm -Rf $ARCHIVES_LOC + echo "No run on VM testing for this variant currently" + exit $STATUS fi - mkdir --parents $ARCHIVES_LOC - scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/autotests/log/tmp.zip $ARCHIVES_LOC - pushd $ARCHIVES_LOC - unzip -qq -DD tmp.zip - rm tmp.zip - if [ -f results_autotests.xml ] - then - FUNCTION=`echo $VM_NAME | sed -e "s@$VM_TEMPLATE@@"` - NEW_NAME=`echo "results_autotests.xml" | sed -e "s@results_autotests@results_autotests-$FUNCTION@"` - echo "" > $NEW_NAME - echo "" >> $NEW_NAME - cat results_autotests.xml >> $NEW_NAME - sed -e "s@TEMPLATE@$FUNCTION@" $JENKINS_WKSP/ci-scripts/template.xsl > $FUNCTION.xsl - #mv results_autotests.xml $NEW_NAME - rm results_autotests.xml - fi - popd - - if [ $KEEP_VM_ALIVE -eq 0 ] + if [[ $RUN_OPTIONS =~ .*run_exec_autotests.* ]] then echo "############################################################" - echo "Destroying VM" + echo "Running test script on VM ($VM_NAME)" echo "############################################################" - uvt-kvm destroy $VM_NAME - ssh-keygen -R $VM_IP_ADDR - fi - rm -f $VM_CMDS + echo "echo \"sudo apt-get --yes --quiet install bc \"" > $VM_CMDS + echo "sudo apt-get update > bc-install.txt 2>&1" >> $VM_CMDS + echo "sudo apt-get --yes install bc >> bc-install.txt 2>&1" >> $VM_CMDS + echo "cd tmp" >> $VM_CMDS + echo "echo \"source oaienv\"" >> $VM_CMDS + echo "source oaienv" >> $VM_CMDS + echo "echo \"cd cmake_targets/autotests\"" >> $VM_CMDS + echo "cd cmake_targets/autotests" >> $VM_CMDS + echo "echo \"rm -Rf log\"" >> $VM_CMDS + echo "rm -Rf log" >> $VM_CMDS + echo "$RUN_OPTIONS" | sed -e 's@"@\\"@g' -e 's@^@echo "@' -e 's@$@"@' >> $VM_CMDS + echo "$RUN_OPTIONS" >> $VM_CMDS + echo "cp /home/ubuntu/bc-install.txt log" >> $VM_CMDS + echo "cd log" >> $VM_CMDS + echo "zip -r -qq tmp.zip *.* 0*" >> $VM_CMDS - echo "############################################################" - echo "Checking run status" - echo "############################################################" + ssh -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR < $VM_CMDS - LOG_FILES=`ls $ARCHIVES_LOC/results_autotests*.xml` - NB_FOUND_FILES=0 - NB_RUNS=0 - NB_FAILURES=0 + echo "############################################################" + echo "Creating a tmp folder to store results and artifacts" + echo "############################################################" - for FULLFILE in $LOG_FILES - do - TESTSUITES=`egrep "testsuite errors" $FULLFILE` - for TESTSUITE in $TESTSUITES - do - if [[ "$TESTSUITE" == *"tests="* ]] - then - RUNS=`echo $TESTSUITE | awk 'BEGIN{FS="="}{print $2}END{}' | sed -e "s@'@@g" ` - NB_RUNS=$((NB_RUNS + RUNS)) - fi - if [[ "$TESTSUITE" == *"failures="* ]] - then - FAILS=`echo $TESTSUITE | awk 'BEGIN{FS="="}{print $2}END{}' | sed -e "s@'@@g" ` - NB_FAILURES=$((NB_FAILURES + FAILS)) - fi - done - NB_FOUND_FILES=$((NB_FOUND_FILES + 1)) - done - - echo "NB_FOUND_FILES = $NB_FOUND_FILES" - echo "NB_RUNS = $NB_RUNS" - echo "NB_FAILURES = $NB_FAILURES" - - if [ $NB_FOUND_FILES -eq 0 ]; then STATUS=-1; fi - if [ $NB_RUNS -eq 0 ]; then STATUS=-1; fi - if [ $NB_FAILURES -ne 0 ]; then STATUS=-1; fi - -fi - -if [[ "$RUN_OPTIONS" == "complex" ]] && [[ $VM_NAME =~ .*-basic-sim.* ]] -then - PING_STATUS=0 - IPERF_STATUS=0 - if [ -d $ARCHIVES_LOC ] - then - rm -Rf $ARCHIVES_LOC - fi - mkdir --parents $ARCHIVES_LOC - - EPC_VM_NAME=`echo $VM_NAME | sed -e "s#basic-sim#epc#"` - LTEBOX=0 - if [ -d /opt/ltebox-archives/ ] - then - # Checking if all ltebox archives are available to run ltebx epc on a brand new VM - if [ -f /opt/ltebox-archives/ltebox_2.2.70_16_04_amd64.deb ] && [ -f /opt/ltebox-archives/etc-conf.zip ] && [ -f /opt/ltebox-archives/hss-sim.zip ] + if [ -d $ARCHIVES_LOC ] then - echo "############################################################" - echo "Test EPC on VM ($EPC_VM_NAME) will be using ltebox" - echo "############################################################" - LTEBOX=1 + rm -Rf $ARCHIVES_LOC fi - fi - # Here we could have other types of EPC detection + mkdir --parents $ARCHIVES_LOC - # Do we need to start the EPC VM - EPC_VM_CMDS=`echo $VM_CMDS | sed -e "s#cmds#epc-cmds#"` - echo "EPC_VM_CMD_FILE = $EPC_VM_CMDS" - IS_EPC_VM_ALIVE=`uvt-kvm list | grep -c $EPC_VM_NAME` - if [ $IS_EPC_VM_ALIVE -eq 0 ] - then - echo "############################################################" - echo "Creating test EPC VM ($EPC_VM_NAME) on Ubuntu Cloud Image base" - echo "############################################################" - uvt-kvm create $EPC_VM_NAME release=xenial --unsafe-caching - fi + scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/autotests/log/tmp.zip $ARCHIVES_LOC + pushd $ARCHIVES_LOC + unzip -qq -DD tmp.zip + rm tmp.zip + if [ -f results_autotests.xml ] + then + FUNCTION=`echo $VM_NAME | sed -e "s@$VM_TEMPLATE@@"` + NEW_NAME=`echo "results_autotests.xml" | sed -e "s@results_autotests@results_autotests-$FUNCTION@"` + echo "" > $NEW_NAME + echo "" >> $NEW_NAME + cat results_autotests.xml >> $NEW_NAME + sed -e "s@TEMPLATE@$FUNCTION@" $JENKINS_WKSP/ci-scripts/template.xsl > $FUNCTION.xsl + #mv results_autotests.xml $NEW_NAME + rm results_autotests.xml + fi + popd - uvt-kvm wait $EPC_VM_NAME --insecure - EPC_VM_IP_ADDR=`uvt-kvm ip $EPC_VM_NAME` - echo "$EPC_VM_NAME has for IP addr = $EPC_VM_IP_ADDR" - scp -o StrictHostKeyChecking=no /etc/apt/apt.conf.d/01proxy ubuntu@$EPC_VM_IP_ADDR:/home/ubuntu - - # ltebox specific actions (install and start) - LTE_BOX_TO_INSTALL=1 - if [ $LTEBOX -eq 1 ] - then - echo "ls -ls /opt/ltebox/tools/start_ltebox" > $EPC_VM_CMDS - RESPONSE=`ssh -o StrictHostKeyChecking=no ubuntu@$EPC_VM_IP_ADDR < $EPC_VM_CMDS` - NB_EXES=`echo $RESPONSE | grep -c ltebox` - if [ $NB_EXES -eq 1 ]; then LTE_BOX_TO_INSTALL=0; fi - fi - - if [ $LTEBOX -eq 1 ] && [ $LTE_BOX_TO_INSTALL -eq 1 ] - then - echo "############################################################" - echo "Copying ltebox archives into EPC VM ($EPC_VM_NAME)" - echo "############################################################" - scp -o StrictHostKeyChecking=no /opt/ltebox-archives/ltebox_2.2.70_16_04_amd64.deb ubuntu@$EPC_VM_IP_ADDR:/home/ubuntu - scp -o StrictHostKeyChecking=no /opt/ltebox-archives/etc-conf.zip ubuntu@$EPC_VM_IP_ADDR:/home/ubuntu - scp -o StrictHostKeyChecking=no /opt/ltebox-archives/hss-sim.zip ubuntu@$EPC_VM_IP_ADDR:/home/ubuntu - - echo "############################################################" - echo "Install EPC on EPC VM ($EPC_VM_NAME)" - echo "############################################################" - echo "sudo cp 01proxy /etc/apt/apt.conf.d/" > $EPC_VM_CMDS - echo "touch /home/ubuntu/.hushlogin" >> $EPC_VM_CMDS - echo "echo \"sudo apt-get --yes --quiet install zip openjdk-8-jre libconfuse-dev libreadline-dev liblog4c-dev libgcrypt-dev libsctp-dev python2.7 python2.7-dev daemon iperf\"" >> $EPC_VM_CMDS - echo "sudo apt-get update > zip-install.txt 2>&1" >> $EPC_VM_CMDS - echo "sudo apt-get --yes install zip openjdk-8-jre libconfuse-dev libreadline-dev liblog4c-dev libgcrypt-dev libsctp-dev python2.7 python2.7-dev daemon iperf >> zip-install.txt 2>&1" >> $EPC_VM_CMDS - - # Installing HSS - echo "echo \"cd /opt\"" >> $EPC_VM_CMDS - echo "cd /opt" >> $EPC_VM_CMDS - echo "echo \"sudo unzip -qq /home/ubuntu/hss-sim.zip\"" >> $EPC_VM_CMDS - echo "sudo unzip -qq /home/ubuntu/hss-sim.zip" >> $EPC_VM_CMDS - echo "echo \"cd /opt/hss_sim0609\"" >> $EPC_VM_CMDS - echo "cd /opt/hss_sim0609" >> $EPC_VM_CMDS - - # Installing ltebox - echo "echo \"cd /home/ubuntu\"" >> $EPC_VM_CMDS - echo "cd /home/ubuntu" >> $EPC_VM_CMDS - echo "echo \"sudo dpkg -i ltebox_2.2.70_16_04_amd64.deb \"" >> $EPC_VM_CMDS - echo "sudo dpkg -i ltebox_2.2.70_16_04_amd64.deb >> zip-install.txt 2>&1" >> $EPC_VM_CMDS - - echo "echo \"cd /opt/ltebox/etc/\"" >> $EPC_VM_CMDS - echo "cd /opt/ltebox/etc/" >> $EPC_VM_CMDS - echo "echo \"sudo unzip -qq -o /home/ubuntu/etc-conf.zip\"" >> $EPC_VM_CMDS - echo "sudo unzip -qq -o /home/ubuntu/etc-conf.zip" >> $EPC_VM_CMDS - echo "sudo sed -i -e 's#EPC_VM_IP_ADDRESS#$EPC_VM_IP_ADDR#' gw.conf" >> $EPC_VM_CMDS - echo "sudo sed -i -e 's#EPC_VM_IP_ADDRESS#$EPC_VM_IP_ADDR#' mme.conf" >> $EPC_VM_CMDS - fi - - # Starting EPC - if [ $LTEBOX -eq 1 ] - then - echo "############################################################" - echo "Start EPC on EPC VM ($EPC_VM_NAME)" - echo "############################################################" - echo "echo \"cd /opt/hss_sim0609\"" >> $EPC_VM_CMDS - echo "cd /opt/hss_sim0609" >> $EPC_VM_CMDS - echo "echo \"sudo daemon --unsafe --name=simulated_hss --chdir=/opt/hss_sim0609 ./starthss_real\"" >> $EPC_VM_CMDS - echo "sudo daemon --unsafe --name=simulated_hss --chdir=/opt/hss_sim0609 ./starthss_real" >> $EPC_VM_CMDS - - echo "echo \"cd /opt/ltebox/tools/\"" >> $EPC_VM_CMDS - echo "cd /opt/ltebox/tools/" >> $EPC_VM_CMDS - echo "echo \"sudo ./start_ltebox\"" >> $EPC_VM_CMDS - echo "nohup sudo ./start_ltebox > /home/ubuntu/ltebox.txt" >> $EPC_VM_CMDS - - ssh -o StrictHostKeyChecking=no ubuntu@$EPC_VM_IP_ADDR < $EPC_VM_CMDS - rm -f $EPC_VM_CMDS - - # We may have some adaptation to do - if [ -f /opt/ltebox-archives/adapt_ue_sim.txt ] + if [ $KEEP_VM_ALIVE -eq 0 ] then echo "############################################################" - echo "Doing some adaptation on UE side" + echo "Destroying VM" echo "############################################################" - ssh -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR < /opt/ltebox-archives/adapt_ue_sim.txt + uvt-kvm destroy $VM_NAME + ssh-keygen -R $VM_IP_ADDR + fi + rm -f $VM_CMDS + + echo "############################################################" + echo "Checking run status" + echo "############################################################" + + LOG_FILES=`ls $ARCHIVES_LOC/results_autotests*.xml` + NB_FOUND_FILES=0 + NB_RUNS=0 + NB_FAILURES=0 + + for FULLFILE in $LOG_FILES + do + TESTSUITES=`egrep "testsuite errors" $FULLFILE` + for TESTSUITE in $TESTSUITES + do + if [[ "$TESTSUITE" == *"tests="* ]] + then + RUNS=`echo $TESTSUITE | awk 'BEGIN{FS="="}{print $2}END{}' | sed -e "s@'@@g" ` + NB_RUNS=$((NB_RUNS + RUNS)) + fi + if [[ "$TESTSUITE" == *"failures="* ]] + then + FAILS=`echo $TESTSUITE | awk 'BEGIN{FS="="}{print $2}END{}' | sed -e "s@'@@g" ` + NB_FAILURES=$((NB_FAILURES + FAILS)) + fi + done + NB_FOUND_FILES=$((NB_FOUND_FILES + 1)) + done + + echo "NB_FOUND_FILES = $NB_FOUND_FILES" + echo "NB_RUNS = $NB_RUNS" + echo "NB_FAILURES = $NB_FAILURES" + + if [ $NB_FOUND_FILES -eq 0 ]; then STATUS=-1; fi + if [ $NB_RUNS -eq 0 ]; then STATUS=-1; fi + if [ $NB_FAILURES -ne 0 ]; then STATUS=-1; fi + + fi + + if [[ "$RUN_OPTIONS" == "complex" ]] && [[ $VM_NAME =~ .*-basic-sim.* ]] + then + PING_STATUS=0 + IPERF_STATUS=0 + if [ -d $ARCHIVES_LOC ] + then + rm -Rf $ARCHIVES_LOC + fi + mkdir --parents $ARCHIVES_LOC + + EPC_VM_NAME=`echo $VM_NAME | sed -e "s#basic-sim#epc#"` + LTEBOX=0 + if [ -d /opt/ltebox-archives/ ] + then + # Checking if all ltebox archives are available to run ltebx epc on a brand new VM + if [ -f /opt/ltebox-archives/ltebox_2.2.70_16_04_amd64.deb ] && [ -f /opt/ltebox-archives/etc-conf.zip ] && [ -f /opt/ltebox-archives/hss-sim.zip ] + then + echo "############################################################" + echo "Test EPC on VM ($EPC_VM_NAME) will be using ltebox" + echo "############################################################" + LTEBOX=1 + fi + fi + # Here we could have other types of EPC detection + + # Do we need to start the EPC VM + EPC_VM_CMDS=`echo $VM_CMDS | sed -e "s#cmds#epc-cmds#"` + echo "EPC_VM_CMD_FILE = $EPC_VM_CMDS" + IS_EPC_VM_ALIVE=`uvt-kvm list | grep -c $EPC_VM_NAME` + if [ $IS_EPC_VM_ALIVE -eq 0 ] + then + echo "############################################################" + echo "Creating test EPC VM ($EPC_VM_NAME) on Ubuntu Cloud Image base" + echo "############################################################" + uvt-kvm create $EPC_VM_NAME release=xenial --unsafe-caching fi - i="0" - echo "ifconfig tun5 | egrep -c \"inet addr\"" > $EPC_VM_CMDS - while [ $i -lt 10 ] - do - sleep 2 - CONNECTED=`ssh -o StrictHostKeyChecking=no ubuntu@$EPC_VM_IP_ADDR < $EPC_VM_CMDS` - if [ $CONNECTED -eq 1 ] - then - i="100" - else - i=$[$i+1] - fi - done - rm $EPC_VM_CMDS - if [ $i -lt 50 ] + uvt-kvm wait $EPC_VM_NAME --insecure + EPC_VM_IP_ADDR=`uvt-kvm ip $EPC_VM_NAME` + echo "$EPC_VM_NAME has for IP addr = $EPC_VM_IP_ADDR" + scp -o StrictHostKeyChecking=no /etc/apt/apt.conf.d/01proxy ubuntu@$EPC_VM_IP_ADDR:/home/ubuntu + + # ltebox specific actions (install and start) + LTE_BOX_TO_INSTALL=1 + if [ $LTEBOX -eq 1 ] then - echo "Problem w/ starting ltebox EPC" + echo "ls -ls /opt/ltebox/tools/start_ltebox" > $EPC_VM_CMDS + RESPONSE=`ssh -o StrictHostKeyChecking=no ubuntu@$EPC_VM_IP_ADDR < $EPC_VM_CMDS` + NB_EXES=`echo $RESPONSE | grep -c ltebox` + if [ $NB_EXES -eq 1 ]; then LTE_BOX_TO_INSTALL=0; fi + fi + + if [ $LTEBOX -eq 1 ] && [ $LTE_BOX_TO_INSTALL -eq 1 ] + then + echo "############################################################" + echo "Copying ltebox archives into EPC VM ($EPC_VM_NAME)" + echo "############################################################" + scp -o StrictHostKeyChecking=no /opt/ltebox-archives/ltebox_2.2.70_16_04_amd64.deb ubuntu@$EPC_VM_IP_ADDR:/home/ubuntu + scp -o StrictHostKeyChecking=no /opt/ltebox-archives/etc-conf.zip ubuntu@$EPC_VM_IP_ADDR:/home/ubuntu + scp -o StrictHostKeyChecking=no /opt/ltebox-archives/hss-sim.zip ubuntu@$EPC_VM_IP_ADDR:/home/ubuntu + + echo "############################################################" + echo "Install EPC on EPC VM ($EPC_VM_NAME)" + echo "############################################################" + echo "sudo cp 01proxy /etc/apt/apt.conf.d/" > $EPC_VM_CMDS + echo "touch /home/ubuntu/.hushlogin" >> $EPC_VM_CMDS + echo "echo \"sudo apt-get --yes --quiet install zip openjdk-8-jre libconfuse-dev libreadline-dev liblog4c-dev libgcrypt-dev libsctp-dev python2.7 python2.7-dev daemon iperf\"" >> $EPC_VM_CMDS + echo "sudo apt-get update > zip-install.txt 2>&1" >> $EPC_VM_CMDS + echo "sudo apt-get --yes install zip openjdk-8-jre libconfuse-dev libreadline-dev liblog4c-dev libgcrypt-dev libsctp-dev python2.7 python2.7-dev daemon iperf >> zip-install.txt 2>&1" >> $EPC_VM_CMDS + + # Installing HSS + echo "echo \"cd /opt\"" >> $EPC_VM_CMDS + echo "cd /opt" >> $EPC_VM_CMDS + echo "echo \"sudo unzip -qq /home/ubuntu/hss-sim.zip\"" >> $EPC_VM_CMDS + echo "sudo unzip -qq /home/ubuntu/hss-sim.zip" >> $EPC_VM_CMDS + echo "echo \"cd /opt/hss_sim0609\"" >> $EPC_VM_CMDS + echo "cd /opt/hss_sim0609" >> $EPC_VM_CMDS + + # Installing ltebox + echo "echo \"cd /home/ubuntu\"" >> $EPC_VM_CMDS + echo "cd /home/ubuntu" >> $EPC_VM_CMDS + echo "echo \"sudo dpkg -i ltebox_2.2.70_16_04_amd64.deb \"" >> $EPC_VM_CMDS + echo "sudo dpkg -i ltebox_2.2.70_16_04_amd64.deb >> zip-install.txt 2>&1" >> $EPC_VM_CMDS + + echo "echo \"cd /opt/ltebox/etc/\"" >> $EPC_VM_CMDS + echo "cd /opt/ltebox/etc/" >> $EPC_VM_CMDS + echo "echo \"sudo unzip -qq -o /home/ubuntu/etc-conf.zip\"" >> $EPC_VM_CMDS + echo "sudo unzip -qq -o /home/ubuntu/etc-conf.zip" >> $EPC_VM_CMDS + echo "sudo sed -i -e 's#EPC_VM_IP_ADDRESS#$EPC_VM_IP_ADDR#' gw.conf" >> $EPC_VM_CMDS + echo "sudo sed -i -e 's#EPC_VM_IP_ADDRESS#$EPC_VM_IP_ADDR#' mme.conf" >> $EPC_VM_CMDS + fi + + # Starting EPC + if [ $LTEBOX -eq 1 ] + then + echo "############################################################" + echo "Start EPC on EPC VM ($EPC_VM_NAME)" + echo "############################################################" + echo "echo \"cd /opt/hss_sim0609\"" >> $EPC_VM_CMDS + echo "cd /opt/hss_sim0609" >> $EPC_VM_CMDS + echo "echo \"sudo daemon --unsafe --name=simulated_hss --chdir=/opt/hss_sim0609 ./starthss_real\"" >> $EPC_VM_CMDS + echo "sudo daemon --unsafe --name=simulated_hss --chdir=/opt/hss_sim0609 ./starthss_real" >> $EPC_VM_CMDS + + echo "echo \"cd /opt/ltebox/tools/\"" >> $EPC_VM_CMDS + echo "cd /opt/ltebox/tools/" >> $EPC_VM_CMDS + echo "echo \"sudo ./start_ltebox\"" >> $EPC_VM_CMDS + echo "nohup sudo ./start_ltebox > /home/ubuntu/ltebox.txt" >> $EPC_VM_CMDS + + ssh -o StrictHostKeyChecking=no ubuntu@$EPC_VM_IP_ADDR < $EPC_VM_CMDS + rm -f $EPC_VM_CMDS + + # We may have some adaptation to do + if [ -f /opt/ltebox-archives/adapt_ue_sim.txt ] + then + echo "############################################################" + echo "Doing some adaptation on UE side" + echo "############################################################" + ssh -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR < /opt/ltebox-archives/adapt_ue_sim.txt + fi + + i="0" + echo "ifconfig tun5 | egrep -c \"inet addr\"" > $EPC_VM_CMDS + while [ $i -lt 10 ] + do + sleep 2 + CONNECTED=`ssh -o StrictHostKeyChecking=no ubuntu@$EPC_VM_IP_ADDR < $EPC_VM_CMDS` + if [ $CONNECTED -eq 1 ] + then + i="100" + else + i=$[$i+1] + fi + done + rm $EPC_VM_CMDS + if [ $i -lt 50 ] + then + echo "Problem w/ starting ltebox EPC" + exit -1 + fi + fi + + # HERE ADD ANY INSTALL ACTIONS FOR ANOTHER EPC + + # Retrieve EPC real IP address + if [ $LTEBOX -eq 1 ] + then + # in our configuration file, we are using pool 5 + echo "ifconfig tun5 | egrep \"inet addr\" | sed -e 's#^.*inet addr:##' -e 's# P-t-P:.*\$##'" > $EPC_VM_CMDS + REAL_EPC_IP_ADDR=`ssh -o StrictHostKeyChecking=no ubuntu@$EPC_VM_IP_ADDR < $EPC_VM_CMDS` + echo "EPC IP Address is : $REAL_EPC_IP_ADDR" + rm $EPC_VM_CMDS + fi + + echo "############################################################" + echo "Starting the eNB in FDD-5MHz mode" + echo "############################################################" + CURRENT_ENB_LOG_FILE=fdd_05MHz_enb.log + start_basic_sim_enb $VM_CMDS $VM_IP_ADDR $EPC_VM_IP_ADDR $CURRENT_ENB_LOG_FILE 25 lte-fdd-basic-sim.conf + + echo "############################################################" + echo "Starting the UE in FDD-5MHz mode" + echo "############################################################" + CURRENT_UE_LOG_FILE=fdd_05MHz_ue.log + start_basic_sim_ue $VM_CMDS $VM_IP_ADDR $CURRENT_UE_LOG_FILE 25 2680 + if [ $UE_SYNC -eq 0 ] + then + echo "Problem w/ eNB and UE not syncing" + terminate_enb_ue_basic_sim $VM_CMDS $VM_IP_ADDR + scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_ENB_LOG_FILE $ARCHIVES_LOC + scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_UE_LOG_FILE $ARCHIVES_LOC + recover_core_dump $VM_CMDS $VM_IP_ADDR $ARCHIVES_LOC/$CURRENT_ENB_LOG_FILE $ARCHIVES_LOC + terminate_ltebox_epc $EPC_VM_CMDS $EPC_VM_IP_ADDR exit -1 fi - fi + get_ue_ip_addr $VM_CMDS $VM_IP_ADDR - # HERE ADD ANY INSTALL ACTIONS FOR ANOTHER EPC + echo "############################################################" + echo "Pinging the UE" + echo "############################################################" + PING_LOG_FILE=fdd_05MHz_ping_ue.txt + ping_ue_ip_addr $EPC_VM_CMDS $EPC_VM_IP_ADDR $UE_IP_ADDR $PING_LOG_FILE + scp -o StrictHostKeyChecking=no ubuntu@$EPC_VM_IP_ADDR:/home/ubuntu/$PING_LOG_FILE $ARCHIVES_LOC + check_ping_result $ARCHIVES_LOC/$PING_LOG_FILE 20 - # Retrieve EPC real IP address - if [ $LTEBOX -eq 1 ] - then - # in our configuration file, we are using pool 5 - echo "ifconfig tun5 | egrep \"inet addr\" | sed -e 's#^.*inet addr:##' -e 's# P-t-P:.*\$##'" > $EPC_VM_CMDS - REAL_EPC_IP_ADDR=`ssh -o StrictHostKeyChecking=no ubuntu@$EPC_VM_IP_ADDR < $EPC_VM_CMDS` - echo "EPC IP Address is : $REAL_EPC_IP_ADDR" - rm $EPC_VM_CMDS - fi + echo "############################################################" + echo "Iperf DL" + echo "############################################################" + CURR_IPERF_LOG_BASE=fdd_05MHz_iperf_dl + iperf_dl $VM_CMDS $VM_IP_ADDR $EPC_VM_CMDS $EPC_VM_IP_ADDR 15 $CURR_IPERF_LOG_BASE + scp -o StrictHostKeyChecking=no ubuntu@$EPC_VM_IP_ADDR:/home/ubuntu/${CURR_IPERF_LOG_BASE}_client.txt $ARCHIVES_LOC + scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/${CURR_IPERF_LOG_BASE}_server.txt $ARCHIVES_LOC + check_iperf $ARCHIVES_LOC/$CURR_IPERF_LOG_BASE 15 - echo "############################################################" - echo "Starting the eNB in FDD-5MHz mode" - echo "############################################################" - CURRENT_ENB_LOG_FILE=fdd_05MHz_enb.log - start_basic_sim_enb $VM_CMDS $VM_IP_ADDR $EPC_VM_IP_ADDR $CURRENT_ENB_LOG_FILE 25 lte-fdd-basic-sim.conf + echo "############################################################" + echo "Iperf UL" + echo "############################################################" + CURR_IPERF_LOG_BASE=fdd_05MHz_iperf_ul + iperf_ul $VM_CMDS $VM_IP_ADDR $EPC_VM_CMDS $EPC_VM_IP_ADDR 2 $CURR_IPERF_LOG_BASE + scp -o StrictHostKeyChecking=no ubuntu@$EPC_VM_IP_ADDR:/home/ubuntu/${CURR_IPERF_LOG_BASE}_server.txt $ARCHIVES_LOC + scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/${CURR_IPERF_LOG_BASE}_client.txt $ARCHIVES_LOC + check_iperf $ARCHIVES_LOC/$CURR_IPERF_LOG_BASE 2 - echo "############################################################" - echo "Starting the UE in FDD-5MHz mode" - echo "############################################################" - CURRENT_UE_LOG_FILE=fdd_05MHz_ue.log - start_basic_sim_ue $VM_CMDS $VM_IP_ADDR $CURRENT_UE_LOG_FILE 25 2680 - if [ $UE_SYNC -eq 0 ] - then - echo "Problem w/ eNB and UE not syncing" + echo "############################################################" + echo "Terminate enb/ue simulators" + echo "############################################################" terminate_enb_ue_basic_sim $VM_CMDS $VM_IP_ADDR scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_ENB_LOG_FILE $ARCHIVES_LOC scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_UE_LOG_FILE $ARCHIVES_LOC recover_core_dump $VM_CMDS $VM_IP_ADDR $ARCHIVES_LOC/$CURRENT_ENB_LOG_FILE $ARCHIVES_LOC - terminate_ltebox_epc $EPC_VM_CMDS $EPC_VM_IP_ADDR - exit -1 - fi - get_ue_ip_addr $VM_CMDS $VM_IP_ADDR + sleep 10 - echo "############################################################" - echo "Pinging the UE" - echo "############################################################" - PING_LOG_FILE=fdd_05MHz_ping_ue.txt - ping_ue_ip_addr $EPC_VM_CMDS $EPC_VM_IP_ADDR $UE_IP_ADDR $PING_LOG_FILE - scp -o StrictHostKeyChecking=no ubuntu@$EPC_VM_IP_ADDR:/home/ubuntu/$PING_LOG_FILE $ARCHIVES_LOC - check_ping_result $ARCHIVES_LOC/$PING_LOG_FILE 20 + echo "############################################################" + echo "Starting the eNB in FDD-10MHz mode" + echo "############################################################" + CURRENT_ENB_LOG_FILE=fdd_10MHz_enb.log + start_basic_sim_enb $VM_CMDS $VM_IP_ADDR $EPC_VM_IP_ADDR $CURRENT_ENB_LOG_FILE 50 lte-fdd-basic-sim.conf - echo "############################################################" - echo "Iperf DL" - echo "############################################################" - CURR_IPERF_LOG_BASE=fdd_05MHz_iperf_dl - iperf_dl $VM_CMDS $VM_IP_ADDR $EPC_VM_CMDS $EPC_VM_IP_ADDR 15 $CURR_IPERF_LOG_BASE - scp -o StrictHostKeyChecking=no ubuntu@$EPC_VM_IP_ADDR:/home/ubuntu/${CURR_IPERF_LOG_BASE}_client.txt $ARCHIVES_LOC - scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/${CURR_IPERF_LOG_BASE}_server.txt $ARCHIVES_LOC - check_iperf $ARCHIVES_LOC/$CURR_IPERF_LOG_BASE 15 + echo "############################################################" + echo "Starting the UE in FDD-10MHz mode" + echo "############################################################" + CURRENT_UE_LOG_FILE=fdd_10MHz_ue.log + start_basic_sim_ue $VM_CMDS $VM_IP_ADDR $CURRENT_UE_LOG_FILE 50 2680 + if [ $UE_SYNC -eq 0 ] + then + echo "Problem w/ eNB and UE not syncing" + terminate_enb_ue_basic_sim $VM_CMDS $VM_IP_ADDR + scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_ENB_LOG_FILE $ARCHIVES_LOC + scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_UE_LOG_FILE $ARCHIVES_LOC + recover_core_dump $VM_CMDS $VM_IP_ADDR $ARCHIVES_LOC/$CURRENT_ENB_LOG_FILE $ARCHIVES_LOC + terminate_ltebox_epc $EPC_VM_CMDS $EPC_VM_IP_ADDR + exit -1 + fi + get_ue_ip_addr $VM_CMDS $VM_IP_ADDR - echo "############################################################" - echo "Iperf UL" - echo "############################################################" - CURR_IPERF_LOG_BASE=fdd_05MHz_iperf_ul - iperf_ul $VM_CMDS $VM_IP_ADDR $EPC_VM_CMDS $EPC_VM_IP_ADDR 2 $CURR_IPERF_LOG_BASE - scp -o StrictHostKeyChecking=no ubuntu@$EPC_VM_IP_ADDR:/home/ubuntu/${CURR_IPERF_LOG_BASE}_server.txt $ARCHIVES_LOC - scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/${CURR_IPERF_LOG_BASE}_client.txt $ARCHIVES_LOC - check_iperf $ARCHIVES_LOC/$CURR_IPERF_LOG_BASE 2 + echo "############################################################" + echo "Pinging the UE" + echo "############################################################" + PING_LOG_FILE=fdd_10MHz_ping_ue.txt + ping_ue_ip_addr $EPC_VM_CMDS $EPC_VM_IP_ADDR $UE_IP_ADDR $PING_LOG_FILE + scp -o StrictHostKeyChecking=no ubuntu@$EPC_VM_IP_ADDR:/home/ubuntu/$PING_LOG_FILE $ARCHIVES_LOC + check_ping_result $ARCHIVES_LOC/$PING_LOG_FILE 20 - echo "############################################################" - echo "Terminate enb/ue simulators" - echo "############################################################" - terminate_enb_ue_basic_sim $VM_CMDS $VM_IP_ADDR - scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_ENB_LOG_FILE $ARCHIVES_LOC - scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_UE_LOG_FILE $ARCHIVES_LOC - recover_core_dump $VM_CMDS $VM_IP_ADDR $ARCHIVES_LOC/$CURRENT_ENB_LOG_FILE $ARCHIVES_LOC + echo "############################################################" + echo "Iperf DL" + echo "############################################################" + CURR_IPERF_LOG_BASE=fdd_10MHz_iperf_dl + iperf_dl $VM_CMDS $VM_IP_ADDR $EPC_VM_CMDS $EPC_VM_IP_ADDR 15 $CURR_IPERF_LOG_BASE + scp -o StrictHostKeyChecking=no ubuntu@$EPC_VM_IP_ADDR:/home/ubuntu/${CURR_IPERF_LOG_BASE}_client.txt $ARCHIVES_LOC + scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/${CURR_IPERF_LOG_BASE}_server.txt $ARCHIVES_LOC + check_iperf $ARCHIVES_LOC/$CURR_IPERF_LOG_BASE 15 - echo "############################################################" - echo "Starting the eNB in FDD-10MHz mode" - echo "############################################################" - CURRENT_ENB_LOG_FILE=fdd_10MHz_enb.log - start_basic_sim_enb $VM_CMDS $VM_IP_ADDR $EPC_VM_IP_ADDR $CURRENT_ENB_LOG_FILE 50 lte-fdd-basic-sim.conf + echo "############################################################" + echo "Iperf UL" + echo "############################################################" + CURR_IPERF_LOG_BASE=fdd_10MHz_iperf_ul + iperf_ul $VM_CMDS $VM_IP_ADDR $EPC_VM_CMDS $EPC_VM_IP_ADDR 2 $CURR_IPERF_LOG_BASE + scp -o StrictHostKeyChecking=no ubuntu@$EPC_VM_IP_ADDR:/home/ubuntu/${CURR_IPERF_LOG_BASE}_server.txt $ARCHIVES_LOC + scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/${CURR_IPERF_LOG_BASE}_client.txt $ARCHIVES_LOC + check_iperf $ARCHIVES_LOC/$CURR_IPERF_LOG_BASE 2 - echo "############################################################" - echo "Starting the UE in FDD-10MHz mode" - echo "############################################################" - CURRENT_UE_LOG_FILE=fdd_10MHz_ue.log - start_basic_sim_ue $VM_CMDS $VM_IP_ADDR $CURRENT_UE_LOG_FILE 50 2680 - if [ $UE_SYNC -eq 0 ] - then - echo "Problem w/ eNB and UE not syncing" + echo "############################################################" + echo "Terminate enb/ue simulators" + echo "############################################################" terminate_enb_ue_basic_sim $VM_CMDS $VM_IP_ADDR scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_ENB_LOG_FILE $ARCHIVES_LOC scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_UE_LOG_FILE $ARCHIVES_LOC recover_core_dump $VM_CMDS $VM_IP_ADDR $ARCHIVES_LOC/$CURRENT_ENB_LOG_FILE $ARCHIVES_LOC - terminate_ltebox_epc $EPC_VM_CMDS $EPC_VM_IP_ADDR - exit -1 - fi - get_ue_ip_addr $VM_CMDS $VM_IP_ADDR + sleep 10 - echo "############################################################" - echo "Pinging the UE" - echo "############################################################" - PING_LOG_FILE=fdd_10MHz_ping_ue.txt - ping_ue_ip_addr $EPC_VM_CMDS $EPC_VM_IP_ADDR $UE_IP_ADDR $PING_LOG_FILE - scp -o StrictHostKeyChecking=no ubuntu@$EPC_VM_IP_ADDR:/home/ubuntu/$PING_LOG_FILE $ARCHIVES_LOC - check_ping_result $ARCHIVES_LOC/$PING_LOG_FILE 20 + echo "############################################################" + echo "Starting the eNB in FDD-20MHz mode" + echo "############################################################" + CURRENT_ENB_LOG_FILE=fdd_20MHz_enb.log + start_basic_sim_enb $VM_CMDS $VM_IP_ADDR $EPC_VM_IP_ADDR $CURRENT_ENB_LOG_FILE 100 lte-fdd-basic-sim.conf - echo "############################################################" - echo "Iperf DL" - echo "############################################################" - CURR_IPERF_LOG_BASE=fdd_10MHz_iperf_dl - iperf_dl $VM_CMDS $VM_IP_ADDR $EPC_VM_CMDS $EPC_VM_IP_ADDR 15 $CURR_IPERF_LOG_BASE - scp -o StrictHostKeyChecking=no ubuntu@$EPC_VM_IP_ADDR:/home/ubuntu/${CURR_IPERF_LOG_BASE}_client.txt $ARCHIVES_LOC - scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/${CURR_IPERF_LOG_BASE}_server.txt $ARCHIVES_LOC - check_iperf $ARCHIVES_LOC/$CURR_IPERF_LOG_BASE 15 + echo "############################################################" + echo "Starting the UE in FDD-20MHz mode" + echo "############################################################" + CURRENT_UE_LOG_FILE=fdd_20MHz_ue.log + start_basic_sim_ue $VM_CMDS $VM_IP_ADDR $CURRENT_UE_LOG_FILE 100 2680 + if [ $UE_SYNC -eq 0 ] + then + echo "Problem w/ eNB and UE not syncing" + terminate_enb_ue_basic_sim $VM_CMDS $VM_IP_ADDR + scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_ENB_LOG_FILE $ARCHIVES_LOC + scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_UE_LOG_FILE $ARCHIVES_LOC + recover_core_dump $VM_CMDS $VM_IP_ADDR $ARCHIVES_LOC/$CURRENT_ENB_LOG_FILE $ARCHIVES_LOC + terminate_ltebox_epc $EPC_VM_CMDS $EPC_VM_IP_ADDR + exit -1 + fi + get_ue_ip_addr $VM_CMDS $VM_IP_ADDR - echo "############################################################" - echo "Iperf UL" - echo "############################################################" - CURR_IPERF_LOG_BASE=fdd_10MHz_iperf_ul - iperf_ul $VM_CMDS $VM_IP_ADDR $EPC_VM_CMDS $EPC_VM_IP_ADDR 2 $CURR_IPERF_LOG_BASE - scp -o StrictHostKeyChecking=no ubuntu@$EPC_VM_IP_ADDR:/home/ubuntu/${CURR_IPERF_LOG_BASE}_server.txt $ARCHIVES_LOC - scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/${CURR_IPERF_LOG_BASE}_client.txt $ARCHIVES_LOC - check_iperf $ARCHIVES_LOC/$CURR_IPERF_LOG_BASE 2 + echo "############################################################" + echo "Pinging the UE" + echo "############################################################" + PING_LOG_FILE=fdd_20MHz_ping_ue.txt + ping_ue_ip_addr $EPC_VM_CMDS $EPC_VM_IP_ADDR $UE_IP_ADDR $PING_LOG_FILE + scp -o StrictHostKeyChecking=no ubuntu@$EPC_VM_IP_ADDR:/home/ubuntu/$PING_LOG_FILE $ARCHIVES_LOC + check_ping_result $ARCHIVES_LOC/$PING_LOG_FILE 20 - echo "############################################################" - echo "Terminate enb/ue simulators" - echo "############################################################" - terminate_enb_ue_basic_sim $VM_CMDS $VM_IP_ADDR - scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_ENB_LOG_FILE $ARCHIVES_LOC - scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_UE_LOG_FILE $ARCHIVES_LOC - recover_core_dump $VM_CMDS $VM_IP_ADDR $ARCHIVES_LOC/$CURRENT_ENB_LOG_FILE $ARCHIVES_LOC + echo "############################################################" + echo "Iperf DL" + echo "############################################################" + CURR_IPERF_LOG_BASE=fdd_20MHz_iperf_dl + iperf_dl $VM_CMDS $VM_IP_ADDR $EPC_VM_CMDS $EPC_VM_IP_ADDR 15 $CURR_IPERF_LOG_BASE + scp -o StrictHostKeyChecking=no ubuntu@$EPC_VM_IP_ADDR:/home/ubuntu/${CURR_IPERF_LOG_BASE}_client.txt $ARCHIVES_LOC + scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/${CURR_IPERF_LOG_BASE}_server.txt $ARCHIVES_LOC + check_iperf $ARCHIVES_LOC/$CURR_IPERF_LOG_BASE 15 - echo "############################################################" - echo "Starting the eNB in FDD-20MHz mode" - echo "############################################################" - CURRENT_ENB_LOG_FILE=fdd_20MHz_enb.log - start_basic_sim_enb $VM_CMDS $VM_IP_ADDR $EPC_VM_IP_ADDR $CURRENT_ENB_LOG_FILE 100 lte-fdd-basic-sim.conf - - echo "############################################################" - echo "Starting the UE in FDD-20MHz mode" - echo "############################################################" - CURRENT_UE_LOG_FILE=fdd_20MHz_ue.log - start_basic_sim_ue $VM_CMDS $VM_IP_ADDR $CURRENT_UE_LOG_FILE 100 2680 - if [ $UE_SYNC -eq 0 ] - then - echo "Problem w/ eNB and UE not syncing" + echo "############################################################" + echo "Terminate enb/ue simulators" + echo "############################################################" terminate_enb_ue_basic_sim $VM_CMDS $VM_IP_ADDR scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_ENB_LOG_FILE $ARCHIVES_LOC scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_UE_LOG_FILE $ARCHIVES_LOC recover_core_dump $VM_CMDS $VM_IP_ADDR $ARCHIVES_LOC/$CURRENT_ENB_LOG_FILE $ARCHIVES_LOC - terminate_ltebox_epc $EPC_VM_CMDS $EPC_VM_IP_ADDR - exit -1 - fi - get_ue_ip_addr $VM_CMDS $VM_IP_ADDR + sleep 10 - echo "############################################################" - echo "Pinging the UE" - echo "############################################################" - PING_LOG_FILE=fdd_20MHz_ping_ue.txt - ping_ue_ip_addr $EPC_VM_CMDS $EPC_VM_IP_ADDR $UE_IP_ADDR $PING_LOG_FILE - scp -o StrictHostKeyChecking=no ubuntu@$EPC_VM_IP_ADDR:/home/ubuntu/$PING_LOG_FILE $ARCHIVES_LOC - check_ping_result $ARCHIVES_LOC/$PING_LOG_FILE 20 + echo "############################################################" + echo "Starting the eNB in TDD-5MHz mode" + echo "############################################################" + CURRENT_ENB_LOG_FILE=tdd_05MHz_enb.log + start_basic_sim_enb $VM_CMDS $VM_IP_ADDR $EPC_VM_IP_ADDR $CURRENT_ENB_LOG_FILE 25 lte-tdd-basic-sim.conf - echo "############################################################" - echo "Iperf DL" - echo "############################################################" - CURR_IPERF_LOG_BASE=fdd_20MHz_iperf_dl - iperf_dl $VM_CMDS $VM_IP_ADDR $EPC_VM_CMDS $EPC_VM_IP_ADDR 15 $CURR_IPERF_LOG_BASE - scp -o StrictHostKeyChecking=no ubuntu@$EPC_VM_IP_ADDR:/home/ubuntu/${CURR_IPERF_LOG_BASE}_client.txt $ARCHIVES_LOC - scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/${CURR_IPERF_LOG_BASE}_server.txt $ARCHIVES_LOC - check_iperf $ARCHIVES_LOC/$CURR_IPERF_LOG_BASE 15 + echo "############################################################" + echo "Starting the UE in TDD-5MHz mode" + echo "############################################################" + CURRENT_UE_LOG_FILE=tdd_05MHz_ue.log + start_basic_sim_ue $VM_CMDS $VM_IP_ADDR $CURRENT_UE_LOG_FILE 25 2350 + if [ $UE_SYNC -eq 0 ] + then + echo "Problem w/ eNB and UE not syncing" + terminate_enb_ue_basic_sim $VM_CMDS $VM_IP_ADDR + scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_ENB_LOG_FILE $ARCHIVES_LOC + scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_UE_LOG_FILE $ARCHIVES_LOC + recover_core_dump $VM_CMDS $VM_IP_ADDR $ARCHIVES_LOC/$CURRENT_ENB_LOG_FILE $ARCHIVES_LOC + terminate_ltebox_epc $EPC_VM_CMDS $EPC_VM_IP_ADDR + exit -1 + fi + get_ue_ip_addr $VM_CMDS $VM_IP_ADDR - echo "############################################################" - echo "Terminate enb/ue simulators" - echo "############################################################" - terminate_enb_ue_basic_sim $VM_CMDS $VM_IP_ADDR - scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_ENB_LOG_FILE $ARCHIVES_LOC - scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_UE_LOG_FILE $ARCHIVES_LOC - recover_core_dump $VM_CMDS $VM_IP_ADDR $ARCHIVES_LOC/$CURRENT_ENB_LOG_FILE $ARCHIVES_LOC + echo "############################################################" + echo "Pinging the UE" + echo "############################################################" + PING_LOG_FILE=tdd_05MHz_ping_ue.txt + ping_ue_ip_addr $EPC_VM_CMDS $EPC_VM_IP_ADDR $UE_IP_ADDR $PING_LOG_FILE + scp -o StrictHostKeyChecking=no ubuntu@$EPC_VM_IP_ADDR:/home/ubuntu/$PING_LOG_FILE $ARCHIVES_LOC + check_ping_result $ARCHIVES_LOC/$PING_LOG_FILE 20 - echo "############################################################" - echo "Starting the eNB in TDD-5MHz mode" - echo "############################################################" - CURRENT_ENB_LOG_FILE=tdd_05MHz_enb.log - start_basic_sim_enb $VM_CMDS $VM_IP_ADDR $EPC_VM_IP_ADDR $CURRENT_ENB_LOG_FILE 25 lte-tdd-basic-sim.conf +# Bug in TDD 5Mhz --- not running it +# echo "############################################################" +# echo "Iperf DL" +# echo "############################################################" +# CURR_IPERF_LOG_BASE=tdd_05MHz_iperf_dl +# iperf_dl $VM_CMDS $VM_IP_ADDR $EPC_VM_CMDS $EPC_VM_IP_ADDR 6 $CURR_IPERF_LOG_BASE +# scp -o StrictHostKeyChecking=no ubuntu@$EPC_VM_IP_ADDR:/home/ubuntu/${CURR_IPERF_LOG_BASE}_client.txt $ARCHIVES_LOC +# scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/${CURR_IPERF_LOG_BASE}_server.txt $ARCHIVES_LOC +# check_iperf $ARCHIVES_LOC/$CURR_IPERF_LOG_BASE 6 - echo "############################################################" - echo "Starting the UE in TDD-5MHz mode" - echo "############################################################" - CURRENT_UE_LOG_FILE=tdd_05MHz_ue.log - start_basic_sim_ue $VM_CMDS $VM_IP_ADDR $CURRENT_UE_LOG_FILE 25 2350 - if [ $UE_SYNC -eq 0 ] - then - echo "Problem w/ eNB and UE not syncing" + echo "############################################################" + echo "Terminate enb/ue simulators" + echo "############################################################" terminate_enb_ue_basic_sim $VM_CMDS $VM_IP_ADDR scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_ENB_LOG_FILE $ARCHIVES_LOC scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_UE_LOG_FILE $ARCHIVES_LOC recover_core_dump $VM_CMDS $VM_IP_ADDR $ARCHIVES_LOC/$CURRENT_ENB_LOG_FILE $ARCHIVES_LOC - terminate_ltebox_epc $EPC_VM_CMDS $EPC_VM_IP_ADDR - exit -1 - fi - get_ue_ip_addr $VM_CMDS $VM_IP_ADDR + sleep 10 - echo "############################################################" - echo "Pinging the UE" - echo "############################################################" - PING_LOG_FILE=tdd_05MHz_ping_ue.txt - ping_ue_ip_addr $EPC_VM_CMDS $EPC_VM_IP_ADDR $UE_IP_ADDR $PING_LOG_FILE - scp -o StrictHostKeyChecking=no ubuntu@$EPC_VM_IP_ADDR:/home/ubuntu/$PING_LOG_FILE $ARCHIVES_LOC - check_ping_result $ARCHIVES_LOC/$PING_LOG_FILE 20 + echo "############################################################" + echo "Starting the eNB in TDD-10MHz mode" + echo "############################################################" + CURRENT_ENB_LOG_FILE=tdd_10MHz_enb.log + start_basic_sim_enb $VM_CMDS $VM_IP_ADDR $EPC_VM_IP_ADDR $CURRENT_ENB_LOG_FILE 50 lte-tdd-basic-sim.conf -# Bug in TDD 5Mhz --- not running it -# echo "############################################################" -# echo "Iperf DL" -# echo "############################################################" -# CURR_IPERF_LOG_BASE=tdd_05MHz_iperf_dl -# iperf_dl $VM_CMDS $VM_IP_ADDR $EPC_VM_CMDS $EPC_VM_IP_ADDR 6 $CURR_IPERF_LOG_BASE -# scp -o StrictHostKeyChecking=no ubuntu@$EPC_VM_IP_ADDR:/home/ubuntu/${CURR_IPERF_LOG_BASE}_client.txt $ARCHIVES_LOC -# scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/${CURR_IPERF_LOG_BASE}_server.txt $ARCHIVES_LOC -# check_iperf $ARCHIVES_LOC/$CURR_IPERF_LOG_BASE 6 + echo "############################################################" + echo "Starting the UE in TDD-10MHz mode" + echo "############################################################" + CURRENT_UE_LOG_FILE=tdd_10MHz_ue.log + start_basic_sim_ue $VM_CMDS $VM_IP_ADDR $CURRENT_UE_LOG_FILE 50 2350 + if [ $UE_SYNC -eq 0 ] + then + echo "Problem w/ eNB and UE not syncing" + terminate_enb_ue_basic_sim $VM_CMDS $VM_IP_ADDR + scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_ENB_LOG_FILE $ARCHIVES_LOC + scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_UE_LOG_FILE $ARCHIVES_LOC + recover_core_dump $VM_CMDS $VM_IP_ADDR $ARCHIVES_LOC/$CURRENT_ENB_LOG_FILE $ARCHIVES_LOC + terminate_ltebox_epc $EPC_VM_CMDS $EPC_VM_IP_ADDR + exit -1 + fi + get_ue_ip_addr $VM_CMDS $VM_IP_ADDR - echo "############################################################" - echo "Terminate enb/ue simulators" - echo "############################################################" - terminate_enb_ue_basic_sim $VM_CMDS $VM_IP_ADDR - scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_ENB_LOG_FILE $ARCHIVES_LOC - scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_UE_LOG_FILE $ARCHIVES_LOC - recover_core_dump $VM_CMDS $VM_IP_ADDR $ARCHIVES_LOC/$CURRENT_ENB_LOG_FILE $ARCHIVES_LOC + echo "############################################################" + echo "Pinging the UE" + echo "############################################################" + PING_LOG_FILE=tdd_10MHz_ping_ue.txt + ping_ue_ip_addr $EPC_VM_CMDS $EPC_VM_IP_ADDR $UE_IP_ADDR $PING_LOG_FILE + scp -o StrictHostKeyChecking=no ubuntu@$EPC_VM_IP_ADDR:/home/ubuntu/$PING_LOG_FILE $ARCHIVES_LOC + check_ping_result $ARCHIVES_LOC/$PING_LOG_FILE 20 - echo "############################################################" - echo "Starting the eNB in TDD-10MHz mode" - echo "############################################################" - CURRENT_ENB_LOG_FILE=tdd_10MHz_enb.log - start_basic_sim_enb $VM_CMDS $VM_IP_ADDR $EPC_VM_IP_ADDR $CURRENT_ENB_LOG_FILE 50 lte-tdd-basic-sim.conf + echo "############################################################" + echo "Iperf DL" + echo "############################################################" + CURR_IPERF_LOG_BASE=tdd_10MHz_iperf_dl + iperf_dl $VM_CMDS $VM_IP_ADDR $EPC_VM_CMDS $EPC_VM_IP_ADDR 6 $CURR_IPERF_LOG_BASE + scp -o StrictHostKeyChecking=no ubuntu@$EPC_VM_IP_ADDR:/home/ubuntu/${CURR_IPERF_LOG_BASE}_client.txt $ARCHIVES_LOC + scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/${CURR_IPERF_LOG_BASE}_server.txt $ARCHIVES_LOC + check_iperf $ARCHIVES_LOC/$CURR_IPERF_LOG_BASE 6 - echo "############################################################" - echo "Starting the UE in TDD-10MHz mode" - echo "############################################################" - CURRENT_UE_LOG_FILE=tdd_10MHz_ue.log - start_basic_sim_ue $VM_CMDS $VM_IP_ADDR $CURRENT_UE_LOG_FILE 50 2350 - if [ $UE_SYNC -eq 0 ] - then - echo "Problem w/ eNB and UE not syncing" + echo "############################################################" + echo "Terminate enb/ue simulators" + echo "############################################################" terminate_enb_ue_basic_sim $VM_CMDS $VM_IP_ADDR scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_ENB_LOG_FILE $ARCHIVES_LOC scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_UE_LOG_FILE $ARCHIVES_LOC recover_core_dump $VM_CMDS $VM_IP_ADDR $ARCHIVES_LOC/$CURRENT_ENB_LOG_FILE $ARCHIVES_LOC - terminate_ltebox_epc $EPC_VM_CMDS $EPC_VM_IP_ADDR - exit -1 + sleep 10 + + echo "############################################################" + echo "Starting the eNB in TDD-20MHz mode" + echo "############################################################" + CURRENT_ENB_LOG_FILE=tdd_20MHz_enb.log + start_basic_sim_enb $VM_CMDS $VM_IP_ADDR $EPC_VM_IP_ADDR $CURRENT_ENB_LOG_FILE 100 lte-tdd-basic-sim.conf + + echo "############################################################" + echo "Starting the UE in TDD-20MHz mode" + echo "############################################################" + CURRENT_UE_LOG_FILE=tdd_20MHz_ue.log + start_basic_sim_ue $VM_CMDS $VM_IP_ADDR $CURRENT_UE_LOG_FILE 100 2350 + if [ $UE_SYNC -eq 0 ] + then + echo "Problem w/ eNB and UE not syncing" + terminate_enb_ue_basic_sim $VM_CMDS $VM_IP_ADDR + scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_ENB_LOG_FILE $ARCHIVES_LOC + scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_UE_LOG_FILE $ARCHIVES_LOC + recover_core_dump $VM_CMDS $VM_IP_ADDR $ARCHIVES_LOC/$CURRENT_ENB_LOG_FILE $ARCHIVES_LOC + terminate_ltebox_epc $EPC_VM_CMDS $EPC_VM_IP_ADDR + exit -1 + fi + get_ue_ip_addr $VM_CMDS $VM_IP_ADDR + + echo "############################################################" + echo "Pinging the UE" + echo "############################################################" + PING_LOG_FILE=tdd_20MHz_ping_ue.txt + ping_ue_ip_addr $EPC_VM_CMDS $EPC_VM_IP_ADDR $UE_IP_ADDR $PING_LOG_FILE + scp -o StrictHostKeyChecking=no ubuntu@$EPC_VM_IP_ADDR:/home/ubuntu/$PING_LOG_FILE $ARCHIVES_LOC + check_ping_result $ARCHIVES_LOC/$PING_LOG_FILE 20 + + echo "############################################################" + echo "Iperf DL" + echo "############################################################" + CURR_IPERF_LOG_BASE=tdd_20MHz_iperf_dl + iperf_dl $VM_CMDS $VM_IP_ADDR $EPC_VM_CMDS $EPC_VM_IP_ADDR 6 $CURR_IPERF_LOG_BASE + scp -o StrictHostKeyChecking=no ubuntu@$EPC_VM_IP_ADDR:/home/ubuntu/${CURR_IPERF_LOG_BASE}_client.txt $ARCHIVES_LOC + scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/${CURR_IPERF_LOG_BASE}_server.txt $ARCHIVES_LOC + check_iperf $ARCHIVES_LOC/$CURR_IPERF_LOG_BASE 6 + + echo "############################################################" + echo "Terminate enb/ue simulators" + echo "############################################################" + terminate_enb_ue_basic_sim $VM_CMDS $VM_IP_ADDR + scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_ENB_LOG_FILE $ARCHIVES_LOC + scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_UE_LOG_FILE $ARCHIVES_LOC + recover_core_dump $VM_CMDS $VM_IP_ADDR $ARCHIVES_LOC/$CURRENT_ENB_LOG_FILE $ARCHIVES_LOC + sleep 10 + + echo "############################################################" + echo "Terminate EPC" + echo "############################################################" + + if [ $LTEBOX -eq 1 ] + then + terminate_ltebox_epc $EPC_VM_CMDS $EPC_VM_IP_ADDR + fi + + if [ $KEEP_VM_ALIVE -eq 0 ] + then + echo "############################################################" + echo "Destroying VMs" + echo "############################################################" + uvt-kvm destroy $VM_NAME + ssh-keygen -R $VM_IP_ADDR + uvt-kvm destroy $EPC_VM_NAME + ssh-keygen -R $EPC_VM_IP_ADDR + fi + + echo "############################################################" + echo "Checking run status" + echo "############################################################" + + if [ $PING_STATUS -ne 0 ]; then STATUS=-1; fi + if [ $IPERF_STATUS -ne 0 ]; then STATUS=-1; fi + fi - get_ue_ip_addr $VM_CMDS $VM_IP_ADDR - - echo "############################################################" - echo "Pinging the UE" - echo "############################################################" - PING_LOG_FILE=tdd_10MHz_ping_ue.txt - ping_ue_ip_addr $EPC_VM_CMDS $EPC_VM_IP_ADDR $UE_IP_ADDR $PING_LOG_FILE - scp -o StrictHostKeyChecking=no ubuntu@$EPC_VM_IP_ADDR:/home/ubuntu/$PING_LOG_FILE $ARCHIVES_LOC - check_ping_result $ARCHIVES_LOC/$PING_LOG_FILE 20 - - echo "############################################################" - echo "Iperf DL" - echo "############################################################" - CURR_IPERF_LOG_BASE=tdd_10MHz_iperf_dl - iperf_dl $VM_CMDS $VM_IP_ADDR $EPC_VM_CMDS $EPC_VM_IP_ADDR 6 $CURR_IPERF_LOG_BASE - scp -o StrictHostKeyChecking=no ubuntu@$EPC_VM_IP_ADDR:/home/ubuntu/${CURR_IPERF_LOG_BASE}_client.txt $ARCHIVES_LOC - scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/${CURR_IPERF_LOG_BASE}_server.txt $ARCHIVES_LOC - check_iperf $ARCHIVES_LOC/$CURR_IPERF_LOG_BASE 6 - - echo "############################################################" - echo "Terminate enb/ue simulators" - echo "############################################################" - terminate_enb_ue_basic_sim $VM_CMDS $VM_IP_ADDR - scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_ENB_LOG_FILE $ARCHIVES_LOC - scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_UE_LOG_FILE $ARCHIVES_LOC - recover_core_dump $VM_CMDS $VM_IP_ADDR $ARCHIVES_LOC/$CURRENT_ENB_LOG_FILE $ARCHIVES_LOC - -# Disabling TDD-20MHz test since it is very unstable -# -# echo "############################################################" -# echo "Starting the eNB in TDD-20MHz mode" -# echo "############################################################" -# CURRENT_ENB_LOG_FILE=tdd_20MHz_enb.log -# start_basic_sim_enb $VM_CMDS $VM_IP_ADDR $EPC_VM_IP_ADDR $CURRENT_ENB_LOG_FILE 100 lte-tdd-basic-sim.conf -# -# echo "############################################################" -# echo "Starting the UE in TDD-20MHz mode" -# echo "############################################################" -# CURRENT_UE_LOG_FILE=tdd_20MHz_ue.log -# start_basic_sim_ue $VM_CMDS $VM_IP_ADDR $CURRENT_UE_LOG_FILE 100 2350 -# if [ $UE_SYNC -eq 0 ] -# then -# echo "Problem w/ eNB and UE not syncing" -# terminate_enb_ue_basic_sim $VM_CMDS $VM_IP_ADDR -# scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_ENB_LOG_FILE $ARCHIVES_LOC -# scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_UE_LOG_FILE $ARCHIVES_LOC -# recover_core_dump $VM_CMDS $VM_IP_ADDR $ARCHIVES_LOC/$CURRENT_ENB_LOG_FILE $ARCHIVES_LOC -# terminate_ltebox_epc $EPC_VM_CMDS $EPC_VM_IP_ADDR -# exit -1 -# fi -# get_ue_ip_addr $VM_CMDS $VM_IP_ADDR -# -# echo "############################################################" -# echo "Pinging the UE" -# echo "############################################################" -# PING_LOG_FILE=tdd_20MHz_ping_ue.txt -# ping_ue_ip_addr $EPC_VM_CMDS $EPC_VM_IP_ADDR $UE_IP_ADDR $PING_LOG_FILE -# scp -o StrictHostKeyChecking=no ubuntu@$EPC_VM_IP_ADDR:/home/ubuntu/$PING_LOG_FILE $ARCHIVES_LOC -# check_ping_result $ARCHIVES_LOC/$PING_LOG_FILE 20 -# -# echo "############################################################" -# echo "Iperf DL" -# echo "############################################################" -# CURR_IPERF_LOG_BASE=tdd_20MHz_iperf_dl -# iperf_dl $VM_CMDS $VM_IP_ADDR $EPC_VM_CMDS $EPC_VM_IP_ADDR 6 $CURR_IPERF_LOG_BASE -# scp -o StrictHostKeyChecking=no ubuntu@$EPC_VM_IP_ADDR:/home/ubuntu/${CURR_IPERF_LOG_BASE}_client.txt $ARCHIVES_LOC -# scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/${CURR_IPERF_LOG_BASE}_server.txt $ARCHIVES_LOC -# check_iperf $ARCHIVES_LOC/$CURR_IPERF_LOG_BASE 6 -# -# echo "############################################################" -# echo "Terminate enb/ue simulators" -# echo "############################################################" -# terminate_enb_ue_basic_sim $VM_CMDS $VM_IP_ADDR -# scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_ENB_LOG_FILE $ARCHIVES_LOC -# scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_UE_LOG_FILE $ARCHIVES_LOC -# recover_core_dump $VM_CMDS $VM_IP_ADDR $ARCHIVES_LOC/$CURRENT_ENB_LOG_FILE $ARCHIVES_LOC - - echo "############################################################" - echo "Terminate EPC" - echo "############################################################" - - if [ $LTEBOX -eq 1 ] - then - terminate_ltebox_epc $EPC_VM_CMDS $EPC_VM_IP_ADDR - fi - - echo "############################################################" - echo "Checking run status" - echo "############################################################" - - if [ $PING_STATUS -ne 0 ]; then STATUS=-1; fi - if [ $IPERF_STATUS -ne 0 ]; then STATUS=-1; fi - -fi - -if [ $STATUS -eq 0 ] -then - echo "STATUS seems OK" -else - echo "STATUS failed?" -fi - -exit $STATUS +} diff --git a/ci-scripts/waitBuildOnVM.sh b/ci-scripts/waitBuildOnVM.sh index 48429cb7e2..bee11f2820 100755 --- a/ci-scripts/waitBuildOnVM.sh +++ b/ci-scripts/waitBuildOnVM.sh @@ -20,8 +20,8 @@ # * contact@openairinterface.org # */ -function usage { - echo "OAI VM Build Check script" +function wait_usage { + echo "OAI CI VM script" echo " Original Author: Raphael Defosseux" echo " Requirements:" echo " -- uvtool uvtool-libvirt apt-cacher" @@ -31,9 +31,9 @@ function usage { echo "" echo "Usage:" echo "------" - echo " waitBuildOnVM.sh [OPTIONS]" + echo " oai-ci-vm-tool wait [OPTIONS]" echo "" - echo "Options:" + echo "Mandatory Options:" echo "--------" echo " --job-name #### OR -jn ####" echo " Specify the name of the Jenkins job." @@ -44,14 +44,11 @@ function usage { echo " --workspace #### OR -ws ####" echo " Specify the workspace." echo "" - echo " --variant enb-usrp OR -v1" - echo " --variant basic-sim OR -v2" - echo " --variant phy-sim OR -v3" - echo " --variant cppcheck OR -v4" - echo " --variant enb-ethernet OR -v7" - echo " --variant ue-ethernet OR -v8" + variant_usage echo " Specify the variant to build." echo "" + echo "Options:" + echo "--------" echo " --keep-vm-alive OR -k" echo " Keep the VM alive after the build." echo "" @@ -60,313 +57,114 @@ function usage { echo "" } -function variant_usage { - echo "OAI VM Build Check script" - echo " Original Author: Raphael Defosseux" - echo "" - echo " --variant enb-usrp OR -v1" - echo " --variant basic-sim OR -v2" - echo " --variant phy-sim OR -v3" - echo " --variant cppcheck OR -v4" - echo " --variant enb-ethernet OR -v7" - echo " --variant ue-ethernet OR -v8" - echo "" +function wait_on_vm_build { + echo "############################################################" + echo "OAI CI VM script" + echo "############################################################" + + echo "VM_NAME = $VM_NAME" + echo "VM_CMD_FILE = $VM_CMDS" + echo "JENKINS_WKSP = $JENKINS_WKSP" + echo "ARCHIVES_LOC = $ARCHIVES_LOC" + echo "BUILD_OPTIONS = $BUILD_OPTIONS" + + IS_VM_ALIVE=`uvt-kvm list | grep -c $VM_NAME` + + if [ $IS_VM_ALIVE -eq 0 ] + then + echo "############################################################" + echo "You should have created the VM before doing anything" + echo "############################################################" + STATUS=1 + return + fi + + echo "Waiting for VM to be started" + uvt-kvm wait $VM_NAME --insecure + + VM_IP_ADDR=`uvt-kvm ip $VM_NAME` + echo "$VM_NAME has for IP addr = $VM_IP_ADDR" + + echo "############################################################" + echo "Waiting build process to end on VM ($VM_NAME)" + echo "############################################################" + + if [[ "$VM_NAME" == *"-cppcheck"* ]] + then + echo "echo \"ps -aux | grep cppcheck \"" >> $VM_CMDS + echo "while [ \$(ps -aux | grep --color=never cppcheck | grep -v grep | wc -l) -gt 0 ]; do sleep 3; done" >> $VM_CMDS + else + echo "echo \"ps -aux | grep build \"" >> $VM_CMDS + echo "while [ \$(ps -aux | grep --color=never build_oai | grep -v grep | wc -l) -gt 0 ]; do sleep 3; done" >> $VM_CMDS + fi + + ssh -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR < $VM_CMDS + rm -f $VM_CMDS } -if [ $# -lt 1 ] || [ $# -gt 9 ] -then - echo "Syntax Error: not the correct number of arguments" - echo "" - usage - exit 1 -fi - -VM_TEMPLATE=ci- -JOB_NAME=XX -BUILD_ID=XX -VM_NAME=ci-enb-usrp -VM_MEMORY=2048 -VM_CPU=4 -ARCHIVES_LOC=enb_usrp -LOG_PATTERN=.Rel14.txt -NB_PATTERN_FILES=4 -BUILD_OPTIONS="--eNB -w USRP" -KEEP_VM_ALIVE=0 - -while [[ $# -gt 0 ]] -do -key="$1" - -case $key in - -h|--help) - shift - usage - exit 0 - ;; - -jn|--job-name) - JOB_NAME="$2" - shift - shift - ;; - -id|--build-id) - BUILD_ID="$2" - shift - shift - ;; - -ws|--workspace) - JENKINS_WKSP="$2" - shift - shift - ;; - -k|--keep-vm-alive) - KEEP_VM_ALIVE=1 - shift - ;; - -v1) - VM_NAME=ci-enb-usrp - ARCHIVES_LOC=enb_usrp - LOG_PATTERN=.Rel14.txt - NB_PATTERN_FILES=4 - BUILD_OPTIONS="--eNB -w USRP --mu" - shift - ;; - -v2) - VM_NAME=ci-basic-sim - ARCHIVES_LOC=basic_sim - LOG_PATTERN=basic_simulator - NB_PATTERN_FILES=2 - BUILD_OPTIONS="--basic-simulator" - VM_MEMORY=8192 - VM_CPU=4 - shift - ;; - -v3) - VM_NAME=ci-phy-sim - ARCHIVES_LOC=phy_sim - LOG_PATTERN=.Rel14.txt - NB_PATTERN_FILES=3 - BUILD_OPTIONS="--phy_simulators" - shift - ;; - -v4) - VM_NAME=ci-cppcheck - VM_MEMORY=4096 - ARCHIVES_LOC=cppcheck - LOG_PATTERN=cppcheck.xml - NB_PATTERN_FILES=1 - BUILD_OPTIONS="--enable=warning --force --xml --xml-version=2" - shift - ;; - -v7) - VM_NAME=ci-enb-ethernet - ARCHIVES_LOC=enb_eth - LOG_PATTERN=.Rel14.txt - NB_PATTERN_FILES=6 - BUILD_OPTIONS="--eNB -t ETHERNET --noS1" - shift - ;; - -v8) - VM_NAME=ci-ue-ethernet - ARCHIVES_LOC=ue_eth - LOG_PATTERN=.Rel14.txt - NB_PATTERN_FILES=6 - BUILD_OPTIONS="--UE -t ETHERNET --noS1" - shift - ;; - --variant) - variant="$2" - case $variant in - enb-usrp) - VM_NAME=ci-enb-usrp - ARCHIVES_LOC=enb_usrp - LOG_PATTERN=.Rel14.txt - NB_PATTERN_FILES=4 - BUILD_OPTIONS="--eNB -w USRP --mu" - ;; - basic-sim) - VM_NAME=ci-basic-sim - ARCHIVES_LOC=basic_sim - LOG_PATTERN=basic_simulator - NB_PATTERN_FILES=2 - BUILD_OPTIONS="--basic-simulator" - VM_MEMORY=8192 - VM_CPU=4 - ;; - phy-sim) - VM_NAME=ci-phy-sim - ARCHIVES_LOC=phy_sim - LOG_PATTERN=.Rel14.txt - NB_PATTERN_FILES=3 - BUILD_OPTIONS="--phy_simulators" - ;; - cppcheck) - VM_NAME=ci-cppcheck - VM_MEMORY=4096 - ARCHIVES_LOC=cppcheck - LOG_PATTERN=cppcheck.xml - NB_PATTERN_FILES=1 - BUILD_OPTIONS="--enable=warning --force --xml --xml-version=2" - ;; - enb-ethernet) - VM_NAME=ci-enb-ethernet - ARCHIVES_LOC=enb_eth - LOG_PATTERN=.Rel14.txt - NB_PATTERN_FILES=6 - BUILD_OPTIONS="--eNB -t ETHERNET --noS1" - ;; - ue-ethernet) - VM_NAME=ci-ue-ethernet - ARCHIVES_LOC=ue_eth - LOG_PATTERN=.Rel14.txt - NB_PATTERN_FILES=6 - BUILD_OPTIONS="--UE -t ETHERNET --noS1" - ;; - *) - echo "" - echo "Syntax Error: Invalid Variant option -> $variant" - echo "" - variant_usage - exit 1 - esac - shift - shift - ;; - *) - echo "Syntax Error: unknown option: $key" - echo "" - usage - exit 1 -esac -done - -if [ ! -f $JENKINS_WKSP/localZip.zip ] -then - echo "Missing localZip.zip file!" - exit 1 -fi -if [ ! -f /etc/apt/apt.conf.d/01proxy ] -then - echo "Missing /etc/apt/apt.conf.d/01proxy file!" - echo "Is apt-cacher installed and configured?" - exit 1 -fi - -if [ "$JOB_NAME" == "XX" ] || [ "$BUILD_ID" == "XX" ] -then - VM_TEMPLATE=ci- -else - VM_TEMPLATE=${JOB_NAME}-b${BUILD_ID}- -fi - -VM_NAME=`echo $VM_NAME | sed -e "s#ci-#$VM_TEMPLATE#"` -VM_CMDS=${VM_NAME}_cmds.txt -ARCHIVES_LOC=${JENKINS_WKSP}/archives/${ARCHIVES_LOC} - -echo "VM_NAME = $VM_NAME" -echo "VM_CMD_FILE = $VM_CMDS" -echo "JENKINS_WKSP = $JENKINS_WKSP" -echo "ARCHIVES_LOC = $ARCHIVES_LOC" -echo "BUILD_OPTIONS = $BUILD_OPTIONS" - -IS_VM_ALIVE=`uvt-kvm list | grep -c $VM_NAME` - -if [ $IS_VM_ALIVE -eq 0 ] -then +function check_on_vm_build { echo "############################################################" - echo "You should have created the VM before doing anything" + echo "Creating a tmp folder to store results and artifacts" echo "############################################################" - exit 1 -fi - -echo "Waiting for VM to be started" -uvt-kvm wait $VM_NAME --insecure - -VM_IP_ADDR=`uvt-kvm ip $VM_NAME` -echo "$VM_NAME has for IP addr = $VM_IP_ADDR" - -echo "############################################################" -echo "Waiting build process to end on VM ($VM_NAME)" -echo "############################################################" - -if [[ "$VM_NAME" == *"-cppcheck"* ]] -then - echo "echo \"ps -aux | grep cppcheck \"" >> $VM_CMDS - echo "while [ \$(ps -aux | grep --color=never cppcheck | grep -v grep | wc -l) -gt 0 ]; do sleep 3; done" >> $VM_CMDS -else - echo "echo \"ps -aux | grep build \"" >> $VM_CMDS - echo "while [ \$(ps -aux | grep --color=never build_oai | grep -v grep | wc -l) -gt 0 ]; do sleep 3; done" >> $VM_CMDS -fi - -ssh -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR < $VM_CMDS - -echo "############################################################" -echo "Creating a tmp folder to store results and artifacts" -echo "############################################################" -if [ ! -d $JENKINS_WKSP/archives ] -then - mkdir $JENKINS_WKSP/archives -fi - -if [ ! -d $ARCHIVES_LOC ] -then - mkdir $ARCHIVES_LOC -fi - -scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/*.txt $ARCHIVES_LOC -if [[ "$VM_NAME" == *"-cppcheck"* ]] -then - scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/*.xml $ARCHIVES_LOC -fi - -if [ $KEEP_VM_ALIVE -eq 0 ] -then - echo "############################################################" - echo "Destroying VM" - echo "############################################################" - uvt-kvm destroy $VM_NAME - ssh-keygen -R $VM_IP_ADDR -fi -rm -f $VM_CMDS - -echo "############################################################" -echo "Checking build status" -echo "############################################################" - -LOG_FILES=`ls $ARCHIVES_LOC/*.txt $ARCHIVES_LOC/*.xml` -STATUS=0 -NB_FOUND_FILES=0 - -for FULLFILE in $LOG_FILES -do - if [[ $FULLFILE == *"$LOG_PATTERN"* ]] + if [ ! -d $JENKINS_WKSP/archives ] then - filename=$(basename -- "$FULLFILE") - if [ "$LOG_PATTERN" == ".Rel14.txt" ] - then - PASS_PATTERN=`echo $filename | sed -e "s#$LOG_PATTERN##"` - fi - if [ "$LOG_PATTERN" == "basic_simulator" ] - then - PASS_PATTERN="lte-" - fi - if [ "$LOG_PATTERN" == "cppcheck.xml" ] - then - PASS_PATTERN="results version" - LOCAL_STAT=`egrep -c "$PASS_PATTERN" $FULLFILE` - else - LOCAL_STAT=`egrep -c "Built target $PASS_PATTERN" $FULLFILE` - fi - if [ $LOCAL_STAT -eq 0 ]; then STATUS=-1; fi - NB_FOUND_FILES=$((NB_FOUND_FILES + 1)) + mkdir $JENKINS_WKSP/archives fi -done -if [ $NB_PATTERN_FILES -ne $NB_FOUND_FILES ]; then STATUS=-1; fi + if [ ! -d $ARCHIVES_LOC ] + then + mkdir $ARCHIVES_LOC + fi -if [ $STATUS -eq 0 ] -then - echo "STATUS seems OK" -else - echo "STATUS failed?" -fi -exit $STATUS + scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/*.txt $ARCHIVES_LOC + if [[ "$VM_NAME" == *"-cppcheck"* ]] + then + scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/*.xml $ARCHIVES_LOC + fi + + if [ $KEEP_VM_ALIVE -eq 0 ] + then + echo "############################################################" + echo "Destroying VM" + echo "############################################################" + uvt-kvm destroy $VM_NAME + ssh-keygen -R $VM_IP_ADDR + fi + rm -f $VM_CMDS + + echo "############################################################" + echo "Checking build status" + echo "############################################################" + + LOG_FILES=`ls $ARCHIVES_LOC/*.txt $ARCHIVES_LOC/*.xml` + STATUS=0 + NB_FOUND_FILES=0 + + for FULLFILE in $LOG_FILES + do + if [[ $FULLFILE == *"$LOG_PATTERN"* ]] + then + filename=$(basename -- "$FULLFILE") + if [ "$LOG_PATTERN" == ".Rel14.txt" ] + then + PASS_PATTERN=`echo $filename | sed -e "s#$LOG_PATTERN##"` + fi + if [ "$LOG_PATTERN" == "basic_simulator" ] + then + PASS_PATTERN="lte-" + fi + if [ "$LOG_PATTERN" == "cppcheck.xml" ] + then + PASS_PATTERN="results version" + LOCAL_STAT=`egrep -c "$PASS_PATTERN" $FULLFILE` + else + LOCAL_STAT=`egrep -c "Built target $PASS_PATTERN" $FULLFILE` + fi + if [ $LOCAL_STAT -eq 0 ]; then STATUS=-1; fi + NB_FOUND_FILES=$((NB_FOUND_FILES + 1)) + fi + done + + if [ $NB_PATTERN_FILES -ne $NB_FOUND_FILES ]; then STATUS=-1; fi + +} From a803adea2a492bbbc065c244d57fc1ceac0a8754 Mon Sep 17 00:00:00 2001 From: Raphael Defosseux Date: Thu, 4 Oct 2018 11:29:29 +0200 Subject: [PATCH 130/233] Doc: initial commit of feature set document Signed-off-by: Raphael Defosseux --- doc/FEATURE_SET.md | 125 ++++++++++++++++++++++++++++++++++ doc/oai_enb_block_diagram.png | Bin 0 -> 277532 bytes 2 files changed, 125 insertions(+) create mode 100644 doc/FEATURE_SET.md create mode 100644 doc/oai_enb_block_diagram.png diff --git a/doc/FEATURE_SET.md b/doc/FEATURE_SET.md new file mode 100644 index 0000000000..750180d980 --- /dev/null +++ b/doc/FEATURE_SET.md @@ -0,0 +1,125 @@ +**Table of Contents** + +1. [OpenAirInterface eNB Feature Set](#openairinterface-enb-feature-set) + 1. [eNB PHY Layer](#enb-phy-layer) + 2. [eNB MAC Layer](#enb-mac-layer) + 3. [eNB RLC Layer](#enb-rlc-layer) + 4. [eNB PDCP Layer](#enb-pdcp-layer) + 5. [eNB RRC Layer](#enb-rrc-layer) + 6. [eNB X2AP](#enb-x2ap) + 7. [eNB Advanced](#enb-advanced) +2. [OpenAirInterface UE Feature Set](#openairinterface-ue-feature-set) + +# OpenAirInterface Block diagram # + +![Block Diagram](./oai_enb_block_diagram.png) + +# OpenAirInterface eNB Feature Set # + +## eNB PHY Layer ## + +The Physical layer implements **3GPP 36.211**, **36.212**, **36.213** and provides the following features: + +- LTE release 8.6 compliant, and implements a subset of release 10 +- FDD and TDD configurations: 1 (experimental) and 3 +- Bandwidth: 5, 10, and 20 MHz +- Transmission modes: 1, 2 (stable), 3, 4, 5, 6, 7 (experimental) +- Max number of antennas: 2 +- CQI/PMI reporting: aperiodic, feedback mode 3 - 0 and 3 - 1 +- PRACH preamble format 0 +- All downlink (DL) channels are supported: PSS, SSS, PBCH, PCFICH, PHICH, PDCCH, PDSCH, PMCH +- All uplink (UL) channels are supported: PRACH, PUSCH, PUCCH (format 1/1a/1b), SRS, DRS +- HARQ support (UL and DL) +- Highly optimized base band processing (including turbo decoder) + +### Performances ### + +**Transmission Mode, Bandwidth** | **Expected Throughput** | **Conditions** +-------------------------------- | ----------------------- | ----------------: +FDD DL: 5 MHz, 25 PRBS/ MCS 28 | 16 - 17 Mbit/s | measured with COTS UE Cat 3/4 +FDD DL: 10 MHz, 50 PRBS/ MCS 28 | 34 - 35 Mbit/s | measured with COTS UE Cat 3/4 +FDD DL: 20 MHz, 100 PRBS/ MCS 28 | 70 Mbit/s | measured with COTS UE Cat 3/4 + | | +FDD UL: 5 MHz, 25 PRBS/ MCS 20 | 9 Mbit/s | measured with COTS UE Cat 3/4 +FDD UL: 10 MHz, 50 PRBS/ MCS 20 | 17 Mbit/s | measured with COTS UE Cat 3/4 +FDD UL: 20 MHz, 100 PRBS/ MCS 20 | 35 Mbit/s | measured with COTS UE Cat 3/4 + | | +TDD DL: 5 MHz, 25 PRBS/ MCS **XX** | **TBC** Mbit/s | +TDD DL: 10 MHz, 50 PRBS/ MCS **XX** | **TBC** Mbit/s | +TDD DL: 20 MHz, 100 PRBS/ MCS **XX** | **TBC** Mbit/s | + | | +TDD UL: 5 MHz, 25 PRBS/ MCS **XX** | **TBC** Mbit/s | +TDD UL: 10 MHz, 50 PRBS/ MCS **XX** | **TBC** Mbit/s | +TDD UL: 20 MHz, 100 PRBS/ MCS **XX** | **TBC** Mbit/s | + +- Number of supported UEs: **To Be Completed** + +## eNB MAC Layer ## + +The MAC layer implements a subset of the **3GPP 36.321** release v8.6 in support of BCH, DLSCH, RACH, and ULSCH channels. + +- RRC interface for CCCH, DCCH, and DTCH +- Proportional fair scheduler (round robin scheduler soon) +- DCI generation +- HARQ Support +- RA procedures and RNTI management +- RLC interface (AM, UM) +- UL power control +- Link adaptation + +## eNB RLC Layer ## + +The RLC layer implements a full specification of the 3GPP 36.322 release v9.3. + +- RLC TM (mainly used for BCCH and CCCH) + * Neither segment nor concatenate RLC SDUs + * Do not include a RLC header in the RLC PDU + * Delivery of received RLC PDUs to upper layers +- RLC UM (mainly used for DTCH) + * Segment or concatenate RLC SDUs according to the TB size selected by MAC + * Include a RLC header in the RLC PDU + * Duplication detection + * PDU reordering and reassembly +- RLC AM, compatible with 9.3 + * Segmentation, re-segmentation, concatenation, and reassembly + * Padding + * Data transfer to the user + * RLC PDU retransmission in support of error control and correction + * Generation of data/control PDUs + +## eNB PDCP Layer ## + +The current PDCP layer is header compliant with **3GPP 36.323** Rel 10.1.0 and implements the following functions: + +- User and control data transfer +- Sequence number management +- RB association with PDCP entity +- PDCP entity association with one or two RLC entities +- Integrity check and encryption using the AES and Snow3G algorithms + +## eNB RRC Layer ## + +The RRC layer is based on **3GPP 36.331** v14.3.0 and implements the following functions: + +- System Information broadcast (SIB 1, 2, 3, and 13) +- RRC connection establishment +- RRC connection reconfiguration (addition and removal of radio bearers, connection release) +- RRC connection release +- RRC connection re-establishment +- Inter-frequency measurement collection and reporting (experimental) +- eMBMS for multicast and broadcast (experimental) +- Handover (experimental) +- Paging (soon) + +## eNB X2AP ## + +**To be completed** + +## Advanced Features ## + +**To be completed** + +# OpenAirInterface UE Feature Set # + +**To be completed** + diff --git a/doc/oai_enb_block_diagram.png b/doc/oai_enb_block_diagram.png new file mode 100644 index 0000000000000000000000000000000000000000..58c8eb9e959fae8616de03cc9f56fcfe2cc0f0e7 GIT binary patch literal 277532 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

hxsnh9RTqxb? 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ఝLNIPN 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

U;VjjKT4T=nly9hAsi&Hx)BXo_uBS~3 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 KT)B+JhyMlE&rUA@ literal 0 HcmV?d00001 From e73169a2321a68f1c766c863ffe6618e384fbc45 Mon Sep 17 00:00:00 2001 From: Raphael Defosseux Date: Thu, 11 Oct 2018 15:40:20 +0200 Subject: [PATCH 131/233] Adding S1-flex support --- doc/FEATURE_SET.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/doc/FEATURE_SET.md b/doc/FEATURE_SET.md index 750180d980..d52a876548 100644 --- a/doc/FEATURE_SET.md +++ b/doc/FEATURE_SET.md @@ -7,7 +7,7 @@ 4. [eNB PDCP Layer](#enb-pdcp-layer) 5. [eNB RRC Layer](#enb-rrc-layer) 6. [eNB X2AP](#enb-x2ap) - 7. [eNB Advanced](#enb-advanced) + 7. [eNB Advanced Features](#enb-advanced-features) 2. [OpenAirInterface UE Feature Set](#openairinterface-ue-feature-set) # OpenAirInterface Block diagram # @@ -102,6 +102,7 @@ The current PDCP layer is header compliant with **3GPP 36.323** Rel 10.1.0 and i The RRC layer is based on **3GPP 36.331** v14.3.0 and implements the following functions: - System Information broadcast (SIB 1, 2, 3, and 13) + * SIB1: Up to 6 PLMN IDs broadcast - RRC connection establishment - RRC connection reconfiguration (addition and removal of radio bearers, connection release) - RRC connection release @@ -115,7 +116,7 @@ The RRC layer is based on **3GPP 36.331** v14.3.0 and implements the following f **To be completed** -## Advanced Features ## +## eNB Advanced Features ## **To be completed** From 9140839f75ec61a8f0b85acf56ea12bc525b5301 Mon Sep 17 00:00:00 2001 From: Konstantinos Alexandris Date: Mon, 15 Oct 2018 11:35:43 +0200 Subject: [PATCH 132/233] Update FEATURE_SET.md --- doc/FEATURE_SET.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/doc/FEATURE_SET.md b/doc/FEATURE_SET.md index d52a876548..9115114867 100644 --- a/doc/FEATURE_SET.md +++ b/doc/FEATURE_SET.md @@ -114,7 +114,10 @@ The RRC layer is based on **3GPP 36.331** v14.3.0 and implements the following f ## eNB X2AP ## -**To be completed** +The X2AP layer is based on **3GPP 36.423** v14.6.0 and implements the following functions: + + - X2 Setup Request + - X2 Setup Response ## eNB Advanced Features ## From d48c7eaef13a84d539f03f99cb8c716c6aa9d3b2 Mon Sep 17 00:00:00 2001 From: Florian Kaltenberger Date: Thu, 18 Oct 2018 10:55:33 +0200 Subject: [PATCH 133/233] removing outdated documentation --- targets/DOCS/api_icic.xml | 95 ---------------------------- targets/DOCS/oaiemu.doc | Bin 5322240 -> 0 bytes targets/DOCS/oaisim_walkthrough.pdf | Bin 805489 -> 0 bytes targets/DOCS/openair_header.tex | 47 -------------- targets/DOCS/path_loss_oaisim.xlsx | Bin 11730 -> 0 bytes 5 files changed, 142 deletions(-) delete mode 100644 targets/DOCS/api_icic.xml delete mode 100644 targets/DOCS/oaiemu.doc delete mode 100644 targets/DOCS/oaisim_walkthrough.pdf delete mode 100755 targets/DOCS/openair_header.tex delete mode 100644 targets/DOCS/path_loss_oaisim.xlsx diff --git a/targets/DOCS/api_icic.xml b/targets/DOCS/api_icic.xml deleted file mode 100644 index 80984fb236..0000000000 --- a/targets/DOCS/api_icic.xml +++ /dev/null @@ -1,95 +0,0 @@ - - - - - SBMAP_CONF - openair2/LAYER2/MAC/defs.h - - sbmap[13] - unsigned char - subband map indicates to scheduler allowed SB for eNB - - - periodicity - unsigned char - in millisecond indicate update instant - - - first_subframe - unsigned char - ... - - - sb_size - unsigned char - number of PRB in this subband - - - nb_active_sb - unsigned char - indicates the number of set subbands - - - - - eNB_MAC_INST - openair2/LAYER2/MAC/defs.h - - ... - - - sbmap_conf - SBMAP_CONF - subband map configuration for each eNB - - openair2/LAYER2/MAC/main.c - mac_top_init - - - - MAC_xface - openair2/PHY_INTERFACE/defs.h - - ... - - - (*get_SB_size)(unsigned char) - function pointer n - return the number of PRB supported in a subband configuration - - openair2/LAYER2/MAC/main.c - l2_init - - - - Get_Cell_SBMap - unsigned char Mod_id - void - openair2/LAYER2/MAC/defs.h - openair2/LAYER2/MAC/eNB_scheduler.c - imlements ICIC algo - - - Get_SB_size - unsigned char n_rb_dl - unsigned char - openair1/PHY/LTE_TRANSPORT/proto.h - openair1/PHY/LTE_TRANSPORT/lte_mcs.c - return the number of PRB supported in a subband configuration. - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/targets/DOCS/oaiemu.doc b/targets/DOCS/oaiemu.doc deleted file mode 100644 index 13433a5f35d916480a21aaeb5ce9cc6315539a60..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5322240 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%0D`_^(qEv?jjgWrpwHnBjL9 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

2XEXJdzq>6+hweqQFK~1@sMM<=yPq0 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%0D_Vv8l{DgP`4*G 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≧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 ($^jvbB6()} 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�R(m;-n06HQ*dKad^j!LuxQ zK~1LSfuryf+XFa=r=h~_%3w}fbY)C2yF9@4nE6MsgFvcnT&;dY5qzLELu^9i7S}ex zSNycUJ9Ao>}b8w=kwYR(a2vQNjrh3&BfSdI$fg?hGTFhRwQ; zbxmU=coeI_g`c;3Eaq3+1>}Rjn{8jUcG=XafD1f(J?Kc#wv$30YP^y!%B3q}#5;yP zf>NERQgh5GGwWPVq3kX1+B1JRi-hikrb9FhpsGf~hh#l5y!9X}3I5#OkG?ch|B&1z zwC@LBarcary*Uzz4qF8nT+x-Qm9VV@V?{&TBs`@APSqQiJ*7Ri{GZ@^;Fb(z`{asA z+fM4DFdbBL$qXPU{R=adSufzMgJcGmO!V21{;77ya*6s&wb~ zPrwkYWE6DgbdN@}779ckt&@1~6d6L39Qh-r*hL4x0;BHE*sZU?A{J883(94P;HmL|`zr{k*Z_aA3kuqp!Dw;!-tLa_v;3LL;?}}Z+(qej~--`N& zjfOF!_r;j-74pWL3F2?S;5X2-UHV%!K44{@hxQ`#R3lk36;G}4<^83492fq%y4$tf8R zGwo`kTU!@wD8rGO${qGj*jr|~9erPF${+Lm83M|A&<0Dnt0uJl6(gOxuu@D5I?ouo zR+t$2g%_a5v)`VDo_LDU#1r6io4p=vkNP&t|0Rb9RyE>zxc#_>mljK|B1ClND{&tJ z4*}=kjZZ-owKCDz@;+3Pqz1zcnwe*x0WogQ1F>f^LwM5ZU#i6CHEo@pze94zlmI2w zUpWUqfL~}BC8s&CS&7+CpBxEDIICnW(~!(|S09bPU>ZXHNtmxaTnD z7?pP)>z1gK*>~WUxVtS){b8YH!UOC=A%xZnY+LnkQ{#4>6#^f2vhlEJLt>6@YFnXJ zI;C9Ee?gk1+wFu*X~XEq=Nx8LnA+&DHLnK8?WxU-S81FS^`3r}<9hU=324v1k* z9EH1iO(>pgSU6IlTA-qUOYOAR*sT}72VKU#-`=7T|ENOHxwDR0*w~dGyb(!a(ew$MYwWv_Ch&_}xT7k2Pu7oX7u2iq3F5fh@8Rdi_PP;x~8-ErOWjDErPh|PdHOOHLy z>Bp0F$UDIx-PX$wNtQ9)X819x*5~)tQ^6;0cTpMI2D|tzV~9K52&8eVNRHn% z34R;MwuZT663dR)no1FDTKPQM(Qycez4TSv`-5zeYggix*h^y zK+tvE$NSYs_!GAE|3H!dmqE-4__{w3_kp%2pB(f*`21JE2JkiJcqQiluVi}9ad?me zXoM|DNd*qLy!k!>d>98!{287pQ(>C63pClZ){AV~uniCLyz;y)DFjulp!9#vTW_W6 zsxCtlj(|x3V5NkY@%(qXo%-P((R5ylP#qVs1%kYPx7Rg)g&;R$1&K|VHk2`ttA2|& zdpkyJDf+8{JjQ78`!`NWerjyEaNmNf>>SXx+ZE>Ie1(r_cu7V0kGB*xf%!+Xu2WEh z&7pMhPmXBLpMdS>46e6&q9 z{rK@Cpm9SrO~MBQrp&5FbA)S$EfbbrRQ4!>>uYoyY-I`6|fe6}CoZ7bsbAyR>^i%zhl>wCB4 zq8jwTG33V}xE#0cfr>|qzt3z?5jr_OU>0!lgHphmpN((ZIc!rH~TBuhE8(^eY*7*i!RV|m2_c<9IMwyEG-bWq{cI}N{*yn6^YQf znZTYh`k*T#`0Mvi#@fcD8!40f2-mipD6=uk_EH}@$?O%AQFaKj>v&&!F?3u(1R1%-g_;u*0R>FC9d zm&5p3h7Zu4vOWUxHxgyS{5%tuM$XJ_R(D~Qr44&Z=Pc-}Jd*U5DE3ccvVcPqJDIUA z(p;qb#C;I6A;KbPwb6cY!MoI~C4L$?(Ktþ{Gyg_LuOuqFY%be!>9P`=XS-wys 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.F)l)*KxPK~ zKq1M#&0b-(w20OP7W7*ZF(72HkJpYS_YEQS2s=GNUW(cYD}j)q4gn?>i+ISFkwC2L z7^!otjSI}vDj!1FD561)ipki5aqY~vonUr(bi$Z($wpkh=i%6|P#OK25 zh6?9DaCVT(=XtH8D`(AiBKTeJ!P;~bj>NG}Y6QUe#hvK!)HYM##$#MC50omaC$(c< zhZs<{LXdEnt*Uf3t=G)})zl3r5}|~c{2k{T7Dr8+XSzat6KP_??uVr#Q()&${N9D5 zR~4?%>XrMt>obxP90=<4rt@@GwQlK0lDaigkMNC=4N3?aE)XQCQB5>R4f>FdKEV7( zqW}j(ki(jZt#y2uw{|Swzetm0{!zzWO~6FA5mOQgf!u39tGN~v1RD=W)JI$Tly>&?QehSlv!Q;tff8S zSn-<=0pKRdR!p^qD?Dpq{Y3?HL%=6&A1r>!_J9bvLF*ND%+Db5;BjlDkS&>ve3fwP zYiDqxN>BIn0@RKgXllf+@~dUPGx@S0yh5O;EVoJv@a0-{GlZ{Xk-i4_tIz>5S#c0- z&NCd?uRa=pZ!`3MwNK+V3v1!Z3c~fCVt!XmernPZ&=^6n0v=XWMtt^exjsn_aO1)o z+5nynRH^trLX!mgAL5lH3xfS5J@E2EdRzCMv!8{+YX6XciP(E!LlCf{2^xXi46i+V zkK+V}9!gwugxwkEpXu-IXgh*hGdb7se%vL~EaswG^Ui%xd)7|$wevj}FfQP}C2Yoi zMT9*Zm#89|OWy4sZUHsz(H_Pox}{ll=7Et zDezq*ZU}+r^!hGLVU&Uy1j~y6mAuOuxMu6T{2r;<6X1EeK>E7yNBJsGx;XGeu)-iP z`t{+EG=Ni&GMsRo7F0t%+LUp(v538?pCoTumgYlAnk07EcGtG4d$++!y4qN+xUobG zj0dq;82dC++*P}DNq4n)68&q;#I(>K;i!F2erI!B=JECAa`SG=#cvCJ%qU~Cy_I7kqbfYL5$R>e z^mSL>HwveI^$^x_K*tlnxczfu-15M!DtcetrFu((m zV*?)O`-L8x=>CCh*TFwlP*|gDZ0rNQagWY6^FS~Yc{r*}8LLA(=6}og*@pGdWRM_C z^h^)1s^Zq97Q}*BTOSuo$sW8|3ZeF)4G4vA;5QwnB10Yj?k3uNCI(pTQmujX9^VP- z8!iQj;GZJU8imxns6}$C=+<*@n8hbFPp;7mhM*PiN0QDSQLJwe%UFgJ11B#N*{Q^Yw#am zZ15}hLN0Q|L7Kp|wrCmwpe}{RJPUcEiE2-WkI$=*@vkp}tB`Hs_?FkZ|74qfD#SZU zt_u9|OZ+z@r(Z3Rbq;@hY`oZu6DP9YDJuv@OJa?6MR`H+Qj$Z`*2Zqt_EXVz2w_Xu zN{-FiXWmy{uR9S^Q4|#%*s~XOPEU{_Ja7H}^0jMF+$XZhA(RmXSb68It_bw>TrB_wq-JZR`aC$f`^Q<=|2wja&a;_R1~ z`n*u9_xm&77!$ME@6hfj@-tarn%^ zql_yf_$g;c-LzcXe|_LwXjz#Kh%lj|wXVy;pZa+Bp03@!bfToGX58vK7JhFQC#~fl zM?oY47PhBHL$g<(9-o(-O>f{Ui~f$m?3<7GZ?3e`W|Z?c@0(q%&uFXr=hr}Yw_T+> zPti0O3mI(=ZX7ZGu@5x!$eXBo_vTPP73aS{XkZ^EMia6QMLm#@zTe;O_IVoN?`z=5 zo6Ztrszv51@{t=0Su4lN{#?{^9L$)Gn8n*v8hphyjvA6K(PqjinQO^XySK(&%TZ85 zm1)$NWq9g3vs(nwZI&)s($z^sp>EpULuJK>idM}A2xxS$E-$xlv-^_fx20q}9 zxFl}ge8)w3+_iBJdK)mDzrxjd=JTypImYkBcz_{Fh#9)f)UNKIW!>(wKv5w(IS6!F zLCq}$FLyC-dIPLZnJaT#GLny|W-&DT#pU<7NY>p@L;mPk%Z}Ta;#QtRdK2i_dYV3b|3l^JubvU1w_22A`JMevso*&!PI!27 z$H$A7{LCr1GmWcWV_BfCWH83%c(2KU`DwjH(*W*6O{{MUu0Ej`U0p;FKH_+byEGSw)4s?00|!xju0zIZtC zsMi~#(0X}lq!C7v6+_8=x$(J!-h2{paU+)j2OR$k8fc=%L`D5y;2z!?O1WLb4RQZV z7G|==FG>sD{ILIvq)u94VNz67RLXTmR#q_O(b{W8J1s43N_KYK=g*&$o!4LXe{@x! z4h;^PKU^IsC@S9DS_(O>@{AbmO%=S(jNb=Vni?6AMerKczJIApDQRUKmO*t@4RUg_&a2i6YIcGmG$3)2Y{b;USBp};}c2w&C!K%f>{f!#xf+K zVXsrK_u`c6|4b!;l!SyX>Gk?($!&kSDA{`AW#7MR>a^PU2O&BUdw(1Oi|gJbx#MoN zdi&JgGqFXrX&1%){e8vv@BMwzSmJSluf(V88<5`ncW>W@<>rz--R&eVH`vV~cLjCn z5*CcT5G{J1Zx0NQjrG;rOo_GeuGg5sqoJW`7#PG2B~u1_UcPqR;dkAhFKcca#5&Ob zS8anSBKX(4;MdbvMR2-l(EXp1`}w6MWfUN^{cd^pMgC8_|LtEwxL@~|d%pJMosBlHZ;`+q-F|^aIRck{Oq3R7fPP#4 z|8*13gnvsY{Nrh2T=f66ZBG5?JlX$Q=HKSxGyAwp+W*5RTOhWwz*7X{t(v*=fM4$O z)^&vG+K(7fRo;r9t`PqG%ZK_SffjFKwEDUaAK%3#4pr@(tM@+h*OV9IAXhzw6qs~u z68&vK_$Bz)R4mMCta)d4ZdXvGw>0oajl&V@T96xMIiK@jKK!S%U-DaZH%okQq0hg@V+Usq|Lg+Ys?%=FAxm5^SylNHO!HD?F}J^- z@^ynN>IO9gS)jfY$7Da67s-3CZ6@41e zdCHftf&%fu+J#;UgD@*(_U#S&?NXBu=zCY&?32fiGPS?&2W;28kbF#0JUYT@6OU?c z`&C8m_3s{qyg%~&>b@?&Yn`~C6$70iEYWj`FDva%xVMCts2;c5n0HZ;V z?o^<9`7DE?=y!;sxt5%_PeUbGec(`1}z%gwJPWk;b&z&F&e+#5Dv zzS3$m8}UqZx+OpI15NL{jN~^TB``Bv+SYZ0BK92CnkRjr*x zB@tqLpFE}1)G7Y{Kj3YSe*#&gw8tp!%b|&$x2*N_lP@KsPMLXFHX3V3eeDr@;%gbW z-~X{&oQbfOIur%dI6;-?rQo#=k9*z6YO+{r!n1P^^V_vvqG9T8RsvEXuU3XRX2}tl9IXIQV@U0RU1QPMXw*IaRa6P z-L4%$*QhxeMOFeFB|Qs@AP2;u5VNXUO@-`~aHmgJ4rj+=?2gP5+J)$A9TCBMHV>@7 zXHkWNyWZy|6%Q{E)e}0|$>ukh^u-Tzk;iCC#%6XL3OE;hlNiS4XYG*6aw!~-mNok* zv#VRf?9Whk&))mjzxP(Xn1%|%t%aDi+27gAB(UN~!$hYfl>8Om_aZD}Y%?=!{B6vC*qh_ruNcf%F!G#6g?+y`U8G?rD!~|(VVhB8t3{HvSbhr?tAtXcZ%BrbgtXbZyo~0 zmcFRjO&J!i3N)Y5dcyNG-`_hS*Ofd^62eSXz{MpkL%GH&btha)PdJlK zQ(=a|#wsWof1iJ^DIK?*{l+j7ZEZmx+wJdTWQEhBw}}yEP*oVr#=AY=8B0Vt6#{1s zng06pNqqYy6mB`WMha%cDpiiuGsljAvE*##vJfDno*6#TjHr(nA3LKEQ%RTQj_mOI zdQ-*vW|YNHd@cHi^X&RJT}J+OeSW*NidxlTw>a8C5N{k)+&C50D3~iYCZxEy0woN7 z8>KjA7)%p4t^pnZ4`}0GiZE4uw4}$>s?> zt!Df6t68%t+32DCk}V_&u*DGx+YDl>_+r?z9_|&0}Qww+E@+pMeKbh4?Q|<)|^$}A~IxNFPHyw>o6@Y zy?L)Ff&8aABhPYd)ebD!V-}6bTf=@!T~i+lXMM-0IH85ufFC|nCM|iYvL}XQ+?%_; z6P?cwi#p>?<4s`rf9(_*NsbEeo6*3=6c?uduKyW3i*swBMv^W^g@bv^hfR z+)kON0J|Yv^|n~UVpN~m7Mkz*upB;fTEIvWpAr{J$fVR-4R>hkk(K4*T$w$fTbWYx z;4Jz*%-5FsttH*sND}Z11u#4)Q+B7x-g3dh%bSb&#b5Y?K35^9u?BNQ9$D7d^$%9S zBXi#DrSv+iqAVtG#%f#3<;V*&2G{)$%5Pd=R^4m`4q0Zgv8bAv{jXx zPh$cX&m0qMfS@!+#2Mbg_<*6K9@orS$F+osEa;~UE-)W#N|F|Z4Y1w9xGXR*8Rv`R zX+j@JwSLtE5HEC)URy1}grwn@TH9_HX-*y__g!i}EtmdC8WbUFArp&lctb-}>D|}+ zjO0$@Z+fTg=pjp%R4rEy;jnYnYr@|c5XDmfcy`J*M3`EKq-Dz2)%{n`m;KQ*m`r8f zi^~Idz3y3pe;2{>JTWo8b(0?p+DKT^lHN+c)>r4@PKuwhEZjJva+80RFID^qbsAm zOI2Q7C$A7l;`-=R+GC4N?+s+DsseFf#s=250=|u)WrN7a1DOC^p+Lf61BJNLQuuj@ zarI}_NtBSDAm_26#EzVr8BP?zFQDmct2h?f;=KdBtwG9Okv5`g4f`VcGaLEuJ{MhmpQY=%cYc}(BOJp^lw?ITFY zziDq^`?Y%ueB4&3z(E0M@P8o03fR~pyi@i#p4I7VN_2?>u(xVoIa~DnwrU01V)7?> zau=a}MVGM^hwl;L3L6j!Vwbks$58o|m`TFkN=O-bn_agjPLo1%)HY?5h#TKIK|vCm z0lwIC;?JZ!?7Afuu6`4Rogyj!jK1jh{kfd?uQKY7-8xGIfhUw|PdT9dRq^e`2hP~iqwxMm!btT4GM4Ou5r^2rK%ZXL?!H$n( z{L}82p~>aKx#PTre@*WeX+ghf0H&ozx$2kJ3f{%({!>HT~a<$ zr6X>ZWC11-vMMM}L?pF%Z{v&8?R`f3C;wpgp&=q!i*D$m$sv64 zV@>8G2BuAt9Iz~T%E*GS`?kW}2i5sx6MhGNFU5dX&*@1B=<+tqj4-fR6=#Zbu&;9^Hh#q(Fl@2D+FD(%v2p zU@FB}p(F+UuqewS9u;tmNK7o(vX8iX~{$gl!Xv3uz^oSkImIJN~)wxePvKv;nr?j3beRu zkwSsu#VJ}GiWPTvFYcs3f#U8C#oaXocXtmIclVHeIp_QC+?&adOp=}1^Co#8*=s$^ z0Zn+m@7^{?>jt+zyubca|bZu7cKSoYvtSjtYI>G0* zSVt2m-$y6NNVHxT{tM7c8@@{trfMeX9mN0EXmn8_OCNlbO474<$#Y=_iHNYNO??aEjDDo(Am+kd~F zA(%EfsJgGvJjzUPXZ>yviQcvP1q9g^jRDAwawVg`G3 zDYc)D0}hQuABbq5XfxSk)EV(H4k=$lBk62a$d(^Iymj!ROy6xn_~5S3oVfJ z4vLXhYX7Wnep?wbRbGpuHCJ}3!#4N_Coyzy^Y_{`3Z|v%zCgcAj;keobDZmJF3&z| zRG!L;bCTHf0_3clRkH04ii~Fr$0$rSai6l?d(5Hick7+M~ zRP}glTAEld^DKWk^4!$y>Y5Ty4@9YbTj!~1ee)Lo8`?wvN6as-ckBW1>M6}Mui%%W z$L&o!aOckvR|g*Ps<_(}j-R;lhUBd)r(bmK8G4TE8 zPm~e7`^EWM?se;g$xRn4)Yz=zUsW;Wx!Xc{7($#5%i%fMVfXE^_I8O(_1VE)n|s!P?dkJ)rgqZ?qHuanLQA3EivH<^+L_SBb4W6) zd&7fz(`6NC>Cxi3UP0}Ux(CR}#d*sU!W;_H^a!cebDN(tKQ_>x!E_-LI+o8qP_?X@ zGmua3msnFfyElLNW4XswJKwbnLt23J@DZd4M)GTz2Kd~;!L`E$7vy|f#QIRsel>R? z%)f(vKXJPW-EDi30U_Rg^aM4}O!t&T42ob^)??`@XYZYn2cYS6V~XZcJpuW6 zcKHjkeLWovQBLR8GQW}H(D%AK0}XIz_}(GpdcjivfW0BG1kck&=Q9j*hwTp}u@DTM z_QeB;>(>$vsK+L2e#g`O6>%joDd%cIW*aiC>m{>m$+*B>@;mm!@R9pTrQ2x*Z%E7S zlbsj_T0;pde~+F|2Yj@z>d6-ud>Lt+{^wA(p|(z=ElV$Tc}4QN^&RO#zpq>^Txa}R2f;O(%207qW_zxbd5b{sBRS(k zn1sVv)vDVD{@pMp$Bo*`qqId8@kxi<4U{#)<>V%7^Ci0HnIFCB$wf*0AO|n8}I&>p}R2S+hC(pohFvYbjQbjLXD`Wo(`R?Y`F`H!pcXt z-|!t$rRCtYwFAU(VMTHq-diIpyZKK(yT`Gh77OC&mLyc;v2CMH6ir`r4D60~{0c`TLOdP}Ff6 zw5*uV04zQ;Jetq;{KWfGT&}+?8@36kv-Udig-9qIGdIvDuA_EhqSp``qCBf$4zQde zg1#?3nG>ERvm3xC+7N^QfzQ>AK3(gH$pVDyX_ptXAh4iD0gvtT>Gt+i(@dE~YzZF# ze{G}yx_dXGdt>l)DU#jlJMBBX=6jXQGmi{6^UJzS6scRU@V0;j(9f1_J3F`ux4T&z z6>(NuQ^49UIX81vG$Abu8h1?Uoe9A|?O3T= zSUydA?sLO-UVXz5;rx7}(qh^Jza#MVa7saE0iDM6yRY+0&h--uswaCYB(r>9KAZGD z-{_B-8sADP-ZNk9xCf!KxY9yy&$F#GHzt<`8E$=Gp{I+DTdXU;ZP5K4ee?2~HBQGU z;5*~um;DCG81P*O@&P3ILif?3$JVE(*pLu7nNI!B#S0!gfVitesQh%N&>LNgqVl_D zrXl@KPKwTb2#<6+G3$E}Uo*V64Scu!dI1vEo#h#vvpG4ofAIAWVj%0^A4MBl-1kV z|M=Viznz`Bo|#a5gb3qD8FV5o`EgHN;MzB~TUKq2?NHkeLts*(yPeDHf+5FM!?Tkk zg^rbOK^aCzQlYB{r?R%UbXlpy9Y2*P2OZl?)|=ULM+gOv97e-5uVA;B>j`f&I=J9j zUgJ=-)nmtAAJVfk<17chtE}z1kNytrdIi000LyZR#~OtN9?b3`LZf-fcQZHM2BsCy zdIvjxzS{c-agWw{Is>7|HWe|`qAHjto4LxLUM`)c`TMUP+m}q-O)g)1ods5{*Io#Z zpD`!;2>=d-7YHF}4G+7IJ00QAwgk}(4|+T0=?U?Be-;FAo5<0eJ7(^KxAIC6&&KWT z4ZzPk7PWiAN7@|wI{h_Ai$?ga66szY7ppa4HO|&)-2%vv5k`xSLip)?Mg9Vdl&e#- zz}(eh3|z~VM|j3ev6lI<_=3zWXzaw4w(yfN%MQ^?_{N=UX#|Jc(sg7E_q7voIvrQc zURB4W{0e>1N@v53!5A!9?rCKTf|<2&eUPce+sWxH<2R9B_l|`M^6>Gysv^ej(>78gzNbvY?0& z?qt#vJdO%yZXj-Ma4fuxxVl^!8d3DAuH4Ib#5XE18Am53IN7yZTsyhr@sXP@)*693 zpZ*HZyT6Ji*|wp(5tyK7uR=VP9ZYrncvHZr=fxNG}URcuZ z8UARX`?D1%2{sq7JOza{071X%1FzQ0K6Q|1ZWlK!Z2*c*OT-ff{1krr`>}4P4`i%9 zjW}^mwh@s7A;lV2R-=c7%fzyL1kQFmZjEF z^Zwup@UWWfs55DL_M3G)Ho!%$(l>8%2Sainzu!e3K}S=0uL2|T`(@WKpR{fhe#oA| z+c0aEQauxA4fGu&$U3g)zRnQzA^sM>WorIf<2D7Ys+w&P0_L7riG!L_r>6%oo$PJQ zp52~rSierFjF663col3Gn7zf5dryj))KbxtN@BI+FW9}6CqBIx zu8F|*Sky<%ZWT}X+Vac5;^W)-1We}R1Qp-v()$)gA=~3)7=6FzXl&HcwKfKKo2eK` zV$E9zk_%UE?m35&QLxhMO%^$XK?}RAdXQIL4%X9FKDKSKwtri8L4{kN{OwsFO5c#9 z;uC(xxzL(|R2~=KYJqG{i!#?+l*p#fz9t_Kk|l$$&9-d5PA~Pd@2F*;sXs19r~*(C z$e#L*g9p9e>U~*j@}sr}I?Dv4?mWMuZ+y)Hvdf0<*D~cgI|9HFtZ;R&o-$HHs+aon zQy+(@O#pn?C%rlTG5J2Yea#qu+=Lvf1bMHy0}1b&({LMY$z@$VKySx@aBZlW;^TS? z_RX$zx=gC*%k4ZhKui9)(cDZAdN+M0MS#b`uT^W<_2$lM!K=5gkBr~-aQy%VC4|a3 z+*5vuVba>W*gWcIG{}60K&z7Pa5FOZ%q;jFyxS~Kn=w!2&RHNFJGaUMtC{?XP`{^> z22vg&$m4-K^l{Ed@CfGK&{PC}x>7hoN=wLIZ_|obYO=a*>_T^S6xlVTJlHml9e4RkEhU2eKR*h7pm;z+6yBJmnXCX|{1&p) z)<_2lS(t3S6NaE7koxCABe~UqUk?mE1h0hoa=a%keo{Ox^z2rTdF8ZFCI{l5Idik8 zpFQ2Joh=a06W>vziYcZqLoqflMAnfY zQFZDMCbBI}A16IoDNfYnF}*BcXdXJHQ{>4kff-*A*-1gOJWfka_F;P^u<90 z+(aJVE)*cUx~8-GEW8^cgf3sf@z&Ggt?M;xo|sANVy{6$Y7rDYrF5rhXe=VE&^`wZj2@}~rGX1S)lC0w+5m2o@ze<3vAUIG{7{EIT!Ew(Db)Cq zGNXz(;Qu+1mqQ^*x7T@Ue#L(PiXuT@7=j&+z1j95?`8r3#Z<{7wW%g5wW-p5c+Jr@2ige-9J5Is=05y4tVsaMF2*@v zycK>7uh99E)!fC9cjn7plt%&gCC2SOSs^y+%4%l%lQtN=nen+R0@9vG7yY$ zPS+4dQmfS$>H zFQ~UGxja+A8#nuc!Xhk3@fh(RMWa7)*r)`TyL4XS!X32QCoSXm#frBdM|E@)p`Ou{AHSUMQ+0WnSQ!;vHkSZzeW~A)D0tPk$giiBt)TfX4 zU+36QPAHQne^h~M6utE;?$3T7D4ssyrR*ZQA_#MnNNmsb%WU?njW0*f5+Nr_^m)0= zi!*W$j+b^nYEoHO9JsCOKhvx51g_@`a$fXQ-~-w0iL@Po*>#7>r(ZktNM8)FMl*<_wsl< z3(NSHEvB4_)I`L64a}+}n!ImL`(QTZ4V8*uj9aN3u5XWk`+z%f>vEl|evuqf&xpbv zp2e}Z)jUQm`BB1rac`@~5dVBz8WJkw>Xnsfs;dmtlD;(D9FVjRQpFKN!*SvTCgFcdazvUg?_Pbh|Et z)ypcT1s?O=Gnbb+?)(pr{#vzrJ3=T{*09qTdubb!%)0>Jn{++&z$oug5)G5fXz_c< z{NIQP%&~VQ{HLI`k_I85iYu{ysl^w|sEem+fPhrs`m}~8pIvl7GMalkB!7>xW3C@I zxFZs|DNOd<_)qu`aC$2?8UI9r@zod4je2~5x>kPt8@AxF(7y^cyXdLgcL!Hqnz1$P z)>VGNn{E-_E`IkXKjS+-G6-KQe4dt$J$MUiXWuW%#;pGbloXcx=RONtC*@D7VkcrJ zP&|rocCRL~Np}zj^RszhZwBKkHBnC~oY_3Wq{Ab_W^xN zw|Sd8ZK}xcsb83;v5JJ8^%_ zRZ|T%Ry=$j{g1iU^le2nGv{O1zRD9OQHVn1WV6fL=`S$zK?E&*3ioBpisX%fPN3q} zp$kY}tGEK?9{kMF0p_2hNM3m z(I;;1-*Fa)H7yp;doa=V=jxm_4dgoiLc2c}-_N(k`_GnSY-5$=yVvon)e>M4sk&jE zeL{c(pIbRu{Bo#;b)`3ve?L2qUWZ1)l_=2VqV#6~@R`8qR2o#AXMDUWhwT@OoS}Tbwr*dOEa`!I(akVn3>IQo zACu|~Iu$FIvL7R)@!v6T*ECtCn684hdH|m(^aRc^iT+vt{KZ!5;_1igA@}32rTxQF z&>otupuJ5_ehf`J<=bflDuwinP`ocuc-U?i383-RcFgxc_0gi? zcZltmlfZGHNbH)`S%;!+x&G(x3s3~rJQR503OCqAAA!Z7B$4f9oc(e#Ebig^g80ih zuvg~LfL{`%tJpQ>&h0{o^QYHYHXrNJ74&Xw5Aw@5QV@9sbA>#yl79_}xSw+iLzDyRU4TWTEU3PEVQu}Lk_VwDWnCqIJ$&lCbcw)L`5bLUgNh*2}IM@p&rq(aZz zy9V$SX;g0ix3iu=RtP(Xt=23}2yK;GA&ppxAL4~o#=j2wnqEA#|@Bb*;XCAlbEg={V*#<71vTZ!v4BIJFRTT6sb5X!TSa$>UoR zvy{E+-fk$Ul+C7koMX|(ynY8pp=LQKs^yQ4aM!PqM(K>MZO4mKE5G=U8#1uc!?Xt^ zf&Z{!Yam>${?M!WL_6rb%$tpElrs=tD36dPpmPbid4L$07WQx(wdt5lT8SkNIqq{- z`_@|3^eh_oK8JLwJTvbB612b|rSs{^3te;N;B@>sA{QvHrGQNU{+)4n$GZn47Dgh( zJWuIVhG)(P3H|}x({X~eOCj-vfg6!@5j~xRim4I(eblx0yqTR+Z;QkqymOpURV6B- zo-eKd?LnX*5F0L)AA+%50h)byAt8^=W(ZIWee}5*e{z})`O4?+{)YR1bHr!Ea^MO@ zD0x31>qB2Gu8=mlPltZiveF~qDhVYo+8oM9fAU$%K4B*KFWYUO4+E4wxN_*83rd@zB?Y9PIvHkXGpA5~83&C%+7 zx_fSNI!3eDE~rx!GaFb)xn`5GH=#}<x*EePCj|TA5j=QBi33_$dA7y6V+_k;r-2z=#ppm`A z!q{Ew*XP2c*Y%ExC0CtIWBJsuY@9irmz4p1`|C3qv0u><2B%21XvJ+#7r1+Kr*$Wt zJ@EB~kd2|Mc6cpU4{VdoN%?*UHXejExt-$dzb#r7<6)o`Uo2aF!07N;R*mym>)>r= zQTUbSsI2;H02y04{08A8@Fetz{$fq?CH0$mx`gma*h|l}q@wI?du6t|Ue9GIW&xmm7^tSImKY%X zmc(x*no`!;Opm3J?4f&QX#f-M@+~Rs&F|fM{Pue=>?60sg*4uGfl9CAOG)0!lLz6r z3y1^r9G(YK(?5{2di@6IcT3nmUuv=kCcV&sdiY5Qppp7UtjY7k#h*P5&&nx&iN}D5 zZ~=wp%qUh)v*1sq(H>0GOIEJ|DJmFf_)|2L@5^h`;!76xjaY?cJ9`@PvL~JB)ihQN zlDT_2`mBJ6{{M;=YJ2m09928-&&X$)xyPwro1z>Do3HkW8<88G^phXq4_jm0l{+5UV0}AXY^$XyU7O+XcHFRaOx9?W%cG;4)(7w@ zy^>-SP%-f$^$SVWCAHVL{n$F#N;N@@QN->f?A_zVHM>pIqEy0f_{NG+r#)%B-GQOz z0(@XDg;wgY-9`W79dOu5uObY_pt`|3TNs1hR&r(j@dS@SjlPl-ZqM!OS!R&5@c7jm z5yA+!=b@pZQ17O5g0$(LsSdY>1;q)V0tz_%5pz1Zm25F<7{aQ&a=OuWfTtrqqw%o@ z-YJ~v#d`l+yGbpxSk-ndhRqth9;N>Q({BBRccj2OGDGq!Vd-}Mua%9;d#Talx= zkCDK$X(Yxm* zJS+P5iun1q$FMezat^lf=UmSf4&B|GQ2<1s+bzIxI81zL>HK-;a*!Zl9S%*sK+Q;hhkcwKU4|$<2lV z)bsod02gMXnJC=U-n)}a|GHiiT+B-r-AeeW>PV1IlGiGQM_S_H;v2M3uF3Pfos+5G z5*wLY6lov4hPgQ71Q*uM#v}QMPi}W15gutBv8#qsr)M^ecyp0<`1}m&5qbHYywFGp z0KJfhJpqdOp&-EEzt8zKzdVHGr@!PDXG`J&aL9{(<*s@DiF*N(YJ$FjgVMAvrYiE! zfthlbEOhU%{~A^GXMP|mnEEH{6ZseDJP|(Knu7hn1Ezq5B9koO6W%7^8hlGZ7@2`x zKR!8iC8l*zf6!zIQaw0k6B@ff_ak#qj15!$3&AM8YUQi$-8#5t;(2k_NS+3~LqkUE z^0S_|pAQDZw567FsO_fMCVW~S{nU@?-D<+07bZ~+m_6|M=#>BS2~_wc(jfl&BrxO4 zYkJ4Vgl&r;6EYI-XxtKM35Nf^1wyktbrZ7K$8u{?rcvv9Eq}-o?$>A{+|S8P7kW$7 zl$OW_>J9!L@V7zkX?V5wfQa5PeBWbD(4N(haN3to%Z16U#$DARnj|ljUk<=Fu-vK? z=*m*ljmN8*Ur298yJhu=_@uQwNM6We!q9T_+|;aSnjvno^|?jdF%FyiC_!GAvaAaW zAai5vGt#jYNN6~wxuK}8h+`XWTh(1wiL(nd1qnP%H(TnOIO{njSNzMO4*CB0{j9d@ zc%fD^JriqAdxsa*X)ueCJ^DySO@wI(xrI(Tpny@6c}RvuW}ZGfGVLT;hP1`TMdKv{ zL~`#(->BVqD4)nYyL+<+y<#=MQnHkXH8iu-@wd-GcTsp_kY`sqkLC~6lRHd+FKc~s zvel!HHuJOjsbf=fc$m(%U}IeT4-!(vA-4l`E!=pcd1F+7YGYy1C2{)5|?tiS=gNYe)1rheCOuB9@ovSgx(?z|8Ni5n@r97;pJFW<4M z0a5b@F&DASkVM3{J2;2iW&-l3CR*7F5_a2`+s7$^wQR%GomGi)!G~`u_QGp*w%_04 zrb_0;mdC8`IB8-0>+}e%k4M^T#b?ZuE=r#eU(Be= zR}<`c?!~n?ESIO7C|h#$_xr;Jn9G)-Df4HyO~UJASG1wo-Wwy>ARl|Wc7C}(l+M{~ zTYI;bFS=PSn=)(>;V?0iT%(cGo=^$3KDg~~hgi93(+|&HwX{ZA^W?bAJF}rY`W=#Q zG=Cg$1>;tk8wLf#E|6Q|i}52EXAG7uZkAb_c%1Zz`SY@tB`vTTCEu6F$WK7|t?(AY5Xi zfpps0@}@JTbB%uDCShRoZWC=Jya~fQyEa%=Y{dqs-QM3D*zLL}FI4Y;4YH;2*5VFz zOw{gQAG6Org9Y3&^}>&iPE=$~e+tUrF`w49WcYvfGF-K`NA-Pm#0o*izeYdge%N?U zTs5r?xamSosg$FNQn$umNtU6mnz=d$I=`c6@YUVS^3lemGwDgMAu&w=O0@8Z2w3c8R-w$EDJev8K>)EV25p@^eQQ5R51rz9@URGc9I~7hT#Sb}bp> zO?XGnWe|s{b+A;tgeld7o)Ib-#=$w!!d`wlPKroozY*V7}vW za*Y8T>Zpr9E@D-GV_Uhn+V}7ZX;ZNHAysS^1DyTz`{C@KNRkrDyUj8m;2a`NEB)wV z-Ie6tyroKRDhZm_%NpVJO@1x-AQKFZ?}3zW(xsOPMxiw97eb*7s^XVw(s8oZP9!Rvf3_ z?cb}7t{Uyg@p%R*e3Ba_Q&6P%*oM>fo%pM^Om#7eh~wud24y6U{7#7IqHUNe93eUh zEq2jWTYUXfczLN-mk&<_2_?WKh0 z>)D-#-8EoGTqvG~<1-{7GTGz%dToms~{~;PZ@dI7sztb`AFX*ctJ^`lbpE5m(fFdPUhQ7M#B>f@#f)K-yPprdd-Cjp> z7_lBQ_E_O&CZlkzak7DQO)*kf^t}m<=f)H<)3C1l67F%fshDlQ>~?19lF_V3C*c0) z%PrAKVY|rCw#GT`tPFQ({UXvPfWqCH3Yo)TeBCz@qQscWJFLR4@1%)SJ{!xCvK|A3 zPiB$N&zrYVhO_Xj%m*>kEU>XuXSt$Lx|I1g5WpxR&LQmCULJ5O-Rk3n=0G9@x@xJYpM?tx+?RqIPWEA7%He zcsiX+nxY?IT+|q{91@WMJt%Mo@rh79d<1Z3Qnhbs3DLKt0@YDc-+BeHCw^DP>HUmD zMdTVF3TqmLAs#az38MC;sa7Hagw-sg3fMq67{U8#7N=~fq`GlIxE+J%6*%x%?vTPC>+5=J6JIC~dK_rHucx@a;K9>i3s$`U2g4&X`YinJ#LN zKagVbu}hQL+5gaYEu^vGjpto~V$x}dk*PwCzbhC;iJbtpv$hbquuBlhT=L72sWz&D zL5D4z#;@l{VKfmn$Ha4K6QHW$?t~f5YZ+>tBFTHK1pnI3tg9C? zm!79uBs*c3IaWdFWx02{1PWiRxf|%-H7MCKqoL)K07KL*bou8KJj^@nW@%O%6KJGTHsGoBc!eF0;3M(W8ln^dUYcqjR5&q{=}Br&k1 z>5qBami69B<2H7dFB8U%Y7}iBub=@LE0IHi-fl5vsb!o6Ou>An?;X*lEPHW~MKzHx zxxSVph^T5w()4(piQ9MXN@o--l(3g(J2C2sTVhVJ&MF#tVj`LTM6kn)gzSEGE z9Qx=?w(YM}^&0SgI^~v2VX$nD8(WDgNgytta^)zk+GV^hDnRon>l0Q^ECVi|`kexzlGTfQ&1Br+tg+;7{- zBh792y4nwSD1Gd{Hx(?AbJgy7jWon{Wxs7k#H@lNO_a(!izI_ngK>YH!f~%Qgr>=Z ze85^GG@TZ5czt%{xhmv?;FkXF#*L{#srExw;|J@<@J0FBIKA&`F@0!Ze9Fdw+uT+y zbic%IB=`n>zd5CUL%*&s=x_j zk+0xp(ZY1E`bzUvjU>HEM{koM>oDn(#B8!hl4&ISF9|;3;M_ZHcgCZAmqNk^f=29g zIXn*OB-V=xqUEBR2>0+6IM5Rdu*J-M5Y))f3vp?b$B&=p9bCHW0;sLz zdj10RI0+myQ`u2G=B!gJ=u`QA06+5r(Fac<4;`R2fC$(c+Y;%J>U)WBN&e>b8T3-a zWl8QWuRa267HEi0D2hEA`NVV90E>Zf{dmmHk+&Q9V~oo?@>JuucB2&Z5FUa0ubv zAC<@Yf6|Lg`=h4c|0l)Bya335C0mdSF>CP*7a3~^*BZ;cmZ{gqm2z$}?VnSR2k~X0 zdi|8awjX2J0tlCXu0Jxsu1WHAr8n-%SQw|dZUXY%ApdI1GnzWGsCg|h2H#j6J>lFt zm&(@ao}hQB&m{g<{C(6Kc`IUWpw(|soh?V*ank+uNj7Zg5a~SMxpbsf;3R&;U9QQX z!C*eo7Hjw|^2zJesLBoZcPWo~R9O9Xn{6Lmrpy^KhMYPQA#YCi3x*~WP=uD{*Zqu5IY zrpS1t_=8n&!YAO-lDNDnvNSO4)w$_p4#vXY!04>ASbF|XBQu&;3q5@N4$yQrWe3%i z2gF`biBxOhKe)$0klgv*NSKoy%2{5?p7Z@DJF4=%=POp!(%{msQhoqdK*-Q)c9riAF$y(O5e6f_9<#t95d_qs>ZH{g9=0o|4~Y-I7DTI zn8tINbxWtvh2=}bd4*!^vHm?gheg)Wkq*F&OC%GrBGKulEH1?2+mX8|&0;a7clp`( zwq5FAtze&{;L~4%m)X=|1=>0{_*w`6?`3E`f@Rw*4*&1BCm+>t%HvPErN_)AD%I=^ zFxXxf`Ecp&qsgNJZe1GG#ddRGdeOj=s*N2V@ToDTzAwJmTtG#C(!A1!O=~QP|7qT- z{87UngHmqqQ{3U?g0{csDn*y;!ZUC&~hf&ALSrt4NB*9Cx%{n0#!#0*_LgR&1%`tXojAqiU1lT;k|V{{>+epC5_r zTQOf!gFNeRsffmrRks1pA`$_Qzupu*&&pus^7)aIDIU2fq=_+-0 zUQ6lo%#wA6)hETH=d&v*Q+yb=-^W2`{X~)cuvar5l1?Ud>jw_>52+~;OR0pFu(xs0 zNhnnEAM$oxgp*|=SC|LHM1L3 z;)R+XZV=n>=m55718Hqm4bA1D^k_JDtw&YvsdyNiyq3V3rIr27ar;S$_V{d5>MG5= ztnnhyi>wt>i(V!ZT}_`hEp}t%?su_QWr(ov6r4$SWTA1rNwfKt(3=|hmAvFKLvMo{ zp{Jo)oR8|Ul?t2BUALjj2m~uv@%O&Bgt=J^pl{JScuUJ;Sh#JI{?@{Fgbn%2spC`s zv@_ghb(IpXTsOG@H4kgu!j%r4FI>`qg z>QyZ3Z(U7M0i0Z(%&JJjckJIXX*yf6hI701M-4at&i8rIXaau3vpB?u1u+d%X_7EE z(^FiNb0#vGT+jI)ET&gjGwIK@ z`gE3=Tni7*g0vgXj;hbD|Fx8`VD;>-?Y99`2w$kDx3QO$Pt?`2ZiTC2lx^TAzXmV4 z{y-&8D!|2q2!6UF2%r%@2Er&5S-b)m=mepJW?BA+1!6G*r)5>dBvLW6TW7shOzemI zmV2Zn-4E(DUm3}ja-XXkFXxWNZx=svboxpKHQ_m5$Z361qs=(*KV6BYNElP`rEmK* z^2OxVE`V&7dj1YHLmk+-2;v7JIY|nd#$MePd(qAMr_pp1q?$qh*+!$?C>hn{WkEmM zsuox=ZBg_(w$kYTwW$sAL?JA-^I7?5TO-9@biU{9lIwD<>@lo+UMB0oir!u2*o`l6 z<}Vn@ZbT1~Kzxwfs>0^v8w>O%$6>arEEo>*F#3F|s5rfS>E-t+CsXzOIuNDgv6e{& z_hqieUE!3U#>*s8E|pzT7VO7WC`a+kdlCySlBedMB~m!jn6Xlf)WeAMmd{_-)fFr7 zPIf+79eU_6i(I7PvniW+E3|_d(spm$b3^J{+aqBbuDE7qFp$^V zSlN5Tu<%kDO2p;(qY6ap{$pk4Qc1~kXESLPKAbTQT+F|?_2Fs-+EORjee5SfbF>1# zgvK2jF;(*qna7TKEDcazwCvT?VX=kL+MjEq7Yr8;O*&}2B0PyVbWJ!&dSfozR9Yd6 zhNEe&XTde~mm>~mIG%LY`%Z_Px**Fr zoj6M$q4{*Uc*E=HzN%8~nqcYdg!%U)lol>ZE7M*#7$-vBimRws1^-m7tVeEax^@5b zhnTH!(%jwXR$Xmn&hh+avF7iL^xXY3JN4p-Xd?>==r>}ECC;#YyPCQ$ixc+>FvjqE zXVWI6{OV!P=Fml1o)P%K0cw40jxuea3GUnXY3!37q5+1xLID5GvVNLp znD~uEBE}8@Q9e&*WkUxr%J{H>Dtq6AclCw87&~@V>^v7IW4S7gGW}P6EB1x!ym@ie z0RiKWL?;aE*CY2O+P~$lxMUFn*o%)`OU}0&;mRm#eu0g0=bM5T?-z{(G}62C`Dg0a zeO{Ti^tCdkm=(3T3aQ^4tVIBuSEQ|1g1dtRn=NTTJB}RlyolZR{wp2R;?~8FhG`e~ zv;s0GZ?*7Bv2jYV*NlR8d_&0IOmBXgG!_sRX~dRFA#2yQDU$U5$m8->AU^@99q<^% zO{a9E#k`&rqcQ9UqR){BYnDG1pY1LxzU1mk#5tWTX}A@$E<4P8_+cCL_*rBn(cW_1 zx%qXXL^y20^~r0ri*QS-fi>`ib!+f8L=DVo=w1D_v=xD=apC4){6-d;dZUy#m{6@G zP4Sp#%5x%%3DwS&yZ=LDp%EBGDI_?)s*% zA)je4mSP1t^+<5UwSI*_?gYyt5_RV<*mj*%vsBF6Wxbs&wP>wS?4BaBPO~|fTANn$ zT$oQ*T0LLSn=Uel;)F=J#OJ0J@5H#Gsa&5w1C!SI6|fR3q@4h@JCHeKAt5Y=9l1Pt zznvVo=T&PhRQLuH>J$!LuwiRJ74Ijrq|+{FGmve{Uiag#S14N0Z**5itGOmt25DxDSCd1kgwG(_y%14MPe=FLGYi4I8-yd;2FWNy3o zrIVzA`iIXZMTAW#OkINh43!w;9Mamys`8-f$DXsYDN2yk<832*-X}_c(SlpL+Ee2CxrIW_cFyKVxBtbQDTj5F!3mCx&CGsUhavwnx#p-GvFmSSuW{qdfl z{G?^wZPTHY=s2uAA=w%uUq!6=J@^6B47FOEtJ|MdHrVjZSN)w(M{ehz86T?76VPI9 zyJzNbAENPVG+*iUM^940hcGiC&%A4e>G|iq(l`}Wpki7>sdFbkdVo!OTh4B8V#UBe z>@RuV)CVn2H~HXO8sIOH@vc;&v;c*iUC5Jh^+;{V#LLC~`+9|tOWBs3J=_M~oChR7 z(wscAG*;EEi;pRC%ag~6viHemV%45R!=g6<#DJI&X#gY$9Nln?FMxV=z^h$!HP`&D zey4#DpHS^xHZ%4u{l5#R6Sqy&C&L$a2VCGPl2|5@`tHI#7h@@3Z=a?+cK3KSho8Z; zWHRhtndS%IjiVl618QU`+Z%B95OgvZpHJKgf2C{h8#tzC?~?j{j|R7z*(0b?_2;a< zy4vc%=z`HRBuL7H{gPzcLKa^Ga|vxNxu@vdK(uf@BLD7Jt!p~om;=^&_5$0c$($3H z7myzzb=Hf``C7}e?NT$(soaeGc2i2eMVar>+f^8WUHcd0 z`5zzDE58EYOLpU)xljBMrzgw>3}%K6O8ISs^=}E>9{hYd7?}JYO;XPh7xm58^Ao3% zRGMDZolM+(YlH+8q}?R+>|G4FIMCA?YMhgG3m?-N?vHhe7b685?vsh*&4if9?3UUz z8&={QGCBBt)Q1m(sbbv(DlDT~g@fkB`u_MJoc!BM0a<&4Kd`fEXBO{pFP#5GhN0Oc zH`TKX6+P@-nx~-(&mA$<2LYg1!pPV8mlaN&^%1DqI{|X|yBE%z+Ce{zT*s&^f+oG7 z9LjaiqV&_8(^Y-ABxzQuOY6*gl{;g%)>AzHiXC|7UBS%#cN}cfDrKkDY zb`GF@k^Ek0IkNU!Ya%2!_2pirpKPH|`ZKW#Yk9fT_LkD-KY24kdad&rU+}+*XEkHR^#iHI2EogMn)&Z4;%GIK$~!H?DX?0n{7Jxn4fhulvJA9f*q8SdJop|6%9|Y zYbdD8m+Z3F5UmeW{In)61))mk@B6US;zr`OyHRmyHMiv}^1{b{?;Y>2)5whe@@;3X ztD@oMFNw&>Z~pfv@n9SE6Cl3$e_84hYkm)XT`2Jp5AhE=r6S`0?WBKPcUrd0PuBVW zRCHdmRsNeT_zyL(q|4}?iqY|*nEsb+)Kldb+YyOR|G!lw{>FlHl>a#OMB4~D!KUIhW^Gcx)bh56Fa(}JEItU{%vRJJ3JU*Z z9q{SI^s^79=W@M*4Qb=z-@)c(z$zA@Zs1?Q{i_O1|BpGcoffk}sc5ZH!vdmkJ&Jnh zBK^r~j_Fg*;yCL=J!5cXT9pNJ#n&)a&3oIuxQ~C!XGf3Q^*OWCDXu*U>#~ojEdn?? z{tsg3W%1dI#}*Od*P7|!?JD&uE-rh(J9ZyJ-uRlc^T_5t6{rydS;w*Y{=p`*1UBY zf}%135YCsx@zf#PfvNq`xsD6WxP1ZaAM#pH#TfMK!$90I-XqgefIx}k| zz%XI2W0`D>S-U889F3o=OV`u*W%P!|T1;B8fNV+ppuEtzwE1r^QYE)1@`G>9OWB6cgk}Wj{MgHn(mQa9 z+P>j2i9S)hUHESzogI|N9rVNxOct#ZXP~DKMZ9>{C$PF|k$Cq7Oxwh3&aY-}Z#bim zy*$3T!%VwH2k5_uR}R>?bXWhWeK_yarj|F7UvAyanN20eG(Ba@GCx4GSb2-7@u&W5 zkvXy>YStG3^&IP1^ZlJA_da{F)qCJVns8nc3F~;S zY%AOCfhX{S#u3S=U%htu1|MeEo>Fc6Z<8l6P9gELX}=6t@|uX7nxfWHt+9pv#>nEV zUa16n>3On3oJ5C+s|rGT9kZH}4x1@kWTGrT0C98R(Sm7@J&DN%(G9sHY!PXXiU1A#;9%u$qFT(4h5wTXAOn) z3R?Mm^@ep%Z2|toNF5m1d1L*uw2tM))J%d9hs{2|DuD`^-hUBCt>-vNOwnraopi!s zF=kN}zKQx$iuTGiPWa{SFK1|ZxZPOh0=ye(6IKQJFv}uC#`Vcjc|O7XkE)O}2B_9J zU$#DkBjfkJt&Sc1a{PG1_P#|wXl*`24Z97|~>ZwkQeONL<`pfvCmA`P_I{ z@cH!zcYs;jXM=9t2c@7-qG?|CFu7dOI{s_O4kr~l8GzuA8hLRwQH+*)iXqPEEs{;D zkWa-*s@i+x@Q54^OmQAAg*8X*$ey4&59r~}Wa1=GqfTIst_T_f5^MDvsB)ugY+%!+ z(&QOx<)1AUw58aYrOvG$Ai+x%sFb@rgvVJUndLLkCBxd6tbto(2zZJ1R6Jwlj=4td z;+OU{oDn`{7Gy|%SJ{vPfz4>cpY&4t8|;*e)JvTxDnm?v%gp+Atd6@-&eAC%yCU5A z^KwR@m11g3F?##j`KY>;kPanf?delNAjOZ71mRw1@RY~d0gGB+>7**7#PM{W88+C6+c&?*p(SnIqMMAs0u_2Ay zY9Gq{x2{X0swJ_oj_#)>7v_J+N0sH&5gN)*{J%D$$N-{ymkh4(?=oGCn51aJ#*eERvK zycr1T2FJ_~m-*C(2#UX<6&(O%iJTQQ0Yh2qC(+u>dn_S05GE$*!Y1OH-_d~r(GDA$ zW3i>wB{U7C3V*MiKHArQx0m{d=Ht(LN%Kf;k@nnM&WmF~J?r$bd5rlR$X~<)VPp5` z7O=AWz~{;79=1g(!N1%#fDIp=44*C>I7vw|01;Ga`XtRo&@=w`g|Hw{h5{n9L<0Kq zGN5qvDeC$M;h-{S+~>3cWxSE@&|wUNLjKVdN5y)--rVW-Ugv}rv-~)n%9uDMlNwX^ z&!I4N=|HwPvh0%z`2gKUb0u1wi?*e)9{5$X?@F8mBZU7_6S|d|FDwrKBE=cv^(v%P z8zYMAR=uK?A*_=Yrd!LfO_w)+t1ph@FC*mP7~ROrGK?xUeJR$XB^X z9)eKt7?6yyRm=~#>T?(h4&({bCDSHY?a%}zw|a;6(8eOqXtUv0`lTZ`L}kAt{}$j; zXM0iJHb-RykVPY;ENvNaC#Ew3RZVE|U|vAz-9Z~7m1bFeveLQKD-5eHMds0yfhq_q zfsJY<{U7W>5M64@4ATIO1>P>zbAaVwqE;=f>>tAUiE9+yO52z|(hIH`WtNU4#8Cb2 zw3VRj?;UK3MR*gWI`DmBwrYKoeQL1w^~`mDR%JH>;Lli~UvfEWX~j$HQ$0ZiEAT}* zYl`{o`&41?PWjE*TY0E&vCmKClrx@KW3$N{=)dGMoh!aPCA4=CYQVOPpgwW3hahn5 zLq0J@^T_8yp}?S|=1b#~NvM$Hl^ao;K(`Uz^^ATfI%nGBJkGx%xxg$}>W(CQ5f}1b zX_3E%sw4R2i@t(mS@!*lHljcBSxoJn1(KDrex{Br(YV*cS%3wo)VRcm2U2#_(&EjS zok&8?fR=d{Z{~CS7c?V~Rdue@F(@%fce26(`?iUS0|W!qp*_=*C-_V%{(@W^_LxdP#?T<$Wz;E-CalVvKo~ zC27Yxy=$!0;hLVR#vqK3of6UtmRBELO8OulX8#9xG6k_uShnKO{Mr;Udh9fU7xmcr zYxUWx(KHKD+c%2vvTkH`>p=H`>hnMn2YPnT_JK=W4M8h_2Z*T7c8EE4{LPF#i9#&l zIb%Ql5F{L%ji}Vx|Dsxu#CKEr=?Nz0DfLTw8yod0MQJ8o8{jW%nC{WrmkD5xMvkZ( zDG{mtA6ZL`D=7};MR}4iIRUiq2IHtUOgH)W5QR8ly(tJnt4F!=YN|}JX024&x;SbJ zB3<6N3-Um=`=?p^;;h2-)BYQ{6#}k?M=R^$kzARzf^m>gzK} z$Ky1v`alrj+FEcmIlkUp(?)C`#Himl2$3lirQh=K_4E}YKH!9YU}YL+_%=xXAV;^I zOCo_Na!slb#1K%;XA$Sb1mxY*oTZQ#$C&++G(O$ud*FS=KN#pi3cq$-gB0B2SR+O#x<6ZVK&E*O@h8|oZwS8R(Q36> zxDUO>I-xiHTXPW_wc03J$u{I%YxRCVtK>5__T%x%1wF#mjO_!ALgV)=DeO}pG z$BGZsGzPk=s+1YRB_4j?M@*sJ=7QUCtg`d&-wy6k?a9*4TXM0p`~emwVH;Pm3QrL_ zMwJki!|Kg~t%A9u=Xs1V3DjK?MK6G2(FT23jHLl1m7W6!bJL?f_ zqR6@$nd~^)VdM9m0$%;QYQHiDfP8rTw_t6Nm+NJLE4XkUDXbtn)|W6>XKEHfR4@XJFr)4+k;V4cV`Sj`S?nxLiE$4@Q_ z>y=jNJ)tblcfP5Gc>veLop3XVm7io%O7Dipk2ZicHd)1Ui{=>auAw*r+`rbMwt>ir z^W$iqZe7IrFJIf1qbPeg<=rc-I7R3W0O9p=N!|~GrS)9sGmz0nMSh``!!XOY z7)UNhA;tC3N!4Jr?7Gc;NfCjw!)!kbhmNgBJ&NW6W_`wUr_Zu)*ubWCK*)PV=z|1e zS;hO{{F#zG)PHUov~c`dyyet--9}aJiaTY6yM56C?tjVLqk4&=^z;kII#CP06%{-f zVuvy}1hK9$)kG2}=eqEhtspO{(PRHTZ_V+LNmiCfLGXnx0@u}V))k8INK_N7|5PNZ zE;*NPoQ&DC{u8d;5qf{e9_(a5OruA5LpW(0_T_DK*@*cD#Iwsa(SmDIm3ODz5%P0k z^qoo^MJ3vi-KLD3R5TKljm?ZFb@umLC2A6H{E!nr>A!+u8_ZJh7Z-g)K-srVbSM+lldj9F=Y4M&UwpR@o~^DxqBCq*@L&6BJ8@*Svr$P)l-DrvQc6Z& z4#?g{38B#%%FECY=Y80)rzoiUSol=v;W6#Y?Z$+^^0vyY!VSm3ce;wo`mxv?(y!FR zw}~0YCoNDY`xSTXC-bw!N*RYnh+eWwH|oWp!hIAhI`vZJJki1Z;d#`+(vMmHJvG%m z_3AUPLHYl@rt|j)R;&^wd_3)cPTzZj)=*cG!1}+3!(5}ijUIVIg2(R}(Q`YX{k)D% z6fKChy`){mA(-z{HJO{!vlSRCwCq+^^Okr}SSh8ld~WW~!L!1g=*484IET={m>d&Y zc5C9P_^)#A&AL%WPnL-S2m3+&LmS&cKHl_hjW`b8Y!+;Jl)r->|V6;jF*^&%1Wu z-ZO%G*X|8cH%Ir*(e=@C=R9*<{j|*^)NW;5A@(CNB+vc*__tD;o@UqcH)Hbj6gw@e z_7>+EHnUZ)UcyZ_-swgHQs4@tCesYHT`^_JwlfEmPc19ajA%c(f7jNjta(KJ#r~yh83} z=smE8Q5YxU1Lh+UpY&e(Z09JD=$cu2e#X~rI<{RvBAZx@Jpg9OU8{-N>sjk+Z%uMy zo8G4D45otTbA%VtN2-W`qQ}%a4H*OSgP@0@FbqQ97SRYAj>l^UmsNJk7NM5ah6y{S zcbyDqkTJ>SuVJ`R){TFlj4r!EzWGkHr{<~jN{Lq<=P*Zc!&)N#LT(ei#68(q>Xx?2 zBCO_@!IaO)ns^X{VK4T?r(j^}wNR|rs9kP~R}JslK|1>BbCiN=qWiP2_Z)H!iYpZNH> z)v0QW?o@S*(fbC=HYm(2vATc;2pj)$zmI;uR%rMFfm?o*h2RzSj4~|ou6WcLzWOH+ zUFd3(AXiH9IiR!96$KIPK=yMxY*YhKVox zVShp!%D?E|1`G5+M?asG)a4|3e9Ii_g}rRFiZDZ2_tm;^Z;?-SN`#jM2<8kFzYV3M z%qMho(zsVJlGjaTTuw!0=`1Y%iJt3Bz$!M*k@gll2F51WGm_sOC8x_b4~Vr5izWkW zX89*g<*XUn)tmo`zPabP$9Hi)CeTw^tJt~Ch5czWcPxIB8WIeb!nZTLw7zSWBhY8h zAMzq|a-Kv$aHlj@A~D*|H=!4@&eoA#f4vA=FH^{&npU6gTuFw`jBFXSnPgPTIvQz2 zk@MQP-4;%4l*vReU~PILec{O)VpV@NxN8PuM5Kv|0Vn3FSJPhol{)82GCPqBy^Wiz zs@3f)>gNG>h10vIaoE<5-K%G=9SN5ya^X9Wz_p?!0*qyfmeSQOW^*mk#Fnk|(a8o* z?}z5s4diL{QyUv!<)H340z)41a)owP9|7~G#52poqqU5U3c&|2myw18rW!_rRIT;g zvlcP&?eVR+9g_V?RZY9(s?|)>!I)rL(LOqEeFYl5LtkokN3#y@sdor6%HoBoF-jYg zmxgV#_B;Y~-!W&Y*~Yknq1XHR#!5V3Q!`9WD?l)y;lVkW$EP?k$Dr%MUlJtk`~xR- zaFB9XFji@GO9o*vNa#MNn6B&}I~!}#p^@PggOU$9Wx9^}nljp$!2N_0XJqtz_W7Lu zfZ0P0?XRHD!)+Ku6Sm3JL^*VSk~!wiVrM3UGtNN;_n_k%7Eb8`1Tir(2i2vcdI$!q za$vzPSyI3x16L5h5Km(Ie%py}LQXITm^}3|m@1Y#?JtQ@{!&FX?Nes6(_-;=(Zn;hvGY*83FNp}JX1td!g+{B9+$Kns*=y&^GND!F=^ z=`s7Col*p)hVLxOuuC(Vl`awH$Uwure;6aVXIf*Q+;|1Q$`wx!$S*( zJoS@^R*0`a?n9XYx(UAopMd^Kbu5>tu7@6AX7TjXJS3UNx#RRmlV1@jayV*!c#t=o z7CdGgFeO(~I$G1Z^UsZ*VTKuSjhV9t+e1jKi&@gD8d-};6ZyCh+wC*6A)dBcJA%o$ z8JD{AChk6x?=4cZV4ljFDmorEzO$y(ay3(j2?MhQ&{mjILD8p(riuc5NJNZDog5-k z5&KxFR6t%m>fL(LFrZ2AyG)lo`m!9y5^a2N;IW32DbL^8-s-QQKkR3m=S$C9i1ScI zcRGEV*DjLre*5*C(7k-=(QgZ%oQ6W}XH$jU5jX3$X9yyM)_LmZNLUz3ba*eEj*EDW z)BJ0R?DSA*eSbenTZAj*i+4tA8FCTxP=Ja~wE73c68Rs80OiLvnr0~gUozVSA&jB|O^L?962%)ZYa`zyh1jtCK1|HA} z%x$M+ChaB<6>3rgYs@9rey0haG!vxq8j*lWSV!ZG5P?Y?G@8cFIHxadgjO`uzM8;Eu}+LVho}85AXXeORA1 z5TjZ?eWYtBZ?U!fg9_3zjlcS_JZMWWxB@i%fYDCc+ARqw(yB|v!b&vdcdSWpi%HP*M;%9Wg8At}`^zl@6; z7Mc4uLrEA3iv4m+X$5v-hQP52n%mYC!QxP%gpr4Z9 z43~DBwz=@M4NArqCf>Lkxp7rFOZSF%%#np@ccf=G;Il> z5mnFY2&aZaLk{ohlnTGiqmmVlv5W&!QbA_3%XlusY@3YoSHsF~RVnRb{aKXja_)nO zRe-q6^|Xr$G+w_ux0#pnQ`t1_qwr2zPz?&)iJK&HEH(VCB^9xj=&%jm@0uuZ)Qe;e zji#BA8IG#Rwl=TZ+xBBKImoN8tc5uqO7In?D8K|%P{cMZZY|>AP*G!oXf1)`)SWmc zmOS7zL))`+@o*P|N{xCPVmVE(b&=)W0OkW*2c+;<&jCb?%Sist8i^LlN$ByqxfUlR zxX8Q5va#1Yb!)lKnYO8y*;Y96%#`XUxrEOI*@xnDk7$oPuJV3RCnEqs5Rny#~9 z0$qRhH46N!~-j44=Yu2v{4iP^yY%I(!3!JnY%VGtbp z)^Yz9dnY?v_9#_ettV zaPyXD5#sM`om`D=ryvx^HcZ4W#1 zzDox6;N3yotcxw(XUg-Tz8&X?q=rXH%B6Aa0!AWuLM?KFnl{cRB(!rn z7jpaqY~RcUy@@A8=?lg%PMR}d*oB=xbS#odK(Z=ry>vfFoUq<6pD6z{^k zh$P+#q)e(Nj)`hn&l-^X#fYPMBxO#0X4f{AskJ&3ItKgf*aE9bI+N{QH8abJ9{iBf zxh-R@esRX&wP~6i2kA%#cdq`Yb@15_Ht{g!_7d~bY!<0#aoEf_?YdYgxICV zQ{I-`PWVw$dO;~97F(=tedvjW~7SB$s{I zv0!-T3S%2evspI%MJh4#V9RBMb5ZrQRryv1f)JS0-P#X`&^yi2a$5ALlfTllX)fEy zvDC;ZD~n5_DF?_aPcNDo(()o0oOs-EJfi}d+WOb2qM0tR+9%oAf}fJ_Cnmmh;2;$e zZ*JqTwy8P^v<-Ig2v6gmK&-*S=kZ4n`YzK=%X#MnctZA#`|;XVzFs9RQG|o^m$|K_ z#4`P>e`#Z6?S?ybT+~+Q89~GZnWE`G(_nu{$>RnOT4_>iQ1R?NqVX6 zMJslzDg2a=#hV&gfO1bOlnol09EM}iNpZf|p{L4wR%I2PwVbiW-0WW30!A~+T+HCb zhj8JAbENG=cq|n){-)vOtg3l>v{IapwPmarru%Qb2rs9?d^RPe#?wzG`Aw!`fd6%^ z`Pj0Ec-knfV?p8a3AzL=4HewA~3-jQRe~TtCC*R^x@#$R{2rmb-Y@H#mq7^{ywN%PlUqkD})n# zEuC}aCgxTr7tw5*7Kkq(2H(I42fd%oFL)TvPIPQB1KK_aM;>R+I4yR4OuUEiT(^na z&;2pcn>!fMdl~VjY@~;jI6pMb@mj;-X+?4uZq{S-Shj0<-en_1D8OMvAh#h0XV=Fv zO-0@vL&iI2Z?*1>Vm>bPufP!+nX)7RwB5e$In(616TLATY?|Mjn|g&Z23gO0$H97* z@ufVkmrGr+kz%D1^Lu5U9gscgLb2ahvSV3%_5Kg1~cGUcc!hGyW( zt2t5P)_P8nhPD5Tu!KTSHkfi-WO|k<9mZ`_&o0ozScS}pkHQt_;g2>mfHPAHlQETx z`l=Btso86LtWr+)_wCxrr28}drMW%JJnWw>M_)(vzvkZz>W*$>5>=^y&aa+jmhzxl zGA*$7ymlB)38gLVRbrBLc-?}I!Jw}~LlQ{%k)mu-uJfcDHpK?jlE}xg3G%wZJjgadtoDur~d4>^b*z7b`^csGWN^lsNE@F zYprib{FKMD3D0|-GRmR%%By)JYR%z;c*SXH=`ml~Q-t&od@E*=UW8dYlDnJcy4ntY z>@gDP6DS3zHtzvd&8y$6^!G;GMsuy~G4;;@E@1+FKK zyX9cD7KyaR4C?sT{Dz>?yCG0f&7#?oO2rEo|Mc|$bB^jfbqS+2E=dM1X+Jc1(KlVd| zulAY^5PNdl9fBk#N2fNxHy_-)01@0Gp@7-X;3b1jx0&uZo_nU_;q>!f;n==?1W-{EOUx2}<9j08 zcR6R2CFQ5`W;i$Ej!cXt*K*?nR7TdIYQZCS`oC;*87iT(b>3u=+%=}wuu zE5G1v`>E>v>duM9XlAV%8PO-FWb32V{8pkfsI)ctqlM=OB;$Vvny83 zNjdrR2Dr=6T6-f&i8&K#scC*hL0rrJogNe>xOWWWrX7AC=UFpy7@9p;EW)9CMSE2j zlZB76T)o=O8ExZ?;j(5wk;0GFbG8wkRc4Mkt1n*a5NsR0eC$kCH4h�(dMt@Wdz> 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%0DWP)_e=)|a}S*cE(kD2Uz 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

  • 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�J} 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

    %|N^w$GQ^q(X9DPBxtme&ku0eZg1@4?WfdCBy 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

    o{O+kNtj$7#JXA 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

    fJ*EeSoM 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 z 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

    m&hgq*5XSBII*C5 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

    (@X@QPbxT~Bp`Vbn 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

    3n#%U)plutfsv&*fcKNgyj7!u4fWH3{c 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%0A%5s6BpWGLP}6_E#V6E8_e#vLxDytJAxQi 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�wR#ncdmM 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�!~H)-h_ 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

    Z$p#HbAOD(nftEEpF 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ℑ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 z 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

    iXKBl(!Tz3n(#X7K8F`DGVwKbk{snBUM9 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 z%0A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

    Mf?V@6Rb6k(y`+`uhe=En2ljI!gyeiZ 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

    %|N^w$GQ^q(X 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�^++{^PH<;adu;rANl% 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

    eRRvWpd}-&|7y}}Vl)nqlEwC$}%wE+` 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

    ^?0x|k-9Mf80HbJDdh7T? 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∨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%0AtS_ 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

    `CN)_JSpf#k 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%0Dm$K3%Wj&!71Uo;9pv}{j> z*||UeLGR|Mw0mdDA-D!h7BjaBU&YX+BHxaQ>1?drWBZObGUQ+bJP7AkW(Z9W%p|GU!PFHzPf;40H} zt^by1EIe*~Bct=AbWS(i_9t{jdOy+*(Te#=&)Q+%*1Nq<#s8(^<=BaW^6rLJT+*1k zasSXcWiVzidAAEz1wnvT!(NP$lnc(=x~z>Y_71@6S;cM>k;qtR^t$WN*z_}zzn1bt z0tch?aB@I@{EO|4Mv#?pX|Xv^`@!W!Pjk#jHv_ts{S?QP?{^|kC*ej<22&n73@L8C zx~;>E7gzmUqP2HfpvpPmvv$J#B=%f-S#P755`f!L*NS$({Ad7r*T;-&1r`}t^V>zgL%0L9dp|*BWO3v@@=cW)`M<;WnMnk-a!1}Vk`Lg^QIpt_qMJz zO(qF|Pluu74gdKYWQ$GpnZfHl`ViZ)t1&2g$8A_>cG0K0*4zZ&n9@`qg$?@#`@O-9 zB1J0CI5bqG3dA<#`JsG_Ep=2Ph(8U-0T>%_-m;HeK2 zoAJpQygM*jJyS~=jAuTzwu{2WzwkgaKq9P#f(joOYb9E^4=urSsOHF0H|Yd@qM>z2 z;&UrO;#A9*ijO~IK}f;hD@Qgu%yFGisZLK@mIRNmjY8G7=?*kgI4a4A2~a_G%jPN< z*H-ebV??dV6-y!oTIes)Ub|1)dV`jYSfAf}m=2oTA3HbSa=2ie(}l0;N6jjpv55cW z3HtjNkGU%CvLcI3;f^C!8u7iI&`@Zyb+p@=2}h|ag-p9}jm_Oo&D<`%d-HrzsmksZ zcAnh}q0aH21SQORp?-y7zWTuO20pRf5Nq5r_=`$}ZyK1C`4X^M}#*!m02&M=R zUpPE?0&`|rL&aQ=1}QFaQJ(^ z76^O6jix2bl-T9v;pI`L-Wn$(!q@?)qB6z3>dIZwN7>+dguOYO1bWHuJn7nb43F+; z^Nn4a5CeCp_M3)3!c|aeNj{mMEIWa8i4otv^Cc~Bag%MYh>yvQq8e@>t`y+G3xc<25tGz1K!gG$q^J@Wi=1A5H7KYuCP zAT!-;SLN7lBus&&_0~o|Vfq^9&E|~{*^dih_#S8Tlt-B|;d^6tc>VP{YgTH9&00}dap^gtnMZ3;TD^wk=6Z-sc=6k()aoy zf@NJz)nqe;Eedtogz)q5cxyCF&lEI-tH*+xaBX+I9#e*Udwz~CFI{0LAIsDGV*PCx z(Z6Eg?XmD@6(L2P)rylG-tnta}E{x zuOg?`IhErx5~)(Fy-t?FH`wu3so(h8jvd?<{TEyE3Q&Cb4KHh|w=XV) zSzVrqxkyT=W(Kb#9Ir?sm)kBxOiFATvErSt47+!=L*Dp=&eWPCDb{2&j7U9OB7JM3 zQvOZ9Y(~Jo^KgN|5a9)5C;0=K!BpM2V4}kH{%c7Ly6(GvYTf!e2)Dj&u3CKfb&dKd11kq;&4S)5R;_#lN0qEeT!N+&S;9JaSxMtl9VDjTTW*h3%K%lK zpwH`pMk%avTvIt(qvL?DGRL3Bnoy9uGA1HiE8-{vR*OEKKDA<32kw&4@N{+IOSl=d zqwdVMGCj@bC6#E?*Wa+GdaW=K{I|*S|T-iM|aa*Cb7H(AH znL5>F2gfP;)!zfuj=pdkYEL$q9NhBs z5t;8If+-`d1G<7-Q{`nTwnqgqZl(;$9%bxJCCu>IKiWu>#H-x*cni(7p*-bWZuwI_VsfYQmi&E!Yd2k?|6 zj2%5XPfiHUI2AY5!&(2mk(KZH_DhgznXFzhnJljtDWHQ5dqjt!`IB{g+{kvE6C3@8 zVR}M6ibwF!#z$FMO%1LfZxTKFL5$YvH**rMt~y?^n`5ws#e>dL#7TWdrkPD6E3vNK z^3iK-@Qc@%o(`sXM6Iz9`&vO?{x5Acv2hp`2LAgw7LIuN` z2^6&ube>#Ods5|z#@=cM(T_#tIOS+MUTUq`LY5x^Ufx<=B!P`T3|2apos@9*zaz8k8leCN-fUs)XJa{SluUQWK28e78u zjdHH9&!c^1C|=Ne@*AZ50|M?A7Sf=!v~-WSxRw>HIDQTfv+(hO@ywYsTs%A{Ya72s zdwVk(2zgXI6QphR*inv5Bx3dphx1y% z904clIb5}z+$FsTeo+l6R zfX>qLOKs^BEG#VKK6BY9JxMbj8bkf7yr=pg~ zFCJMNSKnv^;}PRS)752Uz<{>S)ySGeb94S&{X6i9eB^3-pAt5+z)(-VLsojcHo7e_wZ5Waa*ml| zpks!d&G-WU)poL{bUbH9I7w9eQO{M>Jgi?U_Ct=NJ>c^NM##K zBykTf{~4CbDM5+T_@Ao)Nt9}zFX*1#Mfy-29Jc%U`B9S}3^hN$_vsluXso)GY|g;I z0O~DU=3Ex!p1}3kv13o4J&QtFnUc(Oi_kP^`FTGS+S}OR#=e)mU=vRkTEj>hjz>5uX|1Edp^M%5|tUmzT-$c!uEShRVkY zaxbE&`~LHcUhOyIdM7KZ4?-Dua;ETaQWdiph@9A0ob2p<&>>WfjtBRWKT+Q0pVUN; zG1R9NRevwDbAY2?hnNWpUYMR#=FP8@m6<;T3BR#eQ4?YYbKx)N!aEKWL5X4}m)s+! z5OJJxa61d3RGUbY|I5#PTIWPw7SvQ#>+BS8{Az7K9k_B(Qr+ zoGA$EVHIJ*a{oh zfInnsmgk?3%FSTG$>}?_CPDs@HCQQT8cWnL+Ts{4c!ilj4iTifGN?vCAT|3=XJ`v+ zEul&=v+HTKW@<#B!w`LBi-eWXhNY(F!e;Ou%1CGvHEaI@d&xScqj%*W&}v%3lGV=6 zPI>eW#E7_lL#BfyjBYLX#~fGCLCDF5QVLNIq}RSDdq`~c?rUz6RM@(eJU=pBNf&8+ z{LhKFR5%1t$k1ILxd#7(o@uRej4c=tNbYhC6Ays>uC9QL!V|+-`6Kd_j-D*5{wlMi zDt2MB5sPa+{x~hk1=I84uQ&x*^blR4`@+&i)Px-1HMKCs3~WM`_*}H?GAo9_9;pkE z{7Q%Y=T!xi+ygQ&d`K{C|Jj~3@|*tbeSV(eEPjaQJ<{3LV}R_NFL~m`J${jHllpqj z>32({rKGmO$B*+Z!t}bDk2H#Y1<~1?F1cT@n5^w}IQE6%wFjb8DaP(@F7?2Rse5cw zjd%{HutB>0(((C-X{42SX0~<#tP3KKyf;qoSsOXz=+qFk`fNMIJPPt`llCg%oHikn3J;Wq_1{^*8 zL)$qH`+Fs}Ts=n73scWV>yyL2MW~RO;}OJqGsY5qhMTwTjoutKlXreSE=wYbgv~G5 zcTRC-11CkKb-V7)!-_7Y<~5_J9+^AJ& zJHifLjU6dpQ+MZL>Ppl%6>ixc)Nl!28uG0?2abu5)#dG^VfvJ|Te0`lg<*slr~B## zx38jpqC~TxRqg{=Z_#qRv)6V<)5hrBp7GdEBn^dW@AM|QJng=}7l>YsB~|;S4~erK zH>=6!aIM0#l`PxQv}`qa^7J?XH(Sz!@b#$$j5!7jaxR(TSm4gtBcYp{>RA~3v}MCY zHl+&tIbV!b(b?33x4fy%{_mb6P;9v(v)ov^4n@y_lZlbF$4-OOy7JXw zB!vFPW?Y)BHy_lmRo6;zrugEya@fahKZ>Xj;dkf|ZBE1{f~yQ}-L0o1p;O+BS<~NB zU&LYOo~a*y^tDDYe63?^(Jo3M(8=Rw^5uV2knlG&Ihf`c29Bs>7pW~6B_b}iegASS z%RO@jvyNDFJpPmfz{=7^?#bTt2F=TcM^ih9B6unD z(?@LeHB5%51<=GeS*9_-9zs;FN@>CH_^HL;Bo+kl1?d?%M^_qWCq*ZlWk?q?<2xrY$ z2zpW7K=qn;gCffj9lSBJzNJ#2FNJ6u!K+bkX%2yZ&l9!Ow3{ke@Nk#rrhlyfp?%-z zyTw$^$vMW!2a^iq=|y+Q-dT z+K0x+IB>%VZn8JhA$jw~(8C%UH+*|nFJ-HYPUs5n7v=xKeh%eT&PpHUF6JTGo4YVY ze0mDedd_MU2_qG_QIz_+q-uK;gogb1&p&wQj~KVAl@;kjS(rVL{oOV40S`W@%I(^Y19mxqA+cVMt62^<%rfLGj-Di{KR! zAw0}vLYm-f=~0%Vn7`*E;f8@VN(q@aXQi#}Q8 zz=sJUl8%p}leRbG!hjJ$N1Ec0@c5BguMdSe)ELBVE-xDnA*mRV)WnM%VEzu?Xl#<1 zwjmZmZT>7J{y*GBX1h>f6XKcoqL2a}eRq$vdGt=;zeAR8V*E^Khnm-kemhZaQaOG>=z7p2jyyG_>m#j6+CCgQf1Pl6FpnxZHyF({k@660;F zHxRrA(Td_S-@hL2FpNw7a7Bv@iRvGJnk?-$&x+l|w`?6*aeD-|@P*OdcKC#Ey-A`I zwr_^qVLqF4JCWG|Cl>_4uY_GV?cjB^%wa^sU?R;6NaQE_x>@vw6EG22;V1A z@iCkt4mvSWXl}*cTeQkgMnoE5Wn@5VwFiqad@!Ac z*D|IFle)%=N=m-xvA;CE_sygy8#?=pM+|Ir7$E-j=bW2vKouDLQ&fa1)v2JqWL5s( zukBv&Gy3kpp#7V?oP-;X8PA@PM}#nS-CwIyYnaseSEsH#M*7@F*_es(Bl$4@nDCz0 zS$P(}PyCW&%Jn>qfP>@gZ)pa|aW?A?qH-Gv(n}q^*6i-a+l>=9KYcftpG$_cXR)W7 zhrSMUcq_8vzqf6N=O4e}+sWXC@lt0=UngfW+RmOkw=+BNGg!R4rcYKSJ0m|LY2WmS zoC})0=fa;;*O4)vqn5m0?DdB*%$9LVin@Of$|~tEFKjd@;NkF=7jna{F@4( z_%?YCstT`Oys3P79sO)i^15Q(&cf12;$W-MuM2qWRJH%r%lt{)J1c3iW_vRRfA6bT zw?5UH#J)a>m3tSS-^22Nl5w7E%Q!BL4aM&yE|813n5W?TLsFygwSP0fb&w(#Ce5*{ z(z5}dapLHJ@%?SGPvCG!iCg&KiC9ds4?Vs1jrSFpUVk#2-`e z_UT^rvX@&ietq@A9A!Z`ULOg$I@xyd0(fto{X0CFrjMQ zW_zR~X;NBqyznm7pOFl_R8UL^%yDT#i;fT>0tU-b!En;g$b8~H5`$HenQh3$^6p|C zm8M2MKh!S`KeG~}_khx&6e3IBbt_qNm8wc%wuKjo&%RG})OlQoXW%QLmXk8-81PDb zu<|(VA5L+nWUD9HOe3kD*00r%e0U}(&c6I7P9KH(sAE}kAC;33;&y=T?@9Au^3(C2 z&ToxV3a?Tx5y~?^C2>~&TJFo2eAn<*>Xb997;zRa?D!cT5A(|6{0HUG>R`2R5$!*= z7HX-I8!m3;v~{M7ko*|$pjo-^h0Ncu=W&37$K8XT7^yQEV_y1j2dO2sS1vj@DMGv0 zv$?nZp&**86EnZr>uSMXY|)jlNxF~Wf`b?ZmoZb4}C;^@h@H)L`7?9M-IT~4bQDLat4M0K4T4_N)|IofDGz^q<- zm+r>e2>EtuOv|jkI0(tB*GkmC<&;71sI#K#_Vzl2r=QyTg~jOw8pD_zY^t_Opg){n zX1&WV2+6&6)?Cebl{g?+zlB!ruLrKy_Y63FVe!QsuM+JCzs)59e@3zB6YUMdM~G93%Ote`>yDYNE@JyEr|E}wDA z_{#SzM7w>qNE>*`4L^?1XrFw?CfpA>l4kbFWQE+p{IUhU8RsBrxq0hE|Li+hWG&4} zmpkNu@v)2Ffqx%+AkE}wt8$zaS%k_*HYfjfIU=HOpZ*;>iVir$2sQepb)P}>pKz($ zNyK+-*OO9uGb(3CHmEEGxV-611AE1sKL=QLpFxi_z!s&M{ z7oq;l7lnk5kMa1o8A$InJy?W?FP<4HUG=s>)Xe)cLX~zqu(oVC_+GBW1^o^RS=^7E z-{Y=$Z?C*-J3HQFma-h^iyZ^Ci~H(`j;ANMHO7eS69+qB!9o1Ek$->>5poey#+Iv@ zxJHJ2IWPTtKsJEx;}t77%?|IxhhFJghmV4bLN<7e(w!6}x53HtHu=2xHy*jQ-&A8` z`pq4(gGP(g&*2pvHN;HZ+Ks^aMlm8Vd>yeFH}8bJW6}lPp4(q`Pg?0f@Ly^A;w7nU zM6Ayqx>Nhi5Ba-y?|v=v{yWCTr74~=TlOQAleIsBw?qzefAWIPnR-vqqMs5^mGiC?>4KHaBUvOiDvJ68}`H*Hw^y(1blAl$sZ$zTt0&&RMNnn*HEk z+#~%~C*TznmQwAhi_ZE&u7*8w18Z9$>Up25YclyQN`E8=HiswXL*QEZS543N<0yRQ zKhItez>Y@KHRbId>I`T(K4B!I_Vzb=>bmL)-qBL{NIg%eQr}Vri|6}lTT%sq7&T&- ztVbso$=lF@S%yGJI6tY*f9;h*HD@CrGGp$0KpEAy6CUDF}a=k@k>>@?u`%FiKw+@ZA zvJgB-vyo(YoW=JB2kh(WseC(T@UGyve}lo9eRy|yo?axyYz6;q`?!xOcS#6u!)A7} z^-gx+{4mG!lHxiQBoTYub@Xn^k*wxdT-NDcL%3k0YP?;lAsd@yQp|03bPnm>rbSJE z{aNv3{UnpW2*W3Q=1+1F3}d8$l5e5dN!c!cus2sdFJK}i;i1e^EhAlhIiS_Bl{kJY zUKnMPf(H&9ATiG8csj1OpD5!kAD4%v&#ACGL!S3x;be5!q% zmoSo@ThhPZog`7ckG2op?9?CwMw9xi&#Audgo5SP)4z+#KjFS0H^oz$FJva`qtt$; zX*otRa>U9)41~skeedQTFAjkh=y5nQEWv8{3~}ETFR)8q?!nm&rG_|jK^KhLywkC~ zwY>$F60$zu0_^VLz-oY@&_@pyL`EOn-1FO{9;0nNJ43p8w9wiaUg>f?pA|_br_-}E z_2aAIq#X4 zO@x4*_sL*}Z!px4t>jbBs6q2$i_?&} z`$w2tTTjmlTsR5=!dmk0mFz2c|JTqfoNVOA^Orw0vR1bJg+`nn)E#U`UJn=OAawA?FRyrN)i>pBBKED3Zg#UcuC6%HS^=Cl` z4I^%4W;>iOg5gZzAYVG2C2o|i_M-~%&!EoCxeY&@e9FAMO%{Xw+_^B6mh!AtWgU)xs#J(Zh>Bn1z zyitPr3PGM_gs;;J$E}Yt@y3_vXx5v}$6`n7z2nQa|8pK|?j*FnQclwt&e$h0%O357 zc+}4Kjvak5kUz8S$#Hq!I|!SlZ?2Z#_K1vXQff~8dtHt zwl@BY_u2grlx<{uq4FCaTt_Z;TaAApZ$)+ul_tLDt05XM<0x!OABS-ny7o!e+;L1W zF!6J{_xNGQy&Us`43bE5Q9_s^OZ%WID1~^fDw#AFap}0~1#8(9Q=Eur@R6h+H2Xi6 z&cmDQ_kZJWD|;p?ds9}(NM&RtTNywC`c59p+GbieNV`Mj>j13sjTw|$mvb`Z1(Q&h^nun@l{rdZ+aKAh`hq zZr|oxImkYU_CpW6A}jWO=h5>B(38??XP`jW7`NKzK2*u@C1 z@k<8=ukW_Qdn)DOy?-qKK&W*4kZ!`|00e5f@{@;EBtnzb=X$2S%Vkgv@p33vyAb)X zS8A=*45fl3(8OJ9|uh-B=On@{cer#>msdh}) z#k{>%Lr{ehlB8+KVl=IBiQh;%Dazgetf&9GVrn1lj~8BHLZklkwP+q>37b09c$m1V zX0wv6dzV9QcJMaIit#yee9B*HJ&0_@z0DWLXxN8{$fM!VUb=JY`w_)TV&7Y#mxvVU z>K9Uc+dA;+*BRn$^)yAh#PdhqCE;J;^Y@w#`M(dqzYnrLr19oa%-d&th_~A?g?B*;!t}B^f3JKxk zn@gmeAmj)rabF20<`hR&M2Zp)5S#q$YwVFEWx-5zOS$t-jDH}E7>rsayK-)J;Mp^# zptK9~qp&FR=qYPWyFusXp_k+15$0_V#bI*wEd&+n&uJ-Z%TGueK#zAU6 z;`;5miJvp31}XyM9O!PnXvq9l%nW)TkJ!_MY~DoV9eJ5ItO6u>zJ93uj@9)IjQDeA z$uvnBXg^bAZeuY{26eaI3#s#|ns{FQRDRU|3Kx#%2mMX%FqcKZqZlG|ul)}G0(x?K zv_iDlzt1(ReROdd!kS*A9Mbjbu&rZMtW#y(3AOvTK3Ja%UB|AAZjlcKe$wIcd)ph$ zq5^v8>=Jp{GD6UxmnJ{__-siGj2#6?5p1N7|4V+wHrwAc_>JGcc?-34bcoV1>HP40 zkv|&9o}3Gn4O&{n*w2>pBMWw65Yc#ET&$z54Jv(o{f4B0QkWEuk2}77`xgAl%J(|I z6GT9#Hj!GD;J=di;xRxM@Sb7>!;Y+LPYPrSe8mr^auZbtf;$r6OZv1UvkB7LT*7Iu z3Cy{a4$0*38N!S}S5*}f-mPl{hi{zMg~OOnfK)R1ZD63}BDx=FD4p99CBt;7`|^7- zek%y?cUN+lC0LJZ8E3E8O5ZI<2eIkBz`fxE)gm8fifb>)&=L3BB+2527cTBA8jsVM z%?Cx_H}Svqx+>tg+IZnW{-3XS!B;-BB}V3suxvRIg*QZRBcoN?li~|^FgSeG%(Q5# z&f{`&MXU%Jk#VC|w?BH-K*1Yhx9RCzA_5*lgxB)#O!z+{<3W-_t2_IEhNvbj%UoU3OqKK3;yP zFXts3sr+{Gh7laouIn#v2|6;J0sj+iJC$E5Ex5jYj_Wd6k}rnab~Fc`tYAcOQGP+e zF$)V^HnCm_rBi1F_hp%8)3Se`5KwCM`&;4s5!}9SelpQ-bA#yBkeawjgX<_cRKlWr zoJ<;zy3gN?Q4|QL?&@~D z&kZ^<_2VQ7YIW${sm#+GHW@|q&UE(N$t+E9Epgw|^Ne@}nIKY%irt@oc$lJ{`Q7!V z4P4*7iCK{({?s*k{X7Q#sb%uI{DQbskto&g3kh=)*elDURd37( zyOEzz%tzoMZW7a|uM{3od->dq-}@AXPPW!cS*1u~V0eI1g--sM-{qg9@V zAxI`E3RrE)iec$wV%N^&6NFpk?)u1alBx+fJeXFFrRV;Ft+&#fP^F)f$myT`W4k&* zfDdU8h4Zv|Bog47{Pr1rqRtY?{AWe5~e(s7B~Gez%z5WF5*QYuA`)G+ugSKc?Z%g4i^>%6_X{k~g7 z!$UkLgE!-wIOC0F-WIP+SUB;KTNWghG0vlV zw>4#eDR(IRX;LN+^Al}BHl~US>KymIh%%e-5LRR+NdA_UJk4Fqy0Cw-xw0vG-5)+a zO^;5b?cjm@Ru;LpF`EhK7~S-uUq>CT&u2O$H21fAB!u`oVpvIoQsP)V6#eL>UxFVV zQUx`pD!+*)MnH?SaIk1=a@?VaBD1astftpjhR5J zI#V@(X>=5$5${|p3kcw`TzypjGB*)72`?h};JR5@HSYBRLP)6g5Sf^ zw_H!3S;CG>L|#9)dlXwW$7fH6Z&;!-`WWeZ@iGyZYw0YxoXP$V&+g^5(U6YmAuc;^ zi}T3HBrfi-jr?Kqg$5dXE>OlDR11f#-;Gg~^PFo~UvHEVV6J!$N#mvw;fAe&ts!@B z>Y%J!M9=gh*ZXvv2+mp<2jjI>4v#u$Z-{^Me$Dw8YM_d#F$Uw_~RW_j8Jus_(^S??u&j!C$h_o;RNc-`ZD!q@iu`%Q59dbj2v%;l(K&> z9q%V;9JwE9l{Xuu4Fd3ZjHz!?-8T5lOZ&XA6Qji z^EC!RUNx}lmtC_k2G$P8P^%jflw_Xwgk{NA85c$*r#dU$2_P>gzlvhU<{)%jsF|!< z@*WJgXGPBpcL?ac#!%FK`peDzpFvS~tuEi&xCKw2b(H^ifd~@r`CD60S>R5EGP*b; zE&Ez!eCd}UQJ03ML$0{G@5tq9Wt6RpOH+?OOoa8MYscr1PEkmnE2oN!G-$>6mmwC0 zN5&VSzI}SP1KoZTXteq7leUc-gwqVAT#SLH5lm_6`Wz~Uc~HTgW9O{fMmRJ7txac> zDkGp-|FXZ@p56#t^z(W9Ye}&FYl>^Fk&rui&{nP%&tQ$=URL^?oRKjL&!99!vRQ5?V~wk*YRy8hq%?m4h` z@-yMfa zRFq>VkxK1z2ZItX@dESVk^dVXne5d1T&)&`;X7+b#hq=4Aw=eOJL~Y50Fsi_lXC*8` zCG#js&3R{o+|?S0LshBM}@r<=f~k^Fiub)`?jZpf3OGMKdvTU)Ft+PtcF;bQZqhPx=Y0OHz|>RTa` zcaYoeT1gpJdLL43AImOn20yO-l z?#hqGmb+gadV6Ny7)UK5t%@-mGuUy< zFd(Wzz#1=AP8jc(t7RY{!^tK4{mDvkf6R%6*^3A*WsvNg9{*_&!K(}#)0W?2`w{Ui zd~)HD#Z!1k2+)uzE89bYY2R_*Kb->D#StNW_3=Sw)U_6ro+$rY2rHq|{PkSU?+B+M zP4w}(T><&#Ynrw-(*blP33e+Ud+iC)2Je}{Qkharl0Fqz{kX*d+vLOK2UCTg;wb%D z#}>!oQp6vgR50GtG=u|234|F!=_DwKs_m?TP%r*+JHDd*ChCSb$5fKRRFfOZg3f=a zt~K=m^Rnijw*!5*(c~Op{^ap3S={4Q)MB4JdmI+`tc|TP7KdvDfmBMe3x<0#v$vQe|{BqMkDRBI%NaTKo_W8rla0o5q*Y=1m&6ix1Y^I^VkzU zg|{04*z8^M*5B238X^vo67~)sj$(>Mnrh;E@=Y9Cej8|D$}|O)MN#xSvg-qTd$M?-m-QbGj9FHX0>3Esrt`HZ-u!G1b&VF~%yuN}xdaENX zY!d$P(5%THTYS8NfQ7OUKIt2Sh)w%P6JX_{Lb&!U-ftA`kwDzugh8XSM{_VUKN)`F zsrNsEK7O7$QONBJiX)Tu-?=|C3D&o4JV_4s2&8Rzg>bxwoE(&$oXPeZiZ#JO%Iy2J zo!ee$iKUk8G^B||@y)_%$2o}{BvUVsu$k-V5|h}uJ+JyJ3~}9U>Cy=vy*gBrT^`Tu z39f;^#RdMiAK8lGa{Z`BH+|~`+&%K$w_xhXI_@yXzX_)y?mZXI23t;8DtchI)ZI~!7c7Wv}TMcD3 zy=lBnjAd^QWp2gq>Va=x(;c$_ z`$2G(E`>=qRhh#{oKL-sS@J!s=;bEAUTFFVD_NOh>xW^TIO|e7q;~i}W?*T)}wpPWI-*|q0fuiT?y;eBWK+0&*;n4;=j`kJsW13SObIiHnR zjDmk4*+BZo(R@4!n-R2rQYDCZpHP~49b&&Cy(=(63HJ@g45fcjc01)BhYb@lwR(7$%cM0H?7&Vyaf!zWU%;(-yDT^_Jdsxx3m{A z_8EbnqD>bqi$m~Dz_)4Fx{xd^ z<%<~7NGt?T@w+`QNsBxNizHd{ku4Wr$fhRk+Wuj$1U|ulgWCn-Mo2=(`S3PkJAIq% za{2Dq04H4fA$feCs!kj-W15;W%U-@jV+zg0tDnc*v035vHRsv0SQwrO@Zlx7mtiK4 zg=A_kKmy%9p`XOOW()((?aU?0tCcv({EDBk_s%tl|7jVaY#?#rMk=?nN4mB&^75$8 z9i|SG#jCpPzpEqeH^A{NoR*~VW)5T3Ujt|cU(Mmta9!KoGt=u}b$wPSvqO}GsNMuKaeFAR=EFp(7tY<9xQDxZ;Yu z<h zbZ{tBcd!!JcgR)t7e zXjN2uqR41O{1^(Y1EwrG77+0WnpXK0-UP*Wm*)Aox^y@F<}`c6J}U`rVn}g(M}O1z zanKdpRFS(7X`XXlETW3_xBYOA`Rs55FDV|cd4%@=D0n@yt>3dP?Gt#q-WTfRBdpy) z#?QbV)mKd5(^x>pl9m+tWtI;;JqtX0i|OBCOfH<7WK5ceU9j`&$6V4q)KC7h6<@FW zwL0v&@Un!-M|%Z28iuN4i+`vf@`CBJloEgNs#(a5(FQK%E3zQZA?vkF@iu@FUt&gZ zWuYIE{`fO|U*7Z`mbm8UGosWW_6-I0#X&Wcq$+SFyZv>c@>qkJ!<*peFeb=Iq0Hnt ztd}O>loM!>dV(Pc219$Qm>p?(@ZUC(LQlLqiLD7XBCTGtNT97lm$y}oNnofAjXFX4 z-xRE*|K#{*KYmn{Q#}#6UY3LLfZId{KQ{mk5!ch}v(uyqK!g*~ome26H4E2Y8D;57 z!SzO{nYFP*9)5H>8WrX}E{2!p?#oy7)rqjf_S%p5qgpl~UaU!!Ia1 zL5%eJce&Oc5tVn z|2XvrHVa-QWJO%RUU{IU6`ba5a`N)od*B|IQndRlK^7s>T1%c|3yYYVJeAmWe~d_k z{p;;a&-~(xg)!~G;NXbNRlnBrD)av|Cd6?07TbyPE(R%lXxh8UKdhL9)v|<-qiiG{ zqy|`OFX8JU`q_*!Qk=}C*2a-y{8}G8u6Y3N@ekmzN0xt9<<5{SU z4L7lPmQqk)-%gpqT`8OC@ts7ag?_jBA|E3oG5%7$%&`B9=M7}WD#^V&&5{9&&*u8S zRRw}KUDs}xB)uvtyN*|{{>q=~rzMD(M~Q;X-Me>D^@B%BN{aYL-hWnD*wE9%0!2l| z4+iPk?0Ed21fPLX*FpR{UNL&SK5dj}mg*5G)X+27b9naX$c61dd@Yf8dhe~3hUd?v z;ui|Mfrh_^?rM)-yugRm52UT;+k~-Mgk;6mkWdMQd`lZ$ca2z-D4gdFA{pGnQO^Aq zMGb0JVB4Si^MOna(HmSCIiTJ~-m8KE$v_yGl@4_*QsC>4Wj zC)s&C_V@E62vM{kYFZgbf;kFclzIL7b@DiF0?&S#@^>7MYJH`U&&BRD7Ish2VmL3> za*ln+|N6>I`=79p5odr?60bfDVaNXbbZub6cwhYgdUhWuJjvRL?eH*(;-iPGI}s)= zi{uF+t}|=QcMXDmOleZ z9^yfIdR0F*A3WHba`$dHMBY0rSP|_#*j!bnr}id_4&hZ*D!NQX$>?wWNz(g8eE%qg z)mbwsBz-aVujB}c=z9%|9SvNJ?xZGuYuAG9N9<|B_9OK#P3#A)%l=SeJMqF->955=cd_zw%v2cbeK(QK&Y?k6mI3X--P^7mk= z^o<&MnDr9wUvMjFa$tT7Ebx-HB={vz(tAng>SdJ&$a0yB5vpbW3*>9T6p#l7eV>%3s8CCrYT-1s8;QT{g|uO5{;cFpn>l2pq-m3z0yfU&~3 zXfDs*8(mCQhR3{C&moaUoUx~E-3_Dd&z$$>;51Ck*&<`h&RjzKKGx?#J?DrDV&OB| z>$9f8a9my>Iwa2`v4fpyw()*v!1ix-5t9DMT@!M6?V~z)-JBGKbc!%B(wZS@wVrjn zjduI&?!c|x$)r|VQwbGuxNh*?_YX)Afh7G2M0Ch=V%eA^D{}pUCoZZn}}|J3%9|7yN3TIP%gjfZctkK3WxZ|GWwk#NAN^O z+ruhqi-=yZoLT3;da8vH9>^NN1m(==Ur+*ygyULo1a`Gk+k;H0pR_81&+|}(J#QXHqp`%_U zXr^^ho;bsRJ<>(+_UBCWElH{56NA<#!o!k9S$}EbT$$(0Vy$!voC4i{ z*z#XzBdpqdnqv8c5Z?Ln4H3r&W@z>JG^+J5OCo z;yKSaJy5nMJEQ`X7EH4-ABf*BT?2u`=VM29!SeRM-90Jkrbq|^j#h~I{UxI4oE+4o)Uar~y{zNg}GE~pSTwr^L-y7y; z;%8r%f-dNIuJ`NOTac$VYHsZ$pTw)erb7)()ladv=T!`cxGs@Isk~~y`_wW534>m? z>m@2Vpn2&Qy|AJYfO5ITygKgxX7RND#axtKz!^+sCr75*l4{_wlH>53O6>%sGQRXh zn>(C>3{@oIlvJ*Ur)XWK;;uGsf;aN<9`my!PGJ4ir@yM0TZRVKGIO;?>N&(WK6_Cc z9bXUI$SopE@~i`4tJ>C*xpPAZG~m;y^3V%_YIMl{`&||z$oF8U|h3T2JIb}K&dG&B; zjlnro6+e$}%6=pF7S->+Dh(@jQi^Evun{;53~ENa9>zlc^gxO4<+qRUtX0-$Ir?i0 z&MRMSWG!7^LG4f@4QY?KJJz|+8KskTo51XH>`r?TuNdq$YAjZNI!uM>`-=jt@jMYw z8h#LFEPlQQPeZt$?#uJm##uJsC&qt&2SV^poy2=bP7A!hu=XEmE5-o|aU@%;S>E&bQta)g)0LHUiXtcB7$!YF>Rv3p!Dsx=f+r4luL+;#>O_L(s{Y)OJ3FDUJ?Wm*dSMQ- zmA~}Qvwp6Jb?A?xY0ia>uSn^ovQtR!ac zi0d=FZP~)2EWOW-yN?7=ypfVCrN;0I6Hz^73z4gz@zJD5KB7Kd1@HGfXc!RM?TORD zrC*gW$*pbTw1(}}uOUSKXSV}wg@eS!oB98XleGq><`6xk~s?g1`&xyd+ zv-;NkDOxL-2~fLnw^nrwWzRraMi-s^5BzK4-8THCSw{Ss#*RzghG%jd7yL9`^|aqwMkei#NCo~-v5FClK3 zy;7cecOt-~l5&@3IP(~APAROcMr;wDZ>+h_FNH^7`A!kMp&WtevUw0M+e~ zuw?CkpAg-s%e$B)5Q5kHw~CypGm;Vh$oOTRC$&5DNPT~%f^URiz00$X=5^mqd~y=( zsvxtZMH>D6f3%Z-3HMuZcA*#h6JylxS~($`@R1BQ%XynL=_eeBtc&aTY_|&$aoPHH z=(Ciz57=IOQ#ft4dLC2f7^Af9)19&2B&ZnmJ)8wi_X?j^F-(3%;oITbRBL)?tlb(- z%j(Uo#y|P683mmW<1iaumDiax-@?`%P~Bktql0kwyiRBL!%^@G%?LbcK#_#VMQz{Mi6kbk^DpIb9D${Qf1;Dr zvZx?vZJe`?P(GO-1-IPQpts~r*&SRI z3Ipfchd=-M>r?ZJ1D3=xQ^9f<|989nM%Xx*S0T(Ar-MbSAOo(y#EI&C@YNov zC(_DzQq08oqKK%OHeBykb{UWJ#s^=k+6BR}cX(#vd5QGQ&=)-eTB+JH+T5sRr~7)M zt;7`(9RJMa63>|7Hv2jHDQ-0?oQQWbv9yTD!X1iYSK9`W^AOV#y^vFq#{@%)K#P3a zv+-DXBO`EBj@<%csSb}8FHLU~f|>W}RShOv5Wjp+WaWH^7j(*RO4!)GZ^l~D4!@dX zxxx6nQ{~rjy%UCLy_*@E%c@%jG4dSI4atjf$fBfD{oPsah_~8-V@=^(vRItI@nm+7 zxGSjgu9E1zixzOeS#@3L*=aq5DeoJLl~HTK+Y3%CCMGB7;K0MSVmVTxijL}i%mS7d zWMTe=CQGNRhaN)KPSl#lx>ST*+I*9Z#P$Zcg%|Ir%MdlQ!E0n1*1HOy5iUqqeYx98 z9}s19TK>U)IaZ?4&9KCo9cc`oy=8R1tb7*{yA&L#fVn`T_o!X5GEj&mV$mHo`P>KinJDer#!ZPquzxR{7zRTMxx{!OqT=Y`BO+ z0lK^G2A`amH^9D`6Qr677AMq>vCK%u|71gIyQpOA195e<-XAbejI!c{RAGA6==FC8 zFrED7R)T`hDxOGcP3<~Z=te;HZbY*>GW|lsfhNY^W=~6SiCNvoj6>fQ>6$3$~hCMsWfFE^TvcXTn|- zMP8tfZ)}nQ1FiKVXJ`Lrf;}?O?p&zB1nUJciH+QfT+kf&B4;(4 z8MbtIt5ksFN8P>n=T4bO&=|Jfb)Nnso^g&O7?j1yqiy@8-$ch9$uj}oFeMF{QsU0d)$h-jgwlGR~oHO?Lprg;amrY=veI4 zEp?yeHduol$0RWzJJSpac=nD{v7E#8tEm)WNu)1eSlX?=z(Py{%T)%o-X&5>K#i@u zgyUmtG9)zh%PZMGUW6aDMD@G!UN00dCJK9;tvCUf2!q&LS|lkLP?c*4QaQ*#LhrKQ zU}DN3D9T-!9vVK~1qod@mqzOkzi}Z_LZsZ;?IXw)gDYdlOtNrZzt=x(O~)O(>dwe9 z$kO~mwx6=WF!yII=$o=s93Y>6jJah|5g*3dKiC(d+Z~WUm5;u;<(WLj^X>SM-~Vw{ z#(Nj8emnY9bxU^ydp&d%6E#a7pze$Sm0o_!8Du(ccAE@rQDXMKA(t(e*#u%HHTw*c z$T~3V(jUhBhVc`0#mZ>1^OyJGWnDp?mHyW{ToP=0d|mO57G}j+EdE)pM$xY1#sI(x(r!p5|tc6^_Gk-=WczM*z00s()nF>JkxRfMmp!j2ED zasOerRAIqfjv;}@b=B>a$uBCwU$)%R@ZxR(wA2=Ch3EfE1ItZ~;kpz3?=h&wE1M^s zSci2|N2EmBk@JLOyg0w~;qmi0YwG^b>tX39==^Y?PvqBqiO3~#`=Q$d>@Z0GV88nH zd;$g|$_=kO{y2f9d#tSLeOi>r|ET2FtIU~=7vs)#`*Y_~A-v~!lFjK~yr4~5-`9Is zcNK1l?n}BrH{%abrDodkA!52i^&Gvc*6LtP+D|}3$Mw7ntnMv zNQ1$Y*Y}JQ{yj)tk51qbuY!Z4U|aELAXuGM7&EO)f3dmk ziw?F2A8Vc%8^HN{d(Un|;`4ju-k1LR2h-B{_`v4eF<+J$94w|`WO?aQ42y@gmVz^H z{%&bil7>A`Y!+3aJnqG=ZnfoLu+2D0I=}BX0zN!{T$M4wgrF;rvnJvqwLo{6U~3v~ z_TomD;3q$Xm*G8fGVT_`4yNnbYtHYJ8bKRYS*cvJIg2;D54y6S4ICxzIb2FiIyyS2 zlp!nm$MF3;k`lG|yo`O;fv2rBVI~KQtdJWqekI)JR2sMy_;wcB;$-7l9pRe4J213&YhPCSK57{Ie4a@o@wcG7^blWSU1|>! z%)%<_l|G5!@mRO<&D(2s*u}(Gacr--K03H^pXRggI)xRAeLY1X&s}hc(27bb`mNFYcK3D|)z^LL6yVRfh)lQMEjWj$Ws6zG60E zvi~u4&32uB5QgGT;cN=s2jTtJDqiw)t~jJQtRB_=Og)DEXZ1*LpPV1X;ZwriA=Y=g zz~WJ~{k49608_nzA^-e}#PICO0uk6tX~couNuLj%Dd-;q zJu9hnAofxhVahVx+H+Af8ZVfBH4mEXh=S>|fppNrsVuaxe#@_;49fs-##M9EkL)*K z{%wUNZzer|78@N>A^{sV-_oScQ4@=+u|b4c#|rw zG>Pk9&CPQIQ+&xkqF?$QzIT4=?GhrnqHpV_!XdI`Wo(>z%$az`H31gN8zZSOR2au3YZOFoIo) z5gRu2dPVrGZgMuV#4`ZgQ}HBki^y^C?iAcXxtpd2;&)VJ>TWCPpgufJ>_rppGl(y0 z@*A_RJj1-;ApCeO4Y4_z75%%Mr zXy3iHGU(kK{C-N~lnXdN61lRm5kp(gi(xwneKuqZSV#}$`^({=A{wH=oJxRSV>*hj`)WxeLukpFS8_}fB%OB@ zBV1;Icx*b#VKVS95G-fhwbH+hoI&||Zlsf_Z8i+KzI+Nz{uvLBbHR&rmHMHC35tVF z!tD1$IGd{Qo%oQL1Oe?2FB#ciUdDQ2S%tZQODY6^NS9$Zw6z60Jl_pMAHTIT*fy_DVsinc0hlyv6ktU9|_6%40A#m}t}_&r!pDuk%ZS-KI;J8Z2V2&#f~eo_Xv%4vXZ%7-6?t7p(u!NdAlK!Gr4302Jr$SFr)<6px$${+E^ z5EZ}3Bd5UoACwOn{g~!@K!Fe!H3yBQPf4h^LRUf6<(*(%TyUUl*f)THD%MfwV@n_4 zH!z&>&|e@0G`~F@hU;SIiQAT2=HbE4b~IT%_^8P8OBoT@WY)rqdwt=~ShF-3kU@s+ z_nE4z?5VMkIdFiretW|WL`^by4;hOwDAoPH&WX>kKpa19Lz(Un%&D2z!wpHB_i_LJ zrAga>fB^iM%nq$nBP)Rp=K+z5fFEJoao&%^PyNx-=Y+&#NB>jFFSTHnq1q+wLQ4yh z{^2RtTb&m8JI^E={WwtoDHG2d_UvT7g=bRQF4|HLl<{>v+@^~wfe%g*AJaJ!Vtpa> z`&p;y-pMGud|Ghnlc+`yvikU)=e|dt$Dy-&Vw?-%zriL(8gRXtQGz44GA-7*FA?~H zDo$NS?h$tsGcxj-$qIJC+vvw(37v6ITs8hi6o@FZ(V8D&AztXKb_@4)+A36tunt{zZ*>+QkZ+7XWncFCur zS_z2l^qHLKuE#r4Fu?bApi{+J9Nl5j6BnnyED^Ak&(_=lBK#1m9=RSR7@daT3sR{R z{F+>lcQj;8w;c4vhX$g{e9TQAdpq7`?($*0g1uti0#n5zbx=^}YE!s9nn-k*YR=nD zFN=b7nm%vD==cx354xKpH$bGrm-fk4J5bJaBGo(Qg=Xod1g1~DR@a-brNYU14%2N;s-dUYe<|$nPCt(_^x6!jlf)yl@r5=+gz8X?Bo-e1JgB8! zk$|@2NA|tzWH}G<@Pk)I#b3-J^Gpuyqx;3mc)7tfr4`d^4c4ablDPq`iTFP3k>lnl z$xpz-q?_MM@P0;VTFHiT5P1Ts@+;1ftJB}a-Ch%G^<1)BgtM2K#K|}t%kzjnGsD9Wz>NiyrQX+>RbcflVY5W{7+>Yufig_Vde7~tGw8e7V`WS);fBd`ktCLmtBmkq+SaF37n8t}TEd0HcQ$6g zzjA-a*0NY6kv(jGuIhIr6N=hgE<$hXh7qQClKp0MfR7BRk%Ich@fd=a-3& zpNE1rofGn~Tf^t3@S^#5G&{+!oKjx7izx5eZ`!M|j^OQQCbJU}C87g$=eaI(T&cjZ zj1s{}KebxKCtCjr-f10*15{I{@lS{|D*ISq{G)4+rl9XBdE6varx!IEOm*>hiPwYK zFv{!G?(~B6;N#!Y_4rnV?Md{@s@1DT!4_B4z|p7{C=-6k>wj&CPwZ+R%az|e#Db1V zAR;=W{}A#|_(t$`uYQBxQFqUUydz&h_dw}hk*4zyeDV)n?7KE=PsC^|ZwsEhyiJ&Z z|J2jh5X;ElWTa6wF@mtv-qFE$fRdjDbbppN*hr%fVD)lzpHHP>D0oC_-`wWmJA&xR z;UF$A<1E~`>vkdc$qXGVmE>(oFNYZ;hpPOxEz9xL;g8zq>f&E|XT5`{jlR_HwnbaS zCzbC{;NQQDr5{II$nWrvqfPmkJ?+-^KZsccwX@w697E3A?3B;l%328DyA@4Z)9}Q! zbIsa!jMW2^*@5fbrTqvLp+8ks+GB+iE4AwfCOXY<@$Ur3IHheXwyphUYS)z=!F{{$ zsPuY@0p=S-C9iJz-^P_$dGWxXe=CvpwI!>qrdJmugTm!DqKT0RpzHXtev|NAbTH+rI2MDNS!-ytdHaYH;;~%ismJ6^!G5|Xa9cR9+Kg!LsufR2z=t@ zfs;PM1Z_<44hfTf!mnMaO|fZ|_?T?* zZBK?~H{*=?gl3}zUl8msDl4Q7U=}vh@-*ranFo+<7qYwaabGaulpsIiwP-U1A$h)b z$*lPQFdnk>+ifW~4f{^^bLq1!7>3Y+S7)_YKE~lWjX4QzP&!U9I(=W&ca4dOw#Vdpeu|r}jb> zlS2V4NH$)hry*GyV)~F{GgWa1{pm80!0H*;~A!}q{1l`lg;qgZs& zMmHH6HeOb@^G#adswPMC#ZNuTsI8tf_xyfU0bcS34l&9?bI4Kn>f5hy=Qkech3IC{ z-<3i)`cZ5FlEe@8>mH83Jr;k#sAXTgnL>&$t3BAMd z6TkPJzIP*i#0BLy^&i%|B}Kyj%fs)5eVbQ zGPWG4lyVv0v_rp(mE`!-@g4H$tv75QwmZNm)~QgIa>N>|q&32f^eG!fUQUVRZ}#oR zyue}I3#P+~7&~Qf>m{3Y8Jt+{?`k-v65pa59EqB?y2`LM+~ShZA$370@~yqtw)GB7NDa&&J+W+&X#f1Y_o4y*qIuN$BgIXDiYn)VEgeARCf-2K$6+Fbdue91tdG>8x>Ev--g_a zJ^RfZLxr(lfs5jKt_wO(@29(q4?M#4G)W74AhiXZOFCRHuO<}%-bESwl{<%;4>&A%$%|^jey)PTfGU%S=1|$ zH8{R6>V%|j#9B@J2I0m@d9Nqv{x}w+Zj6JI8cT&xvEMYkVtS+-A2>T4HQUKJb=h2Sp(mlvbjKX94H+=s8(<{y-Yd-=#%)QN?4 zbJJYP!}(`mk?ZH))oomk`b81VFrNqKK{nXzQ)!c11&74>ZT{2D8E|rwEM4QYgNrW(6bCXIJu8Puy|*k$M;$IyaaG$?YrRArcAZI69s0 zWWQ(>f?IEj>ozk2)v)4Ozox`EMFyYOj3Jv3zpmoDdFb$~Gy;-1(vuZoQpe$oxnE3F zDSNiLpmOi+1Y_Xg5!6<41be9kUWLiO@}$?A$LxtSMTW0MGcyL;3qluLI9{AXjqR$c zL|(wTxuH$Nj$Jvr`if|;dop}&=e5_EPgl7b6Tfv0t>a-oUazWdU^!HNpKr+2I3kT@ zErm`pM5Fe={;A0~!$%=|wm+m>tM3!OetlS7z4sB(EJ=Zwm2g9;iRjo_jo?`@=)~mv>84lJW@PlWMpduKSFKe z-}9Ut5|WaVrsj656Y7Huomg!$k9kPBJS14%TMY1VLl%43oD0mSHNS{cpFX_xom)fN z`D2WKDnu0PQX~tbo$=8xiT$}n^(xvteOAOCHQa=x%bQ4xFG9%0FpsiyAi7?Ksi)-L*$ zzQ4T!0rV0Y_5?c_2JWv;>WyB|2j@58byf>&awxtE|0pUGuZKmm1%BJ zKrmLrezfll^PwSZCEW_u5NE}1c7N*g8%CTcW0Lq-`6b5<0-rAL5qzgbhsTm3Vq6cC znsC5XGreuMnGNp$S$~}$b4?fH6iX>F0?c8EZMye~C-i@Xt{2CNS?oh5DC)8(vgs}O z5>s&RALqo~%+aLD5JXdILkt{l?yf!N+voxTMUI_hF4|UDDyVP)M0z)$mUO? zYu)K4X}%x`u3j?CVfDmDzd`S~shRqF3WQB?nU?j|5(Fi!-kM@PHwvVO-qTGJTbcsf z6%yr6vJnNa5j9-OlA?A?|({)ekBCnN6+ zOIWfm(fwN1J`{7+VUdW#W!8zDQlI}=@;{Q=}p7B`yVH`e> zY?7^nWMnHD5wdq?W_FTN%F0Oc$lfENLL!vCvqDxzA(EB7GfT+4|G)n`uY7zw=Q-#6 z?)&?_uGecfmprngK%mUs?Jf4a6>f?b+_+yl#KaCOYM-P3R z=)3g;66ozcOH<0ez`h_4UObL)4Q9jJO8c%j5`$$-f_LYg@BvV?kNFs5wmJ`_qk?T-`C9o0Y}beEq0^>HLJA zUs<3Ae6jocm#0Z+T7`s7qO}zMI}!a4zd_QT#D^F3^%Fbckd5xCrJ#VY4<< z@`CV3>UH(96m2IS;hI&3aFkbz{YeYb0| zIt>&S(kZmMo)3i)(O1QvX(_USc8N=eoRUZy4rEVAsC~`2g8o8+SADzAh*sj!U-Mi+ z5^X<3&Uf*g4`>Fl1xY$H@7Q*zSrU`mrPjX#8g5h8LL^u-Tz_x^Kk#;F6rMHdhB(_Y ze+9KjO0vwYs5vBJr&!Ce=Ok9@f<3`p7SB@+|q_~5#YG5NZzQYUzd zIoasONi&0ai^MmA1f|pPZhW}>%u2*Z$WkwHJ%M9*gLp?F;?5cv(iNgQrv|AkofaCG*vhKE0C!$$yVf`L3>sZ z_k{!wZXTGE2y%`kD0>PCvpHMepYGd2u-T`iZ#%_TKu+^y)@|0IczA9cOfND&;tT#y z3Nzz%$PdA&Y2oqNPp$M&A8Jh`g(+WzskUQ$IG)=|@LZMg-`4k>45*n?=Sx3kY6EIB zDzjGJ4V57KWx|Xqzzg*jS$Vz`a6aaNUa#*w76t5)XwMyODQa+T8Ayw0o36}_=%OLZ z0$C5rfrDnr1N*hb>9c^*a^=bFu^opR>xAFq(Ki!7vB&An*ZFfCK%@C$SuSeR4&0;c zKTT-fYy_hbXJXp!GxIQ-mhDhottSZ%i~TI}Qtl;y5RkKq;UA?TPW8##jht8xsDClb z@o83Z2Ifz4QmUW*mI2;Hf#lK($|*?S^zVjRMtBHd_c&fG#G|nOdtH@_uXVkCp#gy# zwbPHmGDOIj5YBq!*$?}?O_U))PUfH#h)K6j--(AY>nx#2N@-;{S!6qI_5BhPkR8)k zPWx@e1iB>Ss0Lmyh8&hzzCrX9!(f|swVY`;ZxVF>vQpfMe1ME2JOMIAEbSPSh0o(u z|K#?=<8CA?8aIiCK<(4ldxk{sLh>cXQ`ZIWM8l0`=Gw~3*PVeJFH^9*@;4rs;|J7J z2&lDy;)cd@OuN$_gsJ0SOVQfc!mu9-mG7uef(9wuF&W~$W@vOK#iJrt6MP#xQ!PFg zngPdbGyhztelY=0!xKj(pXkJ(IYnCt6%M7KwR}1F=*8cPLD>!Y2r6@VQy_TZI#r=u z69Q#2G+lL188hMP)Wh(rcnLnxuI;F}qT>|>9M0*A;eof$f*lzy;Lf*^U3fPJt(V3S z29zr2LGCT5jN=GO6GwlVxOfs)vb5`1TX)03qWT3B<~BM2nd^1xns_NE=u|P*-_}Mz z+8HZ(O-!0h0m}Jqs=cp{F9koHe^GZe&auH?X%$E3;ZZcibPFFA!5h;dq(+)}+&ABofD%PoL3V54{sj|)uh?>@NIZ`;^@7<6NFG0{YX{;+yfYT@uM*G&(8^F+SCR?; z=KCw0<0)Q&d9uaOe2T9ej24^I7_;2zM=v8X$+d;Z-}y)OB2#z7^hFp<_e|7Fy(b8+ zzM2<3a`y6}wT-tnP3tBjbPa5n#O?QQ18XGdjf*+}YiqDuo69@ep$J7YuQBK=umJIWl#iW57 zkBTc^lpAo;>xW1$vJ*jcG*x$hdPxbybsf_)HYR3-q}OqA{zF5iKuAK;+}w=LAwPcf ze*fNbs{?^m{%oi{8PkRq#tP2LVpb6_%)P!o+2V~#=QS5NCPszoKfqS*hpo(peG z(Qx8u85M=TAFtm0xbz(vToWSqmKPkd;A=p~)$cnW*WuLSBfp1Z53Yht*cG2xmrJxT z<5GN?O*v5)6pfpG7xZQ&Ai+m<`f%FrH^M?YG&?O@A3}8le;be=ZiDCIt50nQ0r}AX z(O#UEP~H|cPqgO(+wgIai{BaQ;Y7u*V$Nf&&xrp3+N{aPB@vyc0JdX2jKrpW{fIfW zM>gRHvT%Q_rZo;H$Or6QBzhJWSA}8uMQB8XlAaz=r=+IZ+SnlDuI2vZ$|-yXv`MQA zuB+ZS1<(70zoS-{W`iT~ySrXqwR%l(3lGHO%*Ns&g9o#0^q5IBb!Q0VoxBUYAld;UI~89k5}7bo=KHrjzM z?9eFT?2$BhwH~bp`%lpV)~$@ui=-V>!oBKE%+=w(r3*(-xVHewsFA4CheZCgnlY74xA*JjB)iEW09--snpza|PkZS(J z76zt^-q8FAuS7=hS+39Qk{sX=yB9&Td^-xdYHE73rqlEwdheDhn<2*!SR?S%p6Df| z0vZj{O8TG848Z9o8FY>V%`2z}ht`u;X=1@Nlz1s!arl{sqh+#U2$#QWbYi|ZpMtl^rUMC zP;P%y324t}0lp_X7wrCV3Box8$A`hKwp-w4Cv}nb1~nTb#q53h^-d!Qa)#|KY}U)E zKuzNs#q}kbw_tdF@32WFxe9pPS`2;duW&%hkYs6K7k&mB=)>4NF4#Td_3as4Y;^E;$C4btZqa$aRH&;OHQV42;NjyOCSt*Q=4HJYT zxi{s{;&E1>W-pLR;B4#wE%DeNirup6hS<%+ww==yJE&KOlz)+gNc^CC7Q4E;K#IX1 zLX<$7oScN-%<-gz1oq4DvilOvQAAi6oJzpjf6I|9fo!ew?1pW7C$I+jTeH!iHiyg6 zf%l?CT{sj+y58J7WxE5}S;P=En^VGx7{kg>802O(s^p{-*-m&!_v1qy&D25FH!W%Bi}lFm;yW} z1Jk5rGB#mP--_c+g+@Gt2FS*aeptoY$*R7vE2u_&=Ml8xZbV+>i33%W@>cW;ft<+W`|jO2e7q_kL{=5I}MQ* z1_#3Lx)hHlduuD#gC5BXqt5$B=Yt^~7D$we{75ouLkrdeS|WK0PgH@@_k+~c=D%7BJWw`MNcgKKC#bT7a;rYprV`J3mPDp5jEeKn#}@9cLSmY?Pfjr z_T%Z^QyYscs3|{hp?KTsG`!5Epjmb}aT)>36OytyrFwxeo2lo<*Xb-Ut(;=lIW@uw zVjs(`Rb)R;0QCs-Qwin7XHa)t!@v7@3j@$FZZ0u%Mj(roOWfTCk(E^#o4Vn~EWjiT zt)1EidJ^u+plp0i#9{@yqrMO5c1i zleg1YJDDI1ME%L_{zY#t!cC9+EzDbbE#w;bgPtmk+*6 z4m9i8Q9^l%H{d8-RX{Z4ED11l;(fqH$&5J&d(52q_0D}gkgTD*c=6(p zC#d7*#i+`V5S-o5{lu6jsTy=!;606<&fI_uu1{>LIkW5_@Q_d~@?)$KVsrkqu}qOg zXXH(C%d&74r1@fI@my)DX@-lj!#qUXWxO!^mSnPT?c)##KBNwz%4=)~(YvOEoc{;B z_={{8eB4SN!aCbMvwCuJVYs8jfsvch%EPV0^Q-cP3IcxoFCQpasYFn+gDvZ^sslWK zq2J9T4Wh?W_BQ{HI==loZPOT7{~K!8>zk1XaTpu`q20p}7E$?NZ@I|#sLfAjzRbf} zjnW^F@*vE7kYB6^coGhbg_Ttb?32auho@68Xb=7!-YTgX0&Egu&$!d*6JWmWa?4N} z8UflVldhPB*lmNE`etAAj{yqU*!u9wdA5!QR+LKHIU8f>LAB<=1haZ>GBnAFQtpkS zPxxj7CH;w_wmsnVQ0I5~95)A-LyH{cGZB-oPH@iO_)SGEgkT#&s-?9Oz-27lc*%{+ z8I-qZQ=0ZS#gG6^euTRIZ32iHwkbNzd7K2E5GA+n50YpLJE6sAOYVev?c47;r`eVt z0nLH-aTkTpIQXq#lKyajcpUB=f440iqwN4+ChyCKwW0Q{Zk% zH{{cQ-FmKmVH}=Hy)5}iUrhjkLyl9EO{$+ z+a11`o|@LyoeG6W8T#n{ExJL7)mwk+TZVEE$&(njw&m^XpvK<7%eLL=110NtdMZ{l zQyh+{-}oRMF#r*aHr=!u?ROBo@RbaXxMB@m!nY+dFUv7QWzM#31LfTSV7$6w7klkw z7zn%!DY4tZvA~-Wla)T-FTbBlO-$ufB<96m2_DiBb z$jGxZ(`fqxo>-b*zdZf&1#mF-nBiORdLYMVqPUr#mL4SD3u!i}Wp@Kpsu1JCkbH!_ z%{8FB;P;0XSgskhXv~RTfEaqSe=40GsQy`MK(ll^IsyiT6#_W1Ux*)06J`2ZOHvhP z6JCX4?G!<<%fM=ycc$?MY!$N+Os0E;1N9l@Xu~c*Iofrw0Vc#OI#e^%{cT z`><#tXdM_XaE|CREGL3sW4_8Ld)|E@h)I^2Z4niO@Qx7~tlA|BT>3)WtI7S7fI>he zd-<%b83fOd&?+-)+<T?D@Pd4FLO~?(w_xd5s`4L{IJ}POT5AR3`$; zVz0QuakJ))$CD_^$4|my@it`fC)`YCeGweR#NmfxCR~yy@XQ7l1h zhzTeI0c9BW?%g{)l$KsJF1Q|a9_s%+-S;yz{Qf^B5^Il1Y6I~%`_k74knZ3~b_ioM z%LrO#pnCiVBjM|Cw`}t6d)z5*FrlZowD?ep2C7tleC3SqDh9=FY)u2#I{|M9=?0Yz z6KX-}(K9MV*Ojy2hPvQE*!Nf@EY0xGVDPM8Zg>9+eOH@N= zRl(^TRaKmiJ39K7I#Epp&>g`cHAXDyGlVR|VcbpEd#IT}yD2VdO_#hMGz{J`*>t#2 zK;VLM{Nw0m3E)3bA;b~Xa}0bYQe(z`?e)S=*L=d)11~pNfknFfq3Y9c`iE0XA|2Nz zbV{23a-94U1o87UO8BY44JBe{zBm z{Ay2KPYQ@#hn%PfF)w0`QXzkC*reF?Juzf-ElZvf`@RR$8@21UQ{AXTSm7--A8Vot z!ZgAa+$GN6U_{G!M$7rCASjr76GnF5m4_}dmggMyqHTaXm-5-aIF<<_X6|sX-Ry9L z{F#8hAB^78{15=al*f#A$iL-%mpfLF#ajkTg-#o@;&_FKi7z0 zkb>oAiDefKT!^;bxhA%WLA;$pzVN(X70}+|&e{XP zRfz=lC+bLceU?K|$XUM!7=G_Qzs-DK4otYGU-}d4EWy9btEOsX-br9e_EBHbdo&oR zy9+1rE$Gg8+3V!>wBg%aKybnAuEbkeNr7VCwKAJ$+OnUgKHE9zP3Cl#p95P&&>l25Yg0`| z$xPdwwK2pw@f6n_Ke4@&^4uH;F$7C7;; zyT_o8{S$LY!%KvS;ul;SA?Ox_wMQrx@zV?4TN7nSKiu>G3?u@Pm}Jf)T3~t_u1|N1 z@)Q!%nb!Pbv3Lvy`lpdi8pV%JlkT3l(t?se-;D#biZ^r=;P`+^>TAqo0DOmdGRY1} z|3LR*2-Z#})&{#X?mbs*MgD-=op3o}%Q_6Qj+wjkC86?kr?2zhOkG4A%!7;hzG1!O zAQIGhg~;n#6)2o25y5c9zoG7U#-^kGnloS%X|8Iv`D`%%tX1ko^JO2XKlPB|yRon} zv~ZhVZXqQt1XQqV4RtAQ0`BdUzXn$=eSlE)sQR`bqWFvZ%HF=S*8BtPP2xHehR4yD z<=C9SM)9WsRC%DE;oJ*WgurKi9=MM%pM|B?X4ioAI2Dj1#JaAfyCEy*52l}SFBmA` zgfI!7UgFCDa4Wu};huk04BzSkH?hzQKOtO&znfI_c>rYia5I+%g!aPaU^`=lP-m1U zd2i2NDoJ||NT}32<@Nj1fV5cscDD)s4#bLf3#SpOd0js#Ifz^`6@cnfrz-_Nbw&aC##JGu{5&e~5KIn!RGs;ncfd!%AkKn>x?&+KLMdzU4ypEH7F%nG#ja`DUk@Lvx&myC=l(0 zkE~;C-=#$YUL?d@5z4D@K=sE5%?{6Q-GI4DCA~|VIV?z{=geuc72pG0#R@l0bff2O zCc6M}(!jPY3`Q52*8awXA#g5}kB2ZP2J%}gokq`=m;=pV-4YQ&rn8= z{VP+>bKW+%K5=F@h@OBQ8raGPoiaVy;FHubzgda-W&|+gyJuc{@)atoO@*sX7t=$Q zMEG!#K(s%6>{QLSXd96Sk=;i+pPkS`+y0B6UE<1qEh(+ zl@J{$#tbkXpV{zJp#Qv-g$_~Yy;-Y?rtputCWZ@8Rn86;Li zbmY%DUIRYDNj8FX&lHgL_ExrR-u(&!A`aV^{<;1DP4#D5AE=(sz-gwbvLc5YM?gy+ zA+oKi$_HBRYCR-rZI8gxmQ=pvME4r}j4l{uv~9i*YHu0$l^&o9c|Lo*;~yriVz549 zDI^N|v;->(_Y(D#@QXkgNpL>J^aDNg-x6%AaZ+=E;n%LJe`A$TKr%&o2{mrs0obd( zXlzx;+CbPvJ@erBS|#${Zbz!Pc%YL}3~N)j6GaK!43ILo`>Hnq7_hnKyYCL;VW<@7 zS$GGPK_^+9o+|G76X?=mF%(hNGk}wVvpe#xML5(pNF(MbK;ch!XXhM3;|Ep{oVu?~ z9d8y2Tz01f$I64^VO6NHP-(o~5gZjIgBb3O*1_@7LDnEgN*a)9z2n^Xw%!uXhgtTG z6t8GN%|Dxo$Cn7@fk~uwR@;3^1`?t*mHI{QHv$*llMHW858!7xiHjYRM_FpiI+8}~ z$NoF>axo(vliU~jfcB&Y0X`1brUrcjE6#)>9=|h}O zr>O%u%i%;DapiruzwvNORr6FUMEBp4Z3!wghiZ-sms!nTe1naLZzobyP`BVgjE(D( z@vsL_^7B8sP~oZsSD%P8n>)tQz@+>`9}Yggr|@%v!Y98{`ynv2hi_%n5Ft!iZWBGB zblDz^QM0@n?D^&eg4b$DSn>&X(Ei{@MwlB@Hr#x0MZ!I*Vi>5pU0U6vri(y8E0*nr zpk4wjcg3Ds<*fP)owz6Zr&698!3$P0>uqh}H_*=ee(GXT5*O-)bwn3>>#=|Yx2m0{ zm6aqsixOfvCaO0IA<0M&o`xhJ+MjJ(ennr+ftu5L2`uD@n{E7o!eVuWIvz{|Uxwcc ztceAgDi5#T;TdlT;D~ zy2_v@aag~4GNTW^8|b>M(Kye+h|P(fbmhydfN!n;+!(Xm0~purEl%;X$ACy>;I^<< zkSE+@>{M5{Y1#p#?twzh;YN}`-l5%aMcQx(jHRo*&czcLK~Q`OSIgXBCKQU%k(Hc% zOA02LVw~hxZi>T)(m#ssw=@u_keL1!?d)w5xLasx%WLDS1!hZk`R1*AAHcTrX7{? z^i)7(=FmL(G^z_TkysbrS8(|YTPo}fmrCvmgY6yO0*16eJ%|sT6nkV%M*;R40Ux5o z^PPZK-|i6uv*Sge=Gsn4%{ws-uHkX7>4SQE;by4>#eP0N6VMzLHhI>t%Rnam!=GeK z&3qsjXG=gJnePScg74G)^1s_dzZav;H%@<7uqZD#coNMx3xTCB?%H^jN8o4okc{?V z=_RC|CK%?U*JgnB=uG8smhK=}&1+W-jS(G$Cw`Z0GlMP9g9bigMtqIA4Dv;}WqBei zI)IT%S+iL0bsI2WmSx9V(oMl*$q6l6EkjSRQ=)3Bd!}ar*P@z!a{WX7#GR|^ok+&8 z3bJgNYtBDv{6w4;{qElDRC_XzVZp`ra3dUKc*DD&N!W!8kbd&9=gyOeFbM1LjmEKz zXG3j~E3NM(LK_6|?ozLqaTx?9LOd_w(bp-5p!Gk!Y|*e2 zbk)?ZwH6cJ=8zxZDQs+T8Fl%)6M0=RM~LVkn_CInK{&Ky}fJB*L3_H z2ns1$dF+y=fC3Df{P5yVg!P%Yw*R-+@HO6@9B;x-4vQxn|MlryCW6V!9GgQT_)7?^ zqv|vC8T+$Nh&2dR?|G3Oz#-Sh1wu?3tsY}!FoTmgcHqJhZ(%2+z2MAoT%&*lX8{at zZ2eB27I6kYN*OVn-j5)V7FG1?eolgPDCsdPSY2Hu1ya(+Gkyo(7T^I9 z5s?KOZJHl;vOBy*u6d{nyehdb7!cw^fpC%x-|$@R6C5(IS@F%p2|N73~f$bPH9B!XB<^8S;a)*QxyB??u=5|&`P%M1z7_@hHt12oID1xHm zI`1o$5orj%(O3 z9n?RvPkrSN4yptvlrUuqRO2Kh!-%*VA(RgLaDS|6YkzrAJM^lEgB1qa?%!=JEm`@2 zpC4@~zoZ63{L7c&i;K4jfta`{N=Lk;9LfW0YA#pan*gCNxDD26sS|#fKa)HI4feHZ z;)R*hZt#bLG=ihWram|FMoxBAbYsElD5TaEq1$e<=&64Q8Q^$t+h}05M99cxm`u{B z@eq{8k4^HKs_zb;d-GB}mVqqWxmSK)1MA(0#dZ+Y?&x5%XTN6S$ZtUos?|JX643|j z$ADU$RBX_N_MW6Nn3o^Hq?y^xU5^ht;191q0+#m+H205wFMK>2ge{*5hmp;z8WXqT zHL`Dw#9risXBz7wVI|15P)zZZU4;lo0qGg+LnQ*C?|@!`kVa2_=_Bln*M3}HXxIk- zOf?zy8`8<}aDK#2(qX*<)(^)fJ`UD2z_Qhj5KSy83iT1hC}Zsp=m1M7=;Fr0k3spp z;r|CZS@5u|tc>%@m3pAV$p?O!XGG{FeeNG$j1A)9weB7JS4#RuV5X^Wb=E$&0rK7n zo_}-Uyg5{4OI&J*?Q?~>liCYP-=~C;@4GI;U}hiX$therI_^jdgEUV_N}bG~1OVg1 zRIMla!w{2yFWr6UZ9fQ0ZSYF)c2COOH0!NDGI7W-%WcjtjA%%-ZE z-68z(8Xk9qpPU*pVSs1M^)EGwVs3!t)oSM>H#7|`w*5QWFw@Ee*0TlvWu|9RpkD!# z>?S`P02axY@*PgL?C>JW4q9JZAAt~T`uVk?i0_lIq=vn~og>&!IxsHZoECufZ-Yar zVlU>P;aFmy!s7%g$hfyWJm1fW{?Qjl+%R>V{KVkC>7Cd8*<1w3!kwx(X-kBMw>v`2ml5Is_NSzlq?5O{(Ak|cGc-Di2Wn@BJ#^k~^1*u1Y~#$FJSunMr&ejO z4sMi@Jg}C1v*ZNkR$Ee6v#|7uYpl6qszFs@`1L~04c<%}k^LgLr%5mWfdfl`XW4Jx z{;c2|M#JgTIGgg9b3h?6`Qhd{Vo}H`=BP}mYf*w^-^(5$Jr z?s}lr0oq}l7r6psW1;`;?7y;uG*ZB}8s&_+u@xxd=ehKdlM{7*cIx)#Up*d&2VBd# z?iQLG;FU_W6shr;8%WZGsAS49c3^>-)mQYG`|FQB&$l&Bwe)B7f-E7MF{Umo4Mo@Y zix_b=+<+m$)5fsFYxupC^Ll)|^1=SZ_;csf0OJ0WV7DANc##H&KrzWJzGb_A2PR-+ zd=!}3iS3}=RcMpsJoqE2r*)ah_I@3ZGBUWaGRFKT2;tkqbUm1UFHJ ze&vLu4!Eo8o0rNPg+jx0djvQ3C>sRJ%zLZ`uH+y#C0~waMZGm}60qAz_g_hYR$}|t zhvS5Vz!O?L%Cjz}zN4mnBR~C~^Q0~EXl>DAeAwTK#5JQ4K8AKQ%-^B*GR3iLFaXZE zQiwcV+6YNI(g-g+-CBkieM7@S*ZFI(eYsRx*#9F1SW3N@oSUm|0oKu|X67>-I^b1& z)4+Ofn*m1us@x;Jx)cjl!i+IN#F0ku#ALNBvG+?8Y*WIWmDGiH`2CBVyv(y3TdozX^FVs07 zFyPX)38Cr%VPo*|)9ujS-dp4S=#dBL6HVeAuu%sD0Y{3g^Jj)2%6EkJSSL3IuEcw| z-9aT1(4RiIH*snn@t=vZJe47-r=ksR$rmQFQYeAR-?*2;L* zKY2ZNa4rv9v?}5kI*k82#F5@iDw7XbY(6QLy9MCHA)iDbuZy6Q1dU~~ocs<@H+Og_ z;*zcg1dYjLE3(eX@V&Gw(Baa=IFLIE+uT}KcY!;n9J*7gQEogp_uuZW%S;mq6Z1rVnL5j4e&VAZr z9f0fbx9Y*o1wo!*kO9Z5U&zRYHUrdQ+7bU33(rbPy|@NBIxZ_iB99-#0p z2csUZx$ts|k9X#{wIWLVM@f0%?2e}C(E!p7RXa}+APzD=oK3H*OR1}qf#;;u3=As& zXO%P!3{lgu4Rl{bhwRXlI)boU&A+DAg14|lPLU+7g_E!Sqea)LoIYx^7361tElNzf zs(nk}nfx5_w}ea)l`K#OX=Oy9B>}7)M>U1@N8Bf(R6Oox9d2Yj+plx|_Ku6-L}Vjm zGGJ^b%g~oqdxQAtNSC5Bs2&f_|1P5O;GPJe71ax zPI+=^K0h@ONk9Eont$p8=Xwx{lGUOtzMKNOpJk?*G&6>w!k)8Mhtc&796Fj`qbmM> z6D~FrZ3`T@-G;hob z>n{AZmNZS#mCAu3;;0)nc9O>-CMtOFPC@7`=wI31*&#du4&1PrYbnA;kj7C5Ur|*wjixd{w+==QG(7*i*PON*!|SJ&2_ia9?s~ zqJRZqyQl}bzxJR|f-&Cfa*7=kmYKOa+v$}eXZuIcD{53GC3iDaS0Ik;o}pohhiTYkb=nV>AyO+X&vAy z^O!e~Slc8U9irDyHiTh) z=TvC5Ir|!Dwf)&$P!cf%-(;5OqCUt~+mrQ$ zjBZ=8&dmd$l5=?)kSEg)`l~~V_e+^7VUNP}-GjyzeRwTuH>^YJ*aEr*d@E)$5$Fxn zFM78yS(*ymElDLfuMQ`{!|3Hp(rN3AXrC&fpFrRF3BKwGCf{x=M6~5fNhuq@&{phhkTvI8n{WapBMJM$;Fs^P7=fz0H&9L)qmeYyT4jOY^Ff@CVY49{B1{E zNClZk2M@cAvtuFQWY7DDGbbzHL%4a;tM+Yc=={J~E6K3f4KG{!O;=3N&{pG|THv+S zn)@L7`)d_*e7vmlQrNKLPlrebm?Kp81P_tK~b4KyO>)*`)j z&B3@;!flleCl6nZ<1PqpOOArjhu9~1;Rs}Nqj*Yq>{D11y2b{zP1`X|s}%7LH0iqb>QnnPI7 z3BE9}^%^?gI)|4=CaHk;)z|T_Vf6mb9q$sSaUi|oHDzz*JqPwrwjL;LbDMyx*&R#C zmFGk-ClnH|vQs+%=a{`&>DYb?7hQ^7_xKTchD{$hvC$q2O_mU;Py)Cjp7Pt1f7HP`R&P zUSI?LMx*4!j&>fA@;<1YC3S$XkEUtOVLRydHP& zn)`z8nS_XNUs=|p3(i8;^%g-NFTy!lxA`xYuM7}7iGxG2H7FVy`21>D|IGe_CBp=6 zET;u!Xzi~h68sfLU9!eg>vl)^X&`p$!;q%1MGSm;w8*c+NFN7fKKub6p1W2+MZ9xT z$rl+taIwb8_dH@q1F{M+LUYlvVR)6Gx!QqSL%*=9Bj}gd(;pDoeDfKTxvw3BlK#C> z*01prI-5&8T|V(iLU8PJiemG!2zWMZpI~&!Z3-M~o2^&7R$>rtR;t>lixv<2%2;`J zY5x!~??)}0-X9c3sF0A-cQIt6kP#u7r=nklpgb%kI>&l9bKxEnOSc}iHy)nPT%sFg zw|WQ6h2~mKREf24ze&zgi4+ZXv7UT4f%7XzK)M)@U3f4q1J}*XjRI0hh9QBNs8S*?9zjtTC-X(kMRt29}sC<5SrrfEu@W|h}-ek0(z^N7Hqdf!`Oh(5b zwetD$a;_5*ocVh9(NN{UQwX~8p|Wyd=Px`-ez&^jr8@wt9s?epYwuklbU;e5kUK1O+AT<6}*LnzFu z618iTK7e1BdVc?O%X9%*qfke(C%TE~!Z@}0yzi(8P$;;6jO%+2l-!+XA2%rc4TI}% z);+>YH<5ym{%6gn7o9L88R>N<$IAtL3seFNS=w{~)_Zp6+=~7{Go{Immw}d9U@Q1K zqi3Z8!H9nLHY$)~JFr7L$JQfA5Ob*cOo7dV43FkzyyV4w!+hWYo_TqBc3p`=@PP<( zA}={ugZnC$(`SFjvK;xo@v32w^!~#IXMF$CJbCiuIV^ffW*w2qhqWn4!(1Zuo%rvAOl(Oc3VgPM+wm5yVbCKUW-2 z^Vd;c$7eY^S&EJvOkchBi+D8{1pE&*h8MzFuxG`bRyPnoTl0)GZzd%Lx|&;r$fZ#B1e*@1S8#AbDc^w=2@L<9c z$~IY3rM@-{Kv~Dgttjcs$kl<|2vXsx6)+~!nJ%hkvI;DDtG^c0J(1$DLgj+{T%;p( zA50WEIq4H0zTAGpR=L`ZuD~^(>py#57)Jp62nSZfdEFiAa#({{E5;ClLfA5lG4;0! zyf`$Wz)tL40Uvq-`P)SZ;m$l1nG96D4IzlFPdOsF6oP)4H#<@qk9gl zMo;}^9bFRy!@9D{3YAl+$MJ2o>fY27C-98CxVX6J5qXH+>&1yx0 zqK_c(^NjMzC0?Xw`MehWc&Ts^TpKC}G9sR;fdhfOukS}k?{#^Hp7AgG6VU|FyGn`= zVXK#eG-7wPSTC8u9Uk-Ncx)uoHxRJwy2b$w@9S{=x}M^%uC6XWecB=vpQmdkfLO=W zjAzg2=-}_I$tAZ0nTJ5zxJ`=x%!f$O5)#uhGfLW^9Yv4L-h*SH61v!jw;tixXVv>< zD^BvAKpq^Vu(eClehuL4{#9>hU#cG*7tG90e!P4WELO#GQzt@>gW8~bM(ye7aWHyU zd&@BJ(H&4Wp}|I6F&T)?qDfUzdzT6hP975v5|5sMKJf^Lir8)+n7R8`a!kVD&wbMSrx93Y^F|U*DWo`3fu;>uV)hSy?#hfn7OCX=%ti zmwfr?$cu0jznMB!x4B4(4)JCLu|UXy(fcioPfS?P9n4`swc#_0S&s-TO9^yNonoDA zJUWDZqZfnHuY5nk#L8obH)}gu@NRH8p5W_E7f7ur5PDbnm3+4ev&0Kv#2R!HcTmJn$JYa#eFG+k~Awf?l(M&~C`Z-PQ_! zryK(wjJR}C47R`;vS@KX3N67$mun%D9@A+Mputx4vBt^0k5^7{iYQ|;y?TFPso%@X z>;LI(@L^Z6--?|>I2?1t$@2wd3qgw2>g_v6qej5!`}N`8j+<)3`k=>W!9AniT#8sd|)!bZGXLBYv-7*=ymv;*dXTQeZPnD{%1Qh~zap?)8 zQ5bt6{v@_i+6`2t1unfSSnUSKG0zW9Us1r@^7&DJO6vMmIJv~H+Z0ef1_QFInqqzD zLc!hS+UbHy7R!4fV(|*GUkhJb*cIbv7+DM1yxk826`w`5M@Y7Ok_Ca9h@(h${NWyD+WEk#YWb6BV{0e%rcBAW-kq{ zP+BK&pRz>Xox0umSIDvjE5EsMks6#?4by#2IQg)mJ^?sB+m?ok+Gin}o1x$JckmCu z?H8CYw8u!o)klZEpEqSkU}`?f_)jK5JKS6RHl@3g9szS?EL%HMv5g>5^6R>fS%W!P zH1w&DFWI=l%kmelaeJMvpc(P1YQ#zFJm{UA3b1w@lLfV(RYQs{s)CSH=2+c#v^)Tb zt_B$dMjokfl`nhO;Das~cqWj_7@?6iVCuQ`3I?^Lupvo=J>&^~Tq|E(Ndu41`s;T_UuprD*l5)mrsuTqHI)n#78Yg! z*++kWC*tm*iEPGmQp||H5r|lsFlJ8Y3g~tC8|xzY(*;5s564+<>v{l#nR8;^>Z3*| zI4w?ClpJLO9u7upwM$ACAUNZ0NcE5j#k{0@oIa1Cc%M#j=GhR}Go^6o^X1*SM?GvX zus7yQQm0W1gRj@Jr<`iVp|#5P#)Z`Narj5p@7wLHWRLhD!mqm)7Ow-v0Y&++wZahi z`>yuwy2>l~ ze^6FClH37G^)@5nhb_kNa9P=vC#>-rsHI;b!#ZtrVTn2mV<$QK=;u3mel>|D@ku)9 zQDEcaj|b;oV{a`3z-h-($?nmaf>gafNrbR#e5#^8DLs3lLiz;94|McO;?@V3?A z1C3tUPj5vR8bH+ct$_dA+6+)JA!rWR$P$ICH8nXSYnCQpVVEH*O^2<)PN5H%6n38i zFed#7tmgm410nw76`s%@kQMkjbn{1a8Z@@(KYJlnaso0P_G7=f2K|71&U?dkFA5MH zDArBqAH}62aL(pWO~>~u1M64|RS`xT4!L~VSE4^>YXb{qSk^)0&^ow^zkgG|LOTIY zBlPkH2833KU;6v^erECm_z-+Ng!VQyIVjzoxBb0;s}fdaGz;KnN=8Pq zGcvNtC_8&zzx(_9-{CmCy`THJuj@R|*GVKTkt#%)0C!tQJsRfK*xR}fu`s)dCV1}0Rp|-l-Ls0T|lpr{mj|1&I z3M!A3r8x-MaGh%D`>g~$RrjkoNtA1#HDZa72xoc$?)?{2CnxH-0{?_mzaA8(*#O7Y z!@I2PQTAY#8F1;K`#&_e+lA@ePm@vy8~$Mtm%5&LsNp@R4fA?ugx~^|^5kN}DALe` z)$4iujf6+8#oSJvWPc|)hEVkx9oO|#5;!@;<8EFdB)J+0#xb4yA=s@BFo>9v^w{~0BAmg80>O@Dy z4tyjC9PCh*O*|$eZQ&Kg4-{+N0&3jAO)ch|@8Q#UOjr0R8hH(W$U1Cmadm+T?aqv+ zJtrCPj}Plz7qe1;hA4S+OY86*_`9>RC;9A%9PTWrq_#YsL!XI4oZ4esMpdBR;uR2R z9UO#LKYrZ#P{q&&bR~YRNwjW!pi3t+Kff%H29qzs%J|GB821{B`{hdqWz_?L!CXG7 z?a^lmgra`MYwQrU34w}S0++vjKL8RhR?f4}_XmNY?eo+lYWoO~pDv!KXc~8d+iJci z9NnV|P)2WoqU+)=P~S-_YK1F509NLY9NYfelLB1vmY0WXMfTu!(Q2w}r)wD`iJECE zba+>RuHN`b(n~#eXcVs|2wWC)1U1^V@J)j|S7Do>S>lZ^-~dO_L;N_9P>d0%auK%{(L(d8!O6fi5Epwuxanul#I9%c%`n-4$(BPBE} zh_nV!RY=3@To-`XoCJYuA{nkAIUzOunh5KFn^>9V$H|rs_!=Km{?A9I4s300H@3F! zT!#k(E~E)5DIG|dG5=pjcn|~yT?=4mV{^~+iFozO(mty)Fbh81@rgE{ub*gW(=}r& zi}BA!LxGyoxc~l42)v)qo^bhx@OHc&)|nX@%PvrL!qoHV{>nPE^G(!EwvFz>^H7?J z%IaD&V7cgOsAOTK2#Umi{`|Qpb_U!$J+0TqKfQ;tH#e`Y3dwgtXD16<=v1nJd}`=o zRcEXkkl{q@c_&{&B#djR%(&Y!IFKb@StZv0lZo#LU8-Qg@GU zeDB^tw~w%~Y|W8$KqR}Sv(|Fl09DX`kNnJqClK@i1EnL8~%n)Haq)&ftR{eXH!_=&dYF9Rs0I2TeXv4y&Z|KXOk z?VNiE#5gAEggAj)sI_WyB53Q>95q7yW8azb63V@OTo zL&@Eyrlx0a?u2w~-7{;SX`jj3qDN(0If-hn*meteFZVpzBy^dDHS6YV`(;xr)IDLn zSTX3~1Z47*iveR*4scP-LnCVMav0i!=MZ6uPd)+Wd^J8EFSi^xjaiE+RM(1tZg`y< zYcfm%fh|mvgHQ+Q@25RW0Y4LyVTe=rQ(r{sOTa%K8l5elCxW2A&VH7|W9ZyGmqKzx+A+)*=;!1;2K6rTJFY(TA?h{{wQHJF7PTLjfwi= z?ItLZBExb`rZvz*;epdQXmb(#Ng{OW?KnH3ny1xjUWqFg9A@r5lAwuM10Kx4v5yq% z2R~=t-JD$2JAjRpkvG3SqXR1vO$ANG{5S~3g}EIoX_5tC@9(qYHvZ%&1xuvaJ)OIL z5&ACRUzW$Nk%A`nP!aoyf=$+!Z{V72FZIDSerEBBICUjZPT+c-+9Kt88lRmt?99Z% zf(MotDn;6h4vnGpK*LHbJ|G@wwYsO`PvTp^zN0}&QH<>n?j2}vHQd^J0J}f!?^HO< z)5FDIRjv{{2aF&$rsVV2ZpjA5I(BS+y&E+G&tF=+YI8*wU~lbX(R4{z?bOv`ahuwd zjo2!v?Mx(`H}m!e@2ED%jwBu?V3KO>%}~JJL9B;9_J{)K325UtCMl|17KICV;^GT8 zL{uPGXa5E+wuUBfqD2w@7u~r)L3?{b?Zq*&1+14@+Utn^jZd>q*?8!#bx`UVdx0}O zVakjzU^tuZ2NKu|#e|nC$SRNrKscd~+VagRxZU>QvEoN*o=op}yF`sqa}WwC$gZFM zc@cum>n+$OZJ2?4#^6?&4?Q20I$x<#GGBcT2Dn*tMnxar!Whv~I9BSu3|eoqvo)_6 zxh}?Dy30q((RN%T1RKt{jZ|jnf?aT%ja+Jx0E6KmH(Eh6@(A$scC(n07W0G^lQt4b zzCsU>?vkmFnsb_fcg(w&ycb)iK(NHM>T1OI0bnzDcyWsdmHaY#KBOP^u(tqPg2fxd zF)sgr=;+~;H%0msG`7;wT#qF01UwJUsq}aI9pE01IcvyXdI&Ao6}RKgIJrVWW!xpk zvZz|Pc%}UyPLnbgQm?03y*|Fd2K=!vIW()J$Y9u5&hi!|pbCu0;qwwo1wMzCVHM-+g@8RCJBkyPa0mR$s#uNUKNeK0kpJPsySHxxWNzVI z5e$18iF;b{voR_PPbp3gdR?(lqCi_Tk=2YV;|Fr?z;D@*+1da}1(-W$Q=k7c!XN&s zHbwOYZvBQ3#um{}yBW&R;PQazoJ}4Am_7SGziV7_7W%GSZ^}HGm4IO4vbTzMGA+Q! z82&HZoe>8NNwLS={1qR26|BxBM!Is&dmSQDq7ixH)~7`616YRX zqMT96>D%cIXCg5UB;DzrWg@_Yoqq&WK7IaC!Bsus-Dzspp6j$UexMK_cL@#7J8Wah z`Shun-ea6#vIZ|!+(3@AEM$Su=R>AW_)^?hOQJDcQ5}73ggtr*EiSXeUycVd;a_n*-Db|>7;I6D&whKAY6e6B zv2?@51x;|d*r@JX<+30=D5n|!>>j%e@7G&ARz-%LV6xrjN6hc1bMU#6{;tDn?m773 z5oss*>sJl@GI%!C6t$lWrGFSRFIxJ%hpxmQ_n77#$@iWbg#=GqFxPbvm_&@w`n4S?yL#H@r+M&hJf8fN%oE^-W_6>fCgboccsbqjp2As_E z9L$50(e(P9hlW2almAQ}qlE^5=HAmI*sK7-ddtHMfnsB*?FyKfaB6rg?5}GTnHq^dF(?h zWgd`A!H;kcdqiYCTIvExPN7*VZ*NDTUL!+uYO=ISh{Um)@x(`U!o#^@H{W4D z?ga=ctz9KsN{^eJBE#Y69anO5ErMh{#`$x`Rcz~oq%n9aw33b_FwTt`)G-kJfFpuH zn$s3!wA>Xm3Rs@{fcX6skyCnUVbws2;o3U7RB%A#YHEV{lWU2v@Iw55mFkF)swKx-IO?DCGpK1Y^9WlqZ5k769DATVa1`{r{R(zM8J zQ-4kgs)M1rilQRb1#Y6hoDBuf z#s}#;==8zHhPo=x^J5(lI!NH8%}?Junxwf$o8c^_fx+E;Qry7ucw<<#B*Q8MNmGzP zVBU_sv{VGGlXP%R#yuIpTifa5;+Y!6ks7ANdgd9d(Zzy!NM4{n25R;qG3OJszRt0H zD44PMJ_gjKmKPH!vCGi(G$up|{|P_*&#UroNCGXyvxGX!{6C;h_P~aQgR4%bP{HV? z&3Lt_3@TK4FI6=7_rkwuvzbSdcNO4zk4Dmce@9wyuTI}RVwh3_!yH2X40w7EXp8=P zCQF>R2PG|~B?KYo1`&t5Y|8BN!c`axD-N}st64`b@4bMTpTn(iD{T4Z2(_{cI9M+h zvhg_bL&a3u_YC^(E!5pOB_(HcnE(i=20h&;KKY>IF#uQeCY3ap@$ehde^00d`-Z7o zol`zHr}m@U?oM*Fi7_A)0)C**gEOemOe7r3nyl}D`u4)iUDMeX2s=(pO{MFV1jLH$ z+18*#o$HnOOi^{Q)G$*s7NRDpa1}&f^n0yc`j!bPE=>Of`1s0zl{LXdi}lPGc=9Hp z<<8njFZ>r~e)o(G@fB3Q(Gb{5_go07n*W<)Bk|-09Ny)}#ErD!FlQ!I*8Adq8x*lz zy%P2;m=heFzq4WYUs1!q7V@X;L1?Q)g>g`fHrV5U#^TD=PdV{J5H9rAoZ@c%D(HBw zsJy^75@G!b6BatJJ_NZ*wDwouf2jqAhqc&-f$=JG!R#3lVdgtfYQP}%q_QR#w94Ft zBPMTP@TD&vi*7QSgHK#KHHkGH#jvW~!Ct5%AiC!UpVLEvpkh1yW z91fEPuwe#vQ^g3OgWFhjZ_Ig&3Zzt2+1N~%lhKxn$?ves!Wz`Y6CK}`+bjW7{puF? zl>gXX;+t%)z~!?SffECv$S@2g}eFmJ3=l6q10 z%-Y9WgQGYiUzQ8)g3zU#wepNJ{dF}ItT+9UK!nX+v{GMoCR&-1E zMWMeW$ZTv1bZ9d8!Z~*;?-oYwdXVhe%)drXjtjctruZy`z0DxZ`_zCeCLkByyome$ zV|VvH#2T_SZO6|ogKOAXv1biP>Xw0v_{bw{e;Hl>(^^r=0Aa-RscwY^-?G`7sH&zv7<# zrK~6dMU0r&|bs2u5E-Gz5* z^8(th8EPPiU`_$iC;egj$csM0ckUY42)#!cTiJK8C3eQ|x)=ZdG#$6i>haHb2 z9SvJP!qcfACB~AuJfPQ-a;uZ}WDgO#+?Z>2 zT+IGZh=V7wRwCj7?~8CGk8|0PG@YF+V9B@q0yTF2p;guU#0*A{JTijPbj0Dc)8u-a z)RhfTy`9nXV>lj7v@;{tLFLW%z=795=HYiM4U!|Yr`SAyN&ulVXDU36#>gR1XNNqn-vSrD?3J0fF`sFGZMGqtPt4cfpx3tl>7NNC0{P

    a(yMeYFFt9Uk@+T8>q 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�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� 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%0A^XZ;SW--Cr{F2S4fJH#dJTt)ga7 zD)`&cR%tBRBwNsnsSIP+Iu{YAXca?8%)hF<@7h|pRM|iJ&_B2VZ`0Z-?5FE)U~0;8 zG}_MA7%DMwm(=}_Z^PU%S<@kYh7th>so36b9lcCoCWQ{4%8fgRNdKv5gVxu{$jyB` zd)ha#0tq`apZPQXNr7&1YAvV4A}_?o1=<(yycNay!0#2p%v&$8apdKV^tO0qsH24@ zZ)49c(8jVm?0l&aj)>jdOKN+y`r$3b)*ML1BY~o4+BN?rJ^F_f>E~aomUqcxpVF&U zAB{h|K|%XYLSHzQq!N4Z0%= zx|d%PL>>-qhv)uOhhgH!sdgedAp!>3MW<$)6*zD~CR;pUGq4B-Ci#_Md`Z|4<4vyF zeiDBP?W*}K8Ha|u@TlXqpw%G1gKv+xojISW^&)7NU(q&ygBLxg&X?|5AQa(2GUkHx z1Lk$$&6q#sETtF>+xJ4}Li|tILxQ?KCndXq@DHdSQvOXFBm(n?`_yCQTjRl8aV7So zDrw4lKG`=#HknUdnBWzkHf;d65C@%9)9%!hK zy7w&cA@7FRiLmbPC&@{-aO;-hjT^^{3QoJQ;ohX zT%<_6dDGtAUHg&;T3%T%BO;8=VZQn-%9YDJ82h`;My@qKlEZ`i8Iy4)g+$ad(}zsG z6`KWR>R8*2@dZ_+$>Fi#)}L3{oS0kHnNn{?%!ZsbdzCdMOuUvAytr1@VNt0Y{XG14 zFR|<|8?hZP4M25L?Hxta@)f9zP%;-P?SG8Nm-Wi-kCJU5L;05bi(c&GbrerwGIFl=ZQfgvu(0}F#%#?)(OP-pP?Q1Z{-;)U z_+=D!D$G9{EqW}7<9HFb{g*Qs=NIWq^{ZqD@$sAe7pb)^Z*0AY+nhnD09@YNi?zSl zwnfR8Osq-Dg`v`@oTGZVzXhKKr+JTUscoa%`-sQaBSrV1F}<0e)%GI_uGy~#oI6|! z;50`xHJF!%k-D$IZDvnRF6gR0c~&x4W?-=0HgMm&<(Kd)iW%x27S#o1N$Y?~0I^Ju zBYdpN%xjWZ*jhSGBWEEZRhcDH9t^BIARc2B_lG%q5TCaK z)Om!s#8JN{xY1oa!hp?92HUf}ye!x#lp22;S5}7&&xlc#4li3Q{G8CMzQZev_qLPjx3>=mGqyE;3BZ)7q?Z@ z;yMbKxHGy7yWStSq_449W;T5{pj z3Iwx&npL_Cu?@f7>rI;Aa-xI(%f*0mvs~rSy_vFfw+s&0FU*y{K*6C8eZA@7rtUR) zsMrfA9gp9?j)vodG+~Ew^|0j&Z{LyqH{om%djgxX{Gj|fuY5Tx=p>vq1wW5@#1jHt zsV8in*-`1J)=b@7A9PV0l3l^K7o(b=z}xtd8aYFY1%6jM9M8~KG(n61f>@;L<=1FY zGUKy<_h$usHhP7%ZmhcyebMak$3p`1#6|3rTj(K!9Z*O9c}k*hL8i!6tRI=t+>>jT0{%AfC?;za4oof5hv*H!eptS?~Ob{j2NmrC*8SjLRJ zlhbm-NfIu4iWS`7!|@n$M}=<*XeP>{WjdNRc^Q6?+WyzIIXwx;2>f{3QEuRm@LC1$ z_ar-Mgbqt>2n_sNfcF_4zxAZghcVR4O7hp3)ke;NqZFSnIfmdAb)gem;0Zd+$;*;> z9S(=U=H#zd&YlEwJn0g&eq6G64qodsnCOaALQSniR5VG=3{-A$hD2-RK1wPh{$nMn z6YMzSKpoMJNn3o6*pc<>6jornx!Ht?a^N>ZnY!b<>%^G%exr6?bx<#A{PL6fY^v+Q z`QVen>VoSel=ek@-Tg@<36w@-di#t#%<*S%!K>*9-vC}12v{x{TM{WJ7<%ZXU+HZmdW##*gFLWu1$f3gu(yvfX;_vZv(` zcKBHMzL=_@BGTGy%keMs=-_j{adXyj`wxN)|3p0KIk9t9x}M;iQ=9##59|DmYFTcj zWCZ*ODQ~mwQNf>#p9*&h+F#>K9c`YrD^XA%2nzSOx+|6jz6@L>S6A0$d~5yp&%N;4 ze!>wPslZa_+t>)j%CBDwy|&!(D&}}vs3@WN6b^szLHxhYLGe+Qa?tD9jzQMBoyp*kO&=DpDKkZv~_}&y3zNgVX z1WIf_%?|VtYkOt4;SjqI3`7O%7JHJ2SH%JtdX&}m6z%VTiJnjE_!$)$Vxd@cJDcy> zZrBgx?cc>pe7kiWy6ayB=Y$YB%*;^hNbx?%rPusX44%qCN$AIaWYNW&c)PPdc1P9} zQ8adWUF)wx;3C7n?YeNgto0da;{_a5R1&Aq6df`;|L~|7rf)tTREk)z!wKH}mlU=K z%)k^gX5}tPeG7ZeS!5o}Ga+8HGzO&znJ zB_G5j3UU~L{0Dp7w|fM9H6ls%+Qp2MztJ7Cy=iKdvj{ehTVK*bC`DjnKPgEzM3s-s zT-8(amNu$jSE{DeUeM~pVe%94Ja-8OY-I8N>>E~YG`L>xd1}W^zX}A=kfx`n?Oe)T zUcLEt$sxeukT{K+~Yind+$C3ut}Ebp4YKOphJzwDT+N0 z@pTuy|Dk*1O}Hzd$>(wc#-Og5@Twf#UV+H=N{d(U&p7<;G)vqt$5M3z7OFFd^VG8l?3d-_ll$%rl05|OB#*PcRerIT8= zVE<%0c4(Wc8n8%^5;>ms1a_s5?w8L6Yazy#k+QQ`%@vbuV%r&DfB`3z zIOKjVD+bdh=fMWaLpRJ;6Zdm!_SbuFJPz+`$-+*`VgTu#amm9=i2eS zB2CSTiDA*+16ypSn5LJX06r zdi(KxBYwRCZ$g-zKgJ=*`fHnY*p-dybnZ$KuA8{tp(c@&gIrxh<6~ZZJ?e{bQ$fLl z2oGFZ<@hzXybH2(;-;qMo--JDXPlW4`il`seP4g}FMc6_yIbkqo!Ns2VKrAW7#>G| z1bh2){O#YwoJO)%3cGXg>ThJv8+ULyzU3hdyFRj$Tg63~4`~rM94)0pxl8DUyX#K9 z$fUiv%C!A99a?wW>;(r2?nQCVX(#$|1vdP?NbRb!Yp(2}cMq`!@O%3nuY)NZha z_5OwhRS6y0Tlwa$sYDh3oHr~q{9_wq(!rJ@4wooM-u=aF!i zFiE}O{p9H_G;wk9ES$ZW3K2=|_f15AaXYNyBaCh z?yi8#)+^h#P`ROT3KDYZ*mv9AUnS5u`L>!FzVFSDL_0r!?b1DAyu2YRBko2MOL$!M zml|UC3PCx7R>4Q@L=Az|8}kV{Jj?vPRsV&0pvbA9;AJa`i+4uMZJ)SKPZd9=>j@>DVUoSdJ_um>9TOF6V8E7%oG2ydJ$NcvHk#rvJSib)of2=5F zN1^P!DEz8-1l{z<8{u{ zW$_te_(94zlA%$q=rdG03;#@}dzcJ(7|G9Pw=QOYuMzd5CmlFNAd1~g=6GpJ(I?M) zbg%wm9Zu;nt_DHvLbEa|nWtxDoWF3v{TIZ<#f@@_h3bQld7!XmprIWM2pkwmvpX-t zxkAIH>ve-NkWeBPWF=(A2|+AfQ}K)AY#_4v?09-!Qww-=h&JXmp0`8!6^&54L<=3T z7dB2+T)RmPJBP&IRX$`DLp58i7gGZZSCcqfIRLFZda~RcFN1yZaF9iP%LRJP3aYY<9C*1eoPz zSVp5u?;|3%;k7F1x%Kt+>mbn5Br6>!UI#+C8O6onAJO2J3C{@K7Re;k%G~w7vai++ zNggND2U|l4@T&Dae{cdHAsp;ZukH8AYeIunP=WV1EK%4pRBG<$DI|xH^x{Sw_|^-P zwYz^89_J~-{O6EMYuP7ZkQF0M;j(mb8fyA}=JOLh>V$8eGkMnb#djdezf|f^LdrA( zSu@$#mkCgVXc)_{EvGgvs3`WpNg4Pu1tOt^Jr4zBbf84vz)U1;pBY4Zd~nqcLV_4yBlOl@VF`ZuD6ImCcK$^s^FaKS_qaN zwzf{~Luf#8)uM2_uVev&KId*eIZ+;mt=( z6z13tV?i)Qwxiqohu?t|Yqq`n_1fX-CcB1`7vV&MCcHEcZE^45{sFhwjbeiYIxNsR zlk$DP9`RksZWwvzb`&52c6Z)?s>7CI0MYU>rb<&IFxw=CouVbk&kFi^+dCiqvL|Mme#H!N>$t*Bh?~TMV&@Ejg6J-$;u0m zB~KQ9we+DCU=dQ%GFOURg#dBse-k`LK`?&7;0CW2oi+3?ZXIo}G+hLv@e7ZgQ&g7V z6adE%-iB*Zp~j zw9`9wEN?{*pvE5?FY!=!HI8D1)aA7>YSB;ScaFhHJ9lPI?Lr1{H8Pf4w>a z0dP3ut)f>8)Z&T4tNL7l@M%OV%;xE)98{X0^nPeddI|@ROgxQgTkpcoe(?McX=GRj z9(+9|yiWZLrRK-oZcOP2fK3?B)jiw$lQ5E-;W6s=0|UmruZ2fxJKCWYj|<0S9nTWP zuPfb`r=WC)?}xumB`#hQg0Pw+wl2&1HZ=LJsG^g9z8;ZJA8cIN>B|8 zI*tK+vrk_z!CVYsyPf$j0_c>e(H7aH7KE$bx~tqz`w~Dfj#lJusO}gP_XRJ0F29-p z<$Jb)U(ci;fQ+%f2-gemKCtoLWr>odsfK6^gYG7`_*zJk`syO`tjPtixb|G;Sfuhn zNxbjODHvreX(f`?-jZ~ALb$c;!7m0xwb&~YzA7iTb_y21!=7bxqnB0e%t>X*6(0_u zUYq2owtJrsU#0dpoM*dI0I%@IXh_4zRajRYFP*mU(uel;{Ayt}y36qXyn>ZTt-?F- z+O+%eLH=10WOS32&CLDVg~|0o*QqyKl&A_89JEtvGy&N>mIC%41C`-{sl0=dCmTvU zTRk1?Nq)r#CI&D2JNwK8A))gNyU4+68(`J5W2Jrk=m&#?gLV4m=A58Y{NX&7R6snW zzEg1M#3G^vVfsI3#$6?wpoGyd$4sVT!(d!FYA0<8fv1Qy>&+as=kV9%^_8;Yi#u?g zm3#drRlz?PKc?gTIfv@vhFu9fyo@&#f&E{_*l6A*QwUQfs1Xdt3_?KnF;lL!;k>g4|IAYD_$1R@zf!Lb8iVzU=nPW)DpX9LsprFH2S#Rf1S zvBsp!of-@YiFnFqgZLZpx>F=uG`O)2B5O2A{13Bh;4fWzi}X;4C~!CU&oAB_MNz8( zwcTr$KPG@TiPtdPQqvTEGF~H!<2DY3Msd>f_xy!_!;S5=8Y8?BO2}#EPOu5oHUm=g zEyqc}umw=C%X}cbPGt@Rl9g}ER#|CbqKW2iLp%2{{FL$fA>+I?4$bqbqQVqhVlYQn z?~f_%3Wn-PR--EKo^22}t?|r=`ThvXb!|3%H#V1mdy+y?-cOPhc5jLNn)maOg>w}; zZ#&sBs3j7MM z@jN=zb}lITzNHaD9cGH_1^s4N8Zi zO|~vQ{|WpMQS^RQ3C@s9Zd;;SE8ifsqA+1Q6-Rmz2|(B21*2 z^;ozU3f<{*8kgO;Z+r;nL`ks*k6sgiuX6kSYC2uS9`Q-;l!%RTg%qWnIe9L;MmP%n z=SlHa!2q`Z60-@2yhVAuN8Hn;`1(;0W;yB==OroxrA}*%l-!ro;cKNf_td=f69`g@ zuQ{%LKmmRQByS~-CS+j0u6k}GN_qkIac7l4GV-J9{*(x?t+! z&!o_{{0n;W{3%GWN(o_4I-z<=k|Y~+$eQ=#6D)7Q0aMjuH{z+=fZKQXj8Rho31RY2 z7j+aHa)EE~n`7h~Ng4=rdt{20_VzDG>Hp1f=ET+oChymuKkF5kfVyS|J9c$x2Aped za4@WO3_A1h8=3a=JE;n5BD9aXqDWM);|T43nVHN;X@dWxrU7yc+5k-M>3Yv}*o0s< zaKrtt85#%B-;X2kWfVh$WG|ZZ2$F9?Pl5O?4N+PKkojw4-)?h>4pziaC7gEv_)Q|}!A-9p|0GS`Vl+Jnso;jE@`m;CrgCfI&4 z$4XVxYlrD} z-E{Ol=){Hx_)*WOf!5s_3F(S&p1|8mZqa* zzd=bj`LJ?nGpd6ISk+__em2aCfzR31PwfUNR^V^1fqJ=u7b+DzTd`lC)Orb_w=+_U zak?+VfoSHn*N;UJ;fZ zoGv1`WwM+)oi&gKexB1lHww71p)2U1S<#D#2`H^vc|Kx)j0eXZGHl;UntrgjIQsHM zAR?(>D!f5>emoyB^tyKkKZicdf_nx$VU%COiQrsgG&Ys#J_@)JVyN=(g&aVeQ4|9a zgWfH0ylkT38PW0@ZB6~~t6;?7g0<=R;s!hQEBI3zLDf};lL#VLeBRU4poe5*;e(mB zAXK3eDP7^0xW6w0ncG>V+W~m!r>NFVyEK%8L9{~$7n5rB6_UzUti^qMFT;7-nc9f^ zubbd`Ai;<;*|STa7k+HF@3Pp8l6n1Ybf({lfa%t>TP)u(5j<;4^VuFodRjNh5bxtg zYXeAcq$k5~Atr=f^31B0p9Wp9yX3!nUdCP){z`TF2~HQ@0B5EG*=HLCJ7~BB+ZXNE zR)Nioyj@^)R~|U5e4y~np~65y&wAWR2YxQpPz|~ZeJEasIc%v6lA0J5kXG$|8%H*m z2C;9R3VZWTh`|Df)oM5fT~nVW;k$o7Djx;LPwsG*ivwOYby z#@r(*IjF`OLb_oH;pW-&+4QG^&eG zX(scJfkkj}3`^sCYZx6%VdiX)E`k^8^q7B%WoD2i`g6lb=TRVVEg!|WUPpWz-a4Lf zJd6UWH#d}4knt?u0Cl6!6SSv%$58HGLY{*o_YU^`HF>AKAAE#2z3Jy(UG7+gUSU1@ z{W{%d$ZJjao!lWnNR~Vv)n^^tQ^2J8G@q}DdK#LlgQ<8hleOSf5cTRf6I%*II#;~f zW{wg2K}f%UaP)x`RF8Qcoh&JzgNs+1eeY}Oy#T6hTP!IKk}Kd$kerusbyNY?XIz9s zWZl(30D!UjpB5}&91|Si~&CN|*2Ll@Qer(EEB*#$oe7@dF z!nhF*KS+2T4VqSf;QQ{Db?xJDU_iwJ^(Mm*u&5;Ddb?3)2$*WGu-d|?T=3bWl32Tm z#F_EpOe#5}A`y5?EJ?obH$Dvf2!aH+ln_HArL)ED^nOgRDXYic{)%FJ6iE$D@+n}FqGP8_!ku# z5Dcn-=Zmzl7`#6A<}4j<(SljctBvSuegbbB=e>Py+KRw_{DvH63+b9=2HFp+N8X`i zqx$8q*&oY)f@Wco1^*-3T^Pg9&_3*G*MYhVrZ(i5;$g)2)pqi;M0gZuH`*7)!kfJ? zaBlllcL>1_^e71GA1Tc~1J$<;$HZ^<0774`^$ADwrGv!2+0CK>+3?k)k6xqpI-sj3W6^*M(1eniO)5REL2pnvsU3AC+n5-se5ND;pJ z@|>WsSTOvnw_oMF&?N?ma&E>{#LL;B^hb04JR#XJ;LC-~^qW&_0}oz7SCA5O3FHS+ zvLvKcB*EXoa*AO|;kWQhOha4I{KGFeW9+|5ab4XVo?TYWC-A?c1mDPmG@ag(EQ18UPL_PB5 zKYRK{{xona_Qm~4_I@8|OrI)Nv9~XPmm-FD{d)Ro;X-f1MC+K19b{F+MAGhft3h6F z0#CSwf+lcK>yFsJU#kNDjU~6|rW6`rXecfJ)9q(4oFq@^$P!fDfG3nSZ}!qB4Pjz! z`KNM{MIo%D_q@NnK&Sxex>qHuJ{;{r(Jjt6gW7&8FmYqporCg5>m*COO z&QG(pj4O!kE9|mFwju{KpB!Qz<&nEVA?Jjgqm(tWb(aKrzWAZQhntjCB*`v2P1|**bAwElx)R3WCE>}WYp)!jIV0i!-KfX zn&0gY8Q?JcN(J^G7ewhRp?gWHFY{>evwvRRcEs)jX~r-|>RLz zPx@(wA_(O1GO3SMRl`Gy==E9~tPx1$;54t*p__$%p5n)rndwR(%Q0!vNMh0tBU%Xs zlf6dK&=C8^!Er7Ut>jRK4`*?$n1NY6y}es4i2xJ}-Zz+ZJ4pnC2KuD7)o_0B9J;e3 zgR_(mWe#1W`g+<-pn9pupxQGf29_NR8r{R)O~BL7^oiO-(Qt@P+PZ-)HR=O-ews_Q z4k75@{ZfCkiDgw0wMlLdj`PY0Lg#hLmltV9oe-lCr`mNRg&nppC}Q|@FcCn!sM*kJ=hH>o1GxeFN+m`3dBRts=AA535ypS=q9`Tb6M zubQZUVMr=}<#u)h9GjkP?;M!v0-o0KDn*44FC5GbM^l=wCBTC(T{nM^{xg6=&sym$ z3_Tru8(3xF>3nZ+5J?;HmC`ka_Sb*#g{9tD?RG#t3=ST`MP*9~e@GjN+5`BQ-T-KvNHizr)Q8rs}ThWP-L!ad3&O_R)U4n;E56}G>SxR?Lh#{8{iE*T7KE?NAq98&no~v8xCrh?GOeW}guN3^i#Dqm#`&7F| zzNmwdS;B~5aR}L&B7n`OkI99C zf+)4ujtTBFJorh;$xS4O6JT-3mHfeUC38!Wnk4Ta%NHNlrMqoGZ zg4@&XpyoBd0+d*I^6r?sX`t$lgmQysJuMUCNBHPB{%9!Ylwl^3jFR1uhcPV&80qnR zV|S%c2Rldy#|7bKfcoIRH{FughqJF_zv5|s6{F9?jAKCPk?8YEuzBsUx$WI#1M%V> zx53ED3i|YI8nQU=>;dh5s2~W79uRlR&`S2k;932}IU%aIQFL`^JSned4L77R+ zZQI`+a*(eqE4;q6_6}b5ItS3`ATr54E798$EFpg&rog}&0oU_jqoHk`jGFH;EE#A^ zyfmGd24xOTM#-FnUC^-(e6qa4(F;X$e~R#Fnx|m-Xvtl`nL!mLPaO7SqDu21>ERgL znckq>OgIDSFS}dxs6!;Ny(pXMGD(Gyh=0S6nVZy4|4=ahRU`U~STwWq?IHR1PB&np z>O3J~ooEY`ka`W%@nR@ouEqq<7=~gIl|a(;+XXI^8g3n{IUc2#r;5(Qd*A30u!Ae8i{5<&2kxsqckl3uLWlE# zYT`e~^joK|o0$r_{jT$2&?Ct`+VFH$2V61;uXACL#O?5f<&8tpOI_66eD)ts?H)=eC5`_k=%@@;p|C$%PEN(R%;$FhlhGn?3nt6mSNW zPIS!&y@soT)*>-}HH=`ChPM?K6)y~D9vz|jAr@$!$of1M{j?FfTy}&SO_rAE!5W`s zja|wK0lF=CO8Wjr$qeI;3#xyKYV1MQ=KU2POwvFF^Q6*9aBF3L|npcWd#*XhMNk6HNI zm**cre9UErtJ!G-)VPZnb8FXZfB@_1S6tT61Ze(zb>`1AC<12GG)tyNrRZzz|Jb&- z!&#tWJW+79QaBFc96ak-Cx|xTX-*c01?yK?nE4Uc9x_}$1v|GI!}r%`9DrovyB&q# zlX;+g<7zV%Fg6EFqsJx$(zDsXS(_%vhUqkhO5NXTh%I{+svZTOuN-=w4_2%zgkOZs zDLsVaZxVV^l#BlV4szsID7~3PlBccY4$+@#{Ij&~ zM}peydAj)v=4iT_hyEm2=w37wH548>W0CGdjv}`YsrUk#yUXon{wm@d3JD6T)cIZE z!H8(d8WP-rzYhg{%!64ty9y9CBqirfn}e>YH%D&HJx9&e&Igf~=R!hs;L25&isVh? zBH3AcC-s#uu)&x28O{frRrWBjv3^bXTA~X07r4T&^Yu*Nkh_*Y?rA~^A9uPlsa&qt zfxoMZfb$c3r{90ovOT(vau0k%DSdpS;4;suby} zz(_l^!SyG3J$Mn`=}@?r+XO$(Qjj*SAA(YQcZ#P-IWRyzu8Fap>0X4cc{!t#rNW;e zqUKt`m-z4w*t^#et$i&NhK*0rMT}lgham^eT33$RB*Rtf9TS5*iC!T69`-e zMtke(K${3C#~+UAgx>D}!zQ|t%nQ#cp?TNoWbqdn7U21%uwj^u>cH_vtHiah)mOnG z?xrcx8Zkb+PbBT~-q@%H)(=C2_7^Hr!KXF6O+JD81`r4@-m~8eaRZXmYW%a8KM<0t zc{q;E%1amSxhwL|k^cSw;=eK_KjY~$L6%-6_u+S0OZaq$kfnkmOBTr8ITKFY@ydZB z+@kn-^8S68e?a7sQ^b7{2>oh8n(G^v;QqfDyW#JFLC|y@Xp<9&UVJZcjoElRx>(?K zkHbCM#{%g7EpfGIbPCI$jN7``!p@v|oY?O(#oy+GyPSLlYehR;dLc zSS-IRpK`^a2JfqoyflXQX!wNjq3y=P}>1RNdHL1mI%a}K8{_+UO8!?vl1#NU8nZqw=DyKV535bNoo{fj-=>h-TU7LL{c z=_vC_4{RxI(3W)u!=Tcz4`ck4wTdpj+m8EdqYEl*~DpF?lh23 zoJsZYKK6k$#nc-oJiLOiG;ciJI76fiYRm{nL({PX$s1dG)nwYbAa{T9Ja_2C42Uwy z>{_+9U4Y20z8qXwu!A2@tO&n19n?b0;qIY-Kx_d_*G_9Hzm!Mr+0UgmH~oq+$g=RO z^N9$&2&L9lKVu^5A3-r9d`x-bqvDg7T7>gX0y`Xxs4TWz`V|a;fvS|0w9}0cTl%Nq zR*pA>6eu;fd$PTSeB;0E!7kT$fYGr&kKsJ=0^Cg!S;%#tafK?p zlpt+l;Q-iM>`eaRY&rpD!`Dd{Ih}PNXV$ChqVdl-Ad;ojA?&P*Lh$f$M(^^|GSKj9 zjBbeWTZDW|GOmO8XTlI)8CEsZf+YkiINXrWhjR{8O-0W>6$ymO(&=317T&`4p2Exxn>ul5>}Iec#jJKf9Gw_@ zo1xcNP?L`|9AmcZhIXGOacR!4y%1C?_+s~kS0!ADx4l!o+wdEhF^eGwTnnXebMQsG zyNBi~jN|(5rN^xwK?U_MeUC`Jj}SVghcTlm$by=?m|wR0bUc9hk(Jc^;}1Vr4=oW- zMr|UeFInylKCW*q7%)y+jxucXgVSX1xb*kuxFA)9#~`BTlkCH`_Gg?0SYFXX3JX3O zIhfsoEp;=qU&OaQ36T32AD}d8?P8#DG*qbm>Qnw}Uyv++P8kfn} zEm3lLAD+@N2z*APyz8##vC?h@gRu<7pl)9OBWM+G6Z-76-`ZrH+OOvJ!K`!;#1Y0F z!yh&Tr=8`t(Ud4^_DDDNUPd8r1YDvEYa8U!Uxa6=M)69Rz)tYqU`Dw=k5CvI@0S1y zB`r`d_vt44aqBM(>NmXIOFWo^B+`LyRpq!zun|*sB$^|QM`%V&SIfY2EGRcMORsoB zn*kD$0#VL$I)fnlI7{4N+BFuoK34{tIsGK z6f{p)ll6Q;SW8R#bwl3Zj9}RL`tDlm&mnB6X!QD*4agea+@+}5=*HcGAq6ef5T~Ah z;6Rx%mm;HW3>SD;X9Qk!$b(%WFU_!e&J56rDqs*upAe3W@ppe3;@o$($(v>G`mIIPK>m4%zz3Aj2aKiTVrZ^I1~l061gPhP48jQ=7v=-$%ZmTd zmC3RnC-8wy{~bA|Fn$k0h_6&Um_um_m7-T&b$r-q5Gp%jWi}8$0N>h=c3GS>ov5WRBw zp{@}JPJ!pQ-Yo@^fy~SUTnF=WIqaH6S7y+&nk+v!aJn2)^yK^7 zD3WSHA15teTpfad5u+p{T>l-N=Q`VtGepqjm}e5kHgK%z2=KK=I8JUXY{L%wGm9Jo z-*s@c6teiFhN{oZAs<4)y;j{lk-2a>Y&vRearaCy}Z20sN%OW#s8fS^`7f_8JEX_q%Yu zyTzK8Qt&Yh7u|2|8jk%8vc$vQqVHcS!-(;>X8|L6`Nyjbk+V($@}8$ahokpw+msjJ@u9V=V2v5`AqZ}rCmdQbS$hPOeENQOjaIhdP>lnlx5Qiv zx@k?%ME^rsY0pVuNj){Bg|=*M2U)+SQz&#bq`-0s)ZM_T!HjLiKnPuR>aKN1I6)WS3kNm*-fLvS;XVwG? zkGdRse#)bOJmXysjM(Ai6S)50A5K>DJatGq`Xx67?mLJX$w~rZ?+&mL5a#YhXV5mWPeqzP_p`n!PW19pVY#iA*wi@ z@AyqK9|4G{aNhZFi=7DaiC5`}+qpB~i7dwPF2>9d&YQ8TwKyOLX4!f&#HA2b*Jj>5 zk4Yi#&VsPy^=ciQGzpjq4uZq07G4m%={0T8KNba|dUw39$CO=$P zrBcC#nkp$dp>95xz_;U%*^tb`0Av=i-79)og5W}$7_tYi)UJVEN}{gV{m<#(wV*sK z8HUk-#NgdIuXS-+gf@zOOlrPk05^RZdbtBR$YGBbSE8)0X&w&l@^o2Pxz+Emg$FBR&ql@wCk1kOgbxKIz0K6|1RlY?`}{N=PMpx^79y{CO&pNsUyk`MkK>B z4c6iL%CAB}81g2l(1VZ&H?*j$?U!Q6WeG-f? z<3E0J2>~a6y*Gl73%X?p#lC1kDR)#0Oc;uGJI~l`ST$&Ey59L`3I*tjxEZGU{6VC( zX`${}2BP2b@28daELa1sl(I2pqx^UHecU}*Ibg~ICdm%if>}etV6ETwuhDA10B9bO zvL1~EY=VCKkCxP%W_^H#t$9qQ40nK3SnL5{%(C<8{U6^1iDmVs zwO)gAAn6$&&`D%u1m42F(s%2Yt#BHZ8QGR$7K&&L&oUZKKQ}|!R@F@b@^)t!NY=u| za3M{8M^u7_)s`w1RCV;j%Cb;qTHdocRg$*z91IonFMa0dm4m*3l7R4M;mhFJadIj; z{9jr20_Miw|5j~-BM8XVqh~2nq=4hK^&inut90mseowrwD2o|f-$v*$J*pN2p-7sI zw{@}az&5l!-$z;eGSuw+tEpQkwgm6FbaQWk_LtDj%(m>jN;m^A*N;4nPCd8b!8LNl zgk0Yl$bXP!!?{>k1-Yw+IqMTDR^WE~ytFCD`XtyF7k~IWnpO!8HTZV73qH7mi9P){ zQnI@zu)SJ(*YSF;1#q(tiGB#pr-c5XeTT56JX~<}^zL~Vaghb=)BSp0J(n4W8R9^d z%v^a{(4b%@o#X2#g-9vyHv}FfR8Wa`I87sYC*VKR&U#00vJJ|vGmbMdvxK3eT)G@P zoc4pAm)mvIySOg^>pe3SrB>VrP*k#)_F(sB0X@>P%%z7KGw|*FZX|QPm^eHb`Ms1Z z_1g=`)8zA&KPg@W<#gSkbdpp-&|Z$ZLZ={O4cEuc&wFQ6YQofS?_sJy4@bBYxHx~u zPI3amUt007PTvfL^+!uKe(F}FaDF~vO3drLDsX2?JM|lVQHNmXa*ruR@@f$CbjnrR zMs;GFch1*wv$P7}PU9Q-`*V^#plaYF+A;0zhgJ$$$v4*CPC(w%`5V1vg&e@h!6{Yo z&c+dL4V?{TzKFdKE_7@IbL;D&P+NPaudk2K(MN_^r+qO$E>auTn*DOfF#ZI9Jcp5~ z*7qZ)d^e=TDEv$rQ4TBwGr)=`B>{tm0r*GX4UGY3sa=j@Q9BqagZWaq(9SX(9?br( zVYZ6h8ofuP_$K17Bhfy;?Hz#*rmIZ`S+=Xep7IF7(F8}wdX}a z^n{>K2JQWj;YV>>a%k`XHayGNlTN8y;h)B+$jfBBA&6F&943BOh#+LTpMT#;X{!NK z{`HC@F|kSroh$h=Ou9P^cKK4-9%4AUutZYAjy<4)0h0R|ngnOpQcvfIPo%+;$wls)>+fY? znhNh-3aU$5~5Fo#owLt?&M<(P-%JVLYlOo3S1^lQKOxvRYm4*}NyxQ^es*6L!E?HaabSDOY$*;+l=Q z(&V6#VrZ`+W~U9y&0JiV(YgSzzpbuUr2b+Hdc2Z?yD~X{LU4D~LDUc1Akb)VIqWN$ zSw!b2SNzumCW3H$u8#%l*Ckg}89p81``5Yxt)uJuipB5*mc7ncn@-w&V0(I0kXD#} z9PS}Hw@u?A3ltD5XxXt`4uQQ+e#0FBL~A)zjS5a}GH+qD?%*nElr{qf_ z=zYxPI-1~S2hD0KsuOs=*}$%{LcG!-Gy~69c}brQMz+C|u#9yr;M#)5Q&z4?>S|{o zw0<(s;`mP=PBvYd7LK=?z_i)->|`EQvbSyE%)$F`8l;vtotx3*FSwKE2sr&pyaS6?*!+|N-mD*QEy~R!ypKrYhMKXd34Bos zV9sYGHimjrA+>v926f;b|L=98$RatYjV;MKUpnyzlNUoDTvz{8LN;3%m5r^a21FSa z3%4J>RRYHSP~#ZH$AG&AK}g6Vp92q}@{x`Z6pU~g<`(K?`$)nM zanY}3K)_{Fo;FOC3^r^T7O9FlV?gR+Jw@L;FABqNCYSrO?nFZJ=U+`+PmnFEzI37I z^%Di$vpjk>%97o-`Of1fb=mJ%I_(v&AMlAVYou@65;=kbh9GQ!xoHQ8t|}2W?-!YZ z3l<3n=0FbJKL15Zo-O9o!;U;%rGMb%BS@_3nm|?P6BtO{aVQ&?Tn3HvBl=wD1rnj3 zjB3Zt<3ck~-^924>NrM&ke#O-m$6NoB9@YN&TR5bgSY1%vhWm1T@cTPu#O|lmOFp zo91ia>o+i2t)X1~Tb2@N?=k-D3^lQU`dn>}OUarTxZtJR)SKk>5lpNaN0ar@-_!oh zn$VlqGpIv{!nmIAoJ;@njTKh3pX{Q&m|2ta7%E=mw3n8Wh>D5=>e#yr;y^*df^)o=L~h^hV#bDQ#Mf<`oDa9R69l5R&_18{u4^^n~ADOyz|%DEpy7PtYG zCWTX5Ur8O{TBXO5CW%=KEGO5Ynz+~#RBbK0+E+qZGoyJwDXfTN&?z6*<#DBM4jo^F zQ7gAsxl4B40y*LND>+wh2C`xCD3;vzzA zfBuY0!>+(0JoxR~tE3YUPwh@^)1K$tbozc|pVmq8#3lqV!bV&D9QSddG+%(SS2es1 zxVZkhJdRKbN7GF-TaCMHXCP)xt0l47x(U_2KbA+!7dJq1XMe(GcV`>ojg}-s+Q{`G z?q5z-yNAyr6db-y>bX-w4J;#0bZjyUc?gl!!XVB@76R=TPW7}Jr{_UocPVkQ=2}18 z5g4xX@eU9G*s%y{U8O4^YDtH4NZ-~NkM&}ct9`}(My4vsN4YP8B}6~OJk z5fE;Bs}k}r`Mu?@>@$FVwRaa+>+;cM!uftM#@*};f+W4RMefRxLi1|kNX_U2Ie0mL z)icS2v>8Tv5~Hb(+X$eZ8%s*!tKp1KKu!I@pK0Yck!KM&jsZ9&*%*36bi4lK=4&*B zexxHGa@+Un<1NXJi*oF zV2DD1V==Wi2Q~%xv0h*y}pR8 z&Ms~Kw+lKUI50jwPAg*XzW|-@dNCSvR`~4Gm?8WySw|Q;xprXs-j5Osu zwmR@({zd5cM72RrBC}4F9JUy6;z^OBHbXT?YinQL+uO5m@{qas;U~@uevT%L;)>w~ zsS?&uz(MV^GEDkc2v{5zzer6(gLWFQV|X8P;x+l2-dKx$ZG^sbSbojlFJQtqL1J-u zivHvLISA6OQY@~S;z9mVcDB5lK?)enlaZ4%p}SU2vubgA!=r*3vp?QF$7PW;A~48+ z>5_|J(+5mXcX!LzuPQSaFyD;dKeHb|`6U#(SBui}fUtj`ERwW?Fd&pC>~j1Oy}(2n zG02j3j5-zKl)7f!V3*FmWfgPq=#InBc_}c(lA4~_oS8WI@4R05SIu6mxB4o_1)#7FEnWk+iP9G+-nwu>nY^;DV>=Q zApFoVN;4?2Z9`Se?w;_yh@6EGbPdQ%Wz>ui<;MYRNhM5ft&AfKWjT}1a%S~S36V-A zB}w+uJ4QhOTYOr#7fZ)}5zD}9H<>5*ux4jOR8E#6BBNfSt=I)N^{D%9@sRr^#6`~c z8!J-y;^MS4AD+Q$?b%o@+){tg9cf*^=}6xQpLSc>uAxm~ptTSGSlYN20GbvK1QU&h zVPNsZ;+^hL3^Mt@t6op(lvUdb=h%AlSuVPG7dAF-vB zakB0&1NW69p4wqQTsRlpH*!fG*(xWR_B&Gr0n1Q$4L7DF~C|lK*yA=4Z%} z#h@f#9Wm(D7!ITobbA~yZ@vF4BejLfEFt8WM|mZ|CNLA)l;Qo0`wa+gxK`ZyrlEt> zy(uns%%}*EktM3BovLa={uW}9ZpW7R1auK#e&gIr5CA`XQderMr`bS)p*3i@$597T zw$3*hdSbqVjP!+I+L@)O6;7FQ9=FNFbkt*7d*n06*G{g={HaK7H zV4-}X*ejd@wp}zGak6slh0QK=1sK#A;t9XJxCG_I6VoHYdiTIVnNV;iJM;|7|4d8% zLcBv@)KA@N*ib`nf~*a@S4NuMP)Ny>7hU4A zueo&0D&WkRERuFY36+(V7Xqq+#$o(XPjByiZ(BftW<@0>#v5>h43%gmCnuq_qQYct zxJU&O1r1p+%&{rJ#$O(k7An63HcW?tRC-M&;6hA}`SI%@3MI^Sn$9jY9fE4-J}Vq< z(E-0r)jLJ3KqELf_&y{`(L4sB2KMiYpZ{$H+*N9W2`$Vjuq#zO{W9P^0FqRX$djpq zcj2L6cBoKu)h{@d_;*L0Itv5a^QAFSPC*q%pXJJDpHg5r(<@@VZDkC$S^L&2KpKx>E*Y&>M=bYEE@$&Cm4K zAp10#!OtS|O$0rD{P=$NW$oF25eW^vvQ85PA=u*eGK!gVQXO=mFlhQ1l6Z&g%(F`opbmTJH z`vnMWaysdEzI_46{+f>+vwLBMy#^Dj+P{y9gY-F3YxRTVCWc>0k4#8I0@9u%`fG#* z1&UTl*Z9Z=PvY9PRQO{7>LL`CJms)UJU`{hXT-KLJh_ANEurKlj~T0l@@}m;ejPqL zCrjKeCykzL+a2EyBXpDo@237;hmk!nE`KkmMwU<*c3QCne7gvn&vz~3H+xFK{B}sJ zQT$^TBy?|meo(b34a9n4zli2K);#A52P&`WmDJ8*Iyi~ma16@&My!+kl| zNlf_4NS2cAcz$nno#05z^}7$c{OV zv46iN@hNk2bN}C7N>5Lp(ebPq`Sf~64weii;AUI==;4kd>WI{}3oTxkWorJ3}KL^F6OH=civ?J8d+Eue{SK@H{aNV=MPw zovUvB_`YDdIq7Hj3X-%WM!%W)Feq`qULp@)o4{Y|9fj8OdIJPnJ?UJurz=5yT3TKn zC%l9!SqvgS4?Yy!6NLd0-cys`^Nol^)DOGgpSXlpjvp7{J-PC?j{rh=e#y9=eWw(m zgpK;e>(?I;{BEy0(GXdOqeGjTBav#pL?ntqn<1xCnYdR%3^tyIF(dPyg5_n^J3f%f zaWU)9Ax(nkDt!b%*BqGhx_SPA=#Q=D{tU}2{OR<37|S}6Y&RzE9ju{#nwLQkkL zd-M`XoVoePf5MvZZnLu-9H}FE-%jU!Kp5ZAueuKWez_WjGePpHtyFfFU{;m9e9BRo6;A)Gg=o!}2>zhlt&Cu8)vIuFzvEc5`1AR8 zv%!hVD^dJc`jGELLE2h(|AJytO16i(|6T~3IF^=~;zbk{;PwfP+9(F(`^oR)Cnv&Z z@{JDVgA=>b!Md^*u69>2A2T7WDjp+IZ{aEbF()@y!?$z$kpIBANX<$0A)uuyyCjh(m=6nT#D;60%yBf3(+Npt#dw`*YY; zBvkSrY~1qBLFtR?I&a&T-=VL~G~RZ3F&y`|zxYLes~yF$#k4uyecQvRFOlf7iLp&X zng+u~6}G}iq_R1@++S@liob7TpOYKd{RUIjP(UJsQ#|S%?lgQ;l+#-g+`%rJ;!|}j z3;uY0%j{!9GggJGjaLV@3CBpMw1U;JTquH~-)>e&sk>nM@n|%;7qPUAls1dlkw?B~ z;Q4KmEu+O8&nwU$Q}3wm`9WMatS-VYM~FT z->lqhntb4uaW^&xKApucD=U6Kg77ZV+M~rZi2=S&J_$a1QpoC)LatKyRJDH#tybPiR1o%#`3=<~?O zO^wf1;gabGy1Q}=)76*5CqAtW$9Y+z>cE1Z{4hbpn6sA%zF1bVyBm|$u@r2#C`ouJ zOZr|`+)M$I;@7$XpUe$p9_Qp76zOmyhVj8h$!)fQt^J7xzh(nAlOncOLw89X-=h~r zWRK+Xur=%HiQg5bGe3)k-9R>CE;5x%GJv&{&n+%HITM^Yz)y8^&&wXrCw9pYK4TJi z-8^5lSai=|AX$owJSyQCZXV6L?Q%BclAy8E{7TKK;Z+I_4S9tFp9!JyxyE*i!*|GD zx-Md_+A0Aaf8`VD8shg*IB2?ieyDW=cPr`?4}03q;xNA=-N+t+4fqc`W-*v{Wg+ia z!tYRrCvrHDp!X2@{}_-aer>vMAf*gToV|-05f8o(nWeKQ*e7RZoHt zq$xD&nt}#0Ol~eQfo#xEa6?+?Hr7`6+~P5jV25Q=dXVN&*x2mfFC4<;D$RfA zt5>u_kBdY&@Oo^qK0Qz~GJd|2@N+oxksIW_JPy5!B0lMwM3m?&m1@*`Dt%QXPbLH> zY_0`?Y=xT?^&z(!EknuwYWJjfB3U_{-@1D&13B0KW~npLFrnsR*T#E?4$tiebGIr* z3o(#4>ry={Q>*GvtTTW7jlbf(;c*&f{1TaIbKdb_e2^e_y(^o4t;Zw1V5uzzp(++~Fc*0T?3SmdNJmH0DsUi54Ulp^~S$Uj(3!|jH? z7@YZ=kUA#zI`PFlF5F->nV)SoNWz+s=DWJC?L}x!%ay;KP&kJnrtU*enGRfoM`c;e z6FR!{*g5`Yh5n&_KWrwZlqY`E?LsW)!ryv%LI{YxmfmT&^oj=7^^PsJO%__9dokK7 zl^>Y{isSjl2fIJ5LWk-JZ-H}z6xtt)zP@?er3k$}KW{3fDI4Psdnf%5p`E@c+xgj{ z_4T0_2ejEsAR#wN-*AjnNazjSH?w7`pxH zD*bUK+`cAz@;Oic6yZ>~=zhWQxi*fOtQbZrf4Ye4yEk1a+K9_a#g0QbE18(j*Um>J1iz30VLh|Wh!XZ&BKe}T*Kkg|D+0v~9x2zQ8*k z#kRw^W!GQmZTEPcuov?2XuloViFpR3L)Uz769zmlf6aD!hXVZ3;L8Ew_49RJtFH^2}z`n`}%W_SVWp6edp zW3@Lx{^5-kJvV46ff5oRj z*0dQBrP1EHNj^`|tn|It){b)=7j*7_kV@@{g9pzKwqKuOW{Eyp1*c^Jw_zlY`{@=9 z|2~8NJ~q?KEj4`sE75O6m&2Ej1}UGqtVhvj!7{b;kmvky;(wN`<`Q5+2zBo)e@!W9 zSg}E*oNump+3qtGCtI8on`adeN6Ga%po!uPr1tJQ?bO)N3$stN$y4){f;e}+f1Gc_ z?il#yzp{VblRXUMD*N-hRtXfYQ6+ZfcI3Jc#()71!w5Ph$XpIE`*Ul1LN=AHY)6&!mypeVgGK{N8$ z6WBAUF+*NM0M_pQj=t^`$plew4s1D|yMb=DkpNkNcSPN)nMbGCl-zw3Tsqlvr^$N; zrdJk3O~(#%;lkRODy@f?E3P@_pH2EE5Qx-J{w}|N$y3nzKwl?QwY3i(lEWn5kAWl@ zH26Cg&Cy#yQ|*^q%|(JV|C%;u^H?ttr+8rWQA^x0`#dBn40pFVv+*Hc&ZjWBD|G;x zg0_kRngKVVe4OOZ?Pa%yK$40;9V7{zkDxZCni3bc8gQwK)G@sE$IPfi3Ss!ofquTm`L%lR$M3+^oDCo*Q#qdHl$}sPx%k2 z=Qd+&gyTp6Yd|)_q>tV?xYf3X$v2PgBwsN0#JYK}X|fyPY+QBD`My%*r?AZ;vypg$ zS4Tn{+58HT!WzVPCx~Rme^fxL2=qn8jo+3J=0n2dYwXb>h650m&6=9s`^OqqADZi1 zA5TAn^Ylkm-7y ze&`KAs8NiByPbn2OXoLfysI3Od?{vM{a%kP z_6xy)^7p1mx?zIL-)moY$0s2Qds!^hhPp*AB6a6R(#<~QSk&wsdU_~))CjGK)o!&7 z3{99`yq=oD6-G2FeK`^%n7X8hQSX``ACiL)BfnMmnPTRPLmm?;obVb1z-<43K|jP^;Pk(+Ug-3@K`!1aO^n+L9n_#SKAmy%n7vL?|;0zx`!wxJDYCs zT=^c{glJP~<(?>jjy|EE{WdWshFuFW(_UDKhgP$*0nf5I18&&Xk&SQOV%x|YekOCR z;r>=T#CK2IT}it=27|rreGlHY$RTNdHq1EE$pv?IdU2CnCJ6G>_vbbrKJ6#`P3oUS zp4%sfqQIlUc3Gf%7*nDW#dr1>$74P2Z?~+4FHtL8&}gS#YnhDq-X9saM+0Zk@F&HE z_Blrg{WJ*PtU@o4m>qFgGp--dm z7fz`{B&UkLF00uEUSJ&Oz&a^R29PDJs+pS2N}q+P?nojlq?3%qYx<>h z+3f$c+QFs}7JhDDB)*ked#plS3(BGKqwx(&_FFQC(o*P8$DKmI#_gQSL*J2Gqd1`8j{3b94$tQ=3DD9!oQjEXtua zh&P+Znaw2UmP4T)xOk>ioclJBK5hsgV&aP)3m_9MnKs4t7Ff?sUQse+p2y#E6^?9y zI-+-DFNs_17vVO0EWbBS#Oib*6h6wgop`$R1x-uLd0`IrsyO6Yn^e^xD+Pb2Uv)+K zB80KEe9GjjGvP{34#}w1 zBe#c7B+K9S6UDv+_=kI%P4W;mM9$i!2cJLLdK=*NDq~F5K zPJ&Y9)-h;S6pV{DTj9#PLk-dTT=Za%%iCdmB(n^8ee0zz)EL-}@{diXAtG4i*1fG+ zX~dW5?B8+g43Vn+^}RfeZPpGBT9seo=f0{y>0it#qlF_3sFJ*K^rp@oMLg}75>rmU z*^SJzDf6sx;yzf}9w2gW*Qs&*l?xZ0kDViC?q=MeDh4dSyNv3s6C6aaof1vA+qb^#e2@giS2xE}lJ63G&T2yiSw9jd?0*T~ocs08 zA10Smqkw&BoO^=+-EO~%*vQI{Gb&GcgW&EAv~pk!gwRbo@> z!eOb(NYb2mBs32fHtV<%$CUeFJN}X{fo>4jrro28iDQsz{h7w-z26EKjfU@j%jq^n zy}iZV`%#O}(fIH$x8rrGtN7PfKPd2!H2_XB8?#@2(DQ@UQT?_bUy$ea`W$VYcA)6{ zVd#BKJmqV5i4SR3EPOv>E*rt9EYNOU@1Ow6Uiu7LmnU1H>HXdAfzXs99LTKv^(Sn*# z%h~ni%a^fb_%N-mtr;2^fK#sXsr7>X4Xi(`OIQBM>AJ-)Jwp9*3LhmwMrn+}I@eU;QgYtRDM!xEiAn++IqME+v*F ziaTqVRGH7|6T-02p?3vgy$EdZn36kEBd~F%bb7F(eXR#DsR@30>{5>N)rpX8c@8kR(j7IF- z_NMhgH0#OAkVg>kZdWC*yC`lGy zZyk?&^GER>%3t(qy-9z;Puy?A>_uu%$6?g)ePG2T^f{O;zT9WbJZ^-UDxPVEy2fCH zC|u=N+ez7osz(B(_+l<5xV<~zP#wBXjuk>)rH=NIK=!?F6(-&jGY}jo=FZ|BEJKay zj-cjX!x9|ul|9#Em`RO>x$>@TkwZ>6c3&>;p*DX4p122;DCGLr;Q)D!GRFZ@KNxa) z3R;OoHP)TeNshA@BXFoB)>pL2h!&h0O}#u)w-dk;;GkRo)!YGRU(+2v7uHS0lbD8n zTeVpm!QFBP)rYX}&B(a^$TnoD#u#$MvhUVzBF^9F-8j5)LH992%BKTzelsZ(@bMSbdNXxBRRtkE?wEipqB#1sJy2+NmPIX6#owwz$`(d7UaVqt}o45<^BKVmm zGZ3mf#f0slav^8NuD#$UPbnw&dh-T?r_-*rKIkGm^G%7qtmVSHF!-F5GJk+f2DD6W z?(XW%gmdH1NiDv~?kj|Y;n9Gn#8AxaS;DHDMYnX2rkZe^470Sx(Q<=oL0X91!0!hx zCRTdOEjjJRx4-#X<&Ag$fL3`R>dj_nGu+pfI&Dgb-@JNsw9p~Jj#TJ-UjO*kFsu)B z^0YO_2RxObrSi#$honYGVm@D-@|2e@VJ9hH(e%B+VFC`3*uqUsErzI%b&;cW*2MGo zv}S~TYZRdn3y;g`IWJVeK_cTt2bnT0!Ns?iO8c?!11FX0dV@$Mr=j}1EbKKT4`E{X zKGleh&lkL-ai^zWW`978#6DfUQ|+dhn|Kj7V3_wB^h5C;+~fwQ@h~kjE^E#}9%2tJ zCwvz=#}7-!H|l(m2l-I!`@WT;q$3fH0hWy#@}%!*3(V6TOe;8#SkVj?ZP7=3xX2r5 z74ZFpE}nFZ(;s0-x5Mq=Qd{41_YWh8X}fnDHQ!_)aU5?)8Wod+e^A4!J6evj>T0~7! zN_CAOY+Z`oA8I6f>qU8vP~TNMPkAwnjfdZ|3N98U>{2t&YYste`ae>Q1^OB zXWRP2BXQDRnf4C_)oIWuZH0+w1zbQv4mZd7kzffp#0VQ~ybdnGto$wBA0Ex$QDHz? zC>|r~fKjILJP#Sdu4Sv>;D4@M?kpZ^OXgNh^&27n5~FxX=M54v6_*T>zUgS-_L{1O zgEGGW_7xZ}M=&#$;gwT<;6r879NHLt*B`{cwL-H8*G{v-t+!w?k5-*t&n+Z&Oflps zS!600ZmK99FuLV}X6O9Sitk3*;CSyfBGG!j1>?a#j%q0BccR2<_iyuO#SF;IrZ(+# z6hDplwFvjpjmuJy^b2nM&UY;sIfEWil+w&Wm~rHf{e#>JE z7i}<1{wH;q%cjK*EA0u^EK|W82faubj;k>|bc-U+g{Mzt?Vx#kk|?@5 zAOKlz@?S-|gbRIuae}B7{44ic9;|aqOAQ}BT!pnX`Qw(B zmJ^VuHnQ;}J6BW(|3H=hc9@e=5eKw)&Q%>I?I(6K_CEjBxjuV^lCV#8>yHjafu*5}rz%ZL z6CYpjkfP@1|F^C@!BHpIR}Y_w(l>5SYoi!94(FjFBia`O>YONjor8if_Ru2V&5z|Z zcD1e@vyEF}#(>qrk-XRPKE%F_u3$p)!Up=i+n4>lGg{&1og*GEsqcelL2m1jPXyy3 z-bl(z>^S}zcL@~T&+1@;^3bd$xqSXI8(K7cKbL+D>c-tR0ilxi1A>?$2$OO@MH~>t zxUqTbb?!dMnATh=Npy_?d5wg9WsyoR{@i#rc|q;KJGk=eU+-!VA($=4Wr`TG1qoWo zZMn;GS~({8-LT`x>4S6+XTLvHUmTcw*`9>=%wdlC5qk9SYfSs``*tE7-fiutBB@%g zqj$qBiIyqQ4%Z$pt*u+{lmQ=Eis}dE9%GC%vFV6Xzm2DU_xQ+UifGU- zVe+AASG_!rwBHN$FM7OtAY5`Fnk0R3ycV0z+rfI@D~YILw07$Bt>jt)B&2hgiaY-^ zG)@1j5;WA?gHK(3!8w^XZ^PkRsLA5D{2u5Yq-x(gma+xrVJctF5@Hcaue2rCdWGHu z>}@U+Z8PZ)5V-U@ul?X_esEJ8Ol!>d34^m~V25P*iW*TfV5sHx4p*>b~U8G%6@vKT5|M$(x?~rlNvHL*DcH#Pe13zE*YT*91DsS zNFYBce{e&Sl5qcNsA;wAro{~d;=3ju7ziAayD{_l<!XBr;3IeH=#3r$K{m#UG-C zzay~is@=c`1O`OLpK}l(szY;)U&h;x>)^Cg-fk~@wlqvQXH@U9h`E7#3yyXbrly(aAH3fCinq7ZO8{xUKe8DFRrHacI8UGPwoxD1 zCj#sW-HvPHb#BK^+R1V`Scx`^?)^YhfV*2u0l~=yWth<^m;3G3w1XIOnERO~&0pX| zXp-oavkxy~Chh7Q+XuIjh&BLI8RH-HghFcmpXF_-By%{77g$#ArUx$gf0Xto9biDu z-bCS(K>Oqp-}Xhse!CWpblM47l39U=rKmGK3?qOLZr*y3Jt2 z;5wN$s84+4(@h>5N&eoRT8*2`h1z9YsW6(M+9`uU>pF5w@&Rit zqz4Z^xVQV58z#aMy`PvF#o@)Mlb~DX+$9)2JNnB0u-ScFX~>-AV6Je%`8z%i+VN9u zsA@D~Uf=R2>JU#S*tbhQ6@`LxX47pkJ4OhWaPXuZA@b%|iP^hkEhw@eH>cC$PmL?f&SbLnE;xbUAnD!EgeO?0jLAz$`3_%|p4`jlU?r zK;?_tPOl@OC!pW49uj(l7dNm*+O&38=q5@nR1E~cwp!nW_v;~KorT%1JaZAE221*^36K=I)VK$ z)$nY>Rx%md%{`SLy@*I7eozV}g@knj70q@k4*8jjFpxJ6_cib9iS6u{PTAdt3T+vZi`U8fz@RDGw}&nV74`R zAZA7SzWsa7rtwD+P#|gpQbVcNTKgO5e7DLDYMJ9!o+7UTuDdPST!yli9EAeM2 zBRFa3a7M<9^uSK&El7+(8(P0ss4-l1HC!X@$^%qZe+85_nU}8{GUu>p0|fI(PT{1ELk^#Xge5PZD7i*{8F^ zOVVWk9|mWhIIRuaqh`#jjVyM@3GC6K`9-}aw3T>ojp=apiDlq4S%pr&@6rPFiYW(^ z-Pi4~Nxd>(NKHy0+K0_7teaRik-W|ywl?KH34vcOD|v~WAS*QL?pZ8-wV9YqWR}8 z8u}4CV?Q}Or@F6*^Ow8B?e>}p;_PGk=C!{gd?0OCl$Rvs~ zG8aFhC!=djxM9~Ka;Fs?L-(guqHJGns9mLwD}?-uMnyGr_T%Bl3#4E39`4B9-@ik; z?!qk2j$iIoNxBsRGABpYsh2tI5H~sgUeBdK2Bn>TGCN{R9bh6`EqzG9G!C&#vN|7I zS>I%S`T!6%`Um^>~7hgaLJVizPM5ger5IM=gt z4ZL?iKKI4b9c0z#o%I@twJ(jG!-b@6IU~^Aj9~I(eC-SM3~8N^$cSakkDUE8pB4e4 z>xOa6*oQ_9CK~qLUeS5~puMy^m;1-pGf>`dW@Y7dMi|{$1LR`CIu2mvDD_${-QI!n zQ%^WIWAx<^nxrUupN-)jwyRF|&0KnR6@t8n#%eXhqG5X5+$62SL=H0#rTbL9+l|q5 zoZ_yV$8KHx>X!anWoYD~Jpm834!JyaA($T81ScV)l%h`*V^pI6f+H!*rO@x**x>}_P- z*rio@+MB?CChNEVcSfudA!G*3?%fh)aQQiTON0GzD<^T>i~?QPi2ZoJ zSYHU$P#b~#<8>B zc(+KK5m55&)q$3`tppKQYFFaF#^lRHPVlm{v-C_O4x9<7;I?|ziX=+?UVhD8b3|G* zO{jbzLlZ0EeuhTlm12Yn+HO7ka?1wqc6%kYSf2@ADOYS@Z7yTAmB3v1S=(t#s$8re z9vo39srU)Q(RIJ4w}`NC^Tv_@DS2xe6Lq^us;7-7F!fi3;4I#;k(ac%E24&oX zPK0lQ5!9rK)%}mW^szm{c88&pkhafg1nprr&7y`n7du-iqXr4=TI{O>tK7~A$eZjP zy0B+Ip{uH_Wu@IMg`?&_y2?E@%`mHFd81(0{0j<`SM~?*-%l`_`kZ-3eZG*uS#ZOH z?5P9sJP;<`+a<$AjZ}Nf7nS6krC`c=F*Vmh5Gk#CRAhfMka9s*GjoaK#Xd*Ti)f1;(~md}3&=J$~zBO{*@fYkE$ z@5}OJ=#jO$SAjO<#UK3nGdca!^no;jil({6_MNzewdC6940CS5qBOyGmAV#zI#_e1wNrasF zBmBu#+#C`M$G7*HzT(24__GT%w=OH-LY);uUT97ME*G6|8#lAKg_4%jVb&Ir`gp}M z;htd`p$t=I-fBj*ByG(6w&b}LODG1H=T0u`?$PFe$h^^NIrZ!`q!jgj9L=I8w!P-B z4)yNecL;TfCt2UN=1!u{fNzWQB9j6tnYUSTvz(i;q&Z|9ryoGL(@XOF+H8Kd;D_*Z z)$r&IZ%oZdxbiuru3<{ZCf)6`xje=-+sZEe^8LBuduI=KtyC)!j@W2$WnvvJuEYFd z)PEDK4wXc;XHCp2#awHMaujWGPslz*zihn4N7wdEw8ZD?RJ)2%67}nkDQI%i(qM5h zwZei{|1ee$c&@DpFA}-2*`{1l*&P#H-$$~4R^!Jp;PJaIX9s8Pg?zBC4nE#Lx4nVc zk;;|+`f?(q{Kg|Bf@k9%Oie}3oeTW?7uJs$yjX{vBd{Sl{d4hBx-s;}L{i!m*E(U7 zDC<#wFeeW|X1|lXt9>8gsn|-|`I|;~2;y2F8pZ?2S2%(wTz0*GDFB_18G1?{6}^h}MIjH^;KZsrU`Qk20kIW{ z)h~OKhY=yg)10WX=>VC@cJGR|PG@9om_5I3Zq|WGF`m!)?{e0VGhlA_Y=*Gb9namx zu{L9I1gyCWL0|SOF`;4$c1#5~KZW^MKNUR;T-91xiamJ_H^N$9 zjQ=-YNLYak?L=hGd_t;wD$x$*D3h5xg5LE36UfkX1Gq7zBiJBeCKZ{{k?vBgn z!xFK_a$x@h_S1Uc*tqrZ!Nx;k(o^bkJGIp(fs%N;u69Z*Z5VX!%@L8fzYiJ(4a0Hm zPD*(6Y%L;~clCpPA=qpF+0w{reCc<$;0_J?%cWc=(+!bG@6W*H`dobeZ#jWGMuEmo*+z5Te40( z7m&vA>jO6W?Xu>WWu;o(>y_w&aF#^5iz8y5pp4VFmbcSh3@M2R3~o?9eS{x^HM?W) zM^oU4&`_$U_5>@Amo8@h*7M1OY5b!n*);>zc=C+w?k59XeJpC{_&)njy`QL0XBhCA z;8ex6uhh(znNwac(8{gPWc#H8LyMg|$dh8KiQ1*MR=@ODpAj6K_ctVYs~@&;Ei2mQ zakdC`>H70Ef0GE-=2hEhr@oJcQ+Hvy&VTydU|GEK_0&MPD?a@@>Tyg*jTO451rCk0 zKFY?XS&#O_x8iz8m(V!szBxzu2o+!DOsaOjgm0C)+CM4{HI!f5*n6xz)*M~>+>8u9 z9R0W<;c>GpT|y0($Jgks8TK}#r99%nlRsKAc%7)$^^QW>3}hyB$-hqJ&Ozxfulw3v z10FP3kR@OJeyRx}b72(aDGNpz9J(N+x1gni9UtCAB4U7G1Sic7YxLO=&LEZ$nQdKS z!$CQ!9l66kMqT(rf$wSO-dFF!p5&dDdyZ=QeAN8OcQbQ$`L&tO`4V(PR3 z3l%&M`my#*#&?4+UHEIEuv{G`c`ni2;HfzaGP{{=p7}ZooC507RzSo@*2_Vfa$)IuaW)!i-TXrn9P-OYA)S9Ib*v^JdF9V&K27fB`2xeQgG z3E=$CPW7|nFO$LaU8Z=4hn@nw>>E7yWS%xbl+@f-^ymHlpkf&n+<4?#N|4vi9)40< zr;8mD#k`E8Cstq|zNJ&=KWc*_R!z5i(m}q68QaZkr4uL!_b>bQm_t{OM?we3H&@L^_BsUGsB?i-(8DGv*W*!`53+L8TIh*DeL&d>lV9xD zFfARBvhgjM8%0t>-|x2(po#^#5MNgMkq@93Zx(fs6feQ`UZaF1ckv6j<8WSdK+vQb zF%ro=hlSf(!18C}l!iLRD6U-?OITXD-vMg1WKD;7A}|*-R2jU7p-%_9J{1P)Jn?kH z;QrOR$bp*YIR9wwd+ID`gSC`1!)L`(JrXZ`bN=Za6|y4%Vc+|P3S{?Bg*F<5x+Xfcn=;6jZ( z%OART*9*~N@%~9glSK>E<3j58ZTTNXt-Ay# znIkym-&TC9OowPi4X)XDYSQ#6m@A&NKansN$48!WSN32$n!&`A@nm&`>Cn3+1X(V}W)B`bg{k=2_mtz0SP^T{WOub@ z!~w$HOutQIySKpq`OPk#D?B&x=1KS@{XVV`T**nhbKb`hI9VThvV&sE82hyUqg+0I zm<3uF@{~d|i!^ZVqHk)%+>h@VEWRA=)tX%czFZ$wyVsn};2&I%R}CzdMa9*|Sf-z& z0TA{+9#VV!>t|4poXbo48g!I>3Nihtr#u#V-;qAV;{33(*^cvI1Z-^4mA#x z;aE0RDeWQl3kdsfG@ie>b`_&l)Qfs;1R*F#b+>(Tbf^jJ9R=vDDq^dUvi{gB@rIW- zVs_cv>CLO2Mce^JJqwTVn>gBB6EUUujRia9|2A_c{OZ6xf~>CAa*6_T&k}=WwszKo z!cmJwOlZO$PVvF?yV{8a!G@-Y$$u@o!lBN+Ax9L`?L)s|Mch1hKNA*YlFi>`k4hue zI5WhlyZIW*HB{(sA9a>PF6Ei=@E)NN*3mNX!4r|9xR46aBqLy)$Ek`~Gb)?F7@|4ID51qmXjzx2X>$$lO__Lvx{L2LR2B)#+6L{Y(#5?KUSO3B`Z+GKM+YgJ z1Or$7BQ2H^$y`6(Z1eA^)38Stf&LOT%NYXE# zWvV8;4?`bZ_k}JJLfg>Qq7|AKykZ2dF7$#}(Ml?EU$QvmxZf9mp8EvFf*e|KTHl&Kyr(%VR{fNt}Inin1Chs)JJlKYe52I{ka>uWOVegfl?KUyQQ0CSF>@u~f2@BSnF4Fe;-e z>3JqK4Uq#CGL6PJ>>%(suz~kjhdI%Hb1RccUyTWbzH;{FX5j4DGtCkAkRmjz!-WYGs0?Gib6 zvf7&!hiiQ{w8aS3eWzJwO6~AXVmbHu_28>@g>WdoydZC=bx{DT-$d=kF8BswTb^56 zMT7|MG3+Q)kx0pngy5cN{Xhoc5SV9tF|!T0OoD2Iam4Y<;$cJ?u9o6s{sS@K=4zD_ zi%R1{)6up;HLfOBm^j`&?8DE}4{OyXvDVcwd2AjtlcD2@48!K@!{5`myqHjNj&Gh=wdBiPvs_t!)mA4hSFm0iONeyWg=ZQVFtjoW$zd2I&6dz^digjCT*oS@<`;=C-*gM^UHP?r!l|`CYy`KBv&hFXcZuL+H2>f1aLFhnWb=vGGO9elSUxP68$_Pr6hHa>U!gwi zC>#mv&L1hY1s@e_Cv|i1KK$y4-uz+zr3K2p-BPE&2e2ZP(&&R7Pp1+3GA}UpO|W<4 z(JP_wb9An0Fm9z8qip_~h|A28c|RPa8*zO3hf=*L?-`;n%0ByDO1v-v+i6=A(xh6E z?j}MC5V^Gv3wKvb*B=T{!-GBae4W!DKRmRiqt4xVxDx*v=Q3`b$@Rj<(k{l{M4LV_t|h_ zRC7euknIFwiiXq9$T<$7g3o8sQP|}io=(oxj0Msh#Mk8oOQKWL8D0K0OY0eD;;@ns z*S{*=PFS`Na4aS09jZXs>tYaGxCu)pIh2(zM{HW|D8YwS-QvA%!cI7_r?>53>yc&LVX-q-yBoiZ6PL%u zpU@ka;qUIY?({q4MlS#P7HPL zP?&3fj!GB%P6wA0&G0)T>u~lX?>EFs3|frovyf1b7VTys%e9U9ql~BidrIjICGz0A z8Vz~+I7JzA_2brQa>yOqK6AE=sRC1FCC~fz@_6CYX({sWO%y7){33+&=31B-c3&ya z5`NL84;hJo>f5mrSj(4@ z7N?C^0TmP9?vD|#PQuDrDU~4uaY0nh@g|6>&K3h*o-)_{SCI>5Fgo$2=w4(;K>< z`_VVHqbJEIayMzOE)t?VS@@^5Mu^G~U#SrCcei0MFCJ#C*LD-EX8rfA&lx!2Ypwc% zS{V^kTuKvadVIdC6vpQztOO%RiNm~|v+%j1mlxc^E?-W{?&reqLr=2%X&Y-HqcLyR zs21f1owYO~{1RM`<+7B0F;SwW5dGDE$)!b;W`O z)~#)o#^F`)u$7Rd z)^X{&uh+&;a(y1Q7KZ67T`{mCtxAm2Mo zs0#a?@I$tD4&;Y7?hV>-Tts;F4(;chp969Ksm@??{4{Y7epuvr{g(17c-iFmIvBqk z$4jmhF`uY{132ZTTXwT2ED+yBzB*k`wK4;{?#LUaK{-$Om>lHs0=%&)4o%>l(s#G;x7IVrS z6Ek%S*VyC?Ve0fK$!d@Q*67_~N+~~IqK1J(OA4tr_af1}VwGZgKj{?iGSAdYF%}bF z{)>l6_st0BlICu&%f_*4Jm7uB^y+3oSs^x=x9=@kxIIG8%6y~e`tEI*3|w@ZQ9OTv zI9mdg|6#r#hJ#_NMLUv*P#mOCN|Q+BvS!a+DBYH+;zb=z*_9jat(4&N99yd#b@)X9 zBHB>7{N?|6I`43-{{Qix+g{l-JF=CT9V#pD>^-tcvNKY4RI-JVY}qR-WX}?^cZ5hX z%jSN5&*!>+*Y6*W>;A_%uX8`o>paKf@e>jn0}W1wH>Ke(-?7@xn8yLM{Qax^FH|lV zp2=O|-s*fI4Z+|r{jPo)7l!m}KKX5TF2h16k7jAzi&gmRYd6VoPx=WgJ-Bjxf2DpG zD74SSTaGuKP(#HwX?n$0F95D9rFI%Q&!IyI5}~7^qIJuv{DyVdg9sg*2pvg+2py3` zJwwI_ojhHgBGWgzZ*+?cF^LAa5jx3u5jyxq1}}5?Q!L4Bfq9VO9U9t!r8<_Bz(w*@95sY#I%++f>BXkWN?nU`T=m;h1 z;Tz=X(iT}v=}sATSrzH;zb!IRv3ux1f2$IjCMcAYkSn2}C`-DhsMKY#eI>R3XIKdL zHJP~ZOA|}s5wAjG!$(RKb(LOF6zM%ZH4zlrG*F60E)MA8PU(*6>SJ(zMwZ$}>fQU1 ztb=v*u-xm;L@W+qya8boK;f(BAazKq^9sB>f&0HTI$n;*dX?H@qX2rdm~AB)0rEYI5^g%#ptr& zWj(BlcW{n(lif)XNYur*zJMvZT49l%@J^4wn$joPz&YO1rXt=O@xaUSDobRrLmoMn z5c*U+tN5G5Dv_v5WKE4Js;EdPDIQHEfw%fq@sBLy9Zuv+NHt4L5N*VBH--@8Yi{>Rzy>z!dS{GLPTQwyTPFwu_f5u)LP2OKwerDY}D~Mdwrz?|i?~ zxhUQ|`(2X?<$x|`O!u2ERzI)ko-VU=78s))B4Mk)VH&uGNvP)m>PtBS*$`lXY))_IIp)=Pc;~Q=%6sY`+4JqjO)Jt9_=?ApP+5qcUA#|4yuGab zh?8Rpu{EXL_;LkzLP>+>eMv7NFGO7#kb0c8KdUh?S%u%GyWy$S0o3|4>g$Tm<0gMZNJna@ajTd=+v( z2%%NtX=mwO#K#)$kiLu@dEkJ%(@IRl%5LbeLmnGR!b;p~%UXWV%K1%WcNJyIh?-#U^l)9Zz8gm%ya*<=TUFC0rGmccer=t z6LG0+t!J$#u9r=X-o4t;4vranAtl;&P7GFWhqKh-Oz;M&Jg(2BGeHqj>E7Y2efjse zvYXfl-8(!jHnQkVu-IN@?0|6m7w_;I@rlj* zJtcY*C&z1Ikpod~tcbUi5?%`T#Fr-u~R2WvO&IYfwy9dgG>_oT;S0q6*R&P$){Rd zC6F-THVH9^SIWgQ1bGYSa_iw<)g`#`Kp!KcC!rT;kmQ9I{s@0@$pQb(qcYteAGX4H zm$LDGd{{w$XYIWcVl=~!-ij%SH6#x~l`TqH{GP=vYuI%qiD3UP>a3(!0-j+IezQG~ zA63XxHvuOM5+bXk6p$7FQVGj#ixF^_cjw6Qpj@l9unBZ@cE^3<9_to3Oo?#uE)N)e zH74k@{c1evj;uQ{U*cV&^ZVgCXUrZP)JDrW?n}2LHphtSB^DeP`urE77T$ljnzK-| zV2dyyAwM%HaeEe~7Je^$J6j;%K6!dv+dz`UwBx?BgIuI*XJckbpbQP=&b*eXo+w@W z&?oa*3fPV#wm%Tt20|ntJSG7XUh*N;qbUyClH7&ZP9U~f$oHtxOwx+OOwml{3gHUH z3PiWUt|GreE$&Ul=gis6p$gQxfO4ZV0f;u^i_d91oeLyWh_;LPcH zbdbD@Va>+$cRuRz_^^QfoYO=8cFtTrv8(9t_)yWo?^V%ZFsE11fmhOlU(!QR(ql+i z(nD0zLsHU1TGB&DR?>5!q=!5k^HOJ}i?Z^s^2AU5yPuRM=@ zR%#FNUZ|q+%l+YtPY(SJBAnTDQdFse#C$&2&?l0QK}(kZzKD6ISE3j4+LQHvQR`36 zr__Q(FL5+#NoP5Kl*pMm*UdqrR%fUyw``V6w*NG?K~$^h))a=3@jqXhtJ;9(z@09n z%_0{ied)YaxReLDsQ0XGQu%*zspV;R+!>f0qhDABpSsKRN=os?&?6w%I;p5+4W^or zf@sHl zPlqwhH>e}2ag3|o=<)sO-=fESMqZKB7sX!pPkowPu;9j$u;C#@NDF>#0#1rhv64JB zj`XHHH7;$v>8&43XtMVS&9n%1f<)yKMw1IykH1&npS~K0FOB92_25W4*{}6+S{8ba zpX?un_SA*x-rrDSyee>29XlbmtwoQaP`pmf&Z~$RQ5uOfS%uM07=+PVjl8J37=v%& z98juQuGn@>rlzg8^|#_zf*Slt8p(gEgz6N##mcV38%_wn@~G6e@h^{w^g_OQz0~1Q zNxGw2sElrBljpwt_)|fHpu|d!sV|ERSiv(3ONAC z>7^20_=LbLM~$b|a>$B9AA_;rEXUJvHYEbt@CnW@>TF8Hh!wS!zeCTihNWpGj*x6E z{*^a+BDcF!mAZvZW30YqT2)zfT7A}Uo8@RzLWHdpt#qyaTH!nIYW%P=TK1b2W1Zy* z4&QQUJ0Z2>#;Ox3A^1c+DB~!x;HKdDH++~v;dcn-ZB-4`y(shvj@&>1i;#h`hsOhl zJ2qb1E+jB3R!NAD4+Qx5gaiZxL_kPLL_$SMLJY(tv=kI%RE$8!#Kb_yz;F>*FLPXE z;bLI`22LSPE?zzX5D;KuzalEk52Ba(1^6(8L_kDBOhQ9SO2f{_%)rd28EhHs5qPDVW*WJ2*PsLyex^4}E<7{2xI;_|u5UXQ)3hDlzF*a!TrJ zc$1cso0tE-01AtWKUCM$)A9s-hhnJUrYcJi=~I431x-Cl%n~bBYpBE9(NGjVH||u}~tQy^)Yz z)lSR>;(9xDwqC;|iuBwPKQ8b7^E~!qfnch*M*(4% z<`RMfR2W<;42mYMC&R@E$Kz66uRLK_jpEC~xs_>@c`vgqATv5MBeOEIBXcY>iwvfp zXk@nw#ScK~`ffjstN(Xc$K~82;tl@~Z8LhB+X=`&U>ObGxuUpR3~U!p8@JCR-5~gN zd18oI>kr`D0py%eVgb%b1Un4_V{E>o2OH%#g5%tu0jrRe_9z_sTiz;2Ypj z<&B??3WXeRrU>NX^1@^kQU(aI8axB!m&|)WV9_FYS^c}f4(#zePS&*LCc>Q+fA%sL zLj^GZFWhw0t!4ufmzWEqwd|z9ny9@!i)3L3Uik-O!_(ZcfZvOi2=35D(PzjBxpV6g zLooZ%L>Vn6(K8#CeVgBtrIUSMQ2Ttg9?VsY)(o@XD;G)T{)ZM1^E>8xE0=`;gL{2J zwB!|LKiRrW!#d0OSvWpm=SRgJ;ch0t-;;@2`?=ZMfaM)^GoTO<1i`|&tu>(?Dy!b$ z#(S9ll6!ciP-e!5%Zo*GQRG|v=gsfka6v9;n$7cg1kRD7;<3-Uvub59R7Q}rsXx;T z_uJ|}SFui62iuj~yJ3@qI4Yn!h}E{;XHx`{r8(}ZwV!Q(S@pm9i?f=IFjj8uO#0jS z60Evz#}z1N(X&Wq#+&n~mEql=xj`WBE-PY6b0?hh+5@rq@g z;_>@snP;8aKRLwKw2n7OI&S<2VOu9X2RD|?Q4-B_{>2o%g4XMwE;cAJjWuP$PV&)X z-=WP-5cd_2t5Zu4fc>)jIgNK3H$cn<`F!w3*a*g=&zk7oJYySbuv4O3YLXi?t2xvm zP#0=@!Qs*vY{OM?V*ey)wjU(YENd!%&y2w!!RIY5`}Uz=99qKlKFKo7JW$a2KZ%a< z`)^yJb$RbjRoEa(?_@ONdr9YP53jalWc-}mJGX`I;lzC$AnZo78o0ccqe|@m&W~%d zRlMC&jrL%+PhCSdp)Ng`g(^G>8DcxAJVjJbD<9$ARU10rs2{vrRUN1O0qU!tRz-ck z`~pZ>()kdlg(%1f5i{=&VpE2O+D%clqEFEfY-V+ITOQqNBgz9(fZ!~nM;9|qMqKxy ziLk2CnV#1l=3Wmn^Zj1lU(hu!#1+IJh(Cgg&SHaW&F^ub7h&!@R($6I#!^dm7@9^f8D0l zyK>~-!3el`xTxfv8qmWBvqHj^sjX;qu3%EMBG|0;1T!Blmc?B-S@U%}Hg_|jyUoQ= z9Ue|uw|s0?MVUc8Qei=NabhzGhgA^6>h117_aKWbd#QpVQ7Los;b<(ygOR1CaoBh) zz4^W|nH1<7U)?^I$DsoKxCdxbJph5#+Scc6%-{aOx_jQ(=2n+Ku-(bq{Zx^327(_Q z>m|-_%!0v($b&)qwC|{mF*cf!y^9*8*N==ZEdLS$pCQU$L2Rx1;OTz-^i58TCFI4> z9EB(+pyfU9DYss;^(VkeS94J+*^U8{>{z>oXFF>k{9oMG5qdF5C!aECaPZc||Qt%=^Lx+m)I1R!RwI znhnYSYP3!Yb;DzeQpzgj&~V|8vAEgMDcs2rw0N}5;sKQ}d6B9MZM+cujnGM_{wxsG zdUvE`4)2b`bDOd5#j5N4@NCmjTqOKY0&Meo-8!(XiwW} z_aN&+;{YN)Oc)&ZXTT2|Nk`sxPHVJ?%;Z!BSA*oj38OI}$b$aaJ?z(ZlJqest374C zzP0HCE52b2@%$hD1L|Te*;Au^Gz=@$h*e@TB*B*OzXT=fVU>Zaja=2kRh8$&3HKstP-tOn=0RE+}?@qCiUa^Hpb*eDkB1 zX?-s$Z99a7FGoeN%sUfgN29Sv=wJqj?n$`;qTLI%rp2kQb!e5n)os16=a1Vt%^<}rHA--bij;Tzo zYXp5L8B1tZRptRYF|xmUmpYKt5SqVn4__X2Errtm5|#Gma({zVQ?Ac($O=EqS!`W? zfy-eF&GI1uWBg7oKtmWi!)-I149KMrX+SOngX{6k_LR!A1URqq#C~cyTLGs6x=9+p zL26(->d)+~pQt?i#5_8TR1OUN1-g-Mc)XjeDIf&Mr{K;Fb?DjPy?-;B#Q}zX%oOB= z$ixBpdBq>uf+=)TMDEmV-q3IsE)u($I)i%faKdP6Iw=dm!P!tkyQ9qo{#Wtd8Fb>#vfK-Y@47z zA)Ba%uuDkcyTOh&u=oAkZSNmZ0Y0o^doy1+%YZw;M*RvPRgho%vHJXvNfc<|wEVFz zE>3`IX}VtrEh3GOsV>`R3;wqb2L)N1Kmx$q@NhZFbJS$p~^J2@`qH@x-p?L zj&G3l?&@J+n(7!_bGq*?_bkN|dLE~J&7mMR1Iu40b-6YrsxX-r^I7Vq2_^h+%jv@r zdo%@hyck(mj#y1Fwow-kO$gWAR>G&%HPvG}L2s|KkXpr)f2rt^lElWI_zH00)xFvLnRt5Rs6~vK7dhT2b6)E3lr%n3ypmapUNbIK)9#Aw_*&iN%B!DI+ zi(clBmfc{GPQJf}B^d|(9%GvO#&%;I6lV1nH7cu7dnxs;f_AUOf>`*gC(z2i zp1}KUdz;A1fnOnDwK2ra`|lSOA!{1z21Sx} zkPV6``#w9X0v`^3i!1a!2?JX7c9BP9u(u+$QpYFQ)hHb$X#~ zU^*T;RIAU|3cfxXt0#0SDrW;UZYiFbjf*}ov=jH`eO3+*xP9zU*-pLQ3fi{~PgR2) zUIN?K;EwmDn{r@QKYpcRa}&k?(Tg2l74NMBso*7|;Fr#ea5{oBEM=}r4MK;S#3!9A{c2sS$z%}l(gwBJ?NKFi>gQ>#%$CaMwiBf-er8( zgLX}R{kymGq>Y z+d5uI!RbT%!DCW9xXW1S5lOklz)=I zZhcnkd8Tp7u*hknKdeqf3=M4^DjDK`*`c?V#I63xXL?w0l))M*&|-kx%{MMlcwrk@ zf(4wV9{oUDPZV1Mu!gp%1NiBA!3T6`8UopO@&+akInjBVwKD;`ySh;1U*9uR-c$rL zzrsd_)K#xR-Qg%l+go%z?JrHtS9M%2T=3`{_%AQV#|Cyrx~?VNo|%UxR)&|?xtxQ5 zIk{%qZTVs@gx2xpKJvAX2Aa_5#YD{Y45Ay<(ttW7w^*BhFGM_H0zdg}&x)z(@33*Ob=g%_;~hM`^0kYn8^d(?%BBx#Gr3;7 z4i}A*oN{L_m!S<)IyoT}DWTvOFPaov5cL$&-+k}R*2^b@%Tl*vt2YGEFW_a>e$P3vixYz7W{B?G6XEUjkFTjupT--A?Ar zrLr7c+DjFe0>s3F&#S$Amjv@0lE9_Yx5{$*cLIE6tT<>M?q~pgY~>-|#SvGy$jItc zEzGhDD@BRMJ_^q{An7<(ZQV436`Eqd^c$q0{HWB^yT5E1*^FAa zh`i+0GoYITWVbPu2%634lGx8<+(BHT{_@J3V-x_)M7T&BH<^Z3Q*D{m>gy7M7r#_$ zh&RU@$HO)6@F97_t4E+-+PW5*k6xy*rcA7q5%(A@U9_JG;|`OC+(*|2BXRe_Kr%82E_10`77_Nr|J$TZq07NTn zv4Iyg+~J>Qf>`MLzz=Q>KIY0@-v!e3f>g{E zVT+mx5}42#6wU~)p+Sji)A&7`ZxQGrwrZYC_bo=jO})l-86#V;*CD;sSgBzRwUNHB z#QP=qP|IvDYSfXt2~P5kA#z^?Uqb8dzZ2DztF^#->DIu))EGY`;KdGaMOUPuNRa9$ zPZRdiAw!9$i7`47?P4u1jZocJokO(Cg1!_M#CDo6M*9iWHYXoQ? z$q#eTE2odV1{6c+U5qL&C$cbYb z20^s9;{Iy`siz>E_eTqfc_DM!d;bp;UEEUtEb0>^zfUtIqX`S#`9+3!Z_v0Ojrem{ z;qJowqO|F}5OkdF^gBM3`*4mYlR?yjK*^>6R`vGV~%}AH# z3VDHV&zqsK>hx2HT1oA=EBQ$lEVr7Lp2wT?!`dAdA|-2L8Fc44IHKx{^?{jtR5CTO zo4G(4n8S@4?>eA>^%3@xXl53$EK3;Pz9Omx=fO8y}9M1TaYPZo)(4HbK~Ab*4>j65jfPEcRv}nOmD<5_B^~hR+U$1|#ZgC~x`9YL55pA8iiBfc>6DqH+HzDOi^WqXQbT@#p$V%6Z@X*dPv+SH*GIcFX)HMSLRa>z9Vu?IpP9-`?au>Y^y+)~@Tq$I0mr8rNRfN1`FcV<5AGU{MTha>_QURvhKhgv zfnIR1DK9JWK9C=3Nh4!rmHDs93l?ti~Zdc0zk8u(phX? zjTyeKuRi#wU0nlhR1Iez^1>IOa3COC#U@e*)Us)7Fw56O;a7~$;<|0)Bam00c^zoP zDF@ZZ85Uvs0`?Hm^^7!Lgq#ovn%(};C?s5fXe}=(JH@787+OC%C{Z>*r zzVJI~8pp%Tix8wgPp$2)-@%;R5Xn2CG}j#~t%0}v75k)xWv*atIdVtP)sPir6z}rk z4A7zy`dI(Od++RHL4_=~fHRZ{5AnSEj+tF zYYt^W^25|@ep_V*C~YwF_`ab!hVQ*3V$w6cvEVZLZ(lJR}SA z3nvt|C!3wvAI|U!4e7IM?0A63O?aXq-5${4g&VQDsY^mH43Jzl2S39l{Q!wK*JM;l<_^Q}^oc#B!3Rdm7 zVx|TKOQ8H_d*f3pw@G*)-;^nJdiN(Bo~LOGGO_Q$sN2_5C&|fg*exmo!l$jv3kKL> zk=g}pv}C;m?3!mMI#Y9_4)7^Nk;Y>C8E~XLR?y{acnpr%$;Rup0##VhiufvyQu zYJ3urJa(9R5l~ZA=dEE5QD{JfLN0}QNWsYT*F&^aePXz!z=4U1VMG{o&{PH-NimT~XIDFi+# z2OLZg8mGWMmBD~e>h5Q3TBYu4%eCYoT;TZe{8z7nL;ZHdLvzbPeLjli$Bth1hNvQtFJpg zgh7*Mm~^)nr78Fq`J{Yuxnl@UAH#??-&4OwyVc!!Io)KA;d$t!JX^t0CAd6pOE@ax z{Rr2&(p25~i0L3(Akwn;GGiaKMF;yBSXVGXA969_$h>nGX7cm|EpB}GfO#K3?w*^M zmf(izREleqss?;1S85w@c1{J^dv&oRJtuiP}L@R|I)>!2!!Y7D9!#m z^o8MW7UJmJeyUL1xGKHI#>#-l4=%Jbw%~w5{?pcuD$QTzXieEbem$HRl zvNZGSVD#B9XjF}s5@b{UGQB24&_Tgv-kowgEDZ!Rm}onDmiU9isHQoWXW(V{^k9e? z-&Uy~5E;_;LBfCukjTIMP%}}h7hDVd!_`L|W8uP0z1o@--B+NoY9J&Y9i0XpXw|1{ z=)w_%&6tNiWqHPWiq0mp z3`+-UlYcUdy1(zkLYFqVb3p4e6!!4k?r&MA2HXohYu?+Gz6+x7+ED!4xH0r=T}|<8 zwc(XCp56+H!1!w*h&8S`{P#UB~Z;)rkHZSIRp*332AFS z3TY5<|DW=e$jAaH>U?CMQny_PnxFB=SZ~+d2Q79F#fO`N;xLvFJ+X+83&4vJ8`smk zWOM}fZ@9>HH(4i$RU|W*Jc-GG)CX?v<+gQCQS!l;c4giyCityw^SwGMc@`3GpKF=- zws669)>O?jiKr#;O@8V-DEgTZ7MkiXJ#t$IP%6hx?eh2LPgt*Ou`r)1Hiy|Q;uP*! z6yGYDD)n|blidt@`T6lg-&{lAXS_rL0=3y+K!x`3gq&6F6!hR+{?uzr{sr0;|2ncq zIHTNlWAFFHI#0P^yri}D<{+wHu`4u5V#{`A1`SWoi=RC&y#oJh=|v=>hgzT|J*Zt4 z(DeXKfrk^|;Wh*SyQhV5mo^0tROc+rb;i|BL!1c9zKYIm?73-Fe1*=L%&s&vjc)$i zs6StYp}7VW6A;u4o(5RjUWxo0Aa4GC^ql-4YMZY}Caff(;Uzx=|6rMHt@^o#zSjEi zJgQm!497e&k8BhoAAt{A8;biuHwxnyoHSmVRwlxTvHuIsr8F_X?YxwpTcpr_h@AMk zS6&@9Wdr8%!6Mtw9-rYn*MYOHB}N*i#X=Ja9Z=6|#i@|s-4GI#NSt}SAD3%L=KMGh z5nA|r5~Kjd^M;Mm8DHH&@Xd2H?Rv}(alsakAL}cbK~5AuVk}r-2GbiStGOk2*`b!_ z-NT7GT{JXxlXqK*cKky}W*fKULq0OXn&g?^F8O2|tkY;aUG7IEF*tSKWS8qtdEisE zT3u?p5iu+iSJ;koj~PP#_`{M9qBnio#s4&$uzS%yi&m^?u|@G!Y`A6A70PU%%X);jE^?`#zi>$&bsqG8;=nB z2~5aL9G-^()65MbWD7-z$w#deq?(VP!A<%m@>=|Ns5cQ$Q#t7O?+~C@e?wW~YWEHH z5Dyo-cHeJ6!8(60ZQ)rPB&xHSTy9oIF*j%Vm&EKN1t28aj{AznhAwQ%Y|{GZ6|ey9 z*l#oAn2A)V{xe#?7{HbUtXn1IulAk=1(ZbXp{2dLKM~>v=T|vR)bET_bd2K^p{=SXG#qdf?H&oQ8Ki zebaC>WM=2%>EQ^KHA#otO-|czCCG5m+H)iXSQo#i{r}SW#|6@UD9&sARr8@b4cIqd z#$}lI#z1vK=Brzs`{htr`)!c(*{s+?Mxf%e4F!=xO|Y| z2OKWkUmkGXW>fcy%j1I6yL6=-`;nW051=s+Eh?4$a0f=`>q4Uhxi%okZS&Qg<;WOR z5o)5(f0UPDqVCFFznWJl=90&&;ES^tI=V9}y~cif0q58oLIAI^cr+=5zRM`#B+%pp#tM7)R&?U9pX))U6; z;9ds7n7ueUBp0z^_Pd^e!UICOqA%GFCp3UzROY@#pyxxlg3fLqk z=K`TLFE4Ka2L^hz{$Y4hmq|g`_|FC{4f-fNjC1U;m`&-Z z1nUCjKjyOEM8UasnR*LRZ52H2&a)h_kDLHG>%?jco~c<7Eiz?13lR^4TqcUCkb9Uz zxO>%7QB5{x3*LIgRzFf@GzI&Gr{4!-;+X)4;KBZ}dXFlaem5e+<;SB!|HAQb%%S6*251=EG5D5(Q<9H3Ue!b zpOV%IRJS05!=8H>NkEPPb3b^0{VFyD?)PM(H5>X?*zZ=1FFrxxI%gq1|0^)`wt>V3 z&qsRtSuTji{`73TAx8$m7m&L-Sqt8+nftoI3!?)fC!m+|ag9nfP#iedG7kgMK{gO* zIjuNerg#F_e^~ZTE#d2+#TCc6eE6&!g6IEb;WhV89j*;&Yl&2C>qkL>=jD#suV&IP zhG&=jI!qDW=f0}#k&Y5NJ?#tRX(!iKk28m{PcB7wiu0V{&PczCP1Q4U_+8*lwl~Wh zj?%_h2YjzyREOx;?BPfz6MLZgrQ-daE@ck|ysjQE$F$7CBl)a1M8~*)Ag=z-^V+7y zAPDwjuivJSNB0d)>t+TMcf-J(Y>%U=Ho+AVneBDVe=4B{3fXv3i{IwIfkF21{dlwn zfsWz`(=u?{e+LtXCNifG!c~wnY<65)vO55RL_RZ>`2!!goVM=$_fonCh_*{h&rgv} zz&G)Kd&|A<-+>*=(_r76mjO-G_a^I01o#gyTaKYRzd&O#qL(wWjDaGOL$H@VCnKaWB27@Kc!?eQ4_ z36YkOW*kE6=72mCen0vTb==>&#lv`T4c0ie2v>(#y&-M-3$iP);@3+ZMDfMVKb!_lkw3Rk9Xq+* zfb%RkGK4oL3+6rJ_H~`Gjabre5iaQ$hHsG{5^87+RbD`>U0|Ij;z_VmKX@%Dpw-PlTE}RQjds>BX%Db-pu>H=5(-$1cIB0v)p?2qFl%Ilkxxldq2yUoS=Og2uQ+Q%TIF5!lk^vmW?aLL^E&K=1^lN4g4*r_M*U(6N`L%2mLQ)`8 zWH9^R68QNwXm$pi%|MQZLy=NlKsOW@HPjjP2`r$V*&%}mfy(HrUaEJAM_Zl%F^-zp z8gjZW~J`X{5xi$zNTMit!gpvRsAdVu> zer`a&o4k)g-OD?`Lp-m0AvA=>ZT)1wA_g9YRl~0i zF4eg;|=-sCL>Z4`sshxU}g$zRkM>QLebH1{`ngi9affwrkTE4lZt zOW-!OZSaZF;uk1=DgMCR-~0t)KH?s{@xrvh|4JqoX83achLB`mEx07#xvT|67b4y# z(X69w1pmta4zV<%fB=@e29NtJs36rX#EFn4+#FgdY6V@6<<)?$HaU;oVZsU2KGw)3 z{;6XDb&WwQGP;H~;EE>0s4cC~gK>aia(VWW0tnu!Pc-5^)q?ITMz(~^Hxr;HIzz4O z=8hBSo*F$XGRfbE{PViEg$m8h&>fRzKKtQ;Djd`K%U5xqB*A1E5+JF{5dn_QUFtkO zL?eLD92KUHcY*^0$C+k{QOGKMVm|a)I3=4y7f96dieUT>xaRlH*3M>b0`XZKnleRS z8~e^a{S11rxd53*^nw*xxU^s!#fKYJGrDuC*uPn^uXCI=7+3jOg@SZJHe_k_$hH|~QoixT$o?n3=TOzz2@sS$Hs*W6My7g2X zmOX_uqz_SKK#xM9t7HyI5)|;wh*WR;K7yE-t=u1{Xi@F164rn8%H?`!t{cnveL*=9 zgilx0kP_A=2t`5@#rp^bq1vzH$hY4-1r*fhdh_n3q(Xw=_EqlUzi5;UoRa%$e~lLG zDW!X5XXq**%xpL-m1Zc;)+_(^2K4HIU@NZ>9Whbrbxun)5bDG`xW`P3lI63jH3m zd}j>yTS#YvDQQ`!m|DjjXqfQ9EqG!74YVpQ<~?}+>>hBETO^8)?M^`Byp2SWS%)y_ zF|Ii^T7BSxTlSZ%OO+W3fl;Sd0U5kwfNuE|eq>fnt3l!VHDMR$4-+uX9U|7nnj#4* zjEgjt0T2J7{gV1i^Ojer;m5>qX~c?AB;ddJG;#G_5?c3f!X=x+b=QJ@BX%Yi?QCag zOiz_{dQ*n_ChAhYb?n_ChNO3)H-r8~48hmiWJN=)vhyH&fkCfMvxyJQuCptCRij#l z!>TwzKd$1ZFq^5ouFFp74<6k<33c)_~z4WDXN z2GZmB9lf--UID*Q!(71TS~1k`OuV?qMSlW@>6dt%l;R74#Po(Ji=Pe#_HnXawg+7d zgAPksVUl*CpWu_IPCtJG6;sZ0+ZFb*y~4ndzwO@d(>5%6K6{H6|6P>?iSOm69v{9S zpr>)H#6sQ~1)Kk`@(RfRDzAyRR=7AYxcDGMXanx3w5&$B`4Wn!sD+rA{^7XZ>5 zQE?8Q+ADlGJ$&6*rjRI6v_Tes3xayDlT)Oi2&x|G;+fSPi9omrh%SfJv@3kKrtm6O zN408ZO`NWdLLNDAjXOM6bi=|Ax_<5Vzmw9gf^SPw89q}&wzXmaGo@Sq)5u0+esj2~Clpb&SAZT#vP7hKC(c}0@)bqO3}j4!N` zKa~O1JpDUlvi~^WdH(@{_u=H$oZ7e0hgQRI1=7|y8>R?Tu~zeC|DqYf8t1-14x*SG|6Qoc>&mR(e*?{6yno@*%`T)cH8pYB9l`8lhP!E5D=_d z{m?xhN6QbozXQ_K`X|9Vc$Z6K)OHRMxCtINM;i|S%jSjHENh>ADC4M=6-2A6A@{R)BNZ8UZ~9}F$Ip3en}2iNlYQm3pTXV4~;wdXM|?3J+1 z>NXOTL&nT^W)mYuE-+cP_+em;npHJD-7m~ho6o_mq?-b?iBc9&QpCs+K1QVn`yv6= z6t_R#0a@&!c4I?|GuXdz&{(<4A_mboZLWj@N^B5fTjXEPxC=@RA)_bVe=bch}!&F z-}GS|Qp9OfbxUJVy*eMR;^=;bGK_4e>Wyx0(*kBS%NFzNaU2Xu4l28#(;#p)a$S-+h|=C zgtLta6a>Gz{e0W~9k@(#9ZfVJ{0ClCghpopSPn2YT(-1dpScJ15eIV?KUHPnDVFP8 z@#0z;)SQ-GZBIR{gZ%7qNm_Fk4Up?`uwi+ixCs9-|H9{xrNF?tukS??i`g!q{Y|Yf z93PhfD!x1ly)Beka3-j2+!Tc-0q;mOQEGW1mm%}ey-kPME*(4+^XUb^!;Z&@H5ct`I^vpyQihA*`rC)|04-GD*2rlGmPI11J|IU_#M5q<^T=@1K+ z-Betlb5lUm4K33o=!t zt?Vk`K9Nr9OflMp`)T3x&o7Jjf)kDHcNy=)A#_jHiOc*EEw$-9D!1J*Q4a!+{EYlO zVy;LO)$*~KwEpk~&~qt7Uf03q!6NzV>$%PqW@xeA-J{?2i9PIPjJ2#9^{9bXmltu5 zm)tIx_Q=-T)ze&rnqNI>L4TSzzb-)vLA@p)*u1p&tN!oC5b(A0i6Mkca_7o|m1W61lVZ|Ppq7|ew6Na_$E?9o zHQJl+K>B&YoiW~rx8QK!;uMewFSyA5(yhiaMG8EbgqLlJI9>qP!P@9Z^Z#*m-ho`c z@z?)I(bk}ds3D`fALm7QJomOaWI=ed8s=lSdT z&tKMkeeUbJ&ikC#Id`6DIN%Fpy?eL{#BA^Iw28P1=9j~gj;yGaA@&p%-_6e99;hiY zjH&ehro;5?<-0>4+A~-13J5{*Pp+lySH{o@N z8i{)!5(IfCT`5ge4bZpM=?VuX!lrSkFJ)uZxR2+$8|$m7`L!ME-; z5(ksPQ;aBGh}#uU2#`H1=i`5;{$@pn>y>^})6;wLYpXk;#wXhw-b-{0&viZxZfy!HIt>Pu=It zQ*dT6{KjGR2Yw)bus11S^(Q6Fq^WOF@(=Xke>Hw09f!cYixd;fkwj&nMR5aDS4kFT zZ#Q=F4|7y)m?Rst96Ym+z5%k*?WfYrGF)NWll^pNK<+ojh<2vIqYM1lToGSAVv^#4 z@+OnB<(ekPv0P&%+}QlN6t#4XTJ+JZbXelMxU4w0wI4!$TN~LR4dc#NN;;5sN8)wK zc**vS4^z0DM89#7N;DHS3@guBx`O2K*4ieMd;Dc7M2%gi!-z-)Y?(Gz%!sTQ;tAga zA?ABP8Ke@s{!L?ekyTs>N^}Xt*vTuMchh~Ipw3gLW&KVF8}zv!a+3!(`QsNkrFqZz z&b_ek|7~wYc$zlUZMK4(h>MRDMKnmy zW>B))&bx7B>N&QGT-~0MjcUQt#kH+4wW6>|olZac?4m5wAKHnfFhLmV=t*2)PpT z`C-?#L#`+KzLq2n3G$`Ql@Gb`vE}^xHuvo3KNiBJH?phy68_hvN0{_h2$vp-M7@1A z11V4F!wMYC#?ZNR%vYanKo+JvyURcdQAP58h5hnJ#*M+I94RS5_4&;P8%c;nF0NIg zfRjQ`Ig9l!{2-Jj`gil5)aQ3xtj3g|{ z1`iT?6ipw&vrmybphHjeUUohqsWz zFvEX4_3a!Ev#dEu*qR>3Uz+qPWJz!(ezg^Z?vR z%%%5}!w{_=_IGAa zEh-*nLWSz}^ryYmG7y{|styw;EIT#Lu*Qnp`sUhOy#*F)vSFM)B z-i?7ZHu8bkn9_F?G}{b5H%~4Cm!bWTvlWXzX4M#b0#?=3;dyvdeCU(I4m_ay?~f2g z6ERhYa21LyUCF^E`_S9-J)cyO`T4HW`|b2S5VPdY2@E_&!h-vKj;MvIFf8{n^juu8 zlfu|Rp;Q^B&UqxWCgl}9b@YXzMZ!->o_kVYXbz8gL#GrE<})!VdZqaRC~Q&8*xHck z#?tK{+tKqW5eV>9RlI#Wvl;(3KFX{s(_|s@k-YBC0kS_3WbH1}e6%|j@7zc=tWl|) zScu3MQRGV0#4(}E7so1vYOvUUU5Mv-oeaVUBIv%!*y+Q~;NEItcZCkl+`SlGlAdOS z9j{Z&v{l&3Fe@Q!Gigai7|Z_Hie9%k-iOA^k5dd=GH>ExNKLSGdq)c{eXZD$_Ohx6 zqd&yI^Xioc;Y#S2BrS=tA#59X%~+p0^d0hD6!N=#oepB(p*)6RnTb^VGrKt>Q}DnH zhL^>SxEx5mIQEmqSBkBQ@I}kcN8Writ_t>>D|U;T+a4fWU{-DE_$!5imM87`i$OCu zuur14bw}-0d}C%65S-GAz}d9oj(<*Um$Ca%R$h_+J{d%e?>LayaOxC%YGtnY<`O%z zAx*&G#yh?e(8`_nPYLwUV+DGwAzwSe*KT=dAyKCU&5jz4-t+N_lmw(vm?=`oK}L2xb5tW zsGHE1`$~mF^{pPQ@(;!#_12e%zlXtX<@Q#EocuBg z$_n-M*>taEgcY#qoQeBShCuNPAI>x+{^r!XD`HGpB`vspy*2iY245YropM_gt9JFH zP-uDA)furu927_y%-qlxz?GN=%NDJxBcL-s`8|cFd?$uiWk=Z?2(xL`QZqWD!=R$d3LXtI+J^1tfb`q^ch5ka zWx?C-fnPOtTD@5|E?+Q5=vG|x_4ud;P|n>J>y;hi#rhqA-X67%G2%Hj_h?mKmIe2Z z=b?XOX@W4wv_{Uq<*EbMi5pq32MD={kL!xdiN&+;!7Th;pf)`y9D2X=HlQdM?~x>svKqS51Ly-#ARwAikDSh~RI^Lh0-k_X$(d!$V(;ghaI8>k{H zj~)IRR8rM^PLOVW;=|rL-36}X*sO1+Z!;mS%H8~Uby`j zC#2Vy~RI>JNMcl2iX%7wLjpaAIx8l@I#h&kxTikJGG0 z`j-ELJ5{rVFy9~NH#kvs2_#`c)pir40>xxDlSSu~eq@y|_s^KT7eiB_MR)KxV=y{9 z`3L$7h{^H)%m0e(*ba4!CkCBgu8CuU2+;E-Odcc7A%0;JQ{Swj_H4yBnDS~oJ56jr z5niSvO-G5T_n2tedyv^CyEcfn2^ z?=C6tQK8+zj|ia|@?xsv@v!fdZ9f%Rx(*4aDIdl6T&d7|*vuB-MQI0%Fl+Kg-W5lT zy9M36&T1wCE_tag>+FyM7+L84tjt|7gnL%xQH4a~D`=SvJtFgMA`u;Znw*hrO2a0KKSP{8YnuI^4|!*hQwcUP34mMk0>@` z7*F7oPX+rzmY>Hz;Q}NZw{X0(of3prt;ziZ1tE{nReh3{gN%5dwF1nkG4}m;;UZMY zl{|7@6g8)UC*y^-cu~4J72fL1#)9;Wwu=KBiiF`MNnuBV-pC-nU0+$tK0-N9oc`aM zf3$+`=!K3_S(#n{oY zeEM=69)#8JjpuHp$0zaYW1C7uG-h9g=5SxPdL8#!nS&BwvyNJd zzkKl}cC5ENT9Em+4&P;}$ICV+6A@$m`$6L~9d11LU5hVV?wQ8N{nU|}W0tz8GbwUp zbusI}ve4X)$Dir-kkA-e6y}*j^nK}8uTeQpE8+U!=7HfS9Tu1q;pdA9&^5x|hk*uH z&xGm`_Z;CA%Y#%2n0hlStQKID3@V-?x}T9O?TDQCIe6i;?_Ugkm22kUDh`46bLAHb zhl5seDP`gg+ukS=C`c!heCF4ai7rBC1;>NZ`H(b@+a?d$QbWNRle_<x_S=ijL<5YnX7eGI z@SsvWX#2M&?a=RwXQzypGh~ndhp$8JpK^9B?Lo81p8%`xA-A!(5GcRAl4K3#_V7EG zS}U6HyL_S9WsGJEBkNCnFV7w6CLZOwwUS*F@ymbpJP@?9eF*LgQ?#iD`tpcoFBK9f zqx6Sl>K>0uO)X;{#f7)nu9jeO)FzO7bea_cQ*9CZtnVdZy<6&Y%89R^u*dpe=cwz?NAR)~5gdBY zMFdp+=}sJHS$KhGDy~ZPov|;lyGe6EM4oaP-Le9$V`%~AQ0p@3)W75x2_sSKU(=R? z#C3FjOI~n@qLXkeC06P(jKx$Xf6&pH zLsr5ip-b(h3sQST8>7Eok3?6%zTc-0C#FHEU`Lc-S7J15$Rj@}-40TPh}P%Fhwl9m zLPu_n(Py$SIZV&D?tC!%We9Sn&LwPR!-UdvIc6rW*`plS%@!{h{yw*f)Ep;^PijIT*RSB73Hd0fW(7uunE^XIw{N2Dt z*Og{74&spFRQKuWcWZlVtW;3NKd!X6fD@gy`4MbAoUk_Uk^fP8u?gbSRGJ+NWf|~L zN-r#-%gG>04SHU6m9l5UE~0v|>Be6*6f&6yJifBXiSvhZ4c{d`Z$|IC{VS!$K^6EQ z{iVp@Sg13;c69O#Nz1ZBZg0IHUJ`!iy-XrF+%(-p0>K}bb~lQ0e4N*X z`;3Ti+~t6)SkTrTa*8$NLe`HO<%n_tf<+RO{AGB)Iu6Q7vrROsUP%y5^^wrNBG-Wy z1*6J=#twosAMvYZ7p3mn+#_)+ql0dO6yG3X6X&D!{X-0B>o_S?s}r43zNV)BJ=oqE z=dyDsByG)Xi5hg45(jz*0f;}>ZA?+Txd$m9PVzjBW;#c_4(P@I3Tv|A^S4WTcQ;6# zMH{ywHP7`V7F2k)g&!-esf3~gqpk~e#8E7;g`BK9)%Or&RezdPxAo>h^V|Nyok+sLQ@Ri39a9YChXR1{(>PS0%z~9{!+5oLF&mSG>I_uKtO=L;Act50Vhs@_Qq) zym4vj+o8{dcGZdTVZtQQ^}F~^B1d$%Uy-XaD;dR64AQ*v$9nLJh%>H%}fU)w9LAj9;==MZu$X6)CnR5%g6Ktg#!uNM8>UK4!C%JOdQ zzI+TJiBp#8SM!KT_zr6GQs$4faN)hZ$<#vFrkj^kuXHt}_rUlf`?-um^5609=YIcc z`(b+I{;`ibxUO~{^!X`csw`}Cn9;Erl)u2*io%mabQe=kY(O)hxR<`CKpN*(&jvmA z{+NU`f?Rlihwumd`%sxaAL12<$@IyN4yOwv;I!7ayT-Lri_^lla;&2a2{}z~RcCvs zPZ4$knPGJ?+rN-2W_oeAPV@$WxZ2`K;y+?jvhBrPoo|z4sRpW-&t?mV**wA`$2eju zN!Rem*|oaRV?h@SF}%4f`|jQ(d|$f+i5X-fOqJh|Jer&hG2ODo6S=8Mfu|?A3`8BN zu|XQj-{IBx%(WS#bG@!r{!ORQ$YmhVbTyn<7Q^jV*rIkjW2F=%na~nj41>h@Db7-^ zvC2w(?`@-|ZP8mOT=dFausE*^u0`^TtQ@|)SW0>quVv8{ zjq$O?e)4XP$o>fl%80cbOC#4Uz7|rvQIFxV7Gw+EPZeKXQp6i>i9>61eydmx{j0Ri z{{lB}r=BwdUov*G0w&#zT<0IbdbR;k2Wtnxst)k{JCV;ssTy zBG2ir!FdGZlsjp*1POui8Aro5>+0M#4!;Xz+gDG7k>maE?f&u1S_5uc`xc#}>4?VI z*z;^j8PNye5pgatR*~R-J=<5;&ot>Z2>E|(ol-4^2OzSbzm|NstB&Ywr+OE%5%&~= zO`3f<^V1#ZKXkc&I!xFW%}<1txT5LzBjB^-Sz3)z$=Gk9Pu`zLzVt1*-U7Ru5G-f-t8FS&iRIS=8na!yXHY1eD4Z@yl$-G1 z6FzeH?Z6DK?ed&{?cI?Ek94mvqkbhNtm@r+#L=bn8@E>;Fors=mEelSYG~y#O$vPE z42{sY7UDtq5gH={b2oM*u&j?WkmRejtp}FVyR`a=WWYjz1>aqo?M56O%f3b{_sR-VR~ZceL)}2*6R&Mk4_q`o3E;H;Hvf&Q8oPxWMz2#aMO;EL=XR5qf#$99ZIKs zrETBQs9^49PC@2}Uxc2Wp0q<%=1u^7%KQ6X`Fg4%ebg|r-#)z>vRW69G}#n=Lh$tL z2cD=tEzEH+gt@+cMT1=0a`79_wTS|QWUVP7v*Ktx3{)_)em?9v_g3G9s4h>|IDz2Y zHuKA=2dD7i#zp;soNz5Xxh-P!ovoDE(9Y&fdkaq8LqzP5QKo|}6+ASr9Y54lO$RNG zHkREF4UQ0vpIrWXBxG4IGcMAm8%!*1t&fCR%a@orNjlYOx4*quf|_j#kC!5{aWHB~ z?bGckr$&yWccbUusua`~&eJ^?Rl0$HU%6zfxA_+E>c17SW6fi&Xz4Ok$diiBMsFV3 zQP~W8#bRuBy8Z6HD1{DU<*HaXBfF$oUxNq@{IA0$Ar&6~R4!8DmrB`jKX z-1nV?nBqZ~3q#@;u+ExuB~5DY8PHnuZ~qB5xQV7PnWvZa9GX(i+NSCa!)gSh2p7_IdNV z6al8pA89qZB`g(>I_f&+>880WL_gBI|3nz{4?#v?{LB3Ki_4g~u+N8CracSvK4N36 zPI=6D{F})^ReHZV9t%s2q>A!xg0E9HnojIDH9q*%an8MO-U;L6x3?tLc%tB&D>xV4 zQ5z3sw@Z`~=h=-w-&t=cut-edw}ONIIvRIm6T)Os>lcS5X#`z=tajj5B`-`ZJ9pLj z%MnE6+LH3;e_e>^O~I<=6D~)26mp-fjEH^u1tIDFKi(7@3*ohlAnoH3+LOo*()RGQ zJ^K^R3S8Y~;}uopCTqQvbG9MO-|Ly~@Vw@|%%C&`w_E^>jVFiaOavXR3Hj zLfHP47)@?npA0`f&szW7E*>c8b2IUaa?25+31^X0 zaq7OM#D$}&wYZaea;jfD`Wko&*b`F}(n>*|*A#25Y3PAWUFrs#p_8&u$|>GZEj1xT z2+{8Qexu%m{^9OvMEQ_G9pcQIaS1Jd38cjFjE|Q;F9jpVqAur4+{ZY)aCV8Fc$#ws zhc)YLY^{CvW4DTIw%_;<89bzsJw-$EW(4<}e;4&?>W-}6j zXR_p`&4#j(_3cvG33s{A*quZ>;l}Gt1>?VFj~3}foRBzq`^Pt*V`b347UW-_>+Fm? z@d`(Ev#liJoKnYfto0~0!j4hg;2=>fLaU9zS7_Lc@Tm_v3qS4(3B!Lml9M3bYf~LHr+FL3pG`)rTS8}vWMOT;6XAJ>=y7Rz&L`Sp1aOX-)-2k40I3G# zo!yr=@-Vic=&5m5l^6ci)^0M@(^L@kBY0hJe(pe$w&~yL6$T~<%#3({^jlj%MCM#V zqu%NVbk=_hQhxP&0L5ucMz1W7+TqrbJK-Zq7e>L{?B_Uof$tI@CzO)WjO@Im}DJRb|D;%neI1Lvtx46mC5d#qm;n{F!x~C zU{H^|h}Y&%bUkx85>RS(|HF>68j*NnR?5NMB$WjkB>`G-%_UB#9q0>X*6lThk^xQI zEApMjc*K6gzUH1;736yxojL*n)sa_pUYeDTV`61BjB(wvDKl;Xy4&oD#zOyPWB&Qc zLNCtbQC!pbLe4lI;pS@Km;Pal;4qRfqxzBQ|<1plR=_rlrlvzehRuz7Wr45Z>DG>GWh z+J0T#i#i=McExjqKVadJiJ{6#(j%fA`3~c=+pR@#w9QPivY@Vo_F^^!Co5?r%a*_|)^j%ul8`m$q>g5hNjyvQCL3&M|hN^WrBWT+?;Mq>ezsAz0jq zV8Y4BB8{&=BZ8Qs!k^c*lb}t#McrM7s$ObkiM3tQsS2MNMHdX^Fh3ULLJ`gC0dqbV zh1-8)10a*kmB?vXL5J>_-tOdXf@8=R|8I!iMOY2r6zMmPIf+W3TJ%%fiTPLDkSX)Z ziDxERVRg*!&50LU+3+yf@`y9G(ZRjzX$lEVBV`~v96q|x{`MOP*-|rWzT^fJS+7R) ziSl1ZYju~#bnC?vn9yY};VrN!KsJ@cE|T3_P=9&#* zhk|rL{N*2J>=r*Ug`}`~i{4JxY4F-?Rz7)4Qr?iJKAC@qvwFq~Y|Iq=EQY;Kc*e(f zwS4OWFCy0-Z8|Pyl5O!RetA^5QdL5Lid$38&d++cK&(XIH+eeSEAX>2WcX7_O@eHy zl{)q;4I!pVQQbZ)cHIQqJ7zb1`f2TvdgG_*h5Nb1IMgS<=TOyiFBBZIOPpcgt_D-2 z@gnaR?M(>(Y|M!hX(go7coiF)W4~tbwrbI`$&dRv=yUX#PB-a1!R1Jj$@<80GKRtu zX8GtH8i=M*i^GLk#K-gR?)?%EqiI<%s6?LpB;O|-ny=EL|9q3n$Mg9LMwbc>cgUw) ze|Xk3oFKOH1~JX&pu^QN=5EuohkpsQ4{ zKD%)^i^yrJpYUumHHSf4bx21Gy*^QzMtaw)FQJN?^UoHTp6KflQ?tkW;vH^J;d|e< z!GEVbOCj>ErfM;2BoJ~8K|lACHJZa{`6;(Z=W(LJhp)ci&bw$fyz%;&NXD}Ch!|Xk zx36>cyhlgy%<(M;yTg#UMH<+v$@T>{hbk%>1Xxew9$BN+A^~SZ{6nUq$neo>3=(Wh zH^CBW{FdeG_{c%_9?l!bSU1uudhqPR>${Ou4?LhTzr(0AVeA^}M8E!VN_g}Gn_)D1 zL)xPa@Ob6k8~ZlLdZoKha+h1}?jAwtx!HgBS2Aq})2rhtQ^|MhVA>Iw{44*;48kkU z-m+u(TLtb0i$@c>>)XiUe_3?CIx7-mB`Q6|j0*=)f9dh@oS#IJ;67W#g3ZacW~6SW z*^&~dN@2Lmn*TtwV9Hiy)lU);Le}H}Iq7SW_V&+t7^RKWSPsT?5rMj@m}3^^∓F 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∓BH&LglMVXA7oxWcYL?@CrMnflU)rzc=rYjweOy+ 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

    kJhn8)W8awaBJSa4m~tJmwQcd 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

    PT%wKIzB5# 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

    %aY5*S05yB`>!dvLGZIptej;&plbV8 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

    |yA|~3U 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�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 a&F~e!wu^H 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 >35JlP=cDi+ES5$A@#wF~ZmurRoo#q0VgL#Bn}N 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 z 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¬BZd2-RiT}HQ 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

    <#O@f+|)E6y0OvE9TC@+nNRJ;NfpiN4 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

    S%6To}A%mhpQL@#}AJ2<{u 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%0A2KZx1!xF2W$0|?Fq;(w*Rv4?;L-~WdJ2@wC~ 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 z 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 CFzp9_j9)UVf&uz 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 Date: Wed, 7 Nov 2018 14:23:00 +0100 Subject: [PATCH 134/233] Update FEATURE_SET.md with latest measurements from CI --- doc/FEATURE_SET.md | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/doc/FEATURE_SET.md b/doc/FEATURE_SET.md index 9115114867..116705d7c9 100644 --- a/doc/FEATURE_SET.md +++ b/doc/FEATURE_SET.md @@ -34,23 +34,23 @@ The Physical layer implements **3GPP 36.211**, **36.212**, **36.213** and provid ### Performances ### -**Transmission Mode, Bandwidth** | **Expected Throughput** | **Conditions** --------------------------------- | ----------------------- | ----------------: -FDD DL: 5 MHz, 25 PRBS/ MCS 28 | 16 - 17 Mbit/s | measured with COTS UE Cat 3/4 -FDD DL: 10 MHz, 50 PRBS/ MCS 28 | 34 - 35 Mbit/s | measured with COTS UE Cat 3/4 -FDD DL: 20 MHz, 100 PRBS/ MCS 28 | 70 Mbit/s | measured with COTS UE Cat 3/4 +**Transmission Mode, Bandwidth** | **Expected Throughput** | **Measured Throughput** | **Measurement Conditions** +-------------------------------- | ----------------------- | ------------------------| ----------------: +FDD DL: 5 MHz, 25 PRBS/ MCS 28 | 16 - 17 Mbit/s | TM1: 17.0 Mbits/s | COTS-UE Cat 4 (150/50 Mbps) +FDD DL: 10 MHz, 50 PRBS/ MCS 28 | 34 - 35 Mbit/s | TM1: 32.8 Mbits/s | COTS-UE Cat 4 (150/50 Mbps) +FDD DL: 20 MHz, 100 PRBS/ MCS 28 | 70 Mbit/s | TM1: 69.9 Mbits/s | COTS-UE Cat 4 (150/50 Mbps) + | | | +FDD UL: 5 MHz, 25 PRBS/ MCS 20 | 9 Mbit/s | TM1: 8.28 Mbits/s | COTS-UE Cat 4 (150/50 Mbps) +FDD UL: 10 MHz, 50 PRBS/ MCS 20 | 17 Mbit/s | TM1: 15.2 Mbits/s | COTS-UE Cat 4 (150/50 Mbps) +FDD UL: 20 MHz, 100 PRBS/ MCS 20 | 35 Mbit/s | TM1: 18.6 Mbits/s | COTS-UE Cat 4 (150/50 Mbps) | | -FDD UL: 5 MHz, 25 PRBS/ MCS 20 | 9 Mbit/s | measured with COTS UE Cat 3/4 -FDD UL: 10 MHz, 50 PRBS/ MCS 20 | 17 Mbit/s | measured with COTS UE Cat 3/4 -FDD UL: 20 MHz, 100 PRBS/ MCS 20 | 35 Mbit/s | measured with COTS UE Cat 3/4 - | | -TDD DL: 5 MHz, 25 PRBS/ MCS **XX** | **TBC** Mbit/s | -TDD DL: 10 MHz, 50 PRBS/ MCS **XX** | **TBC** Mbit/s | -TDD DL: 20 MHz, 100 PRBS/ MCS **XX** | **TBC** Mbit/s | - | | -TDD UL: 5 MHz, 25 PRBS/ MCS **XX** | **TBC** Mbit/s | -TDD UL: 10 MHz, 50 PRBS/ MCS **XX** | **TBC** Mbit/s | -TDD UL: 20 MHz, 100 PRBS/ MCS **XX** | **TBC** Mbit/s | +TDD DL: 5 MHz, 25 PRBS/ MCS **XX** | **TBC** Mbit/s | 3.33 Mbits/s | COTS-UE Cat 4 (150/50 Mbps) +TDD DL: 10 MHz, 50 PRBS/ MCS **XX** | **TBC** Mbit/s | 8.90 Mbits/s | COTS-UE Cat 4 (150/50 Mbps) +TDD DL: 20 MHz, 100 PRBS/ MCS **XX** | **TBC** Mbit/s | N/A | COTS-UE Cat 4 (150/50 Mbps) + | | | +TDD UL: 5 MHz, 25 PRBS/ MCS **XX** | **TBC** Mbit/s | 1.66 Mbits/s | COTS-UE Cat 4 (150/50 Mbps) +TDD UL: 10 MHz, 50 PRBS/ MCS **XX** | **TBC** Mbit/s | 1.89 Mbits/s | COTS-UE Cat 4 (150/50 Mbps) +TDD UL: 20 MHz, 100 PRBS/ MCS **XX** | **TBC** Mbit/s | N/A | COTS-UE Cat 4 (150/50 Mbps) - Number of supported UEs: **To Be Completed** From d00f80b5ddda78c22ac5661efa7d3f40cb87f5c1 Mon Sep 17 00:00:00 2001 From: Raphael Defosseux Date: Thu, 8 Nov 2018 17:29:41 +0100 Subject: [PATCH 135/233] Update FEATURE_SET.md for the UE features --- doc/FEATURE_SET.md | 44 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 43 insertions(+), 1 deletion(-) diff --git a/doc/FEATURE_SET.md b/doc/FEATURE_SET.md index 116705d7c9..103f132728 100644 --- a/doc/FEATURE_SET.md +++ b/doc/FEATURE_SET.md @@ -9,6 +9,11 @@ 6. [eNB X2AP](#enb-x2ap) 7. [eNB Advanced Features](#enb-advanced-features) 2. [OpenAirInterface UE Feature Set](#openairinterface-ue-feature-set) + 1. [LTE UE PHY Layer](#lte-ue-phy-layer) + 2. [LTE UE MAC Layer](#lte-ue-mac-layer) + 3. [LTE UE RLC Layer](#lte-ue-rlc-layer) + 4. [LTE UE PDCP Layer](#lte-ue-pdcp-layer) + 5. [LTE UE RRC Layer](#lte-ue-rrc-layer) # OpenAirInterface Block diagram # @@ -125,5 +130,42 @@ The X2AP layer is based on **3GPP 36.423** v14.6.0 and implements the following # OpenAirInterface UE Feature Set # -**To be completed** +## LTE UE PHY Layer ## +The Physical layer implements **3GPP 36.211**, **36.212**, **36.213** and provides the following features: + +- LTE release 8.6 compliant, and implements a subset of release 10 +- FDD and TDD configurations: 1 (experimental) and 3 +- Bandwidth: 5, 10, and 20 MHz +- Transmission modes: 1, 2 (stable) +- Max number of antennas: 2 +- CQI/PMI reporting: aperiodic, feedback mode 3 - 0 and 3 - 1 +- PRACH preamble format 0 +- All downlink (DL) channels are supported: PSS, SSS, PBCH, PCFICH, PHICH, PDCCH, PDSCH, PMCH +- All uplink (UL) channels are supported: PRACH, PUSCH, PUCCH (format 1/1a/1b), SRS, DRS + +## LTE UE MAC Layer ## + +The MAC layer implements a subset of the **3GPP 36.321** release v8.6 in support of BCH, DLSCH, RACH, and ULSCH channels. + +- RRC interface for CCCH, DCCH, and DTCH +- HARQ Support +- RA procedures and RNTI management +- RLC interface (AM, UM) +- UL power control +- Link adaptation + +## LTE UE RLC Layer ## + +The RLC layer implements a full specification of the 3GPP 36.322 release v9.3. + +## LTE UE PDCP Layer ## + +The current PDCP layer is header compliant with **3GPP 36.323** Rel 10.1.0. + +## LTE UE RRC Layer ## + +The RRC layer is based on **3GPP 36.331** v14.3.0 and implements the following functions: + +- System Information decoding +- RRC connection establishment From d3f8f9d65b83fb150b95a54018dbdbeb87e35107 Mon Sep 17 00:00:00 2001 From: OAI-admin Date: Mon, 12 Nov 2018 07:46:32 +0100 Subject: [PATCH 136/233] End of bug fix: S1 id unknown after detach request for switch off in idle --- openair2/RRC/LTE/rrc_eNB_S1AP.c | 81 ++++++++++++------------------- openair3/S1AP/s1ap_eNB_handlers.c | 11 +++-- 2 files changed, 37 insertions(+), 55 deletions(-) diff --git a/openair2/RRC/LTE/rrc_eNB_S1AP.c b/openair2/RRC/LTE/rrc_eNB_S1AP.c index 81d5a6ae2b..f89bb76cff 100644 --- a/openair2/RRC/LTE/rrc_eNB_S1AP.c +++ b/openair2/RRC/LTE/rrc_eNB_S1AP.c @@ -37,8 +37,8 @@ # include "enb_config.h" # include "common/ran_context.h" /****************************************/ -//# include "../../S1AP/s1ap_eNB_defs.h" -//# include "s1ap_eNB_management_procedures.h" +# include "s1ap_eNB_defs.h" +# include "s1ap_eNB_management_procedures.h" # include "s1ap_eNB_ue_context.h" /****************************************/ @@ -183,12 +183,13 @@ rrc_eNB_S1AP_get_ue_ids( instance_t instance = 0; s1ap_eNB_instance_t *s1ap_eNB_instance_p = NULL; s1ap_eNB_ue_context_t *ue_desc_p = NULL; + rrc_eNB_ue_context_t *ue_context_p = NULL; /*****************************/ hashtable_rc_t h_rc; if (ue_initial_id != UE_INITIAL_ID_INVALID) { h_rc = hashtable_get(rrc_instance_pP->initial_id2_s1ap_ids, (hash_key_t)ue_initial_id, (void**)&result); - + if (h_rc == HASH_TABLE_OK) { if (eNB_ue_s1ap_id > 0) { @@ -216,10 +217,10 @@ rrc_eNB_S1AP_get_ue_ids( if ((result->ue_initial_id != result2->ue_initial_id) || (result->eNB_ue_s1ap_id != result2->eNB_ue_s1ap_id)) { - LOG_E(S1AP, "[eNB %ld] Error while hashtable_get, two rrc_ue_s1ap_ids_t that should be equal, are not: \ - ue_initial_id 1 = %"PRIu16", \ - ue_initial_id 2 = %"PRIu16", \ - eNB_ue_s1ap_id 1 = %"PRIu32", \ + LOG_E(S1AP, "[eNB %ld] Error while hashtable_get, two rrc_ue_s1ap_ids_t that should be equal, are not:\n \ + ue_initial_id 1 = %"PRIu16",\n \ + ue_initial_id 2 = %"PRIu16",\n \ + eNB_ue_s1ap_id 1 = %"PRIu32",\n \ eNB_ue_s1ap_id 2 = %"PRIu32"\n", rrc_instance_pP - RC.rrc[0], result->ue_initial_id, @@ -258,8 +259,7 @@ rrc_eNB_S1AP_get_ue_ids( * -> if the UE is in IDLE, hence no S1 context exist (in this case [h_rc != HASH_TABLE_OK] is normal) * -> ... (?) */ - LOG_E(S1AP, "[eNB %ld] In hashtable_get, couldn't find in s1ap_id2_s1ap_ids eNB_ue_s1ap_id %"PRIu32", trying \ - to find it through S1AP context\n", + LOG_E(S1AP, "[eNB %ld] In hashtable_get, couldn't find in s1ap_id2_s1ap_ids eNB_ue_s1ap_id %"PRIu32", trying to find it through S1AP context\n", rrc_instance_pP - RC.rrc[0], eNB_ue_s1ap_id); @@ -267,15 +267,34 @@ rrc_eNB_S1AP_get_ue_ids( s1ap_eNB_instance_p = s1ap_eNB_get_instance(instance); // get s1ap_eNB_instance + // s1ap_eNB_instance_p = s1ap_eNB_get_instance((uint8_t) rrc_instance_pP - RC.rrc[0]); // get s1ap_eNB_instance + // s1ap_eNB_instance_t *s1ap_eNB_get_instance(uint8_t mod_id); + ue_desc_p = s1ap_eNB_get_ue_context(s1ap_eNB_instance_p, eNB_ue_s1ap_id); // get s1ap_eNB_ue_context if (ue_desc_p != NULL) { + result = rrc_eNB_S1AP_get_ue_ids(rrc_instance_pP, ue_desc_p->ue_initial_id, eNB_ue_s1ap_id); + ue_context_p = rrc_eNB_get_ue_context(RC.rrc[ENB_INSTANCE_TO_MODULE_ID(instance)], result->ue_rnti); + + if ((ue_context_p != NULL) && (ue_context_p->ue_context.eNB_ue_s1ap_id == 0)) { + + ue_context_p->ue_context.eNB_ue_s1ap_id = eNB_ue_s1ap_id; + + } else { + + LOG_E(RRC, "[eNB %ld] Incoherence between RRC context and S1AP context (%d != %d) for UE RNTI %d or UE RRC context doesn't exist\n", + rrc_instance_pP - RC.rrc[0], + ue_context_p->ue_context.eNB_ue_s1ap_id, + eNB_ue_s1ap_id, + result->ue_rnti); + + } + } else { - LOG_E(S1AP, "[eNB %ld] In hashtable_get, couldn't find in s1ap_id2_s1ap_ids eNB_ue_s1ap_id %"PRIu32", even \ - when looking at S1AP context\n", + LOG_E(S1AP, "[eNB %ld] In hashtable_get, couldn't find in s1ap_id2_s1ap_ids eNB_ue_s1ap_id %"PRIu32", even when looking at S1AP context\n", rrc_instance_pP - RC.rrc[0], eNB_ue_s1ap_id); @@ -286,44 +305,6 @@ rrc_eNB_S1AP_get_ue_ids( } // end else (ue_initial_id == UE_INITIAL_ID_INVALID) return result; - - // we assume that a rrc_ue_s1ap_ids_s is initially inserted in initial_id2_s1ap_ids - /* - if (eNB_ue_s1ap_id > 0) { - h_rc = hashtable_get(rrc_instance_pP->s1ap_id2_s1ap_ids, (hash_key_t)eNB_ue_s1ap_id, (void**)&result); - } - - if (ue_initial_id != UE_INITIAL_ID_INVALID) { - h_rc = hashtable_get(rrc_instance_pP->initial_id2_s1ap_ids, (hash_key_t)ue_initial_id, (void**)&result); - - if (h_rc == HASH_TABLE_OK) { - - if (eNB_ue_s1ap_id > 0) { - h_rc = hashtable_get(rrc_instance_pP->s1ap_id2_s1ap_ids, (hash_key_t)eNB_ue_s1ap_id, (void**)&result2); - - if (h_rc != HASH_TABLE_OK) { - result2 = malloc(sizeof(*result2)); - - if (NULL != result2) { - *result2 = *result; - - result2->eNB_ue_s1ap_id = eNB_ue_s1ap_id; - result->eNB_ue_s1ap_id = eNB_ue_s1ap_id; - - h_rc = hashtable_insert(rrc_instance_pP->s1ap_id2_s1ap_ids, (hash_key_t)eNB_ue_s1ap_id, result2); - - if (h_rc != HASH_TABLE_OK) { - LOG_E(S1AP, "[eNB %ld] Error while hashtable_insert in s1ap_id2_s1ap_ids eNB_ue_s1ap_id %"PRIu32"\n", - rrc_instance_pP - RC.rrc[0], - eNB_ue_s1ap_id); - } - } - } - } - } - } - return result; - */ } //------------------------------------------------------------------------------ @@ -1364,7 +1345,7 @@ rrc_eNB_process_S1AP_UE_CONTEXT_RELEASE_COMMAND( eNB_ue_s1ap_id = S1AP_UE_CONTEXT_RELEASE_COMMAND(msg_p).eNB_ue_s1ap_id; ue_context_p = rrc_eNB_get_ue_context_from_s1ap_ids(instance, UE_INITIAL_ID_INVALID, eNB_ue_s1ap_id); - + if (ue_context_p == NULL) { /* Can not associate this message to an UE index */ MessageDef *msg_complete_p = NULL; diff --git a/openair3/S1AP/s1ap_eNB_handlers.c b/openair3/S1AP/s1ap_eNB_handlers.c index 5c6b208b87..4a16450206 100644 --- a/openair3/S1AP/s1ap_eNB_handlers.c +++ b/openair3/S1AP/s1ap_eNB_handlers.c @@ -863,11 +863,7 @@ int s1ap_eNB_handle_ue_context_release_command(uint32_t assoc_id, "existing UE context 0x%06lx\n", assoc_id, enb_ue_s1ap_id); - /*MessageDef *msg_complete_p; - msg_complete_p = itti_alloc_new_message(TASK_RRC_ENB, S1AP_UE_CONTEXT_RELEASE_COMPLETE); - S1AP_UE_CONTEXT_RELEASE_COMPLETE(msg_complete_p).eNB_ue_s1ap_id = enb_ue_s1ap_id; - itti_send_msg_to_task(TASK_S1AP, ue_desc_p->eNB_instance->instance <=> 0, msg_complete_p); - */ + return -1; } else { MSC_LOG_TX_MESSAGE( @@ -877,6 +873,11 @@ int s1ap_eNB_handle_ue_context_release_command(uint32_t assoc_id, "0 S1AP_UE_CONTEXT_RELEASE_COMMAND/%d eNB_ue_s1ap_id "S1AP_UE_ID_FMT" ", enb_ue_s1ap_id); message_p = itti_alloc_new_message(TASK_S1AP, S1AP_UE_CONTEXT_RELEASE_COMMAND); + + if (ue_desc_p->mme_ue_s1ap_id == 0) { // case of Detach Request and switch off from RRC_IDLE mode + ue_desc_p->mme_ue_s1ap_id = mme_ue_s1ap_id; + } + S1AP_UE_CONTEXT_RELEASE_COMMAND(message_p).eNB_ue_s1ap_id = enb_ue_s1ap_id; itti_send_msg_to_task(TASK_RRC_ENB, ue_desc_p->eNB_instance->instance, message_p); return 0; From 4931a300ad234b116cd7cade5cc28b625434b363 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Mon, 12 Nov 2018 10:45:44 +0100 Subject: [PATCH 137/233] T: macpdu2wireshark: run live, limit MIB/SIBs recording, cleanup A new option -live has been added to run live (ie. like the 'enb' tracer) and options -live-ip and -live-port to select IP/port of the machine running the eNodeB. Some new options to control MIB and SIBs recording have been added. Some global variables have been removed. --- common/utils/T/tracer/macpdu2wireshark.c | 90 ++++++++++++++++++++---- 1 file changed, 77 insertions(+), 13 deletions(-) diff --git a/common/utils/T/tracer/macpdu2wireshark.c b/common/utils/T/tracer/macpdu2wireshark.c index f65fdf34c3..d9bcb8b7f5 100644 --- a/common/utils/T/tracer/macpdu2wireshark.c +++ b/common/utils/T/tracer/macpdu2wireshark.c @@ -14,10 +14,10 @@ #define DEFAULT_IP "127.0.0.1" #define DEFAULT_PORT 9999 -#define NO_PREAMBLE -1 +#define DEFAULT_LIVE_IP "127.0.0.1" +#define DEFAULT_LIVE_PORT 2021 -int no_sib = 0; -int no_mib = 0; +#define NO_PREAMBLE -1 typedef struct { int socket; @@ -46,6 +46,15 @@ typedef struct { int rar_frame; int rar_subframe; int rar_data; + /* config */ + int no_mib; + int no_sib; + int max_mib; + int max_sib; + int live; + /* runtime vars */ + int cur_mib; + int cur_sib; } ev_data; void trace(ev_data *d, int direction, int rnti_type, int rnti, @@ -104,7 +113,11 @@ void dl(void *_d, event e) { ev_data *d = _d; - if (e.e[d->dl_rnti].i == 0xffff && no_sib) return; + if (e.e[d->dl_rnti].i == 0xffff) { + if (d->no_sib) return; + if (d->max_sib && d->cur_sib == d->max_sib) return; + d->cur_sib++; + } trace(d, DIRECTION_DOWNLINK, e.e[d->dl_rnti].i != 0xffff ? C_RNTI : SI_RNTI, e.e[d->dl_rnti].i, @@ -117,7 +130,9 @@ void mib(void *_d, event e) { ev_data *d = _d; - if (no_mib) return; + if (d->no_mib) return; + if (d->max_mib && d->cur_mib == d->max_mib) return; + d->cur_mib++; trace(d, DIRECTION_DOWNLINK, NO_RNTI, 0, e.e[d->mib_frame].i, e.e[d->mib_subframe].i, @@ -269,9 +284,18 @@ void usage(void) " -ip send packets to this IP address (default %s)\n" " -p send packets to this port (default %d)\n" " -no-mib do not report MIB\n" -" -no-sib do not report SIBs\n", +" -no-sib do not report SIBs\n" +" -max-mib report at maximum n MIB\n" +" -max-sib report at maximum n SIBs\n" +" -live run live\n" +" -live-ip tracee's IP address (default %p)\n" +" -live-port tracee's port (default %d)\n" +"-i and -live are mutually exclusive options. One of them must be provided\n" +"but not both.\n", DEFAULT_IP, - DEFAULT_PORT + DEFAULT_PORT, + DEFAULT_LIVE_IP, + DEFAULT_LIVE_PORT ); exit(1); } @@ -288,6 +312,9 @@ int main(int n, char **v) ev_data d; char *ip = DEFAULT_IP; int port = DEFAULT_PORT; + char *live_ip = DEFAULT_LIVE_IP; + int live_port = DEFAULT_LIVE_PORT; + int live = 0; memset(&d, 0, sizeof(ev_data)); @@ -299,8 +326,17 @@ int main(int n, char **v) { if (i > n-2) usage(); input_filename = v[++i]; continue; } if (!strcmp(v[i], "-ip")) { if (i > n-2) usage(); ip = v[++i]; continue; } if (!strcmp(v[i], "-p")) {if(i>n-2)usage(); port=atoi(v[++i]); continue; } - if (!strcmp(v[i], "-no-mib")) { no_mib = 1; continue; } - if (!strcmp(v[i], "-no-sib")) { no_sib = 1; continue; } + if (!strcmp(v[i], "-no-mib")) { d.no_mib = 1; continue; } + if (!strcmp(v[i], "-no-sib")) { d.no_sib = 1; continue; } + if (!strcmp(v[i], "-max-mib")) + { if (i > n-2) usage(); d.max_mib = atoi(v[++i]); continue; } + if (!strcmp(v[i], "-max-sib")) + { if (i > n-2) usage(); d.max_sib = atoi(v[++i]); continue; } + if (!strcmp(v[i], "-live")) { live = 1; continue; } + if (!strcmp(v[i], "-live-ip")) + { if (i > n-2) usage(); live_ip = v[++i]; continue; } + if (!strcmp(v[i], "-live-port")) + { if (i > n-2) usage(); live_port = atoi(v[++i]); continue; } usage(); } @@ -309,19 +345,47 @@ int main(int n, char **v) exit(1); } - if (input_filename == NULL) { - printf("ERROR: provide an input file (-i)\n"); + if (input_filename == NULL && live == 0) { + printf("ERROR: provide an input file (-i) or run live (-live)\n"); exit(1); } - in = open(input_filename, O_RDONLY); - if (in == -1) { perror(input_filename); return 1; } + if (input_filename != NULL && live != 0) { + printf("ERROR: cannot use both -i and -live\n"); + exit(1); + } + + if (live == 0) { + in = open(input_filename, O_RDONLY); + if (in == -1) { perror(input_filename); return 1; } + } else + in = connect_to(live_ip, live_port); database = parse_database(database_filename); load_config_file(database_filename); h = new_handler(database); + if (live) { + char mt = 1; + int number_of_events = number_of_ids(database); + int *is_on = calloc(number_of_events, sizeof(int)); + if (is_on == NULL) { printf("ERROR: out of memory\n"); exit(1); } + on_off(database, "ENB_MAC_UE_UL_PDU_WITH_DATA", is_on, 1); + on_off(database, "ENB_MAC_UE_DL_PDU_WITH_DATA", is_on, 1); + on_off(database, "ENB_PHY_MIB", is_on, 1); + on_off(database, "ENB_PHY_INITIATE_RA_PROCEDURE", is_on, 1); + on_off(database, "ENB_MAC_UE_DL_RAR_PDU_WITH_DATA", is_on, 1); + /* activate selected traces */ + if (socket_send(in, &mt, 1) == -1 || + socket_send(in, &number_of_events, sizeof(int)) == -1 || + socket_send(in, is_on, number_of_events * sizeof(int)) == -1) { + printf("ERROR: socket_send failed\n"); + exit(1); + } + free(is_on); + } + ul_id = event_id_from_name(database, "ENB_MAC_UE_UL_PDU_WITH_DATA"); dl_id = event_id_from_name(database, "ENB_MAC_UE_DL_PDU_WITH_DATA"); mib_id = event_id_from_name(database, "ENB_PHY_MIB"); From 17bb5db352f6840ea930b32d160a39983e6a0d7f Mon Sep 17 00:00:00 2001 From: Wang Tsu-Han Date: Mon, 12 Nov 2018 14:48:18 +0100 Subject: [PATCH 138/233] renaming change for UE and simulation --- openair1/SCHED/phy_mac_stub.c | 2 +- openair1/SIMULATION/LTE_PHY/pdcchsim.c | 2 +- openair1/SIMULATION/LTE_PHY/ulsim.c | 6 +++--- openair2/PHY_INTERFACE/phy_stub_UE.c | 14 +++++++------- 4 files changed, 12 insertions(+), 12 deletions(-) diff --git a/openair1/SCHED/phy_mac_stub.c b/openair1/SCHED/phy_mac_stub.c index 664791f7c4..986d1518ba 100644 --- a/openair1/SCHED/phy_mac_stub.c +++ b/openair1/SCHED/phy_mac_stub.c @@ -40,7 +40,7 @@ uint8_t dci_ndi_toggle_even[8] = {0, 0, 0, 0, 0, 0, 0, 0}; uint8_t dci_ndi_toggle_odd[8] = {0, 0, 0, 0, 0, 0, 0, 0}; -void fill_dci(DCI_PDU *DCI_pdu,PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc) +void fill_dci(DCI_PDU *DCI_pdu,PHY_VARS_eNB *eNB,L1_proc_t *proc) { /* SYRTEM */ uint8_t *dci_ndi_toggle_tmp = NULL; diff --git a/openair1/SIMULATION/LTE_PHY/pdcchsim.c b/openair1/SIMULATION/LTE_PHY/pdcchsim.c index ac442ae5e9..039fef2e96 100644 --- a/openair1/SIMULATION/LTE_PHY/pdcchsim.c +++ b/openair1/SIMULATION/LTE_PHY/pdcchsim.c @@ -750,7 +750,7 @@ int main(int argc, char **argv) 0, 0); - eNB_rxtx_proc_t *proc_rxtx = &eNB->proc.proc_rxtx[subframe&1]; + L1_proc_t *proc_rxtx = (subframe == 0)? &eNB->proc.L1_proc: &eNB->proc.L1_proc_tx; eNB->ulsch[0] = new_eNB_ulsch(MAX_TURBO_ITERATIONS,N_RB_DL,0); UE->ulsch[0] = new_ue_ulsch(N_RB_DL,0); diff --git a/openair1/SIMULATION/LTE_PHY/ulsim.c b/openair1/SIMULATION/LTE_PHY/ulsim.c index 35e4b84475..dbb98a6da2 100644 --- a/openair1/SIMULATION/LTE_PHY/ulsim.c +++ b/openair1/SIMULATION/LTE_PHY/ulsim.c @@ -85,8 +85,8 @@ int nfapi_mode = 0; extern void fep_full(RU_t *ru); extern void ru_fep_full_2thread(RU_t *ru); -extern void eNB_fep_full(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc); -extern void eNB_fep_full_2thread(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc); +extern void eNB_fep_full(PHY_VARS_eNB *eNB,L1_proc_t *proc); +extern void eNB_fep_full_2thread(PHY_VARS_eNB *eNB,L1_proc_t *proc); nfapi_dl_config_request_t DL_req; nfapi_ul_config_request_t UL_req; @@ -818,7 +818,7 @@ int main(int argc, char **argv) { UE->frame_parms.pusch_config_common.ul_ReferenceSignalsPUSCH.groupAssignmentPUSCH = 0; eNB->frame_parms.pusch_config_common.ul_ReferenceSignalsPUSCH.groupAssignmentPUSCH = 0; UE->mac_enabled=0; - eNB_rxtx_proc_t *proc_rxtx = &eNB->proc.L1_proc; + L1_proc_t *proc_rxtx = &eNB->proc.L1_proc; UE_rxtx_proc_t *proc_rxtx_ue = &UE->proc.proc_rxtx[subframe&1]; proc_rxtx->frame_rx=1; proc_rxtx->subframe_rx=subframe; diff --git a/openair2/PHY_INTERFACE/phy_stub_UE.c b/openair2/PHY_INTERFACE/phy_stub_UE.c index 166616c368..246b29a5e7 100644 --- a/openair2/PHY_INTERFACE/phy_stub_UE.c +++ b/openair2/PHY_INTERFACE/phy_stub_UE.c @@ -590,7 +590,7 @@ int dl_config_req_UE_MAC(nfapi_dl_config_request_t* req, module_id_t Mod_id) //, //Mod_id = 0; // Currently static (only for one UE) but this should change. /*struct PHY_VARS_eNB_s *eNB = RC.eNB[0][0]; - eNB_rxtx_proc_t *proc = &eNB->proc.proc_rxtx[0];*/ + L1_proc_t *proc = &eNB->proc.L1_proc;*/ nfapi_dl_config_request_pdu_t* dl_config_pdu_list = req->dl_config_request_body.dl_config_pdu_list; nfapi_dl_config_request_pdu_t *dl_config_pdu_tmp; @@ -941,14 +941,14 @@ void UE_config_stub_pnf(void) { /* Dummy functions*/ -void handle_nfapi_hi_dci0_dci_pdu(PHY_VARS_eNB *eNB,int frame,int subframe,eNB_rxtx_proc_t *proc, +void handle_nfapi_hi_dci0_dci_pdu(PHY_VARS_eNB *eNB,int frame,int subframe,L1_proc_t *proc, nfapi_hi_dci0_request_pdu_t *hi_dci0_config_pdu) { } -void handle_nfapi_hi_dci0_hi_pdu(PHY_VARS_eNB *eNB,int frame,int subframe,eNB_rxtx_proc_t *proc, +void handle_nfapi_hi_dci0_hi_pdu(PHY_VARS_eNB *eNB,int frame,int subframe,L1_proc_t *proc, nfapi_hi_dci0_request_pdu_t *hi_dci0_config_pdu) { @@ -957,14 +957,14 @@ void handle_nfapi_hi_dci0_hi_pdu(PHY_VARS_eNB *eNB,int frame,int subframe,eNB_rx void handle_nfapi_dci_dl_pdu(PHY_VARS_eNB *eNB, int frame, int subframe, - eNB_rxtx_proc_t *proc, + L1_proc_t *proc, nfapi_dl_config_request_pdu_t *dl_config_pdu) { } -void handle_nfapi_bch_pdu(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc, +void handle_nfapi_bch_pdu(PHY_VARS_eNB *eNB,L1_proc_t *proc, nfapi_dl_config_request_pdu_t *dl_config_pdu, uint8_t *sdu) { @@ -972,7 +972,7 @@ void handle_nfapi_bch_pdu(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc, } -void handle_nfapi_dlsch_pdu(PHY_VARS_eNB *eNB,int frame,int subframe,eNB_rxtx_proc_t *proc, +void handle_nfapi_dlsch_pdu(PHY_VARS_eNB *eNB,int frame,int subframe,L1_proc_t *proc, nfapi_dl_config_request_pdu_t *dl_config_pdu, uint8_t codeword_index, uint8_t *sdu) @@ -981,7 +981,7 @@ void handle_nfapi_dlsch_pdu(PHY_VARS_eNB *eNB,int frame,int subframe,eNB_rxtx_pr } -void handle_nfapi_ul_pdu(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc, +void handle_nfapi_ul_pdu(PHY_VARS_eNB *eNB,L1_proc_t *proc, nfapi_ul_config_request_pdu_t *ul_config_pdu, uint16_t frame,uint8_t subframe,uint8_t srs_present) { From c9ab59fc4d9e7968628d298b6b8d5933e6719b65 Mon Sep 17 00:00:00 2001 From: Wang Tsu-Han Date: Mon, 12 Nov 2018 15:58:56 +0100 Subject: [PATCH 139/233] fixes for misplacing L1_rxtx_proc_t with L1_proc_t --- openair1/PHY/LTE_UE_TRANSPORT/dci_tools_ue.c | 2 +- openair1/SCHED/phy_mac_stub.c | 2 +- openair1/SIMULATION/LTE_PHY/pdcchsim.c | 2 +- openair1/SIMULATION/LTE_PHY/ulsim.c | 6 +++--- openair2/PHY_INTERFACE/phy_stub_UE.c | 14 +++++++------- 5 files changed, 13 insertions(+), 13 deletions(-) diff --git a/openair1/PHY/LTE_UE_TRANSPORT/dci_tools_ue.c b/openair1/PHY/LTE_UE_TRANSPORT/dci_tools_ue.c index 76176d346e..c31bc587a7 100644 --- a/openair1/PHY/LTE_UE_TRANSPORT/dci_tools_ue.c +++ b/openair1/PHY/LTE_UE_TRANSPORT/dci_tools_ue.c @@ -4222,7 +4222,7 @@ int generate_ue_ulsch_params_from_dci(void *dci_pdu, /* int generate_eNB_ulsch_params_from_dci(PHY_VARS_eNB *eNB, - eNB_rxtx_proc_t *proc, + L1_rxtx_proc_t *proc, void *dci_pdu, uint16_t rnti, DCI_format_t dci_format, diff --git a/openair1/SCHED/phy_mac_stub.c b/openair1/SCHED/phy_mac_stub.c index 986d1518ba..55149f8d2e 100644 --- a/openair1/SCHED/phy_mac_stub.c +++ b/openair1/SCHED/phy_mac_stub.c @@ -40,7 +40,7 @@ uint8_t dci_ndi_toggle_even[8] = {0, 0, 0, 0, 0, 0, 0, 0}; uint8_t dci_ndi_toggle_odd[8] = {0, 0, 0, 0, 0, 0, 0, 0}; -void fill_dci(DCI_PDU *DCI_pdu,PHY_VARS_eNB *eNB,L1_proc_t *proc) +void fill_dci(DCI_PDU *DCI_pdu,PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc) { /* SYRTEM */ uint8_t *dci_ndi_toggle_tmp = NULL; diff --git a/openair1/SIMULATION/LTE_PHY/pdcchsim.c b/openair1/SIMULATION/LTE_PHY/pdcchsim.c index 039fef2e96..569d2226de 100644 --- a/openair1/SIMULATION/LTE_PHY/pdcchsim.c +++ b/openair1/SIMULATION/LTE_PHY/pdcchsim.c @@ -750,7 +750,7 @@ int main(int argc, char **argv) 0, 0); - L1_proc_t *proc_rxtx = (subframe == 0)? &eNB->proc.L1_proc: &eNB->proc.L1_proc_tx; + L1_rxtx_proc_t *proc_rxtx = (subframe == 0)? &eNB->proc.L1_proc: &eNB->proc.L1_proc_tx; eNB->ulsch[0] = new_eNB_ulsch(MAX_TURBO_ITERATIONS,N_RB_DL,0); UE->ulsch[0] = new_ue_ulsch(N_RB_DL,0); diff --git a/openair1/SIMULATION/LTE_PHY/ulsim.c b/openair1/SIMULATION/LTE_PHY/ulsim.c index dbb98a6da2..f246c0cdad 100644 --- a/openair1/SIMULATION/LTE_PHY/ulsim.c +++ b/openair1/SIMULATION/LTE_PHY/ulsim.c @@ -85,8 +85,8 @@ int nfapi_mode = 0; extern void fep_full(RU_t *ru); extern void ru_fep_full_2thread(RU_t *ru); -extern void eNB_fep_full(PHY_VARS_eNB *eNB,L1_proc_t *proc); -extern void eNB_fep_full_2thread(PHY_VARS_eNB *eNB,L1_proc_t *proc); +extern void eNB_fep_full(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc); +extern void eNB_fep_full_2thread(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc); nfapi_dl_config_request_t DL_req; nfapi_ul_config_request_t UL_req; @@ -818,7 +818,7 @@ int main(int argc, char **argv) { UE->frame_parms.pusch_config_common.ul_ReferenceSignalsPUSCH.groupAssignmentPUSCH = 0; eNB->frame_parms.pusch_config_common.ul_ReferenceSignalsPUSCH.groupAssignmentPUSCH = 0; UE->mac_enabled=0; - L1_proc_t *proc_rxtx = &eNB->proc.L1_proc; + L1_rxtx_proc_t *proc_rxtx = &eNB->proc.L1_proc; UE_rxtx_proc_t *proc_rxtx_ue = &UE->proc.proc_rxtx[subframe&1]; proc_rxtx->frame_rx=1; proc_rxtx->subframe_rx=subframe; diff --git a/openair2/PHY_INTERFACE/phy_stub_UE.c b/openair2/PHY_INTERFACE/phy_stub_UE.c index 246b29a5e7..18e2fa4cb7 100644 --- a/openair2/PHY_INTERFACE/phy_stub_UE.c +++ b/openair2/PHY_INTERFACE/phy_stub_UE.c @@ -590,7 +590,7 @@ int dl_config_req_UE_MAC(nfapi_dl_config_request_t* req, module_id_t Mod_id) //, //Mod_id = 0; // Currently static (only for one UE) but this should change. /*struct PHY_VARS_eNB_s *eNB = RC.eNB[0][0]; - L1_proc_t *proc = &eNB->proc.L1_proc;*/ + L1_rxtx_proc_t *proc = &eNB->proc.L1_proc;*/ nfapi_dl_config_request_pdu_t* dl_config_pdu_list = req->dl_config_request_body.dl_config_pdu_list; nfapi_dl_config_request_pdu_t *dl_config_pdu_tmp; @@ -941,14 +941,14 @@ void UE_config_stub_pnf(void) { /* Dummy functions*/ -void handle_nfapi_hi_dci0_dci_pdu(PHY_VARS_eNB *eNB,int frame,int subframe,L1_proc_t *proc, +void handle_nfapi_hi_dci0_dci_pdu(PHY_VARS_eNB *eNB,int frame,int subframe,L1_rxtx_proc_t *proc, nfapi_hi_dci0_request_pdu_t *hi_dci0_config_pdu) { } -void handle_nfapi_hi_dci0_hi_pdu(PHY_VARS_eNB *eNB,int frame,int subframe,L1_proc_t *proc, +void handle_nfapi_hi_dci0_hi_pdu(PHY_VARS_eNB *eNB,int frame,int subframe,L1_rxtx_proc_t *proc, nfapi_hi_dci0_request_pdu_t *hi_dci0_config_pdu) { @@ -957,14 +957,14 @@ void handle_nfapi_hi_dci0_hi_pdu(PHY_VARS_eNB *eNB,int frame,int subframe,L1_pro void handle_nfapi_dci_dl_pdu(PHY_VARS_eNB *eNB, int frame, int subframe, - L1_proc_t *proc, + L1_rxtx_proc_t *proc, nfapi_dl_config_request_pdu_t *dl_config_pdu) { } -void handle_nfapi_bch_pdu(PHY_VARS_eNB *eNB,L1_proc_t *proc, +void handle_nfapi_bch_pdu(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc, nfapi_dl_config_request_pdu_t *dl_config_pdu, uint8_t *sdu) { @@ -972,7 +972,7 @@ void handle_nfapi_bch_pdu(PHY_VARS_eNB *eNB,L1_proc_t *proc, } -void handle_nfapi_dlsch_pdu(PHY_VARS_eNB *eNB,int frame,int subframe,L1_proc_t *proc, +void handle_nfapi_dlsch_pdu(PHY_VARS_eNB *eNB,int frame,int subframe,L1_rxtx_proc_t *proc, nfapi_dl_config_request_pdu_t *dl_config_pdu, uint8_t codeword_index, uint8_t *sdu) @@ -981,7 +981,7 @@ void handle_nfapi_dlsch_pdu(PHY_VARS_eNB *eNB,int frame,int subframe,L1_proc_t * } -void handle_nfapi_ul_pdu(PHY_VARS_eNB *eNB,L1_proc_t *proc, +void handle_nfapi_ul_pdu(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc, nfapi_ul_config_request_pdu_t *ul_config_pdu, uint16_t frame,uint8_t subframe,uint8_t srs_present) { From 76e163625858c025c4dc6b217c3e2cb8cfd07ecf Mon Sep 17 00:00:00 2001 From: Louis Adrien Dufrene Date: Mon, 12 Nov 2018 17:38:19 +0100 Subject: [PATCH 140/233] RRC timer reset in scheduler: format of some functions before first test --- openair2/LAYER2/MAC/eNB_scheduler_dlsch.c | 90 +++++++------ openair2/LAYER2/MAC/eNB_scheduler_fairRR.c | 144 +++++++++++---------- openair2/LAYER2/MAC/eNB_scheduler_ulsch.c | 113 +++++++++------- openair2/RRC/LTE/rrc_eNB_S1AP.c | 4 - 4 files changed, 195 insertions(+), 156 deletions(-) diff --git a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c index d4f7c04d03..4b922e89a5 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c @@ -1033,68 +1033,82 @@ schedule_ue_spec(module_id_t module_idP, int slice_idxP, // TODO: check if the lcid is active LOG_D(MAC, "[eNB %d], Frame %d, DTCH%d->DLSCH, Checking RLC status (tbs %d, len %d)\n", - module_idP, frameP, lcid, TBS, - TBS - ta_len - header_length_total - sdu_length_total - 3); + module_idP, + frameP, + lcid, + TBS, + TBS - ta_len - header_length_total - sdu_length_total - 3); if (TBS - ta_len - header_length_total - sdu_length_total - 3 > 0) { rlc_status = mac_rlc_status_ind(module_idP, - rnti, - module_idP, - frameP, - subframeP, - ENB_FLAG_YES, - MBMS_FLAG_NO, - lcid, - TBS - ta_len - header_length_total - sdu_length_total - 3 + rnti, + module_idP, + frameP, + subframeP, + ENB_FLAG_YES, + MBMS_FLAG_NO, + lcid, + TBS - ta_len - header_length_total - sdu_length_total - 3 #if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - ,0, 0 + , 0, 0 #endif - ); - - + ); if (rlc_status.bytes_in_buffer > 0) { - LOG_D(MAC, - "[eNB %d][USER-PLANE DEFAULT DRB] Frame %d : DTCH->DLSCH, Requesting %d bytes from RLC (lcid %d total hdr len %d)\n", - module_idP, frameP, - TBS - ta_len - header_length_total - sdu_length_total - 3, + LOG_D(MAC, "[eNB %d][USER-PLANE DEFAULT DRB] Frame %d : DTCH->DLSCH, Requesting %d bytes from RLC (lcid %d total hdr len %d)\n", + module_idP, + frameP, + TBS - ta_len - header_length_total - sdu_length_total - 3, lcid, header_length_total); - sdu_lengths[num_sdus] = mac_rlc_data_req(module_idP, rnti, module_idP, frameP, ENB_FLAG_YES, MBMS_FLAG_NO, lcid, - TBS, //not used - (char *)&dlsch_buffer[sdu_length_total] + sdu_lengths[num_sdus] = mac_rlc_data_req(module_idP, + rnti, + module_idP, + frameP, + ENB_FLAG_YES, + MBMS_FLAG_NO, + lcid, + TBS, //not used + (char *)&dlsch_buffer[sdu_length_total] #if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - ,0, 0 + , 0, 0 #endif - ); + ); - T(T_ENB_MAC_UE_DL_SDU, T_INT(module_idP), - T_INT(CC_id), T_INT(rnti), T_INT(frameP), - T_INT(subframeP), T_INT(harq_pid), - T_INT(lcid), T_INT(sdu_lengths[num_sdus])); + T(T_ENB_MAC_UE_DL_SDU, + T_INT(module_idP), + T_INT(CC_id), + T_INT(rnti), + T_INT(frameP), + T_INT(subframeP), + T_INT(harq_pid), + T_INT(lcid), + T_INT(sdu_lengths[num_sdus])); - LOG_D(MAC, - "[eNB %d][USER-PLANE DEFAULT DRB] Got %d bytes for DTCH %d \n", - module_idP, sdu_lengths[num_sdus], lcid); + LOG_D(MAC, "[eNB %d][USER-PLANE DEFAULT DRB] Got %d bytes for DTCH %d \n", + module_idP, + sdu_lengths[num_sdus], + lcid); sdu_lcids[num_sdus] = lcid; sdu_length_total += sdu_lengths[num_sdus]; + UE_list->eNB_UE_stats[CC_id][UE_id].num_pdu_tx[lcid]++; - UE_list->eNB_UE_stats[CC_id][UE_id].lcid_sdu[num_sdus] = lcid; - UE_list->eNB_UE_stats[CC_id][UE_id].sdu_length_tx[lcid] = sdu_lengths[num_sdus]; + UE_list->eNB_UE_stats[CC_id][UE_id].lcid_sdu[num_sdus] = lcid; + UE_list->eNB_UE_stats[CC_id][UE_id].sdu_length_tx[lcid] = sdu_lengths[num_sdus]; UE_list->eNB_UE_stats[CC_id][UE_id].num_bytes_tx[lcid] += sdu_lengths[num_sdus]; - header_length_last = 1 + 1 + (sdu_lengths[num_sdus] >= 128); - header_length_total += header_length_last; + header_length_last = 1 + 1 + (sdu_lengths[num_sdus] >= 128); + header_length_total += header_length_last; num_sdus++; UE_list->UE_sched_ctrl[UE_id].uplane_inactivity_timer = 0; - } - } else { - // no TBS left - break; + + } // end if (rlc_status.bytes_in_buffer > 0) + } else { // no TBS left + break; // break for (lcid = NB_RB_MAX - 1; lcid >= DTCH; lcid--) } } diff --git a/openair2/LAYER2/MAC/eNB_scheduler_fairRR.c b/openair2/LAYER2/MAC/eNB_scheduler_fairRR.c index 9ab4306000..282d906098 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_fairRR.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_fairRR.c @@ -1404,85 +1404,95 @@ schedule_ue_spec_fairRR(module_id_t module_idP, header_len_dtch = 0; header_len_dtch_last = 0; // the header length of the last mac sdu // lcid has to be sorted before the actual allocation (similar struct as ue_list). - /* TODO limited lcid for performance */ - for (lcid = DTCH; lcid >= DTCH; lcid--) { - // TBD: check if the lcid is active + /* TODO limited lcid for performance */ + for (lcid = DTCH; lcid >= DTCH; lcid--) { + // TBD: check if the lcid is active + header_len_dtch += 3; + header_len_dtch_last = 3; - header_len_dtch += 3; - header_len_dtch_last = 3; - LOG_D(MAC, - "[eNB %d], Frame %d, DTCH%d->DLSCH, Checking RLC status (tbs %d, len %d)\n", - module_idP, frameP, lcid, TBS, - TBS - ta_len - header_len_dcch - - sdu_length_total - header_len_dtch); + LOG_D(MAC, "[eNB %d], Frame %d, DTCH%d->DLSCH, Checking RLC status (tbs %d, len %d)\n", + module_idP, + frameP, + lcid, + TBS, + TBS - ta_len - header_len_dcch - sdu_length_total - header_len_dtch); - if (TBS - ta_len - header_len_dcch - sdu_length_total - header_len_dtch > 0) { // NN: > 2 ? - rlc_status = mac_rlc_status_ind(module_idP, - rnti, - module_idP, - frameP, - subframeP, - ENB_FLAG_YES, - MBMS_FLAG_NO, - lcid, - TBS - ta_len - - header_len_dcch - - sdu_length_total - - header_len_dtch + if (TBS - ta_len - header_len_dcch - sdu_length_total - header_len_dtch > 0) { // NN: > 2 ? + rlc_status = mac_rlc_status_ind(module_idP, + rnti, + module_idP, + frameP, + subframeP, + ENB_FLAG_YES, + MBMS_FLAG_NO, + lcid, + TBS - ta_len - header_len_dcch - sdu_length_total - header_len_dtch #ifdef Rel14 - ,0, 0 + , 0, 0 #endif - ); + ); - if (rlc_status.bytes_in_buffer > 0) { - - LOG_D(MAC, - "[eNB %d][USER-PLANE DEFAULT DRB] Frame %d : DTCH->DLSCH, Requesting %d bytes from RLC (lcid %d total hdr len %d)\n", - module_idP, frameP, - TBS - header_len_dcch - - sdu_length_total - header_len_dtch, lcid, + if (rlc_status.bytes_in_buffer > 0) { + LOG_D(MAC,"[eNB %d][USER-PLANE DEFAULT DRB] Frame %d : DTCH->DLSCH, Requesting %d bytes from RLC (lcid %d total hdr len %d)\n", + module_idP, + frameP, + TBS - header_len_dcch - sdu_length_total - header_len_dtch, + lcid, header_len_dtch); - sdu_lengths[num_sdus] = mac_rlc_data_req(module_idP, rnti, module_idP, frameP, ENB_FLAG_YES, MBMS_FLAG_NO, lcid, TBS, //not used - (char - *) - &dlsch_buffer - [sdu_length_total] -#ifdef Rel14 - ,0, 0 -#endif - ); - T(T_ENB_MAC_UE_DL_SDU, T_INT(module_idP), - T_INT(CC_id), T_INT(rnti), T_INT(frameP), - T_INT(subframeP), T_INT(harq_pid), - T_INT(lcid), T_INT(sdu_lengths[num_sdus])); - LOG_D(MAC, - "[eNB %d][USER-PLANE DEFAULT DRB] Got %d bytes for DTCH %d \n", - module_idP, sdu_lengths[num_sdus], lcid); + sdu_lengths[num_sdus] = mac_rlc_data_req(module_idP, + rnti, + module_idP, + frameP, + ENB_FLAG_YES, + MBMS_FLAG_NO, + lcid, + TBS, //not used + (char *)&dlsch_buffer[sdu_length_total] +#ifdef Rel14 + , 0, 0 +#endif + ); + + T(T_ENB_MAC_UE_DL_SDU, + T_INT(module_idP), + T_INT(CC_id), + T_INT(rnti), + T_INT(frameP), + T_INT(subframeP), + T_INT(harq_pid), + T_INT(lcid), + T_INT(sdu_lengths[num_sdus])); + + LOG_D(MAC, "[eNB %d][USER-PLANE DEFAULT DRB] Got %d bytes for DTCH %d \n", + module_idP, + sdu_lengths[num_sdus], + lcid); + sdu_lcids[num_sdus] = lcid; sdu_length_total += sdu_lengths[num_sdus]; - UE_list-> - eNB_UE_stats[CC_id][UE_id].num_pdu_tx[lcid] - += 1; - UE_list-> - eNB_UE_stats[CC_id][UE_id].num_bytes_tx - [lcid] += sdu_lengths[num_sdus]; - if (sdu_lengths[num_sdus] < 128) { - header_len_dtch--; - header_len_dtch_last--; + UE_list->eNB_UE_stats[CC_id][UE_id].num_pdu_tx[lcid] += 1; + UE_list->eNB_UE_stats[CC_id][UE_id].num_bytes_tx[lcid] += sdu_lengths[num_sdus]; + + if (sdu_lengths[num_sdus] < 128) { + header_len_dtch--; + header_len_dtch_last--; } + num_sdus++; - UE_list->UE_sched_ctrl[UE_id].uplane_inactivity_timer = 0; - } // no data for this LCID - else { - header_len_dtch -= 3; - } - } // no TBS left - else { - header_len_dtch -= 3; - break; - } + + UE_list->UE_sched_ctrl[UE_id].uplane_inactivity_timer = 0; + + } else { // no data for this LCID + header_len_dtch -= 3; + } + + } else { // no TBS left + header_len_dtch -= 3; + + break; + } } if (header_len_dtch == 0) header_len_dtch_last = 0; diff --git a/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c b/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c index 31c11e2c0a..8ad23798f7 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c @@ -669,69 +669,88 @@ rx_sdu(const module_id_t enb_mod_idP, // } break; - // all the DRBS + // all the DRBS case DTCH: + default: #if defined(ENABLE_MAC_PAYLOAD_DEBUG) + LOG_T(MAC, "offset: %d\n", - (unsigned char) ((unsigned char *) payload_ptr - sduP)); + (unsigned char) ((unsigned char *) payload_ptr - sduP)); + for (j = 0; j < 32; j++) { - LOG_T(MAC, "%x ", payload_ptr[j]); + LOG_T(MAC, "%x ", payload_ptr[j]); } + LOG_T(MAC, "\n"); -#endif - if (rx_lcids[i] < NB_RB_MAX) { - LOG_D(MAC, - "[eNB %d] CC_id %d Frame %d : ULSCH -> UL-DTCH, received %d bytes from UE %d for lcid %d\n", - enb_mod_idP, CC_idP, frameP, rx_lengths[i], UE_id, - rx_lcids[i]); - if (UE_id != -1) { - // adjust buffer occupancy of the correponding logical channel group - LOG_D(MAC, - "[eNB %d] CC_id %d Frame %d : ULSCH -> UL-DTCH, received %d bytes from UE %d for lcid %d, removing from LCGID %ld, %d\n", - enb_mod_idP, CC_idP, frameP, rx_lengths[i], - UE_id, rx_lcids[i], - UE_list->UE_template[CC_idP][UE_id]. - lcgidmap[rx_lcids[i]], - UE_list->UE_template[CC_idP][UE_id]. - ul_buffer_info[UE_list->UE_template[CC_idP] - [UE_id].lcgidmap[rx_lcids[i]]]); +#endif + + if (rx_lcids[i] < NB_RB_MAX) { + + LOG_D(MAC, "[eNB %d] CC_id %d Frame %d : ULSCH -> UL-DTCH, received %d bytes from UE %d for lcid %d\n", + enb_mod_idP, + CC_idP, + frameP, + rx_lengths[i], + UE_id, + rx_lcids[i]); + + if (UE_id != -1) { + // adjust buffer occupancy of the correponding logical channel group + LOG_D(MAC, "[eNB %d] CC_id %d Frame %d : ULSCH -> UL-DTCH, received %d bytes from UE %d for lcid %d, removing from LCGID %ld, %d\n", + enb_mod_idP, + CC_idP, + frameP, + rx_lengths[i], + UE_id, + rx_lcids[i], + UE_list->UE_template[CC_idP][UE_id].lcgidmap[rx_lcids[i]], + UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[UE_list->UE_template[CC_idP][UE_id].lcgidmap[rx_lcids[i]]]); if (lcgid_updated[UE_list->UE_template[CC_idP][UE_id].lcgidmap[rx_lcids[i]]] == 0) { - if (UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[UE_list->UE_template[CC_idP][UE_id].lcgidmap[rx_lcids[i]]] >= rx_lengths[i]) - UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[UE_list->UE_template[CC_idP][UE_id].lcgidmap[rx_lcids[i]]] -= rx_lengths[i]; - else - UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[UE_list->UE_template[CC_idP][UE_id].lcgidmap[rx_lcids[i]]] = 0; + if (UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[UE_list->UE_template[CC_idP][UE_id].lcgidmap[rx_lcids[i]]] >= rx_lengths[i]) { + UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[UE_list->UE_template[CC_idP][UE_id].lcgidmap[rx_lcids[i]]] -= rx_lengths[i]; + } else { + UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[UE_list->UE_template[CC_idP][UE_id].lcgidmap[rx_lcids[i]]] = 0; + } UE_list->UE_template[CC_idP][UE_id].estimated_ul_buffer = - UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[0] + - UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[1] + - UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[2] + - UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[3]; - //UE_list->UE_template[CC_idP][UE_id].estimated_ul_buffer += UE_list->UE_template[CC_idP][UE_id].estimated_ul_buffer / 4; + UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[0] + + UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[1] + + UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[2] + + UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[3]; } - if ((rx_lengths[i] < SCH_PAYLOAD_SIZE_MAX) && (rx_lengths[i] > 0)) { // MAX SIZE OF transport block - mac_rlc_data_ind(enb_mod_idP, current_rnti, enb_mod_idP, frameP, ENB_FLAG_YES, MBMS_FLAG_NO, rx_lcids[i], (char *) payload_ptr, rx_lengths[i], 1, NULL); //(unsigned int*)crc_status); + if ((rx_lengths[i] < SCH_PAYLOAD_SIZE_MAX) && (rx_lengths[i] > 0)) { // MAX SIZE OF transport block + mac_rlc_data_ind(enb_mod_idP, current_rnti, enb_mod_idP, frameP, ENB_FLAG_YES, MBMS_FLAG_NO, rx_lcids[i], (char *) payload_ptr, rx_lengths[i], 1, NULL); - UE_list->eNB_UE_stats[CC_idP][UE_id].num_pdu_rx[rx_lcids[i]] += 1; - UE_list->eNB_UE_stats[CC_idP][UE_id].num_bytes_rx[rx_lcids[i]] += rx_lengths[i]; - //clear uplane_inactivity_timer - UE_list->UE_sched_ctrl[UE_id].uplane_inactivity_timer = 0; - } else { /* rx_length[i] */ - UE_list->eNB_UE_stats[CC_idP][UE_id].num_errors_rx += 1; - LOG_E(MAC, - "[eNB %d] CC_id %d Frame %d : Max size of transport block reached LCID %d from UE %d ", - enb_mod_idP, CC_idP, frameP, rx_lcids[i], - UE_id); - } - } else { /*(UE_id != -1 */ - LOG_E(MAC, - "[eNB %d] CC_id %d Frame %d : received unsupported or unknown LCID %d from UE %d ", - enb_mod_idP, CC_idP, frameP, rx_lcids[i], UE_id); - } + UE_list->eNB_UE_stats[CC_idP][UE_id].num_pdu_rx[rx_lcids[i]] += 1; + UE_list->eNB_UE_stats[CC_idP][UE_id].num_bytes_rx[rx_lcids[i]] += rx_lengths[i]; + + //clear uplane_inactivity_timer + UE_list->UE_sched_ctrl[UE_id].uplane_inactivity_timer = 0; + + } else { /* rx_length[i] */ + UE_list->eNB_UE_stats[CC_idP][UE_id].num_errors_rx += 1; + + LOG_E(MAC, "[eNB %d] CC_id %d Frame %d : Max size of transport block reached LCID %d from UE %d ", + enb_mod_idP, + CC_idP, + frameP, + rx_lcids[i], + UE_id); + } + + } else { /*(UE_id != -1 */ + LOG_E(MAC,"[eNB %d] CC_id %d Frame %d : received unsupported or unknown LCID %d from UE %d ", + enb_mod_idP, + CC_idP, + frameP, + rx_lcids[i], + UE_id); + } } break; diff --git a/openair2/RRC/LTE/rrc_eNB_S1AP.c b/openair2/RRC/LTE/rrc_eNB_S1AP.c index f89bb76cff..c1371e2ef1 100644 --- a/openair2/RRC/LTE/rrc_eNB_S1AP.c +++ b/openair2/RRC/LTE/rrc_eNB_S1AP.c @@ -256,7 +256,6 @@ rrc_eNB_S1AP_get_ue_ids( * This case is uncommon, but can happen when: * -> if the first NAS message was a Detach Request (non exhaustiv), the UE RRC context exist * but is not associated with eNB_ue_s1ap_id - * -> if the UE is in IDLE, hence no S1 context exist (in this case [h_rc != HASH_TABLE_OK] is normal) * -> ... (?) */ LOG_E(S1AP, "[eNB %ld] In hashtable_get, couldn't find in s1ap_id2_s1ap_ids eNB_ue_s1ap_id %"PRIu32", trying to find it through S1AP context\n", @@ -267,9 +266,6 @@ rrc_eNB_S1AP_get_ue_ids( s1ap_eNB_instance_p = s1ap_eNB_get_instance(instance); // get s1ap_eNB_instance - // s1ap_eNB_instance_p = s1ap_eNB_get_instance((uint8_t) rrc_instance_pP - RC.rrc[0]); // get s1ap_eNB_instance - // s1ap_eNB_instance_t *s1ap_eNB_get_instance(uint8_t mod_id); - ue_desc_p = s1ap_eNB_get_ue_context(s1ap_eNB_instance_p, eNB_ue_s1ap_id); // get s1ap_eNB_ue_context if (ue_desc_p != NULL) { From 287010f82fcf15213a2549368dac7c776689d64e Mon Sep 17 00:00:00 2001 From: Louis Adrien Dufrene Date: Tue, 13 Nov 2018 10:21:38 +0100 Subject: [PATCH 141/233] RRC timer: last format done. Timer reset in scheduling of DTCH (DL/UL). Commit to test. --- openair2/COMMON/platform_types.h | 2 +- openair2/LAYER2/MAC/eNB_scheduler_dlsch.c | 17 +++++++++++++++++ openair2/LAYER2/MAC/eNB_scheduler_ulsch.c | 20 +++++++++++++++++++- openair2/RRC/LTE/rrc_eNB.c | 4 +++- openair2/RRC/LTE/rrc_eNB_S1AP.c | 7 ++++--- 5 files changed, 44 insertions(+), 6 deletions(-) diff --git a/openair2/COMMON/platform_types.h b/openair2/COMMON/platform_types.h index 843f645816..0578e92cbc 100644 --- a/openair2/COMMON/platform_types.h +++ b/openair2/COMMON/platform_types.h @@ -65,7 +65,7 @@ typedef int32_t sdu_size_t; typedef uint32_t frame_t; typedef int32_t sframe_t; typedef uint32_t sub_frame_t; -typedef uint16_t module_id_t; +typedef uint16_t module_id_t; typedef uint8_t slice_id_t; typedef uint8_t eNB_index_t; typedef uint16_t ue_id_t; diff --git a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c index 4b922e89a5..a77d5f36d2 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c @@ -43,6 +43,10 @@ #include "RRC/LTE/rrc_extern.h" #include "RRC/L2_INTERFACE/openair_rrc_L2_interface.h" +/************************************************/ +//#include "RRC/LTE/rrc_eNB_UE_context.h" +//#include "RRC/LTE/rrc_defs.h" +/************************************************/ //#include "LAYER2/MAC/pre_processor.c" #include "pdcp.h" @@ -466,6 +470,8 @@ schedule_ue_spec(module_id_t module_idP, int slice_idxP, int header_length_last; int header_length_total; + rrc_eNB_ue_context_t *ue_contextP; // added by LA + start_meas(&eNB->schedule_dlsch); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_SCHEDULE_DLSCH, VCD_FUNCTION_IN); @@ -1106,6 +1112,17 @@ schedule_ue_spec(module_id_t module_idP, int slice_idxP, UE_list->UE_sched_ctrl[UE_id].uplane_inactivity_timer = 0; + // reset RRC inactivity timer after uplane activity + ue_contextP = rrc_eNB_get_ue_context(RC.rrc[module_idP], rnti); + ue_contextP->ue_context.ue_rrc_inactivity_timer = 1; + + LOG_W(RRC, "After reset, rrc_inactivity_timer is %d, of UE rntiP %d, ue_context_rnti %d, UE_id %d, ue_initial_id %d\n", + ue_contextP->ue_context.ue_rrc_inactivity_timer, + rnti, + ue_contextP->ue_id_rnti, + UE_id, + ue_contextP->ue_context.ue_initial_id); + } // end if (rlc_status.bytes_in_buffer > 0) } else { // no TBS left break; // break for (lcid = NB_RB_MAX - 1; lcid >= DTCH; lcid--) diff --git a/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c b/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c index 8ad23798f7..d8418e7b11 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c @@ -45,6 +45,10 @@ #include "RRC/LTE/rrc_extern.h" #include "RRC/L2_INTERFACE/openair_rrc_L2_interface.h" +/************************************************/ +//#include "RRC/LTE/rrc_eNB_UE_context.h" +//#include "RRC/LTE/rrc_defs.h" +/************************************************/ #include "assertions.h" //#include "LAYER2/MAC/pre_processor.c" @@ -111,6 +115,8 @@ rx_sdu(const module_id_t enb_mod_idP, (RA_t *) & RC.mac[enb_mod_idP]->common_channels[CC_idP].ra[0]; int first_rb = 0; + rrc_eNB_ue_context_t *ue_contextP; // added by LA + start_meas(&mac->rx_ulsch_sdu); if ((UE_id > MAX_MOBILES_PER_ENB) || (UE_id == -1)) @@ -732,6 +738,18 @@ rx_sdu(const module_id_t enb_mod_idP, //clear uplane_inactivity_timer UE_list->UE_sched_ctrl[UE_id].uplane_inactivity_timer = 0; + // reset RRC inactivity timer after uplane activity + ue_contextP = rrc_eNB_get_ue_context(RC.rrc[enb_mod_idP], rntiP); + ue_contextP->ue_context.ue_rrc_inactivity_timer = 1; + + LOG_W(RRC, "After reset, rrc_inactivity_timer is %d, of UE rntiP %d, ue_context_rnti %d, UE_id %d, ue_initial_id %d\n", + ue_contextP->ue_context.ue_rrc_inactivity_timer, + rntiP, + ue_contextP->ue_id_rnti, + UE_id, + ue_contextP->ue_context.ue_initial_id); + + } else { /* rx_length[i] */ UE_list->eNB_UE_stats[CC_idP][UE_id].num_errors_rx += 1; @@ -743,7 +761,7 @@ rx_sdu(const module_id_t enb_mod_idP, UE_id); } - } else { /*(UE_id != -1 */ + } else { // end if (UE_id != -1) LOG_E(MAC,"[eNB %d] CC_id %d Frame %d : received unsupported or unknown LCID %d from UE %d ", enb_mod_idP, CC_idP, diff --git a/openair2/RRC/LTE/rrc_eNB.c b/openair2/RRC/LTE/rrc_eNB.c index d63b289e32..240712aec4 100644 --- a/openair2/RRC/LTE/rrc_eNB.c +++ b/openair2/RRC/LTE/rrc_eNB.c @@ -1036,7 +1036,7 @@ rrc_eNB_process_RRCConnectionSetupComplete( ue_context_pP->ue_context.Srb1.Active = 1; ue_context_pP->ue_context.Status = RRC_CONNECTED; ue_context_pP->ue_context.ue_rrc_inactivity_timer = 1; // set rrc inactivity when UE goes into RRC_CONNECTED - ue_context_pP->ue_context.ue_rrc_inactivity_timer_thres = 10000; // SHOULD NOT BE DONE HERE !!!!! + ue_context_pP->ue_context.ue_rrc_inactivity_timer_thres = 10000; // The value should come from config file T(T_ENB_RRC_CONNECTION_SETUP_COMPLETE, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame), T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti)); @@ -1369,6 +1369,8 @@ rrc_eNB_process_RRCConnectionReestablishmentComplete( uint8_t next_xid = rrc_eNB_get_next_transaction_identifier(ctxt_pP->module_id); ue_context_pP->ue_context.Status = RRC_CONNECTED; + ue_context_pP->ue_context.ue_rrc_inactivity_timer = 1; // set rrc inactivity when UE goes into RRC_CONNECTED + ue_context_pP->ue_context.ue_rrc_inactivity_timer_thres = 10000; // The value should come from config file ue_context_pP->ue_context.reestablishment_xid = next_xid; SRB_configList2 = &ue_context_pP->ue_context.SRB_configList2[xid]; diff --git a/openair2/RRC/LTE/rrc_eNB_S1AP.c b/openair2/RRC/LTE/rrc_eNB_S1AP.c index c1371e2ef1..f7116ff8a4 100644 --- a/openair2/RRC/LTE/rrc_eNB_S1AP.c +++ b/openair2/RRC/LTE/rrc_eNB_S1AP.c @@ -167,7 +167,8 @@ void extract_imsi(uint8_t *pdu_buf, uint32_t pdu_len, rrc_eNB_ue_context_t *ue_c # if defined(ENABLE_ITTI) //------------------------------------------------------------------------------ /* -* TODO +* Get the UE S1 struct containing hashtables S1_id/UE_id. +* Is also used to set the S1_id of the UE, depending on inputs. */ struct rrc_ue_s1ap_ids_s* rrc_eNB_S1AP_get_ue_ids( @@ -305,7 +306,7 @@ rrc_eNB_S1AP_get_ue_ids( //------------------------------------------------------------------------------ /* -* TODO +* Remove UE ids (ue_initial_id and S1_id) from hashtables. */ void rrc_eNB_S1AP_remove_ue_ids( @@ -789,7 +790,7 @@ void rrc_eNB_send_S1AP_UE_CAPABILITIES_IND( //------------------------------------------------------------------------------ /* -* TODO +* Initial UE NAS message on S1AP. */ void rrc_eNB_send_S1AP_NAS_FIRST_REQ( From 961a70a04e1f2332567793659e1df3e6aaf707ba Mon Sep 17 00:00:00 2001 From: Louis Adrien Dufrene Date: Tue, 13 Nov 2018 11:20:14 +0100 Subject: [PATCH 142/233] Fusion wasn't ok, needed some modifications --- openair2/LAYER2/MAC/eNB_scheduler_dlsch.c | 24 +++++++++++------------ openair2/RRC/LTE/MESSAGES/asn1_msg.c | 12 ++++++------ openair2/RRC/LTE/rrc_eNB.c | 2 +- openair2/RRC/LTE/rrc_eNB_S1AP.c | 2 +- 4 files changed, 20 insertions(+), 20 deletions(-) diff --git a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c index a010c4ab9c..76dbd2a0a1 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c @@ -1047,18 +1047,18 @@ schedule_ue_spec(module_id_t module_idP, int slice_idxP, if (TBS - ta_len - header_length_total - sdu_length_total - 3 > 0) { rlc_status = mac_rlc_status_ind(module_idP, - rnti, - module_idP, - frameP, - subframeP, - ENB_FLAG_YES, - MBMS_FLAG_NO, - lcid, - TBS - ta_len - header_length_total - sdu_length_total - 3 -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - , 0, 0 + rnti, + module_idP, + frameP, + subframeP, + ENB_FLAG_YES, + MBMS_FLAG_NO, + lcid, + TBS - ta_len - header_length_total - sdu_length_total - 3 +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + , 0, 0 #endif - ); + ); if (rlc_status.bytes_in_buffer > 0) { LOG_D(MAC, "[eNB %d][USER-PLANE DEFAULT DRB] Frame %d : DTCH->DLSCH, Requesting %d bytes from RLC (lcid %d total hdr len %d)\n", @@ -1077,7 +1077,7 @@ schedule_ue_spec(module_id_t module_idP, int slice_idxP, lcid, TBS, //not used (char *)&dlsch_buffer[sdu_length_total] -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) , 0, 0 #endif ); diff --git a/openair2/RRC/LTE/MESSAGES/asn1_msg.c b/openair2/RRC/LTE/MESSAGES/asn1_msg.c index 4dc6c987ab..566661bd20 100644 --- a/openair2/RRC/LTE/MESSAGES/asn1_msg.c +++ b/openair2/RRC/LTE/MESSAGES/asn1_msg.c @@ -190,27 +190,27 @@ uint8_t do_MIB(rrc_eNB_carrier_data_t *carrier, uint32_t N_RB_DL, uint32_t phich switch (N_RB_DL) { case 6: - mib->message.dl_Bandwidth = MasterInformationBlock__dl_Bandwidth_n6; + mib->message.dl_Bandwidth = LTE_MasterInformationBlock__dl_Bandwidth_n6; break; case 15: - mib->message.dl_Bandwidth = MasterInformationBlock__dl_Bandwidth_n15; + mib->message.dl_Bandwidth = LTE_MasterInformationBlock__dl_Bandwidth_n15; break; case 25: - mib->message.dl_Bandwidth = MasterInformationBlock__dl_Bandwidth_n25; + mib->message.dl_Bandwidth = LTE_MasterInformationBlock__dl_Bandwidth_n25; break; case 50: - mib->message.dl_Bandwidth = MasterInformationBlock__dl_Bandwidth_n50; + mib->message.dl_Bandwidth = LTE_MasterInformationBlock__dl_Bandwidth_n50; break; case 75: - mib->message.dl_Bandwidth = MasterInformationBlock__dl_Bandwidth_n75; + mib->message.dl_Bandwidth = LTE_MasterInformationBlock__dl_Bandwidth_n75; break; case 100: - mib->message.dl_Bandwidth = MasterInformationBlock__dl_Bandwidth_n100; + mib->message.dl_Bandwidth = LTE_MasterInformationBlock__dl_Bandwidth_n100; break; default: AssertFatal(1==0,"Unknown dl_Bandwidth %d\n",N_RB_DL); diff --git a/openair2/RRC/LTE/rrc_eNB.c b/openair2/RRC/LTE/rrc_eNB.c index d9ce73f038..c20a13bf00 100644 --- a/openair2/RRC/LTE/rrc_eNB.c +++ b/openair2/RRC/LTE/rrc_eNB.c @@ -1025,7 +1025,7 @@ void rrc_eNB_process_RRCConnectionSetupComplete( const protocol_ctxt_t *const ctxt_pP, rrc_eNB_ue_context_t *ue_context_pP, - RRCConnectionSetupComplete_r8_IEs_t *rrcConnectionSetupComplete + LTE_RRCConnectionSetupComplete_r8_IEs_t *rrcConnectionSetupComplete ) //----------------------------------------------------------------------------- { diff --git a/openair2/RRC/LTE/rrc_eNB_S1AP.c b/openair2/RRC/LTE/rrc_eNB_S1AP.c index 73316f4673..5fd32d038a 100644 --- a/openair2/RRC/LTE/rrc_eNB_S1AP.c +++ b/openair2/RRC/LTE/rrc_eNB_S1AP.c @@ -796,7 +796,7 @@ void rrc_eNB_send_S1AP_NAS_FIRST_REQ( const protocol_ctxt_t* const ctxt_pP, rrc_eNB_ue_context_t* const ue_context_pP, - RRCConnectionSetupComplete_r8_IEs_t* rrcConnectionSetupComplete + LTE_RRCConnectionSetupComplete_r8_IEs_t* rrcConnectionSetupComplete ) //------------------------------------------------------------------------------ { From 9a080adec57d9761babe49d2a1238a071e670a36 Mon Sep 17 00:00:00 2001 From: Louis Adrien Dufrene Date: Tue, 13 Nov 2018 14:20:16 +0100 Subject: [PATCH 143/233] RRC inactivity timer: first commit to DRX_master --- openair2/LAYER2/MAC/eNB_scheduler_dlsch.c | 13 +------------ openair2/LAYER2/MAC/eNB_scheduler_ulsch.c | 16 ++-------------- openair2/RRC/LTE/rrc_eNB_S1AP.c | 3 +-- 3 files changed, 4 insertions(+), 28 deletions(-) diff --git a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c index 76dbd2a0a1..a79b273a81 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c @@ -43,10 +43,6 @@ #include "RRC/LTE/rrc_extern.h" #include "RRC/L2_INTERFACE/openair_rrc_L2_interface.h" -/************************************************/ -//#include "RRC/LTE/rrc_eNB_UE_context.h" -//#include "RRC/LTE/rrc_defs.h" -/************************************************/ //#include "LAYER2/MAC/pre_processor.c" #include "pdcp.h" @@ -470,7 +466,7 @@ schedule_ue_spec(module_id_t module_idP, int slice_idxP, int header_length_last; int header_length_total; - rrc_eNB_ue_context_t *ue_contextP; // added by LA + rrc_eNB_ue_context_t *ue_contextP = NULL; start_meas(&eNB->schedule_dlsch); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_SCHEDULE_DLSCH, VCD_FUNCTION_IN); @@ -1116,13 +1112,6 @@ schedule_ue_spec(module_id_t module_idP, int slice_idxP, ue_contextP = rrc_eNB_get_ue_context(RC.rrc[module_idP], rnti); ue_contextP->ue_context.ue_rrc_inactivity_timer = 1; - LOG_W(RRC, "After reset, rrc_inactivity_timer is %d, of UE rntiP %d, ue_context_rnti %d, UE_id %d, ue_initial_id %d\n", - ue_contextP->ue_context.ue_rrc_inactivity_timer, - rnti, - ue_contextP->ue_id_rnti, - UE_id, - ue_contextP->ue_context.ue_initial_id); - } // end if (rlc_status.bytes_in_buffer > 0) } else { // no TBS left break; // break for (lcid = NB_RB_MAX - 1; lcid >= DTCH; lcid--) diff --git a/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c b/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c index fcd87d926a..997877d7a8 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c @@ -45,10 +45,6 @@ #include "RRC/LTE/rrc_extern.h" #include "RRC/L2_INTERFACE/openair_rrc_L2_interface.h" -/************************************************/ -//#include "RRC/LTE/rrc_eNB_UE_context.h" -//#include "RRC/LTE/rrc_defs.h" -/************************************************/ #include "assertions.h" //#include "LAYER2/MAC/pre_processor.c" @@ -115,7 +111,7 @@ rx_sdu(const module_id_t enb_mod_idP, (RA_t *) & RC.mac[enb_mod_idP]->common_channels[CC_idP].ra[0]; int first_rb = 0; - rrc_eNB_ue_context_t *ue_contextP; // added by LA + rrc_eNB_ue_context_t *ue_contextP = NULL; start_meas(&mac->rx_ulsch_sdu); @@ -743,15 +739,7 @@ rx_sdu(const module_id_t enb_mod_idP, // reset RRC inactivity timer after uplane activity ue_contextP = rrc_eNB_get_ue_context(RC.rrc[enb_mod_idP], rntiP); - ue_contextP->ue_context.ue_rrc_inactivity_timer = 1; - - LOG_W(RRC, "After reset, rrc_inactivity_timer is %d, of UE rntiP %d, ue_context_rnti %d, UE_id %d, ue_initial_id %d\n", - ue_contextP->ue_context.ue_rrc_inactivity_timer, - rntiP, - ue_contextP->ue_id_rnti, - UE_id, - ue_contextP->ue_context.ue_initial_id); - + ue_contextP->ue_context.ue_rrc_inactivity_timer = 1; } else { /* rx_length[i] */ UE_list->eNB_UE_stats[CC_idP][UE_id].num_errors_rx += 1; diff --git a/openair2/RRC/LTE/rrc_eNB_S1AP.c b/openair2/RRC/LTE/rrc_eNB_S1AP.c index 5fd32d038a..b7d15da58d 100644 --- a/openair2/RRC/LTE/rrc_eNB_S1AP.c +++ b/openair2/RRC/LTE/rrc_eNB_S1AP.c @@ -36,11 +36,10 @@ # include "rrc_eNB_S1AP.h" # include "enb_config.h" # include "common/ran_context.h" -/****************************************/ + # include "s1ap_eNB_defs.h" # include "s1ap_eNB_management_procedures.h" # include "s1ap_eNB_ue_context.h" -/****************************************/ # if defined(ENABLE_ITTI) # include "asn1_conversions.h" From af892cc0580107177e1652a938aa57e61722215d Mon Sep 17 00:00:00 2001 From: laurent Date: Wed, 14 Nov 2018 20:51:41 +0100 Subject: [PATCH 144/233] start fixing parallel threads --- common/utils/LOG/log.c | 4 - nfapi/oai_integration/nfapi_vnf.c | 4 +- openair1/PHY/LTE_TRANSPORT/ulsch_decoding.c | 2 +- .../PHY/LTE_UE_TRANSPORT/dlsch_demodulation.c | 19 ++--- openair1/PHY/defs_common.h | 55 ++++++++++-- openair1/PHY/defs_eNB.h | 3 +- openair1/SCHED/phy_procedures_lte_eNb.c | 4 +- openair1/SIMULATION/LTE_PHY/common_sim.h | 44 ++++++---- openair1/SIMULATION/LTE_PHY/dlsim.c | 80 +++++++----------- openair1/SIMULATION/LTE_PHY/ulsim.c | 83 +++++++------------ targets/RT/USER/lte-enb.c | 13 +-- targets/RT/USER/lte-softmodem.c | 26 +----- targets/RT/USER/lte-uesoftmodem.c | 24 +----- 13 files changed, 153 insertions(+), 208 deletions(-) diff --git a/common/utils/LOG/log.c b/common/utils/LOG/log.c index d6dd97e34f..4f0f379f12 100644 --- a/common/utils/LOG/log.c +++ b/common/utils/LOG/log.c @@ -39,10 +39,6 @@ #include "vcd_signal_dumper.h" #include "assertions.h" -#if defined(ENABLE_ITTI) -# include "intertask_interface.h" -#endif - # include # include #include diff --git a/nfapi/oai_integration/nfapi_vnf.c b/nfapi/oai_integration/nfapi_vnf.c index 8022bc53f4..bd9ce8dc1c 100644 --- a/nfapi/oai_integration/nfapi_vnf.c +++ b/nfapi/oai_integration/nfapi_vnf.c @@ -196,14 +196,12 @@ void oai_create_enb(void) { int bodge_counter=0; PHY_VARS_eNB *eNB = RC.eNB[0][0]; - printf("[VNF] RC.eNB[0][0]. Mod_id:%d CC_id:%d nb_CC[0]:%d abstraction_flag:%d single_thread_flag:%d td:%p te:%p if_inst:%p\n", eNB->Mod_id, eNB->CC_id, RC.nb_CC[0], eNB->abstraction_flag, eNB->single_thread_flag, eNB->td, eNB->te, eNB->if_inst); + printf("[VNF] RC.eNB[0][0]. Mod_id:%d CC_id:%d nb_CC[0]:%d abstraction_flag:%d single_thread_flag:%d if_inst:%p\n", eNB->Mod_id, eNB->CC_id, RC.nb_CC[0], eNB->abstraction_flag, eNB->single_thread_flag, eNB->if_inst); eNB->Mod_id = bodge_counter; eNB->CC_id = bodge_counter; eNB->abstraction_flag = 0; eNB->single_thread_flag = 0;//single_thread_flag; - eNB->td = ulsch_decoding_data_all;//(single_thread_flag==1) ? ulsch_decoding_data_2thread : ulsch_decoding_data; - eNB->te = dlsch_encoding_all;//(single_thread_flag==1) ? dlsch_encoding_2threads : dlsch_encoding; RC.nb_CC[bodge_counter] = 1; diff --git a/openair1/PHY/LTE_TRANSPORT/ulsch_decoding.c b/openair1/PHY/LTE_TRANSPORT/ulsch_decoding.c index 046e456916..50b9ef17ac 100644 --- a/openair1/PHY/LTE_TRANSPORT/ulsch_decoding.c +++ b/openair1/PHY/LTE_TRANSPORT/ulsch_decoding.c @@ -1505,7 +1505,7 @@ unsigned int ulsch_decoding(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc, // Do ULSCH Decoding for data portion - ret = eNB->td(eNB,UE_id,harq_pid,llr8_flag); + ret = ulsch_decoding_data_all(eNB,UE_id,harq_pid,llr8_flag); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_ENB_ULSCH_DECODING0+harq_pid,0); diff --git a/openair1/PHY/LTE_UE_TRANSPORT/dlsch_demodulation.c b/openair1/PHY/LTE_UE_TRANSPORT/dlsch_demodulation.c index e8f20c85de..89b15ece93 100644 --- a/openair1/PHY/LTE_UE_TRANSPORT/dlsch_demodulation.c +++ b/openair1/PHY/LTE_UE_TRANSPORT/dlsch_demodulation.c @@ -1298,7 +1298,7 @@ void dlsch_channel_compensation(int **rxdataF_ext, unsigned short rb; unsigned char aatx,aarx,symbol_mod,pilots=0; __m128i *dl_ch128,*dl_ch128_2,*dl_ch_mag128,*dl_ch_mag128b,*rxdataF128,*rxdataF_comp128,*rho128; - __m128i mmtmpD0,mmtmpD1,mmtmpD2,mmtmpD3,QAM_amp128,QAM_amp128b; + __m128i mmtmpD0,mmtmpD1,mmtmpD2,mmtmpD3,QAM_amp128; symbol_mod = (symbol>=(7-frame_parms->Ncp)) ? symbol-(7-frame_parms->Ncp) : symbol; @@ -1311,9 +1311,9 @@ void dlsch_channel_compensation(int **rxdataF_ext, } for (aatx=0; aatxnb_antenna_ports_eNB; aatx++) { + __m128i QAM_amp128b = _mm_setzero_si128(); if (mod_order == 4) { QAM_amp128 = _mm_set1_epi16(QAM16_n1); // 2/sqrt(10) - QAM_amp128b = _mm_setzero_si128(); } else if (mod_order == 6) { QAM_amp128 = _mm_set1_epi16(QAM64_n1); // QAM_amp128b = _mm_set1_epi16(QAM64_n2); @@ -1766,11 +1766,11 @@ void dlsch_channel_compensation_core(int **rxdataF_ext, int length_mod8 = 0; int length2; __m128i *dl_ch128,*dl_ch_mag128,*dl_ch_mag128b, *dl_ch128_2, *rxdataF128,*rxdataF_comp128,*rho128; - __m128i mmtmpD0,mmtmpD1,mmtmpD2,mmtmpD3,QAM_amp128,QAM_amp128b; + __m128i mmtmpD0,mmtmpD1,mmtmpD2,mmtmpD3,QAM_amp128; int aatx = 0, aarx = 0; for (aatx=0; aatx=(7-frame_parms->Ncp)) ? symbol-(7-frame_parms->Ncp) : symbol; @@ -2167,10 +2167,9 @@ void dlsch_channel_compensation_TM56(int **rxdataF_ext, //printf("comp prec: symbol %d, pilots %d\n",symbol, pilots); - + __m128i QAM_amp128b = _mm_setzero_si128(); if (mod_order == 4) { QAM_amp128 = _mm_set1_epi16(QAM16_n1); - QAM_amp128b = _mm_setzero_si128(); } else if (mod_order == 6) { QAM_amp128 = _mm_set1_epi16(QAM64_n1); QAM_amp128b = _mm_set1_epi16(QAM64_n2); @@ -2621,7 +2620,7 @@ void dlsch_channel_compensation_TM34(LTE_DL_FRAME_PARMS *frame_parms, int **rxdataF_comp0 = pdsch_vars->rxdataF_comp0; int **rxdataF_comp1 = pdsch_vars->rxdataF_comp1[harq_pid][round]; unsigned char *pmi_ext = pdsch_vars->pmi_ext; - __m128i mmtmpD0,mmtmpD1,mmtmpD2,mmtmpD3,QAM_amp0_128,QAM_amp0_128b,QAM_amp1_128,QAM_amp1_128b; + __m128i mmtmpD0,mmtmpD1,mmtmpD2,mmtmpD3,QAM_amp0_128,QAM_amp1_128; symbol_mod = (symbol>=(7-frame_parms->Ncp)) ? symbol-(7-frame_parms->Ncp) : symbol; @@ -2632,17 +2631,17 @@ void dlsch_channel_compensation_TM34(LTE_DL_FRAME_PARMS *frame_parms, // printf("comp prec: symbol %d, pilots %d\n",symbol, pilots); + __m128i QAM_amp0_128b = _mm_setzero_si128(); if (mod_order0 == 4) { QAM_amp0_128 = _mm_set1_epi16(QAM16_n1); - QAM_amp0_128b = _mm_setzero_si128(); } else if (mod_order0 == 6) { QAM_amp0_128 = _mm_set1_epi16(QAM64_n1); QAM_amp0_128b = _mm_set1_epi16(QAM64_n2); } + __m128i QAM_amp1_128b = _mm_setzero_si128(); if (mod_order1 == 4) { QAM_amp1_128 = _mm_set1_epi16(QAM16_n1); - QAM_amp1_128b = _mm_setzero_si128(); } else if (mod_order1 == 6) { QAM_amp1_128 = _mm_set1_epi16(QAM64_n1); QAM_amp1_128b = _mm_set1_epi16(QAM64_n2); diff --git a/openair1/PHY/defs_common.h b/openair1/PHY/defs_common.h index ae0168b53c..9f4a196a9b 100644 --- a/openair1/PHY/defs_common.h +++ b/openair1/PHY/defs_common.h @@ -58,6 +58,7 @@ #include #include "common_lib.h" #include "msc.h" +#include //#include @@ -862,22 +863,60 @@ typedef enum { RESYNCH=4 } UE_MODE_t; -/// Threading Parameter -typedef enum { - PARALLEL_SINGLE_THREAD =0, - PARALLEL_RU_L1_SPLIT =1, - PARALLEL_RU_L1_TRX_SPLIT =2 -}PARALLEL_CONF_t; +#define FOREACH_PARALLEL(GEN) \ + GEN(PARALLEL_SINGLE_THREAD) \ + GEN(PARALLEL_RU_L1_SPLIT) \ + GEN(PARALLEL_RU_L1_TRX_SPLIT) + +#define GENERATE_ENUM(N) N, +#define GENERATE_ENUMTXT(N) {(char*)#N, N}, typedef enum { - WORKER_DISABLE =0, - WORKER_ENABLE =1 + FOREACH_PARALLEL(GENERATE_ENUM) +} PARALLEL_CONF_t; + +#define FOREACH_WORKER(GEN) GEN(WORKER_DISABLE) GEN(WORKER_ENABLE) +typedef enum { + FOREACH_WORKER(GENERATE_ENUM) }WORKER_CONF_t; typedef struct THREAD_STRUCT_s { PARALLEL_CONF_t parallel_conf; WORKER_CONF_t worker_conf; } THREAD_STRUCT; +extern THREAD_STRUCT thread_struct; + +static inline void set_parallel_conf(char *parallel_conf) { + mapping config[]= { + FOREACH_PARALLEL(GENERATE_ENUMTXT) + {NULL,-1} + }; + thread_struct.parallel_conf = (PARALLEL_CONF_t)map_str_to_int(config, parallel_conf); + if (thread_struct.parallel_conf == -1 ) { + LOG_E(ENB_APP,"Impossible value: %s\n", parallel_conf); + thread_struct.parallel_conf = PARALLEL_SINGLE_THREAD; + } +} + +static inline void set_worker_conf(char *worker_conf) { + mapping config[]={ + FOREACH_WORKER(GENERATE_ENUMTXT) + {NULL, -1} + }; + thread_struct.worker_conf = (WORKER_CONF_t)map_str_to_int(config, worker_conf); + if (thread_struct.worker_conf == -1 ) { + LOG_E(ENB_APP,"Impossible value: %s\n", worker_conf); + thread_struct.worker_conf = WORKER_DISABLE ; + } +} + +static inline PARALLEL_CONF_t get_thread_parallel_conf(void) { + return thread_struct.parallel_conf; +} + +static inline WORKER_CONF_t get_thread_worker_conf(void) { + return thread_struct.worker_conf; +} typedef enum {SF_DL, SF_UL, SF_S} lte_subframe_t; diff --git a/openair1/PHY/defs_eNB.h b/openair1/PHY/defs_eNB.h index 2db81aef77..bb147a3963 100644 --- a/openair1/PHY/defs_eNB.h +++ b/openair1/PHY/defs_eNB.h @@ -904,8 +904,6 @@ typedef struct PHY_VARS_eNB_s { /// Ethernet parameters for fronthaul interface eth_params_t eth_params; int rx_total_gain_dB; - int (*td)(struct PHY_VARS_eNB_s *eNB,int UE_id,int harq_pid,int llr8_flag); - int (*te)(struct PHY_VARS_eNB_s *,uint8_t *,uint8_t,LTE_eNB_DLSCH_t *,int,uint8_t,time_stats_t *,time_stats_t *,time_stats_t *,time_stats_t *,time_stats_t *,time_stats_t *,time_stats_t *); int (*start_if)(struct RU_t_s *ru,struct PHY_VARS_eNB_s *eNB); uint8_t local_flag; LTE_DL_FRAME_PARMS frame_parms; @@ -1080,6 +1078,7 @@ typedef struct PHY_VARS_eNB_s { time_stats_t ofdm_mod_stats; time_stats_t dlsch_common_and_dci; + time_stats_t dlsch_ue_specific; time_stats_t dlsch_encoding_stats; time_stats_t dlsch_modulation_stats; time_stats_t dlsch_scrambling_stats; diff --git a/openair1/SCHED/phy_procedures_lte_eNb.c b/openair1/SCHED/phy_procedures_lte_eNb.c index b1d09ba8e9..141f6e43ff 100644 --- a/openair1/SCHED/phy_procedures_lte_eNb.c +++ b/openair1/SCHED/phy_procedures_lte_eNb.c @@ -400,7 +400,7 @@ void pdsch_procedures(PHY_VARS_eNB *eNB, start_meas(&eNB->dlsch_encoding_stats); - eNB->te(eNB, + dlsch_encoding_all(eNB, dlsch_harq->pdu, dlsch_harq->pdsch_start, dlsch, @@ -582,6 +582,7 @@ void phy_procedures_eNB_TX(PHY_VARS_eNB *eNB, } if (do_meas==1) stop_meas(&eNB->dlsch_common_and_dci); + if (do_meas==1) start_meas(&eNB->dlsch_ue_specific); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_ENB_PDCCH_TX,0); @@ -649,6 +650,7 @@ void phy_procedures_eNB_TX(PHY_VARS_eNB *eNB, VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_GENERATE_PHICH,0); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_ENB_TX+(eNB->CC_id),0); + if (do_meas==1) stop_meas(&eNB->dlsch_ue_specific); if (do_meas==1) stop_meas(&eNB->phy_proc_tx); } diff --git a/openair1/SIMULATION/LTE_PHY/common_sim.h b/openair1/SIMULATION/LTE_PHY/common_sim.h index 46f4cdf161..e9ad4dc888 100644 --- a/openair1/SIMULATION/LTE_PHY/common_sim.h +++ b/openair1/SIMULATION/LTE_PHY/common_sim.h @@ -49,22 +49,6 @@ void sumUpStatsSlot(time_stats_t *res, time_stats_t src[RX_NB_TH][2], int lastAc res->p_time=src[lastActive][last].p_time; } -void printStatIndent(time_stats_t *ptr, char *txt) { - printf("|__ %-50s %.2f us (%d trials)\n", - txt, - ptr->trials?inMicroS(ptr->diff/ptr->trials):0, - ptr->trials); -} - -void printStatIndent2(time_stats_t *ptr, char *txt, int turbo_iter) { - double timeBase=1/(1000*cpu_freq_GHz); - printf(" |__ %-45s %.2f us (cycles/block %ld, %5d trials)\n", - txt, - ptr->trials?((double)ptr->diff)/ptr->trials*timeBase:0, - turbo_iter?(uint64_t)round(((double)ptr->diff)/turbo_iter):0, - ptr->trials); -} - double squareRoot(time_stats_t *ptr) { double timeBase=1/(1000*cpu_freq_GHz); return sqrt((double)ptr->diff_square*pow(timeBase,2)/ptr->trials - @@ -73,14 +57,38 @@ double squareRoot(time_stats_t *ptr) { void printDistribution(time_stats_t *ptr, varArray_t *sortedList, char *txt) { double timeBase=1/(1000*cpu_freq_GHz); - printf("%-50s :%.2f us (%d trials)\n", + printf("%-43s %6.2f us (%d trials)\n", txt, (double)ptr->diff/ptr->trials*timeBase, ptr->trials); - printf("|__ Statistics std=%.2f, median=%.2f, q1=%.2f, q3=%.2f µs (on %ld trials)\n", + printf(" Statistics std=%.2f, median=%.2f, q1=%.2f, q3=%.2f µs (on %ld trials)\n", squareRoot(ptr), median(sortedList),q1(sortedList),q3(sortedList), sortedList->size); } +void printStatIndent(time_stats_t *ptr, char *txt) { + printf("|__ %-38s %6.2f us (%3d trials)\n", + txt, + ptr->trials?inMicroS(ptr->diff/ptr->trials):0, + ptr->trials); +} + +void printStatIndent2(time_stats_t *ptr, char *txt) { + double timeBase=1/(1000*cpu_freq_GHz); + printf(" |__ %-34s %6.2f us (%3d trials)\n", + txt, + ptr->trials?((double)ptr->diff)/ptr->trials*timeBase:0, + ptr->trials); +} + +void printStatIndent3(time_stats_t *ptr, char *txt) { + double timeBase=1/(1000*cpu_freq_GHz); + printf(" |__ %-30s %6.2f us (%3d trials)\n", + txt, + ptr->trials?((double)ptr->diff)/ptr->trials*timeBase:0, + ptr->trials); +} + + void logDistribution(FILE* fd, time_stats_t *ptr, varArray_t *sortedList, int dropped) { fprintf(fd,"%f;%f;%f;%f;%f;%f;%d;", squareRoot(ptr), diff --git a/openair1/SIMULATION/LTE_PHY/dlsim.c b/openair1/SIMULATION/LTE_PHY/dlsim.c index 0f4655eb2c..dde026f418 100644 --- a/openair1/SIMULATION/LTE_PHY/dlsim.c +++ b/openair1/SIMULATION/LTE_PHY/dlsim.c @@ -85,30 +85,7 @@ double t_rx_min = 1000000000; /*!< \brief initial min process time for rx */ int n_tx_dropped = 0; /*!< \brief initial max process time for tx */ int n_rx_dropped = 0; /*!< \brief initial max process time for rx */ -char *parallel_config = NULL; -char *worker_config = NULL; -static THREAD_STRUCT thread_struct; -void set_parallel_conf(char *parallel_conf) -{ - if(strcmp(parallel_conf,"PARALLEL_SINGLE_THREAD")==0) thread_struct.parallel_conf = PARALLEL_SINGLE_THREAD; - else if(strcmp(parallel_conf,"PARALLEL_RU_L1_SPLIT")==0) thread_struct.parallel_conf = PARALLEL_RU_L1_SPLIT; - else if(strcmp(parallel_conf,"PARALLEL_RU_L1_TRX_SPLIT")==0) thread_struct.parallel_conf = PARALLEL_RU_L1_TRX_SPLIT; - printf("[CONFIG] parallel conf is set to %d\n",thread_struct.parallel_conf); -} -void set_worker_conf(char *worker_conf) -{ - if(strcmp(worker_conf,"WORKER_DISABLE")==0) thread_struct.worker_conf = WORKER_DISABLE; - else if(strcmp(worker_conf,"WORKER_ENABLE")==0) thread_struct.worker_conf = WORKER_ENABLE; - printf("[CONFIG] worker conf is set to %d\n",thread_struct.worker_conf); -} -PARALLEL_CONF_t get_thread_parallel_conf(void) -{ - return thread_struct.parallel_conf; -} -WORKER_CONF_t get_thread_worker_conf(void) -{ - return thread_struct.worker_conf; -} +THREAD_STRUCT thread_struct; int emulate_rf = 0; @@ -715,7 +692,7 @@ int main(int argc, char **argv) DL_req.dl_config_request_body.dl_config_pdu_list = dl_config_pdu_list; TX_req.tx_request_body.tx_pdu_list = tx_pdu_list; - + set_parallel_conf("PARALLEL_SINGLE_THREAD"); cpuf = cpu_freq_GHz; //signal(SIGSEGV, handler); @@ -758,6 +735,7 @@ int main(int argc, char **argv) { "Subframe", "subframe ",0, iptr:&subframe, defintval:7, TYPE_INT, 0 }, { "Trnti", "rnti",0, u16ptr:&n_rnti, defuintval:0x1234, TYPE_UINT16, 0 }, { "vi_mod", "i_mod",0, iptr:NULL, defintval:0, TYPE_INT, 0 }, + { "Qparallel", "Enable parallel execution",0, strptr:NULL, defstrval:NULL, TYPE_STRING, 0 }, { "Performance", "Display CPU perfomance of each L1 piece", PARAMFLAG_BOOL, iptr:&print_perf, defintval:0, TYPE_INT, 0 }, { "q_tx_port", "Number of TX antennas ports used in eNB",0, iptr:NULL, defintval:0, TYPE_INT, 0 }, { "uEdual", "Enables the Interference Aware Receiver for TM5 (default is normal receiver)",0, iptr:NULL, defintval:0, TYPE_INT, 0 }, @@ -965,6 +943,10 @@ int main(int argc, char **argv) break; + case 'Q': + set_parallel_conf(optarg); + break; + default: printf("Wrong option: %s\n",long_options[option_index].name); exit(1); @@ -982,8 +964,8 @@ int main(int argc, char **argv) if (help) exit(0); - set_parallel_conf("PARALLEL_RU_L1_TRX_SPLIT"); - set_worker_conf("WORKER_ENABLE"); + if (thread_struct.parallel_conf != PARALLEL_SINGLE_THREAD) + set_worker_conf("WORKER_ENABLE"); if (transmission_mode>1) pa=dBm3; printf("dlsim: tmode %d, pa %d\n",transmission_mode,pa); @@ -1079,11 +1061,7 @@ int main(int argc, char **argv) ru->do_precoding=1; eNB->mac_enabled=1; - if (two_thread_flag == 0) { - eNB->te = dlsch_encoding; - } - else { - eNB->te = dlsch_encoding_2threads; + if(get_thread_worker_conf() == WORKER_ENABLE) { extern void init_td_thread(PHY_VARS_eNB *); extern void init_te_thread(PHY_VARS_eNB *); init_td_thread(eNB); @@ -1442,6 +1420,8 @@ int main(int argc, char **argv) reset_meas(&eNB->dlsch_interleaving_stats); reset_meas(&eNB->dlsch_rate_matching_stats); reset_meas(&eNB->dlsch_turbo_encoding_stats); + reset_meas(&eNB->dlsch_common_and_dci); + reset_meas(&eNB->dlsch_ue_specific); for (int i=0; iphy_proc_rx[i]); // total UE rx reset_meas(&UE->ue_front_end_stat[i]); @@ -1783,9 +1763,6 @@ int main(int argc, char **argv) } - - - if (UE->dlsch[UE->current_thread_id[subframe]][eNB_id][0]->harq_ack[subframe].ack == 1) { avg_iter += UE->dlsch[UE->current_thread_id[subframe]][eNB_id][0]->last_iteration_cnt; @@ -2011,21 +1988,22 @@ int main(int argc, char **argv) printf("\neNB TX function statistics (per 1ms subframe)\n"); printDistribution(&eNB->phy_proc_tx,table_tx,"PHY proc tx"); printStatIndent(&eNB->dlsch_common_and_dci,"DL common channels and dci time"); - printStatIndent(&eNB->dlsch_encoding_stats,"DLSCH encoding time"); - printStatIndent2(&eNB->dlsch_rate_matching_stats,"DLSCH rate matching time",eNB->dlsch_rate_matching_stats.trials); - printStatIndent2(&eNB->dlsch_turbo_encoding_stats,"DLSCH turbo encoding time", eNB->dlsch_turbo_encoding_stats.trials); - printStatIndent2(&eNB->dlsch_interleaving_stats,"DLSCH interleaving time", eNB->dlsch_interleaving_stats.trials); - printStatIndent(&eNB->dlsch_scrambling_stats, "DLSCH scrambling time"); - printStatIndent(&eNB->dlsch_modulation_stats, "DLSCH modulation time"); + printStatIndent(&eNB->dlsch_ue_specific,"DL per ue part time"); + printStatIndent2(&eNB->dlsch_encoding_stats,"DLSCH encoding time"); + printStatIndent3(&eNB->dlsch_rate_matching_stats,"DLSCH rate matching time"); + printStatIndent3(&eNB->dlsch_turbo_encoding_stats,"DLSCH turbo encoding time"); + printStatIndent3(&eNB->dlsch_interleaving_stats,"DLSCH interleaving time"); + printStatIndent2(&eNB->dlsch_scrambling_stats, "DLSCH scrambling time"); + printStatIndent2(&eNB->dlsch_modulation_stats, "DLSCH modulation time"); printDistribution(&eNB->ofdm_mod_stats,table_tx_ifft,"OFDM_mod (idft) time"); printf("\nUE RX function statistics (per 1ms subframe)\n"); printDistribution(&phy_proc_rx_tot, table_rx,"Total PHY proc rx"); printStatIndent(&ue_front_end_tot,"Front end processing"); printStatIndent(&dlsch_llr_tot,"rx_pdsch processing"); - printStatIndent2(&pdsch_procedures_tot,"pdsch processing", pdsch_procedures_tot.trials); - printStatIndent2(&dlsch_procedures_tot,"dlsch processing", dlsch_procedures_tot.trials); - printStatIndent2(&UE->crnti_procedures_stats,"C-RNTI processing", UE->crnti_procedures_stats.trials); + printStatIndent2(&pdsch_procedures_tot,"pdsch processing"); + printStatIndent2(&dlsch_procedures_tot,"dlsch processing"); + printStatIndent2(&UE->crnti_procedures_stats,"C-RNTI processing"); printStatIndent(&UE->ofdm_demod_stats,"ofdm demodulation"); printStatIndent(&UE->dlsch_channel_estimation_stats,"DLSCH channel estimation time"); printStatIndent(&UE->dlsch_freq_offset_estimation_stats,"DLSCH frequency offset estimation time"); @@ -2041,13 +2019,13 @@ int main(int argc, char **argv) (double)UE->dlsch_turbo_decoding_stats.diff/UE->dlsch_turbo_decoding_stats.trials*timeBase, (int)((double)UE->dlsch_turbo_decoding_stats.diff/UE->dlsch_turbo_decoding_stats.trials), UE->dlsch_turbo_decoding_stats.trials); - printStatIndent2(&UE->dlsch_tc_init_stats,"init", UE->dlsch_tc_init_stats.trials); - printStatIndent2(&UE->dlsch_tc_alpha_stats,"alpha", UE->dlsch_tc_init_stats.trials); - printStatIndent2(&UE->dlsch_tc_beta_stats,"beta", UE->dlsch_tc_init_stats.trials); - printStatIndent2(&UE->dlsch_tc_gamma_stats,"gamma", UE->dlsch_tc_init_stats.trials); - printStatIndent2(&UE->dlsch_tc_ext_stats,"ext", UE->dlsch_tc_init_stats.trials); - printStatIndent2(&UE->dlsch_tc_intl1_stats,"turbo internal interleaver", UE->dlsch_tc_init_stats.trials); - printStatIndent2(&UE->dlsch_tc_intl2_stats,"intl2+HardDecode+CRC", UE->dlsch_tc_init_stats.trials); + printStatIndent2(&UE->dlsch_tc_init_stats,"init"); + printStatIndent2(&UE->dlsch_tc_alpha_stats,"alpha"); + printStatIndent2(&UE->dlsch_tc_beta_stats,"beta"); + printStatIndent2(&UE->dlsch_tc_gamma_stats,"gamma"); + printStatIndent2(&UE->dlsch_tc_ext_stats,"ext"); + printStatIndent2(&UE->dlsch_tc_intl1_stats,"turbo internal interleaver"); + printStatIndent2(&UE->dlsch_tc_intl2_stats,"intl2+HardDecode+CRC"); } diff --git a/openair1/SIMULATION/LTE_PHY/ulsim.c b/openair1/SIMULATION/LTE_PHY/ulsim.c index c015063b60..52d7f023f1 100644 --- a/openair1/SIMULATION/LTE_PHY/ulsim.c +++ b/openair1/SIMULATION/LTE_PHY/ulsim.c @@ -96,30 +96,7 @@ nfapi_tx_request_pdu_t tx_pdu_list[MAX_NUM_TX_REQUEST_PDU]; nfapi_tx_request_t TX_req; Sched_Rsp_t sched_resp; -char *parallel_config = NULL; -char *worker_config = NULL; -static THREAD_STRUCT thread_struct; -void set_parallel_conf(char *parallel_conf) -{ - if(strcmp(parallel_conf,"PARALLEL_SINGLE_THREAD")==0) thread_struct.parallel_conf = PARALLEL_SINGLE_THREAD; - else if(strcmp(parallel_conf,"PARALLEL_RU_L1_SPLIT")==0) thread_struct.parallel_conf = PARALLEL_RU_L1_SPLIT; - else if(strcmp(parallel_conf,"PARALLEL_RU_L1_TRX_SPLIT")==0) thread_struct.parallel_conf = PARALLEL_RU_L1_TRX_SPLIT; - printf("[CONFIG] parallel conf is set to %d\n",thread_struct.parallel_conf); -} -void set_worker_conf(char *worker_conf) -{ - if(strcmp(worker_conf,"WORKER_DISABLE")==0) thread_struct.worker_conf = WORKER_DISABLE; - else if(strcmp(worker_conf,"WORKER_ENABLE")==0) thread_struct.worker_conf = WORKER_ENABLE; - printf("[CONFIG] worker conf is set to %d\n",thread_struct.worker_conf); -} -PARALLEL_CONF_t get_thread_parallel_conf(void) -{ - return thread_struct.parallel_conf; -} -WORKER_CONF_t get_thread_worker_conf(void) -{ - return thread_struct.worker_conf; -} +THREAD_STRUCT thread_struct; void fill_nfapi_ulsch_config_request(nfapi_ul_config_request_pdu_t *ul_config_pdu, @@ -410,7 +387,6 @@ int main(int argc, char **argv) { double effective_rate=0.0; char channel_model_input[10]= {0}; static int max_turbo_iterations=4; - static int parallel_flag=0; int nb_rb_set = 0; int sf; static int threequarter_fs=0; @@ -428,6 +404,8 @@ int main(int argc, char **argv) { TX_req.tx_request_body.tx_pdu_list = tx_pdu_list; cpu_freq_GHz = (double)get_cpu_freq_GHz(); cpuf = cpu_freq_GHz; + set_parallel_conf("PARALLEL_SINGLE_THREAD"); + printf("Detected cpu_freq %f GHz\n",cpu_freq_GHz); AssertFatal(load_configmodule(argc,argv) != NULL, "cannot load configuration module, exiting\n"); @@ -455,7 +433,7 @@ int main(int argc, char **argv) { { "Doppler", "Maximum doppler shift",0, dblptr:&maxDoppler, defdblval:0.0, TYPE_DOUBLE, 0 }, { "Zdump", "dump table",PARAMFLAG_BOOL, iptr:&dump_table, defintval:0, TYPE_INT, 0 }, { "Forms", "Display the soft scope", PARAMFLAG_BOOL, iptr:&xforms, defintval:0, TYPE_INT, 0 }, - { "Lparallel", "Enable parallel execution", PARAMFLAG_BOOL, iptr:¶llel_flag, defintval:0, TYPE_INT, 0 }, + { "Lparallel", "Enable parallel execution",0, strptr:NULL, defstrval:NULL, TYPE_STRING, 0 }, { "Iterations", "Number of iterations of turbo decoder", 0, iptr:&max_turbo_iterations, defintval:4, TYPE_INT, 0 }, { "Performance", "Display CPU perfomance of each L1 piece", PARAMFLAG_BOOL, iptr:NULL, defintval:0, TYPE_INT, 0 }, { "Q_cqi", "Enable CQI", PARAMFLAG_BOOL, iptr:&cqi_flag, defintval:0, TYPE_INT, 0 }, @@ -600,6 +578,10 @@ int main(int argc, char **argv) { opp_enabled=1; break; + case 'L': + set_parallel_conf(optarg); + break; + default: printf("Wrong option: %s\n",long_options[option_index].name); exit(1); @@ -618,8 +600,8 @@ int main(int argc, char **argv) { if (help) exit(0); - set_parallel_conf("PARALLEL_RU_L1_TRX_SPLIT"); - set_worker_conf("WORKER_ENABLE"); + if (thread_struct.parallel_conf != PARALLEL_SINGLE_THREAD) + set_worker_conf("WORKER_ENABLE"); RC.nb_L1_inst = 1; RC.nb_RU = 1; lte_param_init(&eNB,&UE,&ru, @@ -767,7 +749,7 @@ int main(int argc, char **argv) { UE->ulsch[0] = new_ue_ulsch(N_RB_DL,0); printf("ULSCH %p\n",UE->ulsch[0]); - if (parallel_flag == 1) { + if(get_thread_worker_conf() == WORKER_ENABLE) { extern void init_fep_thread(PHY_VARS_eNB *, pthread_attr_t *); extern void init_td_thread(PHY_VARS_eNB *); init_fep_thread(eNB,NULL); @@ -1175,8 +1157,7 @@ int main(int argc, char **argv) { } start_meas(&eNB->phy_proc_rx); - ru->feprx = (parallel_flag == 1) ? ru_fep_full_2thread : fep_full; - eNB->td = (parallel_flag == 1) ? ulsch_decoding_data_2thread : ulsch_decoding_data; + ru->feprx = (get_thread_worker_conf() == WORKER_ENABLE) ? ru_fep_full_2thread : fep_full; ru->feprx(ru); phy_procedures_eNB_uespec_RX(eNB,proc_rxtx); stop_meas(&eNB->phy_proc_rx); @@ -1377,20 +1358,18 @@ int main(int argc, char **argv) { printStatIndent(&UE->ulsch_rate_matching_stats,"ULSCH rate-matching time"); printStatIndent(&UE->ulsch_interleaving_stats,"ULSCH sub-block interleaving"); printStatIndent(&UE->ulsch_multiplexing_stats,"ULSCH multiplexing time"); - printDistribution(&eNB->phy_proc_rx,table_rx,"\nTotal PHY proc rx subframe"); - printDistribution(&ru->ofdm_demod_stats,table_rx_fft,"OFDM_demod time"); - printDistribution(&eNB->ulsch_demodulation_stats,table_rx_demod,"ULSCH demodulation time"); - printf("ULSCH Decoding time (%.2f Mbit/s, avg iter %.2f) :%.2f us (%d trials, max %.2f)\n", - UE->ulsch[0]->harq_processes[harq_pid]->TBS/1000.0,(double)iter_trials, - (double)eNB->ulsch_decoding_stats.diff/eNB->ulsch_decoding_stats.trials*timeBase, - eNB->ulsch_decoding_stats.trials, - (double)eNB->ulsch_decoding_stats.max*timeBase); - printf("|__ Statistics std: %.2fus median %.2fus q1 %.2fus q3 %.2fus \n", - squareRoot(&eNB->ulsch_decoding_stats), - median(table_rx_dec), q1(table_rx_dec), q3(table_rx_dec)); - printStatIndent(&eNB->ulsch_deinterleaving_stats,"sub-block interleaving" ); - printStatIndent(&eNB->ulsch_demultiplexing_stats,"sub-block demultiplexing" ); - printStatIndent(&eNB->ulsch_rate_unmatching_stats,"sub-block rate-matching" ); + printf("\n"); + printDistribution(&eNB->phy_proc_rx,table_rx,"Total PHY proc rx subframe"); + printDistribution(&ru->ofdm_demod_stats,table_rx_fft,"|__ OFDM_demod time"); + printDistribution(&eNB->ulsch_demodulation_stats,table_rx_demod,"|__ ULSCH demodulation time"); + printDistribution(&eNB->ulsch_decoding_stats,table_rx_dec,"|__ ULSCH Decoding time"); + printf(" (%.2f Mbit/s, avg iter %.2f, max %.2f)\n", + UE->ulsch[0]->harq_processes[harq_pid]->TBS/1000.0, + (double)iter_trials, + (double)eNB->ulsch_decoding_stats.max*timeBase); + printStatIndent2(&eNB->ulsch_deinterleaving_stats,"sub-block interleaving" ); + printStatIndent2(&eNB->ulsch_demultiplexing_stats,"sub-block demultiplexing" ); + printStatIndent2(&eNB->ulsch_rate_unmatching_stats,"sub-block rate-matching" ); printf("|__ turbo_decoder(%d bits), avg iterations: %.1f %.2f us (%d cycles, %d trials)\n", eNB->ulsch[0]->harq_processes[harq_pid]->Cminus ? eNB->ulsch[0]->harq_processes[harq_pid]->Kminus : @@ -1399,13 +1378,13 @@ int main(int argc, char **argv) { (double)eNB->ulsch_turbo_decoding_stats.diff/eNB->ulsch_turbo_decoding_stats.trials*timeBase, (int)((double)eNB->ulsch_turbo_decoding_stats.diff/eNB->ulsch_turbo_decoding_stats.trials), eNB->ulsch_turbo_decoding_stats.trials); - printStatIndent2(&eNB->ulsch_tc_init_stats,"init", eNB->ulsch_tc_init_stats.trials); - printStatIndent2(&eNB->ulsch_tc_alpha_stats,"alpha", eNB->ulsch_tc_init_stats.trials); - printStatIndent2(&eNB->ulsch_tc_beta_stats,"beta", eNB->ulsch_tc_init_stats.trials); - printStatIndent2(&eNB->ulsch_tc_gamma_stats,"gamma", eNB->ulsch_tc_init_stats.trials); - printStatIndent2(&eNB->ulsch_tc_ext_stats,"ext", eNB->ulsch_tc_init_stats.trials); - printStatIndent2(&eNB->ulsch_tc_intl1_stats,"turbo internal interleaver", eNB->ulsch_tc_init_stats.trials); - printStatIndent2(&eNB->ulsch_tc_intl2_stats,"intl2+HardDecode+CRC", eNB->ulsch_tc_init_stats.trials); + printStatIndent3(&eNB->ulsch_tc_init_stats,"init"); + printStatIndent3(&eNB->ulsch_tc_alpha_stats,"alpha"); + printStatIndent3(&eNB->ulsch_tc_beta_stats,"beta"); + printStatIndent3(&eNB->ulsch_tc_gamma_stats,"gamma"); + printStatIndent3(&eNB->ulsch_tc_ext_stats,"ext"); + printStatIndent3(&eNB->ulsch_tc_intl1_stats,"turbo internal interleaver"); + printStatIndent3(&eNB->ulsch_tc_intl2_stats,"intl2+HardDecode+CRC"); } if(abstx) { //ABSTRACTION diff --git a/targets/RT/USER/lte-enb.c b/targets/RT/USER/lte-enb.c index 6bda86d603..509ee6c0ac 100644 --- a/targets/RT/USER/lte-enb.c +++ b/targets/RT/USER/lte-enb.c @@ -149,8 +149,6 @@ void wakeup_prach_eNB(PHY_VARS_eNB *eNB,RU_t *ru,int frame,int subframe); #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) void wakeup_prach_eNB_br(PHY_VARS_eNB *eNB,RU_t *ru,int frame,int subframe); #endif -extern PARALLEL_CONF_t get_thread_parallel_conf(void); -extern WORKER_CONF_t get_thread_worker_conf(void); extern uint8_t nfapi_mode; extern void oai_subframe_ind(uint16_t sfn, uint16_t sf); @@ -855,9 +853,9 @@ static void* process_stats_thread(void* param) { while (!oai_exit) { sleep(1); if (opp_enabled == 1) { - if (eNB->td) print_meas(&eNB->ulsch_decoding_stats,"ulsch_decoding",NULL,NULL); - if (eNB->te) - { + if ( eNB->ulsch_decoding_stats.trials>0) + print_meas(&eNB->ulsch_decoding_stats,"ulsch_decoding",NULL,NULL); + if (eNB->dlsch_encoding_stats.trials >0) { print_meas(&eNB->dlsch_turbo_encoding_preperation_stats,"dlsch_coding_crc",NULL,NULL); print_meas(&eNB->dlsch_turbo_encoding_segmentation_stats,"dlsch_segmentation",NULL,NULL); print_meas(&eNB->dlsch_encoding_stats,"dlsch_encoding",NULL,NULL); @@ -1319,11 +1317,6 @@ void init_eNB(int single_thread_flag,int wait_for_sync) { #ifndef OCP_FRAMEWORK LOG_I(PHY,"Initializing eNB %d CC_id %d\n",inst,CC_id); #endif - - - eNB->td = ulsch_decoding_data_all; - eNB->te = dlsch_encoding_all; - LOG_I(PHY,"Registering with MAC interface module\n"); AssertFatal((eNB->if_inst = IF_Module_init(inst))!=NULL,"Cannot register interface"); diff --git a/targets/RT/USER/lte-softmodem.c b/targets/RT/USER/lte-softmodem.c index 03a461454f..74eb37355b 100644 --- a/targets/RT/USER/lte-softmodem.c +++ b/targets/RT/USER/lte-softmodem.c @@ -219,31 +219,7 @@ int numerology = 0; char *parallel_config = NULL; char *worker_config = NULL; -static THREAD_STRUCT thread_struct; -void set_parallel_conf(char *parallel_conf) -{ - if(strcmp(parallel_conf,"PARALLEL_SINGLE_THREAD")==0) thread_struct.parallel_conf = PARALLEL_SINGLE_THREAD; - else if(strcmp(parallel_conf,"PARALLEL_RU_L1_SPLIT")==0) thread_struct.parallel_conf = PARALLEL_RU_L1_SPLIT; - else if(strcmp(parallel_conf,"PARALLEL_RU_L1_TRX_SPLIT")==0) thread_struct.parallel_conf = PARALLEL_RU_L1_TRX_SPLIT; - printf("[CONFIG] parallel conf is set to %d\n",thread_struct.parallel_conf); -} -void set_worker_conf(char *worker_conf) -{ - if(strcmp(worker_conf,"WORKER_DISABLE")==0) thread_struct.worker_conf = WORKER_DISABLE; - else if(strcmp(worker_conf,"WORKER_ENABLE")==0) thread_struct.worker_conf = WORKER_ENABLE; - printf("[CONFIG] worker conf is set to %d\n",thread_struct.worker_conf); -} -PARALLEL_CONF_t get_thread_parallel_conf(void) -{ - return thread_struct.parallel_conf; -} -WORKER_CONF_t get_thread_worker_conf(void) -{ - return thread_struct.worker_conf; -} - - - +THREAD_STRUCT thread_struct; /* struct for ethernet specific parameters given in eNB conf file */ eth_params_t *eth_params; diff --git a/targets/RT/USER/lte-uesoftmodem.c b/targets/RT/USER/lte-uesoftmodem.c index 3071544133..5c4ca6ed2e 100644 --- a/targets/RT/USER/lte-uesoftmodem.c +++ b/targets/RT/USER/lte-uesoftmodem.c @@ -226,29 +226,7 @@ char *worker_config = NULL; char* usrp_args=NULL; char* usrp_clksrc=NULL; -static THREAD_STRUCT thread_struct; -void set_parallel_conf(char *parallel_conf) -{ - if(strcmp(parallel_conf,"PARALLEL_SINGLE_THREAD")==0) thread_struct.parallel_conf = PARALLEL_SINGLE_THREAD; - else if(strcmp(parallel_conf,"PARALLEL_RU_L1_SPLIT")==0) thread_struct.parallel_conf = PARALLEL_RU_L1_SPLIT; - else if(strcmp(parallel_conf,"PARALLEL_RU_L1_TRX_SPLIT")==0) thread_struct.parallel_conf = PARALLEL_RU_L1_TRX_SPLIT; - printf("[CONFIG] parallel conf is set to %d\n",thread_struct.parallel_conf); -} -void set_worker_conf(char *worker_conf) -{ - if(strcmp(worker_conf,"WORKER_DISABLE")==0) thread_struct.worker_conf = WORKER_DISABLE; - else if(strcmp(worker_conf,"WORKER_ENABLE")==0) thread_struct.worker_conf = WORKER_ENABLE; - printf("[CONFIG] worker conf is set to %d\n",thread_struct.worker_conf); -} -PARALLEL_CONF_t get_thread_parallel_conf(void) -{ - return thread_struct.parallel_conf; -} -WORKER_CONF_t get_thread_worker_conf(void) -{ - return thread_struct.worker_conf; -} - +THREAD_STRUCT thread_struct; /* struct for ethernet specific parameters given in eNB conf file */ eth_params_t *eth_params; From 2f11541973ea24b54cae0cbabe6aaf05129620dd Mon Sep 17 00:00:00 2001 From: Louis Adrien Dufrene Date: Thu, 15 Nov 2018 13:21:48 +0100 Subject: [PATCH 145/233] test commit --- targets/RT/USER/lte-enb.c | 181 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 181 insertions(+) diff --git a/targets/RT/USER/lte-enb.c b/targets/RT/USER/lte-enb.c index 6bda86d603..d194ea42ae 100644 --- a/targets/RT/USER/lte-enb.c +++ b/targets/RT/USER/lte-enb.c @@ -724,12 +724,193 @@ void wakeup_prach_eNB_br(PHY_VARS_eNB *eNB,RU_t *ru,int frame,int subframe) { } } +<<<<<<< HEAD // check if we have to detect PRACH first if (is_prach_subframe(fp,frame,subframe)>0) { LOG_D(PHY,"Triggering prach br processing, frame %d, subframe %d\n",frame,subframe); if (proc->instance_cnt_prach_br == 0) { LOG_W(PHY,"[eNB] Frame %d Subframe %d, dropping PRACH BR\n", frame,subframe); return; +======= + } + + eNB_thread_asynch_rxtx_status=0; + return(&eNB_thread_asynch_rxtx_status); +} + + + + + +void rx_rf(PHY_VARS_eNB *eNB,int *frame,int *subframe) { + + eNB_proc_t *proc = &eNB->proc; + LTE_DL_FRAME_PARMS *fp = &eNB->frame_parms; + void *rxp[fp->nb_antennas_rx],*txp[fp->nb_antennas_tx]; + unsigned int rxs,txs; + int i; + int tx_sfoffset = (eNB->single_thread_flag == 1) ? 3 : 2; + openair0_timestamp ts,old_ts; + + if (proc->first_rx==0) { + + // Transmit TX buffer based on timestamp from RX + // printf("trx_write -> USRP TS %llu (sf %d)\n", (proc->timestamp_rx+(3*fp->samples_per_tti)),(proc->subframe_rx+2)%10); + VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TST, (proc->timestamp_rx+(tx_sfoffset*fp->samples_per_tti)-openair0_cfg[0].tx_sample_advance)&0xffffffff ); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE, 1 ); + // prepare tx buffer pointers + + lte_subframe_t SF_type = subframe_select(fp,(proc->subframe_rx+tx_sfoffset)%10); + lte_subframe_t prevSF_type = subframe_select(fp,(proc->subframe_rx+tx_sfoffset+9)%10); + lte_subframe_t nextSF_type = subframe_select(fp,(proc->subframe_rx+tx_sfoffset+1)%10); + int sf_extension = 0; + + if ((SF_type == SF_DL) || + (SF_type == SF_S)) { + + int siglen=fp->samples_per_tti,flags=1; + + if (SF_type == SF_S) { + siglen = (fp->dl_symbols_in_S_subframe+1)*(fp->ofdm_symbol_size+fp->nb_prefix_samples0); + flags=3; // end of burst + } + if ((fp->frame_type == TDD) && + (SF_type == SF_DL)&& + (prevSF_type == SF_UL) && + (nextSF_type == SF_DL)) { + flags = 2; // start of burst + sf_extension = eNB->N_TA_offset<<1; + } + if ((fp->frame_type == TDD) && + (SF_type == SF_DL)&& + (prevSF_type == SF_UL) && + (nextSF_type == SF_UL)) { + flags = 4; // start of burst and end of burst (only one DL SF between two UL) + sf_extension = eNB->N_TA_offset<<1; + } + + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE, 1 ); + VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_WRITE_FLAGS,flags); + + for (i=0; inb_antennas_tx; i++) + txp[i] = (void*)&eNB->common_vars.txdata[0][i][((proc->subframe_rx+tx_sfoffset)%10)*fp->samples_per_tti-sf_extension]; + + txs = eNB->rfdevice.trx_write_func(&eNB->rfdevice, + proc->timestamp_rx+eNB->ts_offset+(tx_sfoffset*fp->samples_per_tti)-openair0_cfg[0].tx_sample_advance-sf_extension, + txp, + siglen+sf_extension, + fp->nb_antennas_tx, + flags); + clock_gettime( CLOCK_MONOTONIC, &end_rf); + end_rf_ts = proc->timestamp_rx+eNB->ts_offset+(tx_sfoffset*fp->samples_per_tti)-openair0_cfg[0].tx_sample_advance; + if (recv_if_count != 0 ) { + recv_if_count = recv_if_count-1; + LOG_D(HW,"[From Timestamp %"PRId64" to Timestamp %"PRId64"] RTT_RF: %"PRId64"; RTT_RF\n", start_rf_prev_ts, end_rf_ts, clock_difftime_ns(start_rf_prev, end_rf)); + LOG_D(HW,"[From Timestamp %"PRId64" to Timestamp %"PRId64"] RTT_RF: %"PRId64"; RTT_RF\n",start_rf_prev2_ts, end_rf_ts, clock_difftime_ns(start_rf_prev2, end_rf)); + } + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE, 0 ); + + + + if (txs != siglen+sf_extension) { + LOG_E(PHY,"TX : Timeout (sent %d/%d)\n",txs, fp->samples_per_tti); + exit_fun( "problem transmitting samples" ); + } + } + } + + for (i=0; inb_antennas_rx; i++) + rxp[i] = (void*)&eNB->common_vars.rxdata[0][i][*subframe*fp->samples_per_tti]; + + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ, 1 ); + + old_ts = proc->timestamp_rx; + + rxs = eNB->rfdevice.trx_read_func(&eNB->rfdevice, + &ts, + rxp, + fp->samples_per_tti, + fp->nb_antennas_rx); + start_rf_prev2= start_rf_prev; + start_rf_prev2_ts= start_rf_prev_ts; + start_rf_prev = start_rf_new; + start_rf_prev_ts = start_rf_new_ts; + clock_gettime( CLOCK_MONOTONIC, &start_rf_new); + start_rf_new_ts = ts; + LOG_D(PHY,"rx_rf: first_rx %d received ts %"PRId64" (sptti %d)\n",proc->first_rx,ts,fp->samples_per_tti); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ, 0 ); + + proc->timestamp_rx = ts-eNB->ts_offset; + + if (rxs != fp->samples_per_tti) + LOG_E(PHY,"rx_rf: Asked for %d samples, got %d from USRP\n",fp->samples_per_tti,rxs); + + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ, 0 ); + + if (proc->first_rx == 1) { + eNB->ts_offset = proc->timestamp_rx; + proc->timestamp_rx=0; + } + else { + + if (proc->timestamp_rx - old_ts != fp->samples_per_tti) { + LOG_I(PHY,"rx_rf: rfdevice timing drift of %"PRId64" samples (ts_off %"PRId64")\n",proc->timestamp_rx - old_ts - fp->samples_per_tti,eNB->ts_offset); + eNB->ts_offset += (proc->timestamp_rx - old_ts - fp->samples_per_tti); + proc->timestamp_rx = ts-eNB->ts_offset; + } + } + proc->frame_rx = (proc->timestamp_rx / (fp->samples_per_tti*10))&1023; + proc->subframe_rx = (proc->timestamp_rx / fp->samples_per_tti)%10; + proc->frame_rx = (proc->frame_rx+proc->frame_offset)&1023; + proc->frame_tx = proc->frame_rx; + if (proc->subframe_rx > 5) proc->frame_tx=(proc->frame_tx+1)&1023; + // synchronize first reception to frame 0 subframe 0 + + proc->timestamp_tx = proc->timestamp_rx+(4*fp->samples_per_tti); + // printf("trx_read <- USRP TS %lu (offset %d sf %d, f %d, first_rx %d)\n", proc->timestamp_rx,eNB->ts_offset,proc->subframe_rx,proc->frame_rx,proc->first_rx); + + if (proc->first_rx == 0) { + if (proc->subframe_rx != *subframe){ + LOG_E(PHY,"rx_rf: Received Timestamp (%"PRId64") doesn't correspond to the time we think it is (proc->subframe_rx %d, subframe %d)\n",proc->timestamp_rx,proc->subframe_rx,*subframe); + exit_fun("Exiting"); + } + int f2 = (*frame+proc->frame_offset)&1023; + if (proc->frame_rx != f2) { + LOG_E(PHY,"rx_rf: Received Timestamp (%"PRId64") doesn't correspond to the time we think it is (proc->frame_rx %d frame %d, frame_offset %d, f2 %d)\n",proc->timestamp_rx,proc->frame_rx,*frame,proc->frame_offset,f2); + exit_fun("Exiting"); + } + } else { + proc->first_rx--; + *frame = proc->frame_rx; + *subframe = proc->subframe_rx; + } + + //printf("timestamp_rx %lu, frame %d(%d), subframe %d(%d)\n",proc->timestamp_rx,proc->frame_rx,frame,proc->subframe_rx,subframe); + + VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TS, proc->timestamp_rx&0xffffffff ); + + if (rxs != fp->samples_per_tti) + exit_fun( "problem receiving samples" ); + + + +} + +void rx_fh_if5(PHY_VARS_eNB *eNB,int *frame, int *subframe) { + + LTE_DL_FRAME_PARMS *fp = &eNB->frame_parms; + eNB_proc_t *proc = &eNB->proc; + + recv_IF5(eNB, &proc->timestamp_rx, *subframe, IF5_RRH_GW_UL); + + proc->frame_rx = (proc->timestamp_rx / (fp->samples_per_tti*10))&1023; + proc->subframe_rx = (proc->timestamp_rx / fp->samples_per_tti)%10; + + if (proc->first_rx == 0) { + if (proc->subframe_rx != *subframe){ + LOG_E(PHY,"rx_fh_if5: Received Timestamp doesn't correspond to the time we think it is (proc->subframe_rx %d, subframe %d)\n",proc->subframe_rx,*subframe); + exit_fun("Exiting"); +>>>>>>> ae0494b0bc431bf664e300b0b5a10f348d6b6757 } // wake up thread for PRACH RX From 22e44306f884fe9d1c191da3c0b147ca097d8728 Mon Sep 17 00:00:00 2001 From: Louis Adrien Dufrene Date: Thu, 15 Nov 2018 13:28:59 +0100 Subject: [PATCH 146/233] RRC inactivity timer deactivated --- openair2/RRC/LTE/rrc_eNB.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/openair2/RRC/LTE/rrc_eNB.c b/openair2/RRC/LTE/rrc_eNB.c index c20a13bf00..412128b017 100644 --- a/openair2/RRC/LTE/rrc_eNB.c +++ b/openair2/RRC/LTE/rrc_eNB.c @@ -5375,7 +5375,6 @@ rrc_eNB_generate_RRCConnectionReconfiguration_handover( //----------------------------------------------------------------------------- /* * TODO: * add function description -* * add ue_rrc_inactivity_timer set * * format the function correctly */ void @@ -7915,7 +7914,7 @@ rrc_rx_tx( pthread_mutex_unlock(&rrc_release_freelist); if (ue_context_p->ue_context.ue_rrc_inactivity_timer > 0) { - ue_context_p->ue_context.ue_rrc_inactivity_timer++; + // ue_context_p->ue_context.ue_rrc_inactivity_timer++; // (un)comment this line to (de)activate the RRC inactivity timer if (ue_context_p->ue_context.ue_rrc_inactivity_timer >= ue_context_p->ue_context.ue_rrc_inactivity_timer_thres) { LOG_I(RRC, "Removing UE %x instance because of rrc_inactivity_timer timeout\n", From 700437f184332e4198f465f0750e4dd4663fb0be Mon Sep 17 00:00:00 2001 From: Louis Adrien Dufrene Date: Fri, 16 Nov 2018 08:49:28 +0100 Subject: [PATCH 147/233] astyle applied --- common/utils/T/tracer/gui/x.c | 283 +- openair2/COMMON/platform_types.h | 108 +- openair2/ENB_APP/enb_config.c | 60 +- openair2/LAYER2/MAC/eNB_scheduler_dlsch.c | 1353 ++-- openair2/LAYER2/MAC/eNB_scheduler_fairRR.c | 4050 ++++++------ openair2/LAYER2/MAC/eNB_scheduler_ulsch.c | 1927 +++--- openair2/RRC/LTE/L2_interface.c | 352 +- openair2/RRC/LTE/MESSAGES/asn1_msg.c | 1719 ++---- openair2/RRC/LTE/MESSAGES/asn1_msg.h | 86 +- openair2/RRC/LTE/rrc_defs.h | 256 +- openair2/RRC/LTE/rrc_eNB.c | 6464 +++++++++----------- openair2/RRC/LTE/rrc_eNB_S1AP.c | 1274 ++-- openair3/S1AP/s1ap_eNB.c | 115 +- openair3/S1AP/s1ap_eNB_handlers.c | 238 +- openair3/S1AP/s1ap_eNB_nas_procedures.c | 134 +- targets/RT/USER/lte-enb.c | 1708 +++--- 16 files changed, 9390 insertions(+), 10737 deletions(-) diff --git a/common/utils/T/tracer/gui/x.c b/common/utils/T/tracer/gui/x.c index 7b8c130ea8..3176810ec3 100644 --- a/common/utils/T/tracer/gui/x.c +++ b/common/utils/T/tracer/gui/x.c @@ -7,21 +7,19 @@ #include #include -int x_connection_fd(x_connection *_x) -{ +int x_connection_fd(x_connection *_x) { struct x_connection *x = _x; return ConnectionNumber(x->d); } -static GC create_gc(Display *d, char *color) -{ +static GC create_gc(Display *d, char *color) { GC ret = XCreateGC(d, DefaultRootWindow(d), 0, NULL); XGCValues gcv; XColor rcol, scol; - XCopyGC(d, DefaultGC(d, DefaultScreen(d)), -1L, ret); + if (XAllocNamedColor(d, DefaultColormap(d, DefaultScreen(d)), - color, &scol, &rcol)) { + color, &scol, &rcol)) { gcv.foreground = scol.pixel; XChangeGC(d, ret, GCForeground, &gcv); } else ERR("X: could not allocate color '%s'\n", color); @@ -29,82 +27,81 @@ static GC create_gc(Display *d, char *color) return ret; } -int x_new_color(x_connection *_x, char *color) -{ +int x_new_color(x_connection *_x, char *color) { struct x_connection *x = _x; x->ncolors++; - x->colors = realloc(x->colors, x->ncolors * sizeof(GC)); - if (x->colors == NULL) OOM; - x->colors[x->ncolors-1] = create_gc(x->d, color); + if (x->colors == NULL) OOM; + + x->colors[x->ncolors-1] = create_gc(x->d, color); x->xft_colors = realloc(x->xft_colors, x->ncolors * sizeof(XftColor)); + if (x->xft_colors == NULL) OOM; + if (XftColorAllocName(x->d, DefaultVisual(x->d, DefaultScreen(x->d)), - DefaultColormap(x->d, DefaultScreen(x->d)), - color, &x->xft_colors[x->ncolors-1]) == False) + DefaultColormap(x->d, DefaultScreen(x->d)), + color, &x->xft_colors[x->ncolors-1]) == False) ERR("could not allocate color '%s'\n", color); return x->ncolors - 1; } -int x_new_font(x_connection *_x, char *font) -{ +int x_new_font(x_connection *_x, char *font) { struct x_connection *x = _x; /* TODO: allocate fonts only once */ x->nfonts++; x->fonts = realloc(x->fonts, x->nfonts * sizeof(XftFont *)); + if (x->fonts == NULL) OOM; + x->fonts[x->nfonts-1] = XftFontOpenName(x->d, DefaultScreen(x->d), font); + if (x->fonts[x->nfonts-1] == NULL) ERR("failed allocating font '%s'\n", font); + return x->nfonts - 1; } -x_connection *x_open(void) -{ +x_connection *x_open(void) { struct x_connection *ret; - ret = calloc(1, sizeof(struct x_connection)); + if (ret == NULL) OOM; ret->d = XOpenDisplay(0); LOGD("XOpenDisplay display %p return x_connection %p\n", ret->d, ret); + if (ret->d == NULL) ERR("error calling XOpenDisplay: no X? you root?\n"); x_new_color(ret, "white"); /* background color */ x_new_color(ret, "black"); /* foreground color */ - x_new_font(ret, "sans-8"); - return ret; } x_window *x_create_window(x_connection *_x, int width, int height, - char *title) -{ + char *title) { struct x_connection *x = _x; struct x_window *ret; - ret = calloc(1, sizeof(struct x_window)); + if (ret == NULL) OOM; ret->w = XCreateSimpleWindow(x->d, DefaultRootWindow(x->d), 0, 0, - width, height, 0, WhitePixel(x->d, DefaultScreen(x->d)), - WhitePixel(x->d, DefaultScreen(x->d))); + width, height, 0, WhitePixel(x->d, DefaultScreen(x->d)), + WhitePixel(x->d, DefaultScreen(x->d))); ret->width = width; ret->height = height; - XStoreName(x->d, ret->w, title); - ret->p = XCreatePixmap(x->d, ret->w, width, height, - DefaultDepth(x->d, DefaultScreen(x->d))); + DefaultDepth(x->d, DefaultScreen(x->d))); XFillRectangle(x->d, ret->p, x->colors[BACKGROUND_COLOR], - 0, 0, width, height); - + 0, 0, width, height); ret->xft = XftDrawCreate(x->d, ret->p, - DefaultVisual(x->d, DefaultScreen(x->d)), - DefaultColormap(x->d, DefaultScreen(x->d))); + DefaultVisual(x->d, DefaultScreen(x->d)), + DefaultColormap(x->d, DefaultScreen(x->d))); + if (ret->xft == NULL) ERR("XftDrawCreate failed\n"); /* enable backing store */ @@ -113,23 +110,19 @@ x_window *x_create_window(x_connection *_x, int width, int height, att.backing_store = Always; XChangeWindowAttributes(x->d, ret->w, CWBackingStore, &att); } - XSelectInput(x->d, ret->w, - KeyPressMask | - ButtonPressMask | - ButtonReleaseMask | - PointerMotionMask | - ExposureMask | - StructureNotifyMask); - + KeyPressMask | + ButtonPressMask | + ButtonReleaseMask | + PointerMotionMask | + ExposureMask | + StructureNotifyMask); XMapWindow(x->d, ret->w); - return ret; } x_image *x_create_image(x_connection *_x, unsigned char *data, - int width, int height) -{ + int width, int height) { struct x_connection *x = _x; struct x_image *ret; XImage *ximage; @@ -137,8 +130,9 @@ x_image *x_create_image(x_connection *_x, unsigned char *data, XVisualInfo template; int nvs; Visual *v; + ret = calloc(1, sizeof(struct x_image)); - ret = calloc(1, sizeof(struct x_image)); if (ret == NULL) OOM; + if (ret == NULL) OOM; template.class = TrueColor; template.depth = 32; @@ -146,68 +140,65 @@ x_image *x_create_image(x_connection *_x, unsigned char *data, template.green_mask = 0x00ff00; template.blue_mask = 0x0000ff; template.bits_per_rgb = 8; - vs = XGetVisualInfo(x->d, VisualDepthMask | VisualClassMask | - VisualRedMaskMask | VisualGreenMaskMask | VisualBlueMaskMask | - VisualBitsPerRGBMask, &template, &nvs); + VisualRedMaskMask | VisualGreenMaskMask | VisualBlueMaskMask | + VisualBitsPerRGBMask, &template, &nvs); if (vs == NULL) { /* try again with 32 bpp */ template.depth = 32; vs = XGetVisualInfo(x->d, VisualDepthMask | VisualClassMask | - VisualRedMaskMask | VisualGreenMaskMask | VisualBlueMaskMask | - VisualBitsPerRGBMask, &template, &nvs); + VisualRedMaskMask | VisualGreenMaskMask | VisualBlueMaskMask | + VisualBitsPerRGBMask, &template, &nvs); } if (vs == NULL) ERR("no good visual found\n"); v = vs[0].visual; XFree(vs); - ximage = XCreateImage(x->d, v, 24, ZPixmap, 0, - (char*)data, width, height, 32, 0); + (char *)data, width, height, 32, 0); + if (ximage == NULL) ERR("image creation failed\n"); ret->p = XCreatePixmap(x->d, DefaultRootWindow(x->d), width, height, 24); - XPutImage(x->d, ret->p, DefaultGC(x->d, DefaultScreen(x->d)), - ximage, 0, 0, 0, 0, width, height); - + ximage, 0, 0, 0, 0, width, height); /* TODO: be sure it's fine to set data to NULL */ ximage->data = NULL; XDestroyImage(ximage); - ret->width = width; ret->height = height; - return ret; } -static struct toplevel_window_widget *find_x_window(struct gui *g, Window id) -{ +static struct toplevel_window_widget *find_x_window(struct gui *g, Window id) { struct widget_list *cur; struct toplevel_window_widget *w; struct x_window *xw; cur = g->toplevel; + while (cur) { w = (struct toplevel_window_widget *)cur->item; xw = w->x; + if (xw->w == id) return w; + cur = cur->next; } + return NULL; } -void x_events(gui *_gui) -{ +void x_events(gui *_gui) { struct gui *g = _gui; struct widget_list *cur; struct x_connection *x = g->x; struct toplevel_window_widget *w; - LOGD("x_events START\n"); /* preprocessing (to "compress" events) */ cur = g->toplevel; + while (cur) { struct x_window *xw; w = (struct toplevel_window_widget *)cur->item; @@ -222,58 +213,84 @@ void x_events(gui *_gui) XEvent ev; XNextEvent(x->d, &ev); LOGD("XEV %d\n", ev.type); + switch (ev.type) { - case MapNotify: - case Expose: - if ((w = find_x_window(g, ev.xexpose.window)) != NULL) { - struct x_window *xw = w->x; - xw->redraw = 1; - } - break; - case ConfigureNotify: - if ((w = find_x_window(g, ev.xconfigure.window)) != NULL) { - struct x_window *xw = w->x; - xw->resize = 1; - xw->new_width = ev.xconfigure.width; - xw->new_height = ev.xconfigure.height; - if (xw->new_width < 10) xw->new_width = 10; - if (xw->new_height < 10) xw->new_height = 10; - LOGD("ConfigureNotify %d %d\n", ev.xconfigure.width, ev.xconfigure.height); - } - break; - case ButtonPress: - if ((w = find_x_window(g, ev.xbutton.window)) != NULL) { - int key_modifiers = 0; - if (ev.xbutton.state & ShiftMask) key_modifiers |= KEY_SHIFT; - if (ev.xbutton.state & Mod1Mask) key_modifiers |= KEY_ALT; - if (ev.xbutton.state & ControlMask) key_modifiers |= KEY_CONTROL; - w->common.button(g, w, ev.xbutton.x, ev.xbutton.y, key_modifiers, - ev.xbutton.button, 0); - } - break; - case ButtonRelease: - if ((w = find_x_window(g, ev.xbutton.window)) != NULL) { - int key_modifiers = 0; - if (ev.xbutton.state & ShiftMask) key_modifiers |= KEY_SHIFT; - if (ev.xbutton.state & Mod1Mask) key_modifiers |= KEY_ALT; - if (ev.xbutton.state & ControlMask) key_modifiers |= KEY_CONTROL; - w->common.button(g, w, ev.xbutton.x, ev.xbutton.y, key_modifiers, - ev.xbutton.button, 1); - } - break; - default: if (gui_logd) WARN("TODO: X event type %d\n", ev.type); break; + case MapNotify: + case Expose: + if ((w = find_x_window(g, ev.xexpose.window)) != NULL) { + struct x_window *xw = w->x; + xw->redraw = 1; + } + + break; + + case ConfigureNotify: + if ((w = find_x_window(g, ev.xconfigure.window)) != NULL) { + struct x_window *xw = w->x; + xw->resize = 1; + xw->new_width = ev.xconfigure.width; + xw->new_height = ev.xconfigure.height; + + if (xw->new_width < 10) xw->new_width = 10; + + if (xw->new_height < 10) xw->new_height = 10; + + LOGD("ConfigureNotify %d %d\n", ev.xconfigure.width, ev.xconfigure.height); + } + + break; + + case ButtonPress: + if ((w = find_x_window(g, ev.xbutton.window)) != NULL) { + int key_modifiers = 0; + + if (ev.xbutton.state & ShiftMask) key_modifiers |= KEY_SHIFT; + + if (ev.xbutton.state & Mod1Mask) key_modifiers |= KEY_ALT; + + if (ev.xbutton.state & ControlMask) key_modifiers |= KEY_CONTROL; + + w->common.button(g, w, ev.xbutton.x, ev.xbutton.y, key_modifiers, + ev.xbutton.button, 0); + } + + break; + + case ButtonRelease: + if ((w = find_x_window(g, ev.xbutton.window)) != NULL) { + int key_modifiers = 0; + + if (ev.xbutton.state & ShiftMask) key_modifiers |= KEY_SHIFT; + + if (ev.xbutton.state & Mod1Mask) key_modifiers |= KEY_ALT; + + if (ev.xbutton.state & ControlMask) key_modifiers |= KEY_CONTROL; + + w->common.button(g, w, ev.xbutton.x, ev.xbutton.y, key_modifiers, + ev.xbutton.button, 1); + } + + break; + + default: + if (gui_logd) WARN("TODO: X event type %d\n", ev.type); + + break; } } /* postprocessing */ LOGD("post processing\n"); cur = g->toplevel; + while (cur) { struct toplevel_window_widget *w = - (struct toplevel_window_widget *)cur->item; + (struct toplevel_window_widget *)cur->item; struct x_window *xw = w->x; + if (xw->resize) { LOGD("resize old %d %d new %d %d\n", xw->width, xw->height, xw->new_width, xw->new_height); + if (xw->width != xw->new_width || xw->height != xw->new_height) { w->common.allocate(g, w, 0, 0, xw->new_width, xw->new_height); xw->width = xw->new_width; @@ -281,46 +298,47 @@ void x_events(gui *_gui) XftDrawDestroy(xw->xft); XFreePixmap(x->d, xw->p); xw->p = XCreatePixmap(x->d, xw->w, xw->width, xw->height, - DefaultDepth(x->d, DefaultScreen(x->d))); + DefaultDepth(x->d, DefaultScreen(x->d))); XFillRectangle(x->d, xw->p, x->colors[BACKGROUND_COLOR], - 0, 0, xw->width, xw->height); + 0, 0, xw->width, xw->height); xw->xft = XftDrawCreate(x->d, xw->p, - DefaultVisual(x->d, DefaultScreen(x->d)), - DefaultColormap(x->d, DefaultScreen(x->d))); + DefaultVisual(x->d, DefaultScreen(x->d)), + DefaultColormap(x->d, DefaultScreen(x->d))); + if (xw->xft == NULL) ERR("XftDrawCreate failed\n"); //xw->repaint = 1; } } + if (xw->repaint) { w->common.paint(g, w); xw->redraw = 1; } + if (xw->redraw) { struct x_connection *x = g->x; LOGD("XCopyArea w h %d %d\n", xw->width, xw->height); XCopyArea(x->d, xw->p, xw->w, x->colors[1], - 0, 0, xw->width, xw->height, 0, 0); + 0, 0, xw->width, xw->height, 0, 0); } + cur = cur->next; } + LOGD("x_events DONE\n"); } -void x_flush(x_connection *_x) -{ +void x_flush(x_connection *_x) { struct x_connection *x = _x; XFlush(x->d); } void x_text_get_dimensions(x_connection *_c, int font, const char *t, - int *width, int *height, int *baseline) -{ + int *width, int *height, int *baseline) { struct x_connection *c = _c; XGlyphInfo ext; - XftTextExtentsUtf8(c->d, c->fonts[font], (FcChar8 *)t, strlen(t), &ext); - *width = ext.width; *height = c->fonts[font]->height; *baseline = c->fonts[font]->ascent; @@ -331,63 +349,57 @@ void x_text_get_dimensions(x_connection *_c, int font, const char *t, /***********************************************************************/ void x_draw_line(x_connection *_c, x_window *_w, int color, - int x1, int y1, int x2, int y2) -{ + int x1, int y1, int x2, int y2) { struct x_connection *c = _c; struct x_window *w = _w; XDrawLine(c->d, w->p, c->colors[color], x1, y1, x2, y2); } void x_draw_rectangle(x_connection *_c, x_window *_w, int color, - int x, int y, int width, int height) -{ + int x, int y, int width, int height) { struct x_connection *c = _c; struct x_window *w = _w; XDrawRectangle(c->d, w->p, c->colors[color], x, y, width, height); } void x_fill_rectangle(x_connection *_c, x_window *_w, int color, - int x, int y, int width, int height) -{ + int x, int y, int width, int height) { struct x_connection *c = _c; struct x_window *w = _w; XFillRectangle(c->d, w->p, c->colors[color], x, y, width, height); } void x_draw_string(x_connection *_c, x_window *_w, int font, int color, - int x, int y, const char *t) -{ + int x, int y, const char *t) { struct x_connection *c = _c; struct x_window *w = _w; int tlen = strlen(t); XftDrawStringUtf8(w->xft, &c->xft_colors[color], c->fonts[font], - x, y, (const unsigned char *)t, tlen); + x, y, (const unsigned char *)t, tlen); } void x_draw_clipped_string(x_connection *_c, x_window *_w, int font, - int color, int x, int y, const char *t, - int clipx, int clipy, int clipwidth, int clipheight) -{ + int color, int x, int y, const char *t, + int clipx, int clipy, int clipwidth, int clipheight) { struct x_window *w = _w; - XRectangle clip = { clipx, clipy, clipwidth, clipheight }; + if (XftDrawSetClipRectangles(w->xft, 0, 0, &clip, 1) == False) abort(); + x_draw_string(_c, _w, font, color, x, y, t); + if (XftDrawSetClip(w->xft, NULL) == False) abort(); } -void x_draw_image(x_connection *_c, x_window *_w, x_image *_img, int x, int y) -{ +void x_draw_image(x_connection *_c, x_window *_w, x_image *_img, int x, int y) { struct x_connection *c = _c; struct x_window *w = _w; struct x_image *img = _img; - XCopyArea(c->d, img->p, w->p, DefaultGC(c->d, DefaultScreen(c->d)), - 0, 0, img->width, img->height, x, y); + 0, 0, img->width, img->height, x, y); } -void x_draw(x_connection *_c, x_window *_w) -{ +void x_draw(x_connection *_c, x_window *_w) { struct x_connection *c = _c; struct x_window *w = _w; LOGD("x_draw XCopyArea w h %d %d display %p window %d pixmap %d\n", w->width, w->height, c->d, (int)w->w, (int)w->p); @@ -397,13 +409,13 @@ void x_draw(x_connection *_c, x_window *_w) /* those two special functions are to plot many points * first call x_add_point many times then x_plot_points once */ -void x_add_point(x_connection *_c, int x, int y) -{ +void x_add_point(x_connection *_c, int x, int y) { struct x_connection *c = _c; if (c->pts_size == c->pts_maxsize) { c->pts_maxsize += 65536; c->pts = realloc(c->pts, c->pts_maxsize * sizeof(XPoint)); + if (c->pts == NULL) OOM; } @@ -412,12 +424,11 @@ void x_add_point(x_connection *_c, int x, int y) c->pts_size++; } -void x_plot_points(x_connection *_c, x_window *_w, int color) -{ +void x_plot_points(x_connection *_c, x_window *_w, int color) { struct x_connection *c = _c; LOGD("x_plot_points %d points\n", c->pts_size); struct x_window *w = _w; XDrawPoints(c->d, w->p, c->colors[color], c->pts, c->pts_size, - CoordModeOrigin); + CoordModeOrigin); c->pts_size = 0; } diff --git a/openair2/COMMON/platform_types.h b/openair2/COMMON/platform_types.h index 0578e92cbc..d24be0575e 100644 --- a/openair2/COMMON/platform_types.h +++ b/openair2/COMMON/platform_types.h @@ -31,7 +31,7 @@ # define __PLATFORM_TYPES_H__ #if !defined(NAS_NETLINK) -#include + #include #endif //----------------------------------------------------------------------------- @@ -42,19 +42,19 @@ * let's protect potential redefinition */ #ifndef _BOOLEAN_T_DEFINED_ -#define _BOOLEAN_T_DEFINED_ + #define _BOOLEAN_T_DEFINED_ -typedef signed char boolean_t; + typedef signed char boolean_t; -#if !defined(TRUE) -#define TRUE (boolean_t)0x01 -#endif + #if !defined(TRUE) + #define TRUE (boolean_t)0x01 + #endif -#if !defined(FALSE) -#define FALSE (boolean_t)0x00 -#endif + #if !defined(FALSE) + #define FALSE (boolean_t)0x00 + #endif -#define BOOL_NOT(b) (b^TRUE) + #define BOOL_NOT(b) (b^TRUE) #endif /* _BOOLEAN_T_DEFINED_ */ @@ -102,19 +102,19 @@ typedef enum rb_type_e { } rb_type_t; typedef enum { - CR_ROUND = 0, - CR_SRB12 = 1, - CR_HOL = 2, - CR_LC = 3, - CR_CQI = 4, - CR_LCP = 5, - CR_NUM = 6 + CR_ROUND = 0, + CR_SRB12 = 1, + CR_HOL = 2, + CR_LC = 3, + CR_CQI = 4, + CR_LCP = 5, + CR_NUM = 6 } sorting_criterion_t; typedef enum { - POL_FAIR = 0, - POL_GREEDY = 1, - POL_NUM = 2 + POL_FAIR = 0, + POL_GREEDY = 1, + POL_NUM = 2 } accounting_policy_t; //----------------------------------------------------------------------------- // PHY TYPES @@ -188,19 +188,19 @@ typedef uint32_t m_tmsi_t; //Random UE identity length = 40 bits #if ! defined(NOT_A_RANDOM_UE_IDENTITY) -#define NOT_A_RANDOM_UE_IDENTITY (uint64_t)0xFFFFFFFF + #define NOT_A_RANDOM_UE_IDENTITY (uint64_t)0xFFFFFFFF #endif #if ! defined(NOT_A_RNTI) -#define NOT_A_RNTI (rnti_t)0 + #define NOT_A_RNTI (rnti_t)0 #endif #if ! defined(M_RNTI) -#define M_RNTI (rnti_t)0xFFFD + #define M_RNTI (rnti_t)0xFFFD #endif #if ! defined(P_RNTI) -#define P_RNTI (rnti_t)0xFFFE + #define P_RNTI (rnti_t)0xFFFE #endif #if ! defined(SI_RNTI) -#define SI_RNTI (rnti_t)0xFFFF + #define SI_RNTI (rnti_t)0xFFFF #endif typedef enum config_action_e { CONFIG_ACTION_NULL = 0, @@ -225,7 +225,7 @@ typedef uint8_t ebi_t; // eps bearer id //----------------------------------------------------------------------------- // may be ITTI not enabled, but type instance is useful also for OTG, #if !defined(instance_t) -typedef uint16_t instance_t; + typedef uint16_t instance_t; #endif typedef struct protocol_ctxt_s { module_id_t module_id; /*!< \brief Virtualized module identifier */ @@ -247,51 +247,51 @@ typedef struct protocol_ctxt_s { #define MODULE_ID_TO_INSTANCE(mODULE_iD, iNSTANCE, eNB_fLAG) \ - if(eNB_fLAG == ENB_FLAG_YES) \ - iNSTANCE = ENB_MODULE_ID_TO_INSTANCE(mODULE_iD); \ - else \ - iNSTANCE = UE_MODULE_ID_TO_INSTANCE(mODULE_iD) + if(eNB_fLAG == ENB_FLAG_YES) \ + iNSTANCE = ENB_MODULE_ID_TO_INSTANCE(mODULE_iD); \ + else \ + iNSTANCE = UE_MODULE_ID_TO_INSTANCE(mODULE_iD) #define INSTANCE_TO_MODULE_ID(iNSTANCE, mODULE_iD, eNB_fLAG) \ - if(eNB_fLAG == ENB_FLAG_YES) \ - mODULE_iD = ENB_INSTANCE_TO_MODULE_ID(iNSTANCE); \ - else \ - mODULE_iD = UE_INSTANCE_TO_MODULE_ID(iNSTANCE) + if(eNB_fLAG == ENB_FLAG_YES) \ + mODULE_iD = ENB_INSTANCE_TO_MODULE_ID(iNSTANCE); \ + else \ + mODULE_iD = UE_INSTANCE_TO_MODULE_ID(iNSTANCE) #define PROTOCOL_CTXT_COMPUTE_MODULE_ID(CtXt_h) \ - INSTANCE_TO_MODULE_ID( (CtXt_h)->instance , (CtXt_h)->module_id , (CtXt_h)->enb_flag ) + INSTANCE_TO_MODULE_ID( (CtXt_h)->instance , (CtXt_h)->module_id , (CtXt_h)->enb_flag ) #define PROTOCOL_CTXT_COMPUTE_INSTANCE(CtXt_h) \ - MODULE_ID_TO_INSTANCE( (CtXt_h)->module_id , (CtXt_h)->instance , (CtXt_h)->enb_flag ) + MODULE_ID_TO_INSTANCE( (CtXt_h)->module_id , (CtXt_h)->instance , (CtXt_h)->enb_flag ) #define PROTOCOL_CTXT_SET_BY_MODULE_ID(Ctxt_Pp, mODULE_iD, eNB_fLAG, rNTI, fRAME, sUBfRAME, eNB_iNDEX) \ - (Ctxt_Pp)->module_id = mODULE_iD; \ - (Ctxt_Pp)->enb_flag = eNB_fLAG; \ - (Ctxt_Pp)->rnti = rNTI; \ - (Ctxt_Pp)->frame = fRAME; \ - (Ctxt_Pp)->subframe = sUBfRAME; \ - (Ctxt_Pp)->eNB_index = eNB_iNDEX; \ - PROTOCOL_CTXT_COMPUTE_INSTANCE(Ctxt_Pp) + (Ctxt_Pp)->module_id = mODULE_iD; \ + (Ctxt_Pp)->enb_flag = eNB_fLAG; \ + (Ctxt_Pp)->rnti = rNTI; \ + (Ctxt_Pp)->frame = fRAME; \ + (Ctxt_Pp)->subframe = sUBfRAME; \ + (Ctxt_Pp)->eNB_index = eNB_iNDEX; \ + PROTOCOL_CTXT_COMPUTE_INSTANCE(Ctxt_Pp) #define PROTOCOL_CTXT_SET_BY_INSTANCE(Ctxt_Pp, iNSTANCE, eNB_fLAG, rNTI, fRAME, sUBfRAME) \ - (Ctxt_Pp)->instance = iNSTANCE; \ - (Ctxt_Pp)->enb_flag = eNB_fLAG; \ - (Ctxt_Pp)->rnti = rNTI; \ - (Ctxt_Pp)->frame = fRAME; \ - (Ctxt_Pp)->subframe = sUBfRAME; \ - PROTOCOL_CTXT_COMPUTE_MODULE_ID(Ctxt_Pp) + (Ctxt_Pp)->instance = iNSTANCE; \ + (Ctxt_Pp)->enb_flag = eNB_fLAG; \ + (Ctxt_Pp)->rnti = rNTI; \ + (Ctxt_Pp)->frame = fRAME; \ + (Ctxt_Pp)->subframe = sUBfRAME; \ + PROTOCOL_CTXT_COMPUTE_MODULE_ID(Ctxt_Pp) #define PROTOCOL_CTXT_FMT "[FRAME %05u][%s][MOD %02u][RNTI %" PRIx16 "]" #define PROTOCOL_CTXT_ARGS(CTXT_Pp) \ - (CTXT_Pp)->frame, \ - ((CTXT_Pp)->enb_flag == ENB_FLAG_YES) ? "eNB":" UE", \ - (CTXT_Pp)->module_id, \ - (CTXT_Pp)->rnti + (CTXT_Pp)->frame, \ + ((CTXT_Pp)->enb_flag == ENB_FLAG_YES) ? "eNB":" UE", \ + (CTXT_Pp)->module_id, \ + (CTXT_Pp)->rnti #define CHECK_CTXT_ARGS(CTXT_Pp) #define exit_fun(msg) exit_function(__FILE__,__FUNCTION__,__LINE__,msg) -void exit_function(const char* file, const char* function, const int line, const char* s); +void exit_function(const char *file, const char *function, const int line, const char *s); #endif diff --git a/openair2/ENB_APP/enb_config.c b/openair2/ENB_APP/enb_config.c index d9dedc8e17..3eaa2ad7ad 100644 --- a/openair2/ENB_APP/enb_config.c +++ b/openair2/ENB_APP/enb_config.c @@ -36,13 +36,13 @@ #include "UTIL/OTG/otg.h" #include "UTIL/OTG/otg_externs.h" #if defined(ENABLE_ITTI) -#include "intertask_interface.h" -#if defined(ENABLE_USE_MME) -#include "s1ap_eNB.h" -#include "sctp_eNB_task.h" -#else -#define EPC_MODE_ENABLED 0 -#endif + #include "intertask_interface.h" + #if defined(ENABLE_USE_MME) + #include "s1ap_eNB.h" + #include "sctp_eNB_task.h" + #else + #define EPC_MODE_ENABLED 0 + #endif #endif #include "sctp_default_values.h" #include "LTE_SystemInformationBlockType2.h" @@ -2043,12 +2043,12 @@ int RCconfig_gtpu(void ) { //----------------------------------------------------------------------------- /* -* Configure the s1ap_register_enb_req in itti message for future +* Configure the s1ap_register_enb_req in itti message for future * communications between eNB(s) and MME. */ int RCconfig_S1( - MessageDef *msg_p, - uint32_t i) + MessageDef *msg_p, + uint32_t i) //----------------------------------------------------------------------------- { int enb_id = 0; @@ -2210,17 +2210,17 @@ int RCconfig_S1( if (strcmp(ENBSParams[ENB_ACTIVE_ENBS_IDX].strlistptr[j], *(ENBParamList.paramarray[k][ENB_ENB_NAME_IDX].strptr)) == 0) { paramdef_t PLMNParams[] = PLMNPARAMS_DESC; paramlist_def_t PLMNParamList = {ENB_CONFIG_STRING_PLMN_LIST, NULL, 0}; - paramdef_t CCsParams[] = CCPARAMS_DESC; - /* map parameter checking array instances to parameter definition array instances */ checkedparam_t config_check_CCparams[] = CCPARAMS_CHECK; + for (int I = 0; I < (sizeof(CCsParams) / sizeof(paramdef_t)); I++) { CCsParams[I].chkPptr = &(config_check_CCparams[I]); } - + /* map parameter checking array instances to parameter definition array instances */ checkedparam_t config_check_PLMNParams [] = PLMNPARAMS_CHECK; + for (int I = 0; I < sizeof(PLMNParams) / sizeof(paramdef_t); ++I) { PLMNParams[I].chkPptr = &(config_check_PLMNParams[I]); } @@ -2229,10 +2229,8 @@ int RCconfig_S1( paramlist_def_t S1ParamList = {ENB_CONFIG_STRING_MME_IP_ADDRESS, NULL, 0}; paramdef_t SCTPParams[] = SCTPPARAMS_DESC; paramdef_t NETParams[] = NETPARAMS_DESC; - char aprefix[MAX_OPTNAME_SIZE*2 + 8]; sprintf(aprefix, "%s.[%i]", ENB_CONFIG_STRING_ENB_LIST, k); - S1AP_REGISTER_ENB_REQ (msg_p).eNB_id = enb_id; if (strcmp(*(ENBParamList.paramarray[k][ENB_CELL_TYPE_IDX].strptr), "CELL_MACRO_ENB") == 0) { @@ -2242,14 +2240,13 @@ int RCconfig_S1( } else { AssertFatal(0, "Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for cell_type choice: CELL_MACRO_ENB or CELL_HOME_ENB !\n", - RC.config_file_name, - i, + RC.config_file_name, + i, *(ENBParamList.paramarray[k][ENB_CELL_TYPE_IDX].strptr)); } S1AP_REGISTER_ENB_REQ (msg_p).eNB_name = strdup(*(ENBParamList.paramarray[k][ENB_ENB_NAME_IDX].strptr)); S1AP_REGISTER_ENB_REQ(msg_p).tac = *ENBParamList.paramarray[k][ENB_TRACKING_AREA_CODE_IDX].uptr; - AssertFatal(!ENBParamList.paramarray[k][ENB_MOBILE_COUNTRY_CODE_IDX_OLD].strptr && !ENBParamList.paramarray[k][ENB_MOBILE_NETWORK_CODE_IDX_OLD].strptr, "It seems that you use an old configuration file. Please change the existing\n" @@ -2259,10 +2256,9 @@ int RCconfig_S1( "to\n" " tracking_area_code = 1; // no string!!\n" " plmn_list = ( { mcc = 208; mnc = 93; mnc_length = 2; } )\n"); - config_getlist(&PLMNParamList, PLMNParams, sizeof(PLMNParams)/sizeof(paramdef_t), aprefix); - if (PLMNParamList.numelt < 1 || PLMNParamList.numelt > 6){ + if (PLMNParamList.numelt < 1 || PLMNParamList.numelt > 6) { AssertFatal(0, "The number of PLMN IDs must be in [1,6], but is %d\n", PLMNParamList.numelt); } @@ -2273,7 +2269,6 @@ int RCconfig_S1( S1AP_REGISTER_ENB_REQ(msg_p).mcc[l] = *PLMNParamList.paramarray[l][ENB_MOBILE_COUNTRY_CODE_IDX].uptr; S1AP_REGISTER_ENB_REQ(msg_p).mnc[l] = *PLMNParamList.paramarray[l][ENB_MOBILE_NETWORK_CODE_IDX].uptr; S1AP_REGISTER_ENB_REQ(msg_p).mnc_digit_length[l] = *PLMNParamList.paramarray[l][ENB_MNC_DIGIT_LENGTH].u8ptr; - AssertFatal(S1AP_REGISTER_ENB_REQ(msg_p).mnc_digit_length[l] == 3 || S1AP_REGISTER_ENB_REQ(msg_p).mnc[l] < 100, "MNC %d cannot be encoded in two digits as requested (change mnc_digit_length to 3)\n", @@ -2289,12 +2284,13 @@ int RCconfig_S1( */ sprintf(aprefix, "%s.[%i].%s.[%i]", ENB_CONFIG_STRING_ENB_LIST, k, ENB_CONFIG_STRING_COMPONENT_CARRIERS, 0); config_get(CCsParams, sizeof(CCsParams)/sizeof(paramdef_t), aprefix); + switch (pcch_defaultPagingCycle) { case 32: { S1AP_REGISTER_ENB_REQ(msg_p).default_drx = 0; break; } - + case 64: { S1AP_REGISTER_ENB_REQ(msg_p).default_drx = 1; break; @@ -2312,32 +2308,26 @@ int RCconfig_S1( default: { LOG_E(S1AP, "Default I-DRX value in conf file is invalid (%i). Should be 32, 64, 128 or 256. \ - Default DRX set to 32 in MME configuration\n", - pcch_defaultPagingCycle); - + Default DRX set to 32 in MME configuration\n", + pcch_defaultPagingCycle); S1AP_REGISTER_ENB_REQ(msg_p).default_drx = 0; } } /* MME connection params */ sprintf(aprefix, "%s.[%i]", ENB_CONFIG_STRING_ENB_LIST, k); - config_getlist(&S1ParamList, S1Params, sizeof(S1Params)/sizeof(paramdef_t), aprefix); - S1AP_REGISTER_ENB_REQ (msg_p).nb_mme = 0; for (int l = 0; l < S1ParamList.numelt; l++) { S1AP_REGISTER_ENB_REQ (msg_p).nb_mme += 1; - strcpy(S1AP_REGISTER_ENB_REQ (msg_p).mme_ip_address[l].ipv4_address,*(S1ParamList.paramarray[l][ENB_MME_IPV4_ADDRESS_IDX].strptr)); strcpy(S1AP_REGISTER_ENB_REQ (msg_p).mme_ip_address[l].ipv6_address,*(S1ParamList.paramarray[l][ENB_MME_IPV6_ADDRESS_IDX].strptr)); if (strcmp(*(S1ParamList.paramarray[l][ENB_MME_IP_ADDRESS_PREFERENCE_IDX].strptr), "ipv4") == 0) { S1AP_REGISTER_ENB_REQ (msg_p).mme_ip_address[l].ipv4 = 1; - } else if (strcmp(*(S1ParamList.paramarray[l][ENB_MME_IP_ADDRESS_PREFERENCE_IDX].strptr), "ipv6") == 0) { S1AP_REGISTER_ENB_REQ (msg_p).mme_ip_address[l].ipv6 = 1; - } else if (strcmp(*(S1ParamList.paramarray[l][ENB_MME_IP_ADDRESS_PREFERENCE_IDX].strptr), "no") == 0) { S1AP_REGISTER_ENB_REQ (msg_p).mme_ip_address[l].ipv4 = 1; S1AP_REGISTER_ENB_REQ (msg_p).mme_ip_address[l].ipv6 = 1; @@ -2358,7 +2348,6 @@ int RCconfig_S1( for (int el = 0; el < S1AP_REGISTER_ENB_REQ(msg_p).broadcast_plmn_num[l]; ++el) { /* UINTARRAY gets mapped to int, see config_libconfig.c:223 */ S1AP_REGISTER_ENB_REQ(msg_p).broadcast_plmn_index[l][el] = S1ParamList.paramarray[l][ENB_MME_BROADCAST_PLMN_INDEX].iptr[el]; - AssertFatal(S1AP_REGISTER_ENB_REQ(msg_p).broadcast_plmn_index[l][el] >= 0 && S1AP_REGISTER_ENB_REQ(msg_p).broadcast_plmn_index[l][el] < S1AP_REGISTER_ENB_REQ(msg_p).num_plmn, "index for MME's MCC/MNC (%d) is an invalid index for the registered PLMN IDs (%d)\n", @@ -2370,7 +2359,7 @@ int RCconfig_S1( if (S1AP_REGISTER_ENB_REQ(msg_p).broadcast_plmn_num[l] == 0) { S1AP_REGISTER_ENB_REQ(msg_p).broadcast_plmn_num[l] = S1AP_REGISTER_ENB_REQ(msg_p).num_plmn; - for (int el = 0; el < S1AP_REGISTER_ENB_REQ(msg_p).num_plmn; ++el){ + for (int el = 0; el < S1AP_REGISTER_ENB_REQ(msg_p).num_plmn; ++el) { S1AP_REGISTER_ENB_REQ(msg_p).broadcast_plmn_index[l][el] = el; } } @@ -2382,18 +2371,14 @@ int RCconfig_S1( if (EPC_MODE_ENABLED) { sprintf(aprefix,"%s.[%i].%s",ENB_CONFIG_STRING_ENB_LIST,k,ENB_CONFIG_STRING_SCTP_CONFIG); - config_get( SCTPParams,sizeof(SCTPParams)/sizeof(paramdef_t),aprefix); - S1AP_REGISTER_ENB_REQ (msg_p).sctp_in_streams = (uint16_t)*(SCTPParams[ENB_SCTP_INSTREAMS_IDX].uptr); S1AP_REGISTER_ENB_REQ (msg_p).sctp_out_streams = (uint16_t)*(SCTPParams[ENB_SCTP_OUTSTREAMS_IDX].uptr); } sprintf(aprefix,"%s.[%i].%s",ENB_CONFIG_STRING_ENB_LIST,k,ENB_CONFIG_STRING_NETWORK_INTERFACES_CONFIG); - // NETWORK_INTERFACES config_get( NETParams,sizeof(NETParams)/sizeof(paramdef_t),aprefix); - cidr = *(NETParams[ENB_IPV4_ADDRESS_FOR_S1_MME_IDX].strptr); address = strtok(cidr, "/"); S1AP_REGISTER_ENB_REQ (msg_p).enb_ip_address.ipv6 = 0; @@ -2583,10 +2568,8 @@ int RCconfig_X2(MessageDef *msg_p, uint32_t i) { || X2AP_REGISTER_ENB_REQ(msg_p).mnc < 100, "MNC %d cannot be encoded in two digits as requested (change mnc_digit_length to 3)\n", X2AP_REGISTER_ENB_REQ(msg_p).mnc); - /* CC params */ config_getlist(&CCsParamList, NULL, 0, aprefix); - X2AP_REGISTER_ENB_REQ (msg_p).num_cc = CCsParamList.numelt; if (CCsParamList.numelt > 0) { @@ -2633,7 +2616,6 @@ int RCconfig_X2(MessageDef *msg_p, uint32_t i) { AssertFatal(X2ParamList.numelt <= X2AP_MAX_NB_ENB_IP_ADDRESS, "value of X2ParamList.numelt %d must be lower than X2AP_MAX_NB_ENB_IP_ADDRESS %d value: reconsider to increase X2AP_MAX_NB_ENB_IP_ADDRESS\n", X2ParamList.numelt,X2AP_MAX_NB_ENB_IP_ADDRESS); - X2AP_REGISTER_ENB_REQ (msg_p).nb_x2 = 0; for (l = 0; l < X2ParamList.numelt; l++) { diff --git a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c index a79b273a81..4073c54846 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c @@ -47,12 +47,12 @@ //#include "LAYER2/MAC/pre_processor.c" #include "pdcp.h" -#include "SIMULATION/TOOLS/sim.h" // for taus +#include "SIMULATION/TOOLS/sim.h" // for taus #include "assertions.h" #if defined(ENABLE_ITTI) -#include "intertask_interface.h" + #include "intertask_interface.h" #endif #include @@ -74,15 +74,12 @@ add_ue_dlsch_info(module_id_t module_idP, //------------------------------------------------------------------------------ { //LOG_D(MAC, "%s(module_idP:%d, CC_id:%d, UE_id:%d, subframeP:%d, status:%d) serving_num:%d rnti:%x\n", __FUNCTION__, module_idP, CC_id, UE_id, subframeP, status, eNB_dlsch_info[module_idP][CC_id][UE_id].serving_num, UE_RNTI(module_idP,UE_id)); - eNB_dlsch_info[module_idP][CC_id][UE_id].rnti = - UE_RNTI(module_idP, UE_id); + UE_RNTI(module_idP, UE_id); // eNB_dlsch_info[module_idP][CC_id][ue_mod_idP].weight = weight; eNB_dlsch_info[module_idP][CC_id][UE_id].subframe = subframeP; eNB_dlsch_info[module_idP][CC_id][UE_id].status = status; - eNB_dlsch_info[module_idP][CC_id][UE_id].serving_num++; - } //------------------------------------------------------------------------------ @@ -91,7 +88,6 @@ schedule_next_dlue(module_id_t module_idP, int CC_id, sub_frame_t subframeP) //------------------------------------------------------------------------------ { - int next_ue; UE_list_t *UE_list = &RC.mac[module_idP]->UE_list; @@ -111,7 +107,6 @@ schedule_next_dlue(module_id_t module_idP, int CC_id, } return (-1); //next_ue; - } //------------------------------------------------------------------------------ @@ -127,11 +122,9 @@ generate_dlsch_header(unsigned char *mac_header, unsigned short post_padding) //------------------------------------------------------------------------------ { - SCH_SUBHEADER_FIXED *mac_header_ptr = (SCH_SUBHEADER_FIXED *) mac_header; uint8_t first_element = 0, last_size = 0, i; uint8_t mac_header_control_elements[16], *ce_ptr; - ce_ptr = &mac_header_control_elements[0]; // compute header components @@ -194,10 +187,10 @@ generate_dlsch_header(unsigned char *mac_header, if (first_element > 0) { mac_header_ptr->E = 1; /* - printf("[eNB][MAC] last subheader : %x (R%d,E%d,LCID%d)\n",*(unsigned char*)mac_header_ptr, - ((SCH_SUBHEADER_FIXED *)mac_header_ptr)->R, - ((SCH_SUBHEADER_FIXED *)mac_header_ptr)->E, - ((SCH_SUBHEADER_FIXED *)mac_header_ptr)->LCID); + printf("[eNB][MAC] last subheader : %x (R%d,E%d,LCID%d)\n",*(unsigned char*)mac_header_ptr, + ((SCH_SUBHEADER_FIXED *)mac_header_ptr)->R, + ((SCH_SUBHEADER_FIXED *)mac_header_ptr)->E, + ((SCH_SUBHEADER_FIXED *)mac_header_ptr)->LCID); */ mac_header_ptr++; } else { @@ -208,16 +201,15 @@ generate_dlsch_header(unsigned char *mac_header, mac_header_ptr->E = 0; mac_header_ptr->LCID = UE_CONT_RES; last_size = 1; - LOG_T(MAC, "[eNB ][RAPROC] Generate contention resolution msg: %x.%x.%x.%x.%x.%x\n", ue_cont_res_id[0], ue_cont_res_id[1], ue_cont_res_id[2], ue_cont_res_id[3], ue_cont_res_id[4], ue_cont_res_id[5]); - memcpy(ce_ptr, ue_cont_res_id, 6); ce_ptr += 6; // msg("(cont_res) : offset %d\n",ce_ptr-mac_header_control_elements); } + //msg("last_size %d,mac_header_ptr %p\n",last_size,mac_header_ptr); for (i = 0; i < num_sdus; i++) { @@ -227,9 +219,9 @@ generate_dlsch_header(unsigned char *mac_header, if (first_element > 0) { mac_header_ptr->E = 1; /*msg("last subheader : %x (R%d,E%d,LCID%d)\n",*(unsigned char*)mac_header_ptr, - ((SCH_SUBHEADER_FIXED *)mac_header_ptr)->R, - ((SCH_SUBHEADER_FIXED *)mac_header_ptr)->E, - ((SCH_SUBHEADER_FIXED *)mac_header_ptr)->LCID); + ((SCH_SUBHEADER_FIXED *)mac_header_ptr)->R, + ((SCH_SUBHEADER_FIXED *)mac_header_ptr)->E, + ((SCH_SUBHEADER_FIXED *)mac_header_ptr)->LCID); */ mac_header_ptr += last_size; //msg("last_size %d,mac_header_ptr %p\n",last_size,mac_header_ptr); @@ -255,10 +247,10 @@ generate_dlsch_header(unsigned char *mac_header, last_size = 3; #ifdef DEBUG_HEADER_PARSING LOG_D(MAC, - "[eNB] generate long sdu, size %x (MSB %x, LSB %x)\n", - sdu_lengths[i], - ((SCH_SUBHEADER_LONG *) mac_header_ptr)->L_MSB, - ((SCH_SUBHEADER_LONG *) mac_header_ptr)->L_LSB); + "[eNB] generate long sdu, size %x (MSB %x, LSB %x)\n", + sdu_lengths[i], + ((SCH_SUBHEADER_LONG *) mac_header_ptr)->L_MSB, + ((SCH_SUBHEADER_LONG *) mac_header_ptr)->L_LSB); #endif } } @@ -300,10 +292,10 @@ generate_dlsch_header(unsigned char *mac_header, memcpy((void *) mac_header_ptr, mac_header_control_elements, ce_ptr - mac_header_control_elements); mac_header_ptr += - (unsigned char) (ce_ptr - mac_header_control_elements); + (unsigned char) (ce_ptr - mac_header_control_elements); } - //msg("After CEs %d\n",(uint8_t*)mac_header_ptr - mac_header); + //msg("After CEs %d\n",(uint8_t*)mac_header_ptr - mac_header); return ((unsigned char *) mac_header_ptr - mac_header); } @@ -313,11 +305,11 @@ set_ul_DAI(int module_idP, int UE_idP, int CC_idP, int frameP, int subframeP) //------------------------------------------------------------------------------ { - eNB_MAC_INST *eNB = RC.mac[module_idP]; UE_list_t *UE_list = &eNB->UE_list; unsigned char DAI; COMMON_channels_t *cc = &eNB->common_channels[CC_idP]; + if (cc->tdd_Config != NULL) { //TDD DAI = (UE_list->UE_template[CC_idP][UE_idP].DAI - 1) & 3; LOG_D(MAC, @@ -332,24 +324,25 @@ set_ul_DAI(int module_idP, int UE_idP, int CC_idP, int frameP, case 1: switch (subframeP) { - case 0: - case 1: - UE_list->UE_template[CC_idP][UE_idP].DAI_ul[7] = DAI; - break; + case 0: + case 1: + UE_list->UE_template[CC_idP][UE_idP].DAI_ul[7] = DAI; + break; - case 4: - UE_list->UE_template[CC_idP][UE_idP].DAI_ul[8] = DAI; - break; + case 4: + UE_list->UE_template[CC_idP][UE_idP].DAI_ul[8] = DAI; + break; - case 5: - case 6: - UE_list->UE_template[CC_idP][UE_idP].DAI_ul[2] = DAI; - break; + case 5: + case 6: + UE_list->UE_template[CC_idP][UE_idP].DAI_ul[2] = DAI; + break; - case 9: - UE_list->UE_template[CC_idP][UE_idP].DAI_ul[3] = DAI; - break; + case 9: + UE_list->UE_template[CC_idP][UE_idP].DAI_ul[3] = DAI; + break; } + break; case 2: @@ -410,7 +403,6 @@ set_ul_DAI(int module_idP, int UE_idP, int CC_idP, int frameP, //------------------------------------------------------------------------------ void schedule_dlsch(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP, int *mbsfn_flag) { - int i = 0; slice_info_t *sli = &RC.mac[module_idP]->slice_info; memset(sli->rballoc_sub, 0, sizeof(sli->rballoc_sub)); @@ -419,7 +411,6 @@ schedule_dlsch(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP, in // Run each enabled slice-specific schedulers one by one sli->dl[i].sched_cb(module_idP, i, frameP, subframeP, mbsfn_flag/*, dl_info*/); } - } // changes to pre-processor for eMTC @@ -445,7 +436,6 @@ schedule_ue_spec(module_id_t module_idP, int slice_idxP, int harq_pid = 0; eNB_UE_STATS *eNB_UE_stats = NULL; int sdu_length_total = 0; - eNB_MAC_INST *eNB = RC.mac[module_idP]; COMMON_channels_t *cc = eNB->common_channels; UE_list_t *UE_list = &eNB->UE_list; @@ -465,65 +455,79 @@ schedule_ue_spec(module_id_t module_idP, int slice_idxP, int ta_update; int header_length_last; int header_length_total; - rrc_eNB_ue_context_t *ue_contextP = NULL; - start_meas(&eNB->schedule_dlsch); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_SCHEDULE_DLSCH, VCD_FUNCTION_IN); // for TDD: check that we have to act here, otherwise return if (cc[0].tdd_Config) { tdd_sfa = cc[0].tdd_Config->subframeAssignment; + switch (subframeP) { case 0: // always continue break; + case 1: return; break; + case 2: return; break; + case 3: if ((tdd_sfa != 2) && (tdd_sfa != 5)) return; + break; + case 4: if ((tdd_sfa != 1) && (tdd_sfa != 2) && (tdd_sfa != 4) && (tdd_sfa != 5)) return; + break; + case 5: break; + case 6: case 7: if ((tdd_sfa != 3) && (tdd_sfa != 4) && (tdd_sfa != 5)) return; + break; + case 8: if ((tdd_sfa != 2) && (tdd_sfa != 3) && (tdd_sfa != 4) && (tdd_sfa != 5)) return; + break; + case 9: if (tdd_sfa == 0) return; + break; } } + //weight = get_ue_weight(module_idP,UE_id); aggregation = 2; + for (CC_id = 0; CC_id < RC.nb_mac_CC[module_idP]; CC_id++) { N_RB_DL[CC_id] = to_prb(cc[CC_id].mib->message.dl_Bandwidth); min_rb_unit[CC_id] = get_min_rb_unit(module_idP, CC_id); // get number of PRBs less those used by common channels total_nb_available_rb[CC_id] = N_RB_DL[CC_id]; + for (i = 0; i < N_RB_DL[CC_id]; i++) if (cc[CC_id].vrb_map[i] != 0) total_nb_available_rb[CC_id]--; N_RBG[CC_id] = to_rbg(cc[CC_id].mib->message.dl_Bandwidth); - // store the global enb stats: eNB->eNB_stats[CC_id].num_dlactive_UEs = UE_list->num_UEs; eNB->eNB_stats[CC_id].available_prbs = total_nb_available_rb[CC_id]; @@ -535,7 +539,6 @@ schedule_ue_spec(module_id_t module_idP, int slice_idxP, // CALLING Pre_Processor for downlink scheduling // (Returns estimation of RBs required by each UE and the allocation on sub-band) VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_PREPROCESSOR, VCD_FUNCTION_IN); - start_meas(&eNB->schedule_dlsch_preprocessor); dlsch_scheduler_pre_processor(module_idP, slice_idxP, @@ -544,15 +547,14 @@ schedule_ue_spec(module_id_t module_idP, int slice_idxP, mbsfn_flag, eNB->slice_info.rballoc_sub); stop_meas(&eNB->schedule_dlsch_preprocessor); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_PREPROCESSOR, VCD_FUNCTION_OUT); //RC.mac[module_idP]->slice_info.slice_counter--; // Do the multiplexing and actual allocation only when all slices have been pre-processed. //if (RC.mac[module_idP]->slice_info.slice_counter > 0) { - //stop_meas(&eNB->schedule_dlsch); - //VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_SCHEDULE_DLSCH, VCD_FUNCTION_OUT); - //return; + //stop_meas(&eNB->schedule_dlsch); + //VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_SCHEDULE_DLSCH, VCD_FUNCTION_OUT); + //return; //} if (RC.mac[module_idP]->slice_info.interslice_share_active) { @@ -564,7 +566,6 @@ schedule_ue_spec(module_id_t module_idP, int slice_idxP, for (CC_id = 0; CC_id < RC.nb_mac_CC[module_idP]; CC_id++) { LOG_D(MAC, "doing schedule_ue_spec for CC_id %d\n", CC_id); - dl_req = &eNB->DL_req[CC_id].dl_config_request_body; if (mbsfn_flag[CC_id] > 0) @@ -604,11 +605,13 @@ schedule_ue_spec(module_id_t module_idP, int slice_idxP, ue_sched_ctl->dl_cqi[CC_id], format1); break; + case 3: aggregation = get_aggregation(get_bw_index(module_idP, CC_id), ue_sched_ctl->dl_cqi[CC_id], format2A); break; + default: LOG_W(MAC, "Unsupported transmission mode %d\n", get_tmode(module_idP, CC_id, UE_id)); aggregation = 2; @@ -616,13 +619,13 @@ schedule_ue_spec(module_id_t module_idP, int slice_idxP, } /* if (continue_flag != 1 */ - if ((ue_sched_ctl->pre_nb_available_rbs[CC_id] == 0) || // no RBs allocated - CCE_allocation_infeasible(module_idP, CC_id, 1, subframeP, - aggregation, rnti)) { - LOG_D(MAC, - "[eNB %d] Frame %d : no RB allocated for UE %d on CC_id %d: continue \n", - module_idP, frameP, UE_id, CC_id); - continue_flag = 1; //to next user (there might be rbs availiable for other UEs in TM5 + if ((ue_sched_ctl->pre_nb_available_rbs[CC_id] == 0) || // no RBs allocated + CCE_allocation_infeasible(module_idP, CC_id, 1, subframeP, + aggregation, rnti)) { + LOG_D(MAC, + "[eNB %d] Frame %d : no RB allocated for UE %d on CC_id %d: continue \n", + module_idP, frameP, UE_id, CC_id); + continue_flag = 1; //to next user (there might be rbs availiable for other UEs in TM5 } // If TDD @@ -642,10 +645,8 @@ schedule_ue_spec(module_id_t module_idP, int slice_idxP, } nb_available_rb = ue_sched_ctl->pre_nb_available_rbs[CC_id]; - harq_pid = frame_subframe2_dl_harq_pid(cc->tdd_Config,frameP ,subframeP); - + harq_pid = frame_subframe2_dl_harq_pid(cc->tdd_Config,frameP,subframeP); round = ue_sched_ctl->round[CC_id][harq_pid]; - UE_list->eNB_UE_stats[CC_id][UE_id].crnti = rnti; UE_list->eNB_UE_stats[CC_id][UE_id].rrc_status = mac_eNB_get_rrc_status(module_idP, rnti); UE_list->eNB_UE_stats[CC_id][UE_id].harq_pid = harq_pid; @@ -689,21 +690,20 @@ schedule_ue_spec(module_id_t module_idP, int slice_idxP, /* process retransmission */ if (round != 8) { - // get freq_allocation nb_rb = UE_list->UE_template[CC_id][UE_id].nb_rb[harq_pid]; TBS = get_TBS_DL(UE_list->UE_template[CC_id][UE_id].oldmcs1[harq_pid], nb_rb); - if (nb_rb <= nb_available_rb) { - if (cc[CC_id].tdd_Config != NULL) { - UE_list->UE_template[CC_id][UE_id].DAI++; - update_ul_dci(module_idP, CC_id, rnti, - UE_list->UE_template[CC_id][UE_id].DAI, subframeP); - LOG_D(MAC, - "DAI update: CC_id %d subframeP %d: UE %d, DAI %d\n", - CC_id, subframeP, UE_id, - UE_list->UE_template[CC_id][UE_id].DAI); - } + if (nb_rb <= nb_available_rb) { + if (cc[CC_id].tdd_Config != NULL) { + UE_list->UE_template[CC_id][UE_id].DAI++; + update_ul_dci(module_idP, CC_id, rnti, + UE_list->UE_template[CC_id][UE_id].DAI, subframeP); + LOG_D(MAC, + "DAI update: CC_id %d subframeP %d: UE %d, DAI %d\n", + CC_id, subframeP, UE_id, + UE_list->UE_template[CC_id][UE_id].DAI); + } if (nb_rb == ue_sched_ctl->pre_nb_available_rbs[CC_id]) { for (j = 0; j < N_RBG[CC_id]; ++j) { // for indicating the rballoc for each sub-band @@ -717,6 +717,7 @@ schedule_ue_spec(module_id_t module_idP, int slice_idxP, if (ue_sched_ctl->rballoc_sub_UE[CC_id][j] == 1) { if (UE_list->UE_template[CC_id][UE_id].rballoc_subband[harq_pid][j]) printf("WARN: rballoc_subband not free for retrans?\n"); + UE_list->UE_template[CC_id][UE_id].rballoc_subband[harq_pid][j] = ue_sched_ctl->rballoc_sub_UE[CC_id][j]; if ((j == N_RBG[CC_id] - 1) && ((N_RB_DL[CC_id] == 25) || (N_RB_DL[CC_id] == 50))) { @@ -746,7 +747,6 @@ schedule_ue_spec(module_id_t module_idP, int slice_idxP, case 7: default: LOG_D(MAC, "retransmission DL_REQ: rnti:%x\n", rnti); - dl_config_pdu = &dl_req->dl_config_pdu_list[dl_req->number_pdu]; memset((void *) dl_config_pdu, 0, sizeof(nfapi_dl_config_request_pdu_t)); dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE; @@ -754,13 +754,12 @@ schedule_ue_spec(module_id_t module_idP, int slice_idxP, dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tl.tag = NFAPI_DL_CONFIG_REQUEST_DCI_DL_PDU_REL8_TAG; dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.dci_format = NFAPI_DL_DCI_FORMAT_1; dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level = - get_aggregation(get_bw_index(module_idP, CC_id), - ue_sched_ctl->dl_cqi[CC_id], - format1); + get_aggregation(get_bw_index(module_idP, CC_id), + ue_sched_ctl->dl_cqi[CC_id], + format1); dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti = rnti; dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti_type = 1; // CRNTI: see Table 4-10 from SCF082 - nFAPI specifications dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.transmission_power = 6000; // equal to RS power - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.harq_process = harq_pid; dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tpc = 1; // Don't adjust power when retransmitting dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.new_data_indicator_1 = UE_list->UE_template[CC_id][UE_id].oldNDI[harq_pid]; @@ -770,7 +769,7 @@ schedule_ue_spec(module_id_t module_idP, int slice_idxP, // TDD if (cc[CC_id].tdd_Config != NULL) { dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.downlink_assignment_index = - (UE_list->UE_template[CC_id][UE_id].DAI - 1) & 3; + (UE_list->UE_template[CC_id][UE_id].DAI - 1) & 3; LOG_D(MAC, "[eNB %d] Retransmission CC_id %d : harq_pid %d, round %d, dai %d, mcs %d\n", module_idP, CC_id, harq_pid, round, @@ -781,17 +780,15 @@ schedule_ue_spec(module_id_t module_idP, int slice_idxP, "[eNB %d] Retransmission CC_id %d : harq_pid %d, round %d, mcs %d\n", module_idP, CC_id, harq_pid, round, UE_list->UE_template[CC_id][UE_id].oldmcs1[harq_pid]); + } - } - if (!CCE_allocation_infeasible(module_idP, CC_id, 1, subframeP, - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level, rnti)) { - dl_req->number_dci++; - dl_req->number_pdu++; - dl_req->tl.tag = NFAPI_DL_CONFIG_REQUEST_BODY_TAG; - - eNB->DL_req[CC_id].sfn_sf = frameP<<4 | subframeP; - eNB->DL_req[CC_id].header.message_id = NFAPI_DL_CONFIG_REQUEST; - + if (!CCE_allocation_infeasible(module_idP, CC_id, 1, subframeP, + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level, rnti)) { + dl_req->number_dci++; + dl_req->number_pdu++; + dl_req->tl.tag = NFAPI_DL_CONFIG_REQUEST_BODY_TAG; + eNB->DL_req[CC_id].sfn_sf = frameP<<4 | subframeP; + eNB->DL_req[CC_id].header.message_id = NFAPI_DL_CONFIG_REQUEST; fill_nfapi_dlsch_config(eNB, dl_req, TBS, -1, /* retransmission, no pdu_index */ rnti, 0, // type 0 allocation from 7.1.6 in 36.213 @@ -804,7 +801,7 @@ schedule_ue_spec(module_id_t module_idP, int slice_idxP, cc[CC_id].p_eNB == 1 ? 0 : 1, // transmission_scheme 1, // number of layers 1, // number of subbands - // uint8_t codebook_index, + // uint8_t codebook_index, 4, // UE category capacity UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->pdsch_ConfigDedicated->p_a, 0, // delta_power_offset for TM5 @@ -813,12 +810,10 @@ schedule_ue_spec(module_id_t module_idP, int slice_idxP, cc[CC_id].p_eNB == 1 ? 1 : 2, // transmission mode 0, //number of PRBs treated as one subband, not used here 0 // number of beamforming vectors, not used here - ); - + ); LOG_D(MAC, "Filled NFAPI configuration for DCI/DLSCH %d, retransmission round %d\n", eNB->pdu_index[CC_id], round); - program_dlsch_acknak(module_idP, CC_id, UE_id, frameP, subframeP, dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.cce_idx); // No TX request for retransmission (check if null request for FAPI) @@ -830,32 +825,32 @@ schedule_ue_spec(module_id_t module_idP, int slice_idxP, } add_ue_dlsch_info(module_idP, CC_id, UE_id, subframeP, S_DL_SCHEDULED); + //eNB_UE_stats->dlsch_trials[round]++; + UE_list->eNB_UE_stats[CC_id][UE_id].num_retransmission += 1; + UE_list->eNB_UE_stats[CC_id][UE_id].rbs_used_retx = nb_rb; + UE_list->eNB_UE_stats[CC_id][UE_id].total_rbs_used_retx += nb_rb; + UE_list->eNB_UE_stats[CC_id][UE_id].dlsch_mcs1 = eNB_UE_stats->dlsch_mcs1; + UE_list->eNB_UE_stats[CC_id][UE_id].dlsch_mcs2 = eNB_UE_stats->dlsch_mcs1; + } else { + LOG_D(MAC, + "[eNB %d] Frame %d CC_id %d : don't schedule UE %d, its retransmission takes more resources than we have\n", + module_idP, frameP, CC_id, UE_id); + } + } else { /* This is a potentially new SDU opportunity */ + rlc_status.bytes_in_buffer = 0; + // Now check RLC information to compute number of required RBs + // get maximum TBS size for RLC request + TBS = get_TBS_DL(eNB_UE_stats->dlsch_mcs1, nb_available_rb); - //eNB_UE_stats->dlsch_trials[round]++; - UE_list->eNB_UE_stats[CC_id][UE_id].num_retransmission += 1; - UE_list->eNB_UE_stats[CC_id][UE_id].rbs_used_retx = nb_rb; - UE_list->eNB_UE_stats[CC_id][UE_id].total_rbs_used_retx += nb_rb; - UE_list->eNB_UE_stats[CC_id][UE_id].dlsch_mcs1 = eNB_UE_stats->dlsch_mcs1; - UE_list->eNB_UE_stats[CC_id][UE_id].dlsch_mcs2 = eNB_UE_stats->dlsch_mcs1; - } else { - LOG_D(MAC, - "[eNB %d] Frame %d CC_id %d : don't schedule UE %d, its retransmission takes more resources than we have\n", - module_idP, frameP, CC_id, UE_id); - } - } else { /* This is a potentially new SDU opportunity */ - rlc_status.bytes_in_buffer = 0; - - // Now check RLC information to compute number of required RBs - // get maximum TBS size for RLC request - TBS = get_TBS_DL(eNB_UE_stats->dlsch_mcs1, nb_available_rb); - - // add the length for all the control elements (timing adv, drx, etc) : header + payload + // add the length for all the control elements (timing adv, drx, etc) : header + payload if (ue_sched_ctl->ta_timer == 0) { ta_update = ue_sched_ctl->ta_update; + /* if we send TA then set timer to not send it for a while */ if (ta_update != 31) ue_sched_ctl->ta_timer = 20; + /* reset ta_update */ ue_sched_ctl->ta_update = 31; } else { @@ -864,44 +859,43 @@ schedule_ue_spec(module_id_t module_idP, int slice_idxP, ta_len = (ta_update != 31) ? 2 : 0; - // RLC data on DCCH - if (TBS - ta_len - header_length_total - sdu_length_total - 3 > 0) { - rlc_status = mac_rlc_status_ind(module_idP, rnti, module_idP, frameP, subframeP, ENB_FLAG_YES, MBMS_FLAG_NO, DCCH, + // RLC data on DCCH + if (TBS - ta_len - header_length_total - sdu_length_total - 3 > 0) { + rlc_status = mac_rlc_status_ind(module_idP, rnti, module_idP, frameP, subframeP, ENB_FLAG_YES, MBMS_FLAG_NO, DCCH, TBS - ta_len - header_length_total - sdu_length_total - 3 #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - ,0, 0 + ,0, 0 #endif - ); - + ); sdu_lengths[0] = 0; - if (rlc_status.bytes_in_buffer > 0) { - LOG_D(MAC, "[eNB %d] SFN/SF %d.%d, DL-DCCH->DLSCH CC_id %d, Requesting %d bytes from RLC (RRC message)\n", - module_idP, frameP, subframeP, CC_id, - TBS - ta_len - header_length_total - sdu_length_total - 3); - - sdu_lengths[0] = mac_rlc_data_req(module_idP, rnti, module_idP, frameP, ENB_FLAG_YES, MBMS_FLAG_NO, DCCH, + if (rlc_status.bytes_in_buffer > 0) { + LOG_D(MAC, "[eNB %d] SFN/SF %d.%d, DL-DCCH->DLSCH CC_id %d, Requesting %d bytes from RLC (RRC message)\n", + module_idP, frameP, subframeP, CC_id, + TBS - ta_len - header_length_total - sdu_length_total - 3); + sdu_lengths[0] = mac_rlc_data_req(module_idP, rnti, module_idP, frameP, ENB_FLAG_YES, MBMS_FLAG_NO, DCCH, TBS, //not used - (char *)&dlsch_buffer[0] + (char *)&dlsch_buffer[0] #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - ,0, 0 + ,0, 0 #endif - ); - + ); pthread_mutex_lock(&rrc_release_freelist); - if((rrc_release_info.num_UEs > 0) && (rlc_am_mui.rrc_mui_num > 0)){ + + if((rrc_release_info.num_UEs > 0) && (rlc_am_mui.rrc_mui_num > 0)) { uint16_t release_total = 0; - for(uint16_t release_num = 0;release_num < NUMBER_OF_UE_MAX;release_num++){ - if(rrc_release_info.RRC_release_ctrl[release_num].flag > 0){ + + for(uint16_t release_num = 0; release_num < NUMBER_OF_UE_MAX; release_num++) { + if(rrc_release_info.RRC_release_ctrl[release_num].flag > 0) { release_total++; - }else{ + } else { continue; } - if(rrc_release_info.RRC_release_ctrl[release_num].flag == 1){ - if(rrc_release_info.RRC_release_ctrl[release_num].rnti == rnti){ - for(uint16_t mui_num = 0;mui_num < rlc_am_mui.rrc_mui_num;mui_num++){ - if(rrc_release_info.RRC_release_ctrl[release_num].rrc_eNB_mui == rlc_am_mui.rrc_mui[mui_num]){ + if(rrc_release_info.RRC_release_ctrl[release_num].flag == 1) { + if(rrc_release_info.RRC_release_ctrl[release_num].rnti == rnti) { + for(uint16_t mui_num = 0; mui_num < rlc_am_mui.rrc_mui_num; mui_num++) { + if(rrc_release_info.RRC_release_ctrl[release_num].rrc_eNB_mui == rlc_am_mui.rrc_mui[mui_num]) { rrc_release_info.RRC_release_ctrl[release_num].flag = 3; LOG_D(MAC,"DLSCH Release send:index %d rnti %x mui %d mui_num %d flag 1->3\n",release_num,rnti,rlc_am_mui.rrc_mui[mui_num],mui_num); break; @@ -909,10 +903,11 @@ schedule_ue_spec(module_id_t module_idP, int slice_idxP, } } } - if(rrc_release_info.RRC_release_ctrl[release_num].flag == 2){ - if(rrc_release_info.RRC_release_ctrl[release_num].rnti == rnti){ - for(uint16_t mui_num = 0;mui_num < rlc_am_mui.rrc_mui_num;mui_num++){ - if(rrc_release_info.RRC_release_ctrl[release_num].rrc_eNB_mui == rlc_am_mui.rrc_mui[mui_num]){ + + if(rrc_release_info.RRC_release_ctrl[release_num].flag == 2) { + if(rrc_release_info.RRC_release_ctrl[release_num].rnti == rnti) { + for(uint16_t mui_num = 0; mui_num < rlc_am_mui.rrc_mui_num; mui_num++) { + if(rrc_release_info.RRC_release_ctrl[release_num].rrc_eNB_mui == rlc_am_mui.rrc_mui[mui_num]) { rrc_release_info.RRC_release_ctrl[release_num].flag = 4; LOG_D(MAC,"DLSCH Release send:index %d rnti %x mui %d mui_num %d flag 2->4\n",release_num,rnti,rlc_am_mui.rrc_mui[mui_num],mui_num); break; @@ -920,17 +915,19 @@ schedule_ue_spec(module_id_t module_idP, int slice_idxP, } } } + if(release_total >= rrc_release_info.num_UEs) break; } } - pthread_mutex_unlock(&rrc_release_freelist); + pthread_mutex_unlock(&rrc_release_freelist); RA_t *ra = &eNB->common_channels[CC_id].ra[0]; + for (uint8_t ra_ii = 0; ra_ii < NB_RA_PROC_MAX; ra_ii++) { - if((ra[ra_ii].rnti == rnti) && (ra[ra_ii].state == MSGCRNTI)){ - for(uint16_t mui_num = 0;mui_num < rlc_am_mui.rrc_mui_num;mui_num++){ - if(ra[ra_ii].crnti_rrc_mui == rlc_am_mui.rrc_mui[mui_num]){ + if((ra[ra_ii].rnti == rnti) && (ra[ra_ii].state == MSGCRNTI)) { + for(uint16_t mui_num = 0; mui_num < rlc_am_mui.rrc_mui_num; mui_num++) { + if(ra[ra_ii].crnti_rrc_mui == rlc_am_mui.rrc_mui[mui_num]) { ra[ra_ii].crnti_harq_pid = harq_pid; ra[ra_ii].state = MSGCRNTI_ACK; break; @@ -943,26 +940,21 @@ schedule_ue_spec(module_id_t module_idP, int slice_idxP, T_INT(CC_id), T_INT(rnti), T_INT(frameP), T_INT(subframeP), T_INT(harq_pid), T_INT(DCCH), T_INT(sdu_lengths[0])); - - LOG_D(MAC, "[eNB %d][DCCH] CC_id %d Got %d bytes from RLC\n", - module_idP, CC_id, sdu_lengths[0]); - - sdu_length_total = sdu_lengths[0]; - sdu_lcids[0] = DCCH; + LOG_D(MAC, "[eNB %d][DCCH] CC_id %d Got %d bytes from RLC\n", + module_idP, CC_id, sdu_lengths[0]); + sdu_length_total = sdu_lengths[0]; + sdu_lcids[0] = DCCH; UE_list->eNB_UE_stats[CC_id][UE_id].lcid_sdu[0] = DCCH; UE_list->eNB_UE_stats[CC_id][UE_id].sdu_length_tx[DCCH] = sdu_lengths[0]; - UE_list->eNB_UE_stats[CC_id][UE_id].num_pdu_tx[DCCH] += 1; - UE_list->eNB_UE_stats[CC_id][UE_id].num_bytes_tx[DCCH] += sdu_lengths[0]; - + UE_list->eNB_UE_stats[CC_id][UE_id].num_pdu_tx[DCCH] += 1; + UE_list->eNB_UE_stats[CC_id][UE_id].num_bytes_tx[DCCH] += sdu_lengths[0]; header_length_last = 1 + 1 + (sdu_lengths[0] >= 128); header_length_total += header_length_last; - - num_sdus = 1; - + num_sdus = 1; #ifdef DEBUG_eNB_SCHEDULER LOG_T(MAC, - "[eNB %d][DCCH] CC_id %d Got %d bytes :", - module_idP, CC_id, sdu_lengths[0]); + "[eNB %d][DCCH] CC_id %d Got %d bytes :", + module_idP, CC_id, sdu_lengths[0]); for (j = 0; j < sdu_lengths[0]; ++j) { LOG_T(MAC, "%x ", dlsch_buffer[j]); @@ -970,55 +962,48 @@ schedule_ue_spec(module_id_t module_idP, int slice_idxP, LOG_T(MAC, "\n"); #endif - } - } + } + } - // RLC data on DCCH1 - if (TBS - ta_len - header_length_total - sdu_length_total - 3 > 0) { - rlc_status = mac_rlc_status_ind(module_idP, rnti, module_idP, frameP, subframeP, ENB_FLAG_YES, MBMS_FLAG_NO, DCCH + 1, + // RLC data on DCCH1 + if (TBS - ta_len - header_length_total - sdu_length_total - 3 > 0) { + rlc_status = mac_rlc_status_ind(module_idP, rnti, module_idP, frameP, subframeP, ENB_FLAG_YES, MBMS_FLAG_NO, DCCH + 1, TBS - ta_len - header_length_total - sdu_length_total - 3 #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - ,0, 0 + ,0, 0 #endif ); + // DCCH SDU + sdu_lengths[num_sdus] = 0; - // DCCH SDU - sdu_lengths[num_sdus] = 0; - - if (rlc_status.bytes_in_buffer > 0) { - LOG_D(MAC, "[eNB %d], Frame %d, DCCH1->DLSCH, CC_id %d, Requesting %d bytes from RLC (RRC message)\n", - module_idP, frameP, CC_id, - TBS - ta_len - header_length_total - sdu_length_total - 3); - - sdu_lengths[num_sdus] += mac_rlc_data_req(module_idP, rnti, module_idP, frameP, ENB_FLAG_YES, MBMS_FLAG_NO, DCCH + 1, - TBS, //not used - (char *)&dlsch_buffer[sdu_length_total] + if (rlc_status.bytes_in_buffer > 0) { + LOG_D(MAC, "[eNB %d], Frame %d, DCCH1->DLSCH, CC_id %d, Requesting %d bytes from RLC (RRC message)\n", + module_idP, frameP, CC_id, + TBS - ta_len - header_length_total - sdu_length_total - 3); + sdu_lengths[num_sdus] += mac_rlc_data_req(module_idP, rnti, module_idP, frameP, ENB_FLAG_YES, MBMS_FLAG_NO, DCCH + 1, + TBS, //not used + (char *)&dlsch_buffer[sdu_length_total] #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - ,0, 0 + ,0, 0 #endif - ); - + ); T(T_ENB_MAC_UE_DL_SDU, T_INT(module_idP), T_INT(CC_id), T_INT(rnti), T_INT(frameP), T_INT(subframeP), T_INT(harq_pid), T_INT(DCCH + 1), T_INT(sdu_lengths[num_sdus])); - - sdu_lcids[num_sdus] = DCCH1; - sdu_length_total += sdu_lengths[num_sdus]; + sdu_lcids[num_sdus] = DCCH1; + sdu_length_total += sdu_lengths[num_sdus]; UE_list->eNB_UE_stats[CC_id][UE_id].lcid_sdu[num_sdus] = DCCH1; UE_list->eNB_UE_stats[CC_id][UE_id].sdu_length_tx[DCCH1] = sdu_lengths[num_sdus]; - UE_list->eNB_UE_stats[CC_id][UE_id].num_pdu_tx[DCCH1] += 1; - UE_list->eNB_UE_stats[CC_id][UE_id].num_bytes_tx[DCCH1] += sdu_lengths[num_sdus]; - + UE_list->eNB_UE_stats[CC_id][UE_id].num_pdu_tx[DCCH1] += 1; + UE_list->eNB_UE_stats[CC_id][UE_id].num_bytes_tx[DCCH1] += sdu_lengths[num_sdus]; header_length_last = 1 + 1 + (sdu_lengths[num_sdus] >= 128); header_length_total += header_length_last; - - num_sdus++; - + num_sdus++; #ifdef DEBUG_eNB_SCHEDULER LOG_T(MAC, - "[eNB %d][DCCH1] CC_id %d Got %d bytes :", - module_idP, CC_id, sdu_lengths[num_sdus]); + "[eNB %d][DCCH1] CC_id %d Got %d bytes :", + module_idP, CC_id, sdu_lengths[num_sdus]); for (j = 0; j < sdu_lengths[num_sdus]; ++j) { LOG_T(MAC, "%x ", dlsch_buffer[j]); @@ -1026,97 +1011,85 @@ schedule_ue_spec(module_id_t module_idP, int slice_idxP, LOG_T(MAC, "\n"); #endif + } + } - } - } + // TODO: lcid has to be sorted before the actual allocation (similar struct as ue_list). + for (lcid = NB_RB_MAX - 1; lcid >= DTCH; lcid--) { + // TODO: check if the lcid is active + LOG_D(MAC, "[eNB %d], Frame %d, DTCH%d->DLSCH, Checking RLC status (tbs %d, len %d)\n", + module_idP, + frameP, + lcid, + TBS, + TBS - ta_len - header_length_total - sdu_length_total - 3); - // TODO: lcid has to be sorted before the actual allocation (similar struct as ue_list). - for (lcid = NB_RB_MAX - 1; lcid >= DTCH; lcid--) { - // TODO: check if the lcid is active + if (TBS - ta_len - header_length_total - sdu_length_total - 3 > 0) { + rlc_status = mac_rlc_status_ind(module_idP, + rnti, + module_idP, + frameP, + subframeP, + ENB_FLAG_YES, + MBMS_FLAG_NO, + lcid, + TBS - ta_len - header_length_total - sdu_length_total - 3 +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + , 0, 0 +#endif + ); - LOG_D(MAC, "[eNB %d], Frame %d, DTCH%d->DLSCH, Checking RLC status (tbs %d, len %d)\n", - module_idP, - frameP, - lcid, - TBS, - TBS - ta_len - header_length_total - sdu_length_total - 3); - - if (TBS - ta_len - header_length_total - sdu_length_total - 3 > 0) { - rlc_status = mac_rlc_status_ind(module_idP, + if (rlc_status.bytes_in_buffer > 0) { + LOG_D(MAC, "[eNB %d][USER-PLANE DEFAULT DRB] Frame %d : DTCH->DLSCH, Requesting %d bytes from RLC (lcid %d total hdr len %d)\n", + module_idP, + frameP, + TBS - ta_len - header_length_total - sdu_length_total - 3, + lcid, + header_length_total); + sdu_lengths[num_sdus] = mac_rlc_data_req(module_idP, rnti, module_idP, frameP, - subframeP, ENB_FLAG_YES, MBMS_FLAG_NO, lcid, - TBS - ta_len - header_length_total - sdu_length_total - 3 + TBS, //not used + (char *)&dlsch_buffer[sdu_length_total] #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - , 0, 0 + , 0, 0 #endif - ); - - if (rlc_status.bytes_in_buffer > 0) { - LOG_D(MAC, "[eNB %d][USER-PLANE DEFAULT DRB] Frame %d : DTCH->DLSCH, Requesting %d bytes from RLC (lcid %d total hdr len %d)\n", - module_idP, - frameP, - TBS - ta_len - header_length_total - sdu_length_total - 3, - lcid, - header_length_total); - - sdu_lengths[num_sdus] = mac_rlc_data_req(module_idP, - rnti, - module_idP, - frameP, - ENB_FLAG_YES, - MBMS_FLAG_NO, - lcid, - TBS, //not used - (char *)&dlsch_buffer[sdu_length_total] -#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - , 0, 0 -#endif - ); - - T(T_ENB_MAC_UE_DL_SDU, - T_INT(module_idP), - T_INT(CC_id), - T_INT(rnti), - T_INT(frameP), - T_INT(subframeP), - T_INT(harq_pid), - T_INT(lcid), - T_INT(sdu_lengths[num_sdus])); - - LOG_D(MAC, "[eNB %d][USER-PLANE DEFAULT DRB] Got %d bytes for DTCH %d \n", - module_idP, - sdu_lengths[num_sdus], - lcid); - - sdu_lcids[num_sdus] = lcid; - sdu_length_total += sdu_lengths[num_sdus]; - - UE_list->eNB_UE_stats[CC_id][UE_id].num_pdu_tx[lcid]++; - UE_list->eNB_UE_stats[CC_id][UE_id].lcid_sdu[num_sdus] = lcid; - UE_list->eNB_UE_stats[CC_id][UE_id].sdu_length_tx[lcid] = sdu_lengths[num_sdus]; - UE_list->eNB_UE_stats[CC_id][UE_id].num_bytes_tx[lcid] += sdu_lengths[num_sdus]; - - header_length_last = 1 + 1 + (sdu_lengths[num_sdus] >= 128); - header_length_total += header_length_last; - - num_sdus++; - - UE_list->UE_sched_ctrl[UE_id].uplane_inactivity_timer = 0; - - // reset RRC inactivity timer after uplane activity - ue_contextP = rrc_eNB_get_ue_context(RC.rrc[module_idP], rnti); - ue_contextP->ue_context.ue_rrc_inactivity_timer = 1; - - } // end if (rlc_status.bytes_in_buffer > 0) - } else { // no TBS left - break; // break for (lcid = NB_RB_MAX - 1; lcid >= DTCH; lcid--) - } - } + ); + T(T_ENB_MAC_UE_DL_SDU, + T_INT(module_idP), + T_INT(CC_id), + T_INT(rnti), + T_INT(frameP), + T_INT(subframeP), + T_INT(harq_pid), + T_INT(lcid), + T_INT(sdu_lengths[num_sdus])); + LOG_D(MAC, "[eNB %d][USER-PLANE DEFAULT DRB] Got %d bytes for DTCH %d \n", + module_idP, + sdu_lengths[num_sdus], + lcid); + sdu_lcids[num_sdus] = lcid; + sdu_length_total += sdu_lengths[num_sdus]; + UE_list->eNB_UE_stats[CC_id][UE_id].num_pdu_tx[lcid]++; + UE_list->eNB_UE_stats[CC_id][UE_id].lcid_sdu[num_sdus] = lcid; + UE_list->eNB_UE_stats[CC_id][UE_id].sdu_length_tx[lcid] = sdu_lengths[num_sdus]; + UE_list->eNB_UE_stats[CC_id][UE_id].num_bytes_tx[lcid] += sdu_lengths[num_sdus]; + header_length_last = 1 + 1 + (sdu_lengths[num_sdus] >= 128); + header_length_total += header_length_last; + num_sdus++; + UE_list->UE_sched_ctrl[UE_id].uplane_inactivity_timer = 0; + // reset RRC inactivity timer after uplane activity + ue_contextP = rrc_eNB_get_ue_context(RC.rrc[module_idP], rnti); + ue_contextP->ue_context.ue_rrc_inactivity_timer = 1; + } // end if (rlc_status.bytes_in_buffer > 0) + } else { // no TBS left + break; // break for (lcid = NB_RB_MAX - 1; lcid >= DTCH; lcid--) + } + } /* last header does not have length field */ if (header_length_total) { @@ -1124,13 +1097,11 @@ schedule_ue_spec(module_id_t module_idP, int slice_idxP, header_length_total++; } - // there is at least one SDU or TA command - // if (num_sdus > 0 ){ - if (ta_len + sdu_length_total + header_length_total > 0) { - - // Now compute number of required RBs for total sdu length - // Assume RAH format 2 - + // there is at least one SDU or TA command + // if (num_sdus > 0 ){ + if (ta_len + sdu_length_total + header_length_total > 0) { + // Now compute number of required RBs for total sdu length + // Assume RAH format 2 mcs = eNB_UE_stats->dlsch_mcs1; if (mcs == 0) { @@ -1138,17 +1109,18 @@ schedule_ue_spec(module_id_t module_idP, int slice_idxP, } else { nb_rb = min_rb_unit[CC_id]; } + TBS = get_TBS_DL(mcs, nb_rb); - while (TBS < sdu_length_total + header_length_total + ta_len) { - nb_rb += min_rb_unit[CC_id]; // + while (TBS < sdu_length_total + header_length_total + ta_len) { + nb_rb += min_rb_unit[CC_id]; // - if (nb_rb > nb_available_rb) { // if we've gone beyond the maximum number of RBs - // (can happen if N_RB_DL is odd) - TBS = get_TBS_DL(eNB_UE_stats->dlsch_mcs1, nb_available_rb); - nb_rb = nb_available_rb; - break; - } + if (nb_rb > nb_available_rb) { // if we've gone beyond the maximum number of RBs + // (can happen if N_RB_DL is odd) + TBS = get_TBS_DL(eNB_UE_stats->dlsch_mcs1, nb_available_rb); + nb_rb = nb_available_rb; + break; + } TBS = get_TBS_DL(eNB_UE_stats->dlsch_mcs1, nb_rb); } @@ -1176,41 +1148,40 @@ schedule_ue_spec(module_id_t module_idP, int slice_idxP, } } - // decrease mcs until TBS falls below required length - while ((TBS > sdu_length_total + header_length_total + ta_len) && (mcs > 0)) { - mcs--; - TBS = get_TBS_DL(mcs, nb_rb); - } + // decrease mcs until TBS falls below required length + while ((TBS > sdu_length_total + header_length_total + ta_len) && (mcs > 0)) { + mcs--; + TBS = get_TBS_DL(mcs, nb_rb); + } - // if we have decreased too much or we don't have enough RBs, increase MCS - while ((TBS < sdu_length_total + header_length_total + ta_len) - && (((ue_sched_ctl->dl_pow_off[CC_id] > 0) - && (mcs < 28)) - || ((ue_sched_ctl->dl_pow_off[CC_id] == 0) - && (mcs <= 15)))) { - mcs++; - TBS = get_TBS_DL(mcs, nb_rb); - } + // if we have decreased too much or we don't have enough RBs, increase MCS + while ((TBS < sdu_length_total + header_length_total + ta_len) + && (((ue_sched_ctl->dl_pow_off[CC_id] > 0) + && (mcs < 28)) + || ((ue_sched_ctl->dl_pow_off[CC_id] == 0) + && (mcs <= 15)))) { + mcs++; + TBS = get_TBS_DL(mcs, nb_rb); + } LOG_D(MAC, "dlsch_mcs before and after the rate matching = (%d, %d)\n", eNB_UE_stats->dlsch_mcs1, mcs); - #ifdef DEBUG_eNB_SCHEDULER LOG_D(MAC, - "[eNB %d] CC_id %d Generated DLSCH header (mcs %d, TBS %d, nb_rb %d)\n", - module_idP, CC_id, mcs, TBS, nb_rb); + "[eNB %d] CC_id %d Generated DLSCH header (mcs %d, TBS %d, nb_rb %d)\n", + module_idP, CC_id, mcs, TBS, nb_rb); // msg("[MAC][eNB ] Reminder of DLSCH with random data %d %d %d %d \n", // TBS, sdu_length_total, offset, TBS-sdu_length_total-offset); #endif - if (TBS - header_length_total - sdu_length_total - ta_len <= 2) { - padding = TBS - header_length_total - sdu_length_total - ta_len; - post_padding = 0; - } else { - padding = 0; - post_padding = 1; - } + if (TBS - header_length_total - sdu_length_total - ta_len <= 2) { + padding = TBS - header_length_total - sdu_length_total - ta_len; + post_padding = 0; + } else { + padding = 0; + post_padding = 1; + } offset = generate_dlsch_header((unsigned char *) UE_list->DLSCH_pdu[CC_id][0][UE_id].payload[0], num_sdus, //num_sdus @@ -1220,17 +1191,18 @@ schedule_ue_spec(module_id_t module_idP, int slice_idxP, NULL, // contention res id padding, post_padding); - //#ifdef DEBUG_eNB_SCHEDULER - if (ta_update != 31) { - LOG_D(MAC, - "[eNB %d][DLSCH] Frame %d Generate header for UE_id %d on CC_id %d: sdu_length_total %d, num_sdus %d, sdu_lengths[0] %d, sdu_lcids[0] %d => payload offset %d,timing advance value : %d, padding %d,post_padding %d,(mcs %d, TBS %d, nb_rb %d),header_length %d\n", - module_idP, frameP, UE_id, CC_id, - sdu_length_total, num_sdus, sdu_lengths[0], - sdu_lcids[0], offset, ta_update, padding, - post_padding, mcs, TBS, nb_rb, - header_length_total); - } - //#endif + //#ifdef DEBUG_eNB_SCHEDULER + if (ta_update != 31) { + LOG_D(MAC, + "[eNB %d][DLSCH] Frame %d Generate header for UE_id %d on CC_id %d: sdu_length_total %d, num_sdus %d, sdu_lengths[0] %d, sdu_lcids[0] %d => payload offset %d,timing advance value : %d, padding %d,post_padding %d,(mcs %d, TBS %d, nb_rb %d),header_length %d\n", + module_idP, frameP, UE_id, CC_id, + sdu_length_total, num_sdus, sdu_lengths[0], + sdu_lcids[0], offset, ta_update, padding, + post_padding, mcs, TBS, nb_rb, + header_length_total); + } + + //#endif #ifdef DEBUG_eNB_SCHEDULER LOG_T(MAC, "[eNB %d] First 16 bytes of DLSCH : \n"); @@ -1240,98 +1212,91 @@ schedule_ue_spec(module_id_t module_idP, int slice_idxP, LOG_T(MAC, "\n"); #endif - // cycle through SDUs and place in dlsch_buffer memcpy(&UE_list->DLSCH_pdu[CC_id][0][UE_id].payload[0][offset], dlsch_buffer, sdu_length_total); // memcpy(RC.mac[0].DLSCH_pdu[0][0].payload[0][offset],dcch_buffer,sdu_lengths[0]); - // fill remainder of DLSCH with 0 - for (j = 0; j < (TBS - sdu_length_total - offset); j++) { - UE_list->DLSCH_pdu[CC_id][0][UE_id].payload[0][offset + sdu_length_total + j] = 0; - } + // fill remainder of DLSCH with 0 + for (j = 0; j < (TBS - sdu_length_total - offset); j++) { + UE_list->DLSCH_pdu[CC_id][0][UE_id].payload[0][offset + sdu_length_total + j] = 0; + } - if (opt_enabled == 1) { - trace_pdu(DIRECTION_DOWNLINK, - (uint8_t *) UE_list->DLSCH_pdu[CC_id][0][UE_id].payload[0], - TBS, module_idP, WS_C_RNTI, - UE_RNTI(module_idP, UE_id), eNB->frame, - eNB->subframe, 0, 0); - LOG_D(OPT, - "[eNB %d][DLSCH] CC_id %d Frame %d rnti %x with size %d\n", - module_idP, CC_id, frameP, - UE_RNTI(module_idP, UE_id), TBS); - } - - T(T_ENB_MAC_UE_DL_PDU_WITH_DATA, T_INT(module_idP), - T_INT(CC_id), T_INT(rnti), T_INT(frameP), - T_INT(subframeP), T_INT(harq_pid), - T_BUFFER(UE_list->DLSCH_pdu[CC_id][0][UE_id].payload[0], TBS)); + if (opt_enabled == 1) { + trace_pdu(DIRECTION_DOWNLINK, + (uint8_t *) UE_list->DLSCH_pdu[CC_id][0][UE_id].payload[0], + TBS, module_idP, WS_C_RNTI, + UE_RNTI(module_idP, UE_id), eNB->frame, + eNB->subframe, 0, 0); + LOG_D(OPT, + "[eNB %d][DLSCH] CC_id %d Frame %d rnti %x with size %d\n", + module_idP, CC_id, frameP, + UE_RNTI(module_idP, UE_id), TBS); + } + T(T_ENB_MAC_UE_DL_PDU_WITH_DATA, T_INT(module_idP), + T_INT(CC_id), T_INT(rnti), T_INT(frameP), + T_INT(subframeP), T_INT(harq_pid), + T_BUFFER(UE_list->DLSCH_pdu[CC_id][0][UE_id].payload[0], TBS)); UE_list->UE_template[CC_id][UE_id].nb_rb[harq_pid] = nb_rb; - add_ue_dlsch_info(module_idP, CC_id, UE_id, subframeP, S_DL_SCHEDULED); // store stats eNB->eNB_stats[CC_id].dlsch_bytes_tx += sdu_length_total; eNB->eNB_stats[CC_id].dlsch_pdus_tx += 1; - - UE_list->eNB_UE_stats[CC_id][UE_id].rbs_used = nb_rb; + UE_list->eNB_UE_stats[CC_id][UE_id].rbs_used = nb_rb; UE_list->eNB_UE_stats[CC_id][UE_id].num_mac_sdu_tx = num_sdus; - UE_list->eNB_UE_stats[CC_id][UE_id].total_rbs_used += nb_rb; - UE_list->eNB_UE_stats[CC_id][UE_id].dlsch_mcs1 = eNB_UE_stats->dlsch_mcs1; - UE_list->eNB_UE_stats[CC_id][UE_id].dlsch_mcs2 = mcs; - UE_list->eNB_UE_stats[CC_id][UE_id].TBS = TBS; - + UE_list->eNB_UE_stats[CC_id][UE_id].total_rbs_used += nb_rb; + UE_list->eNB_UE_stats[CC_id][UE_id].dlsch_mcs1 = eNB_UE_stats->dlsch_mcs1; + UE_list->eNB_UE_stats[CC_id][UE_id].dlsch_mcs2 = mcs; + UE_list->eNB_UE_stats[CC_id][UE_id].TBS = TBS; UE_list->eNB_UE_stats[CC_id][UE_id].overhead_bytes = TBS - sdu_length_total; UE_list->eNB_UE_stats[CC_id][UE_id].total_sdu_bytes += sdu_length_total; UE_list->eNB_UE_stats[CC_id][UE_id].total_pdu_bytes += TBS; UE_list->eNB_UE_stats[CC_id][UE_id].total_num_pdus += 1; - if (cc[CC_id].tdd_Config != NULL) { // TDD - UE_list->UE_template[CC_id][UE_id].DAI++; - update_ul_dci(module_idP, CC_id, rnti, - UE_list->UE_template[CC_id][UE_id].DAI, + if (cc[CC_id].tdd_Config != NULL) { // TDD + UE_list->UE_template[CC_id][UE_id].DAI++; + update_ul_dci(module_idP, CC_id, rnti, + UE_list->UE_template[CC_id][UE_id].DAI, subframeP); - } + } - // do PUCCH power control - // this is the normalized RX power - eNB_UE_stats = &UE_list->eNB_UE_stats[CC_id][UE_id]; + // do PUCCH power control + // this is the normalized RX power + eNB_UE_stats = &UE_list->eNB_UE_stats[CC_id][UE_id]; + /* unit is not dBm, it's special from nfapi */ + // converting to dBm: ToDo: Noise power hard coded to 30 + normalized_rx_power = (5*ue_sched_ctl->pucch1_snr[CC_id]-640)/10+30; + target_rx_power= eNB->puCch10xSnr/10 + 30; + // this assumes accumulated tpc + // make sure that we are only sending a tpc update once a frame, otherwise the control loop will freak out + int32_t framex10psubframe = UE_list->UE_template[CC_id][UE_id].pucch_tpc_tx_frame * 10 + UE_list->UE_template[CC_id][UE_id].pucch_tpc_tx_subframe; - /* unit is not dBm, it's special from nfapi */ - // converting to dBm: ToDo: Noise power hard coded to 30 - normalized_rx_power = (5*ue_sched_ctl->pucch1_snr[CC_id]-640)/10+30; - target_rx_power= eNB->puCch10xSnr/10 + 30; - // this assumes accumulated tpc - // make sure that we are only sending a tpc update once a frame, otherwise the control loop will freak out - int32_t framex10psubframe = UE_list->UE_template[CC_id][UE_id].pucch_tpc_tx_frame * 10 + UE_list->UE_template[CC_id][UE_id].pucch_tpc_tx_subframe; - if (((framex10psubframe + 10) <= (frameP * 10 + subframeP)) || //normal case - ((framex10psubframe > (frameP * 10 + subframeP)) && (((10240 - framex10psubframe + frameP * 10 + subframeP) >= 10)))) //frame wrap-around - if (ue_sched_ctl->pucch1_cqi_update[CC_id] == 1) { - ue_sched_ctl->pucch1_cqi_update[CC_id] = 0; + if (((framex10psubframe + 10) <= (frameP * 10 + subframeP)) || //normal case + ((framex10psubframe > (frameP * 10 + subframeP)) && (((10240 - framex10psubframe + frameP * 10 + subframeP) >= 10)))) //frame wrap-around + if (ue_sched_ctl->pucch1_cqi_update[CC_id] == 1) { + ue_sched_ctl->pucch1_cqi_update[CC_id] = 0; + UE_list->UE_template[CC_id][UE_id].pucch_tpc_tx_frame = frameP; + UE_list->UE_template[CC_id][UE_id].pucch_tpc_tx_subframe = subframeP; - UE_list->UE_template[CC_id][UE_id].pucch_tpc_tx_frame = frameP; - UE_list->UE_template[CC_id][UE_id].pucch_tpc_tx_subframe = subframeP; + if (normalized_rx_power > (target_rx_power + 4)) { + tpc = 0; //-1 + } else if (normalized_rx_power < (target_rx_power - 4)) { + tpc = 2; //+1 + } else { + tpc = 1; //0 + } - if (normalized_rx_power > (target_rx_power + 4)) { - tpc = 0; //-1 - } else if (normalized_rx_power < (target_rx_power - 4)) { - tpc = 2; //+1 - } else { - tpc = 1; //0 - } - - LOG_D(MAC, - "[eNB %d] DLSCH scheduler: frame %d, subframe %d, harq_pid %d, tpc %d, normalized/target rx power %d/%d\n", - module_idP, frameP, subframeP, harq_pid, tpc, - normalized_rx_power, target_rx_power); - - } // Po_PUCCH has been updated - else { - tpc = 1; //0 - } // time to do TPC update - else { - tpc = 1; //0 - } + LOG_D(MAC, + "[eNB %d] DLSCH scheduler: frame %d, subframe %d, harq_pid %d, tpc %d, normalized/target rx power %d/%d\n", + module_idP, frameP, subframeP, harq_pid, tpc, + normalized_rx_power, target_rx_power); + } // Po_PUCCH has been updated + else { + tpc = 1; //0 + } // time to do TPC update + else { + tpc = 1; //0 + } dl_config_pdu = &dl_req->dl_config_pdu_list[dl_req->number_pdu]; memset((void *) dl_config_pdu, 0, sizeof(nfapi_dl_config_request_pdu_t)); @@ -1339,16 +1304,15 @@ schedule_ue_spec(module_id_t module_idP, int slice_idxP, dl_config_pdu->pdu_size = (uint8_t) (2 + sizeof(nfapi_dl_config_dci_dl_pdu)); dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.dci_format = NFAPI_DL_DCI_FORMAT_1; dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level = - get_aggregation(get_bw_index(module_idP, CC_id), ue_sched_ctl->dl_cqi[CC_id], format1); + get_aggregation(get_bw_index(module_idP, CC_id), ue_sched_ctl->dl_cqi[CC_id], format1); dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tl.tag = NFAPI_DL_CONFIG_REQUEST_DCI_DL_PDU_REL8_TAG; dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti = rnti; dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti_type = 1; // CRNTI : see Table 4-10 from SCF082 - nFAPI specifications dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.transmission_power = 6000; // equal to RS power - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.harq_process = harq_pid; dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tpc = tpc; // dont adjust power when retransmitting dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.new_data_indicator_1 = - 1 - UE_list->UE_template[CC_id][UE_id].oldNDI[harq_pid]; + 1 - UE_list->UE_template[CC_id][UE_id].oldNDI[harq_pid]; dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.mcs_1 = mcs; dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.redundancy_version_1 = 0; //deactivate second codeword @@ -1357,7 +1321,7 @@ schedule_ue_spec(module_id_t module_idP, int slice_idxP, if (cc[CC_id].tdd_Config != NULL) { //TDD dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.downlink_assignment_index = - (UE_list->UE_template[CC_id][UE_id].DAI - 1) & 3; + (UE_list->UE_template[CC_id][UE_id].DAI - 1) & 3; LOG_D(MAC, "[eNB %d] Initial transmission CC_id %d : harq_pid %d, dai %d, mcs %d\n", module_idP, CC_id, harq_pid, @@ -1367,115 +1331,102 @@ schedule_ue_spec(module_id_t module_idP, int slice_idxP, LOG_D(MAC, "[eNB %d] Initial transmission CC_id %d : harq_pid %d, mcs %d\n", module_idP, CC_id, harq_pid, mcs); + } - } - - LOG_D(MAC, "Checking feasibility pdu %d (new sdu)\n", - dl_req->number_pdu); - - if (!CCE_allocation_infeasible(module_idP, CC_id, 1, subframeP, - dl_config_pdu->dci_dl_pdu. - dci_dl_pdu_rel8.aggregation_level, rnti)) { - ue_sched_ctl->round[CC_id][harq_pid] = 0; - dl_req->number_dci++; - dl_req->number_pdu++; - dl_req->tl.tag = NFAPI_DL_CONFIG_REQUEST_BODY_TAG; + LOG_D(MAC, "Checking feasibility pdu %d (new sdu)\n", + dl_req->number_pdu); + if (!CCE_allocation_infeasible(module_idP, CC_id, 1, subframeP, + dl_config_pdu->dci_dl_pdu. + dci_dl_pdu_rel8.aggregation_level, rnti)) { + ue_sched_ctl->round[CC_id][harq_pid] = 0; + dl_req->number_dci++; + dl_req->number_pdu++; + dl_req->tl.tag = NFAPI_DL_CONFIG_REQUEST_BODY_TAG; eNB->DL_req[CC_id].sfn_sf = frameP << 4 | subframeP; eNB->DL_req[CC_id].header.message_id = NFAPI_DL_CONFIG_REQUEST; - // Toggle NDI for next time LOG_D(MAC, "CC_id %d Frame %d, subframeP %d: Toggling Format1 NDI for UE %d (rnti %x/%d) oldNDI %d\n", CC_id, frameP, subframeP, UE_id, rnti, harq_pid, UE_list->UE_template[CC_id][UE_id].oldNDI[harq_pid]); - - UE_list->UE_template[CC_id][UE_id].oldNDI[harq_pid] = 1 - UE_list->UE_template[CC_id][UE_id].oldNDI[harq_pid]; - UE_list->UE_template[CC_id][UE_id].oldmcs1[harq_pid] = mcs; - UE_list->UE_template[CC_id][UE_id].oldmcs2[harq_pid] = 0; - AssertFatal(UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated != NULL, - "physicalConfigDedicated is NULL\n"); - AssertFatal(UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->pdsch_ConfigDedicated != NULL, - "physicalConfigDedicated->pdsch_ConfigDedicated is NULL\n"); - - fill_nfapi_dlsch_config(eNB, dl_req, TBS, eNB->pdu_index[CC_id], rnti, 0, // type 0 allocation from 7.1.6 in 36.213 - 0, // virtual_resource_block_assignment_flag, unused here - 0, // resource_block_coding, to be filled in later - getQm(mcs), 0, // redundancy version - 1, // transport blocks - 0, // transport block to codeword swap flag - cc[CC_id].p_eNB == 1 ? 0 : 1, // transmission_scheme - 1, // number of layers - 1, // number of subbands - // uint8_t codebook_index, - 4, // UE category capacity - UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->pdsch_ConfigDedicated->p_a, 0, // delta_power_offset for TM5 - 0, // ngap - 0, // nprb - cc[CC_id].p_eNB == 1 ? 1 : 2, // transmission mode - 0, //number of PRBs treated as one subband, not used here - 0 // number of beamforming vectors, not used here - ); - eNB->TX_req[CC_id].sfn_sf = fill_nfapi_tx_req(&eNB->TX_req[CC_id].tx_request_body, - (frameP * 10) + subframeP, - TBS, eNB->pdu_index[CC_id], - eNB->UE_list.DLSCH_pdu[CC_id][0][UE_id].payload[0]); - - LOG_D(MAC, - "Filled NFAPI configuration for DCI/DLSCH/TXREQ %d, new SDU\n", - eNB->pdu_index[CC_id]); - - eNB->pdu_index[CC_id]++; - program_dlsch_acknak(module_idP, CC_id, UE_id, - frameP, subframeP, - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.cce_idx); - } else { - LOG_W(MAC, - "Frame %d, Subframe %d: Dropping DLSCH allocation for UE %d/%x, infeasible CCE allocations\n", - frameP, subframeP, UE_id, rnti); - } - } else { // There is no data from RLC or MAC header, so don't schedule - - } + UE_list->UE_template[CC_id][UE_id].oldNDI[harq_pid] = 1 - UE_list->UE_template[CC_id][UE_id].oldNDI[harq_pid]; + UE_list->UE_template[CC_id][UE_id].oldmcs1[harq_pid] = mcs; + UE_list->UE_template[CC_id][UE_id].oldmcs2[harq_pid] = 0; + AssertFatal(UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated != NULL, + "physicalConfigDedicated is NULL\n"); + AssertFatal(UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->pdsch_ConfigDedicated != NULL, + "physicalConfigDedicated->pdsch_ConfigDedicated is NULL\n"); + fill_nfapi_dlsch_config(eNB, dl_req, TBS, eNB->pdu_index[CC_id], rnti, 0, // type 0 allocation from 7.1.6 in 36.213 + 0, // virtual_resource_block_assignment_flag, unused here + 0, // resource_block_coding, to be filled in later + getQm(mcs), 0, // redundancy version + 1, // transport blocks + 0, // transport block to codeword swap flag + cc[CC_id].p_eNB == 1 ? 0 : 1, // transmission_scheme + 1, // number of layers + 1, // number of subbands + // uint8_t codebook_index, + 4, // UE category capacity + UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->pdsch_ConfigDedicated->p_a, 0, // delta_power_offset for TM5 + 0, // ngap + 0, // nprb + cc[CC_id].p_eNB == 1 ? 1 : 2, // transmission mode + 0, //number of PRBs treated as one subband, not used here + 0 // number of beamforming vectors, not used here + ); + eNB->TX_req[CC_id].sfn_sf = fill_nfapi_tx_req(&eNB->TX_req[CC_id].tx_request_body, + (frameP * 10) + subframeP, + TBS, eNB->pdu_index[CC_id], + eNB->UE_list.DLSCH_pdu[CC_id][0][UE_id].payload[0]); + LOG_D(MAC, + "Filled NFAPI configuration for DCI/DLSCH/TXREQ %d, new SDU\n", + eNB->pdu_index[CC_id]); + eNB->pdu_index[CC_id]++; + program_dlsch_acknak(module_idP, CC_id, UE_id, + frameP, subframeP, + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.cce_idx); + } else { + LOG_W(MAC, + "Frame %d, Subframe %d: Dropping DLSCH allocation for UE %d/%x, infeasible CCE allocations\n", + frameP, subframeP, UE_id, rnti); + } + } else { // There is no data from RLC or MAC header, so don't schedule + } } if (cc[CC_id].tdd_Config != NULL) { // TDD set_ul_DAI(module_idP, UE_id, CC_id, frameP, subframeP); } - } // UE_id loop - } // CC_id loop + } // UE_id loop + } // CC_id loop fill_DLSCH_dci(module_idP, frameP, subframeP, mbsfn_flag); - stop_meas(&eNB->schedule_dlsch); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_SCHEDULE_DLSCH, VCD_FUNCTION_OUT); } //------------------------------------------------------------------------------ void dlsch_scheduler_interslice_multiplexing(module_id_t Mod_id, - int frameP, - sub_frame_t subframeP, - uint8_t rballoc_sub[NFAPI_CC_MAX][N_RBG_MAX]) + int frameP, + sub_frame_t subframeP, + uint8_t rballoc_sub[NFAPI_CC_MAX][N_RBG_MAX]) //------------------------------------------------------------------------------ { // FIXME: I'm prototyping the algorithm, so there may be arrays and variables that carry redundant information here and in pre_processor_results struct. - int UE_id, CC_id, rbg, i; int N_RB_DL, min_rb_unit, tm; int owned, used; - UE_list_t *UE_list = &RC.mac[Mod_id]->UE_list; slice_info_t *sli = &RC.mac[Mod_id]->slice_info; UE_sched_ctrl *ue_sched_ctl; COMMON_channels_t *cc; int N_RBG[NFAPI_CC_MAX]; - int slice_sorted_list[MAX_NUM_SLICES]; int slice_idx; int8_t free_rbgs_map[NFAPI_CC_MAX][N_RBG_MAX]; int has_traffic[NFAPI_CC_MAX][MAX_NUM_SLICES]; uint8_t allocation_mask[NFAPI_CC_MAX][N_RBG_MAX]; - uint16_t (*nb_rbs_remaining)[MAX_MOBILES_PER_ENB]; uint16_t (*nb_rbs_required)[MAX_MOBILES_PER_ENB]; uint8_t (*MIMO_mode_indicator)[N_RBG_MAX]; @@ -1488,9 +1439,11 @@ void dlsch_scheduler_interslice_multiplexing(module_id_t Mod_id, for (CC_id = 0; CC_id < RC.nb_mac_CC[Mod_id]; ++CC_id) { cc = &RC.mac[Mod_id]->common_channels[CC_id]; N_RBG[CC_id] = to_rbg(cc->mib->message.dl_Bandwidth); + for (rbg = 0; rbg < N_RBG[CC_id]; ++rbg) { for (i = 0; i < sli->n_dl; ++i) { owned = sli->pre_processor_results[i].slice_allocation_mask[CC_id][rbg]; + if (owned) { used = rballoc_sub[CC_id][rbg]; free_rbgs_map[CC_id][rbg] = used ? -1 : i; @@ -1505,6 +1458,7 @@ void dlsch_scheduler_interslice_multiplexing(module_id_t Mod_id, for (CC_id = 0; CC_id < RC.nb_mac_CC[Mod_id]; ++CC_id) { for (i = 0; i < sli->n_dl; ++i) { has_traffic[CC_id][i] = 0; + for (UE_id = 0; UE_id < MAX_MOBILES_PER_ENB; ++UE_id) { if (sli->pre_processor_results[i].nb_rbs_remaining[CC_id][UE_id] > 0) { has_traffic[CC_id][i] = 1; @@ -1519,7 +1473,6 @@ void dlsch_scheduler_interslice_multiplexing(module_id_t Mod_id, // MULTIPLEXING // This part is an adaptation of dlsch_scheduler_pre_processor_allocate() code for (CC_id = 0; CC_id < RC.nb_mac_CC[Mod_id]; ++CC_id) { - N_RB_DL = to_prb(RC.mac[Mod_id]->common_channels[CC_id].mib->message.dl_Bandwidth); min_rb_unit = get_min_rb_unit(Mod_id, CC_id); @@ -1535,11 +1488,13 @@ void dlsch_scheduler_interslice_multiplexing(module_id_t Mod_id, allocation_mask[CC_id][rbg] = 0; continue; } + if (sli->dl[free_rbgs_map[CC_id][rbg]].isol == 1) { // RBG belongs to an isolated slice allocation_mask[CC_id][rbg] = 0; continue; } + // RBG is free allocation_mask[CC_id][rbg] = 1; } @@ -1548,7 +1503,6 @@ void dlsch_scheduler_interslice_multiplexing(module_id_t Mod_id, // (UE list gets sorted every time pre_processor is called so it is probably dirty at this point) // FIXME: There is only one UE_list for all slices, so it must be sorted again each time we use it sort_UEs(Mod_id, slice_idx, frameP, subframeP); - nb_rbs_remaining = sli->pre_processor_results[slice_idx].nb_rbs_remaining; nb_rbs_required = sli->pre_processor_results[slice_idx].nb_rbs_required; MIMO_mode_indicator = sli->pre_processor_results[slice_idx].MIMO_mode_indicator; @@ -1559,13 +1513,17 @@ void dlsch_scheduler_interslice_multiplexing(module_id_t Mod_id, tm = get_tmode(Mod_id, CC_id, UE_id); for (rbg = 0; rbg < N_RBG[CC_id]; ++rbg) { - // FIXME: I think that some of these checks are redundant if (allocation_mask[CC_id][rbg] == 0) continue; + if (rballoc_sub[CC_id][rbg] != 0) continue; + if (ue_sched_ctl->rballoc_sub_UE[CC_id][rbg] != 0) continue; + if (nb_rbs_remaining[CC_id][UE_id] <= 0) continue; + if (ue_sched_ctl->pre_nb_available_rbs[CC_id] >= nb_rbs_required[CC_id][UE_id]) continue; + if (ue_sched_ctl->dl_pow_off[CC_id] == 0) continue; if ((rbg == N_RBG[CC_id] - 1) && ((N_RB_DL == 25) || (N_RB_DL == 50))) { @@ -1575,9 +1533,11 @@ void dlsch_scheduler_interslice_multiplexing(module_id_t Mod_id, free_rbgs_map[CC_id][rbg] = -1; ue_sched_ctl->rballoc_sub_UE[CC_id][rbg] = 1; MIMO_mode_indicator[CC_id][rbg] = 1; + if (tm == 5) { ue_sched_ctl->dl_pow_off[CC_id] = 1; } + nb_rbs_remaining[CC_id][UE_id] = nb_rbs_remaining[CC_id][UE_id] - min_rb_unit + 1; ue_sched_ctl->pre_nb_available_rbs[CC_id] = ue_sched_ctl->pre_nb_available_rbs[CC_id] + min_rb_unit - 1; } @@ -1588,9 +1548,11 @@ void dlsch_scheduler_interslice_multiplexing(module_id_t Mod_id, free_rbgs_map[CC_id][rbg] = -1; ue_sched_ctl->rballoc_sub_UE[CC_id][rbg] = 1; MIMO_mode_indicator[CC_id][rbg] = 1; + if (tm == 5) { ue_sched_ctl->dl_pow_off[CC_id] = 1; } + nb_rbs_remaining[CC_id][UE_id] = nb_rbs_remaining[CC_id][UE_id] - min_rb_unit; ue_sched_ctl->pre_nb_available_rbs[CC_id] = ue_sched_ctl->pre_nb_available_rbs[CC_id] + min_rb_unit; } @@ -1612,14 +1574,12 @@ void dlsch_scheduler_qos_multiplexing(module_id_t Mod_id, int frameP, sub_frame_ for (CC_id = 0; CC_id < RC.nb_mac_CC[Mod_id]; ++CC_id) { for (i = 0; i < sli->n_dl; ++i) { - // Sort UE again // FIXME: There is only one UE_list for all slices, so it must be sorted again each time we use it sort_UEs(Mod_id, (uint8_t)i, frameP, subframeP); for (UE_id = UE_list->head; UE_id >= 0; UE_id = UE_list->next[UE_id]) { //ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; - // TODO: Do something here // ue_sched_ctl->pre_nb_available_rbs[CC_id]; } @@ -1634,7 +1594,6 @@ fill_DLSCH_dci(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP, int *mbsfn_flagP) //------------------------------------------------------------------------------ { - // loop over all allocated UEs and compute frequency allocations for PDSCH int UE_id = -1; uint8_t /* first_rb, */ nb_rb = 3; @@ -1642,7 +1601,6 @@ fill_DLSCH_dci(module_id_t module_idP, //unsigned char *vrb_map; uint8_t rballoc_sub[25]; //uint8_t number_of_subbands=13; - //unsigned char round; unsigned char harq_pid; int i; @@ -1652,7 +1610,6 @@ fill_DLSCH_dci(module_id_t module_idP, int N_RBG; int N_RB_DL; COMMON_channels_t *cc; - start_meas(&eNB->fill_DLSCH_dci); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME (VCD_SIGNAL_DUMPER_FUNCTIONS_FILL_DLSCH_DCI, VCD_FUNCTION_IN); @@ -1674,11 +1631,10 @@ fill_DLSCH_dci(module_id_t module_idP, eNB_dlsch_info[module_idP][CC_id][UE_id].status); if (eNB_dlsch_info[module_idP][CC_id][UE_id].status == S_DL_SCHEDULED) { - // clear scheduling flag eNB_dlsch_info[module_idP][CC_id][UE_id].status = S_DL_WAITING; rnti = UE_RNTI(module_idP, UE_id); - harq_pid = frame_subframe2_dl_harq_pid(cc->tdd_Config,frameP ,subframeP); + harq_pid = frame_subframe2_dl_harq_pid(cc->tdd_Config,frameP,subframeP); nb_rb = UE_list->UE_template[CC_id][UE_id].nb_rb[harq_pid]; /// Synchronizing rballoc with rballoc_sub @@ -1693,22 +1649,22 @@ fill_DLSCH_dci(module_id_t module_idP, i < DL_req[CC_id].dl_config_request_body.number_pdu; i++) { dl_config_pdu = &DL_req[CC_id].dl_config_request_body.dl_config_pdu_list[i]; + if ((dl_config_pdu->pdu_type == NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE) && (dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti == rnti) && (dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.dci_format != 1)) { dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.resource_block_coding = allocate_prbs_sub(nb_rb, N_RB_DL, N_RBG, - rballoc_sub); + rballoc_sub); dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.resource_allocation_type = 0; } else if ((dl_config_pdu->pdu_type == NFAPI_DL_CONFIG_DLSCH_PDU_TYPE) && (dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.rnti == rnti) && (dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_allocation_type == 0)) { dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_block_coding = allocate_prbs_sub(nb_rb, N_RB_DL, N_RBG, - rballoc_sub); + rballoc_sub); } } } } - } stop_meas(&eNB->fill_DLSCH_dci); @@ -1721,20 +1677,17 @@ unsigned char *get_dlsch_sdu(module_id_t module_idP, uint8_t TBindex) //------------------------------------------------------------------------------ { - int UE_id; eNB_MAC_INST *eNB = RC.mac[module_idP]; if (rntiP == SI_RNTI) { LOG_D(MAC, "[eNB %d] CC_id %d Frame %d Get DLSCH sdu for BCCH \n", module_idP, CC_id, frameP); - return ((unsigned char *) &eNB->common_channels[CC_id].BCCH_pdu.payload[0]); } if (rntiP == P_RNTI) { LOG_D(MAC, "[eNB %d] CC_id %d Frame %d Get PCH sdu for PCCH \n", module_idP, CC_id, frameP); - return ((unsigned char *) &eNB->common_channels[CC_id].PCCH_pdu.payload[0]); } @@ -1751,34 +1704,29 @@ unsigned char *get_dlsch_sdu(module_id_t module_idP, module_idP, frameP, CC_id, rntiP); return NULL; } - } //------------------------------------------------------------------------------ void update_ul_dci(module_id_t module_idP, - uint8_t CC_idP, rnti_t rntiP, uint8_t daiP, sub_frame_t subframe) + uint8_t CC_idP, rnti_t rntiP, uint8_t daiP, sub_frame_t subframe) //------------------------------------------------------------------------------ { - nfapi_hi_dci0_request_t *HI_DCI0_req = &RC.mac[module_idP]->HI_DCI0_req[CC_idP][subframe]; nfapi_hi_dci0_request_pdu_t *hi_dci0_pdu = - &HI_DCI0_req->hi_dci0_request_body.hi_dci0_pdu_list[0]; + &HI_DCI0_req->hi_dci0_request_body.hi_dci0_pdu_list[0]; COMMON_channels_t *cc = &RC.mac[module_idP]->common_channels[CC_idP]; int i; - - if (cc->tdd_Config != NULL) { // TDD + if (cc->tdd_Config != NULL) { // TDD for (i = 0; - i hi_dci0_request_body.number_of_dci + HI_DCI0_req->hi_dci0_request_body.number_of_hi; - i++) { - + i hi_dci0_request_body.number_of_dci + HI_DCI0_req->hi_dci0_request_body.number_of_hi; + i++) { if ((hi_dci0_pdu[i].pdu_type == NFAPI_HI_DCI0_DCI_PDU_TYPE) && (hi_dci0_pdu[i].dci_pdu.dci_pdu_rel8.rnti == rntiP)) hi_dci0_pdu[i].dci_pdu.dci_pdu_rel8.dl_assignment_index = (daiP - 1) & 3; - } } } @@ -1884,7 +1832,6 @@ void schedule_PCH(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP) uint8_t Lcrbs = 0; uint16_t rb_bit = 168; /* RB bit number value is unsure */ #endif - start_meas(&eNB->schedule_pch); for (CC_id = 0; CC_id < RC.nb_mac_CC[module_idP]; CC_id++) { @@ -1892,10 +1839,12 @@ void schedule_PCH(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP) vrb_map = (void *) &cc->vrb_map; n_rb_dl = to_prb(cc->mib->message.dl_Bandwidth); dl_req = &eNB->DL_req[CC_id].dl_config_request_body; + for (uint16_t i = 0; i < MAX_MOBILES_PER_ENB; i++) { if (UE_PF_PO[CC_id][i].enable_flag != TRUE) { continue; } + if (frameP % UE_PF_PO[CC_id][i].T == UE_PF_PO[CC_id][i].PF_min && subframeP == UE_PF_PO[CC_id][i].PO) { pcch_sdu_length = mac_rrc_data_req(module_idP, CC_id, @@ -1903,140 +1852,166 @@ void schedule_PCH(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP) PCCH, 1, &cc->PCCH_pdu.payload[0], i); // used for ue index + if (pcch_sdu_length == 0) { LOG_D(MAC, "[eNB %d] Frame %d subframe %d: PCCH not active(size = 0 byte)\n", module_idP, frameP, subframeP); continue; } + LOG_D(MAC, "[eNB %d] Frame %d subframe %d: PCCH->PCH CC_id %d UE_id %d, Received %d bytes \n", module_idP, frameP, subframeP, CC_id, i, pcch_sdu_length); #ifdef FORMAT1C - //NO SIB - if ((subframeP == 0 || subframeP == 1 || subframeP == 2 || subframeP == 4 || subframeP == 6 || subframeP == 9) || - (subframeP == 5 && ((frameP % 2) != 0 && (frameP % 8) != 1))) { - switch (n_rb_dl) { - case 25: - n_gap = GAP_MAP[3][0]; /* expect: 12 */ - n_vrb_dl = 2*((n_gap < (n_rb_dl - n_gap)) ? n_gap : (n_rb_dl - n_gap)); /* expect: 24 */ - first_rb = 10; - break; - case 50: - n_gap = GAP_MAP[6][gap_index]; /* expect: 27 or 9 */ - if (gap_index > 0) { - n_vrb_dl = (n_rb_dl / (2*n_gap)) * (2*n_gap); /* 36 */ - } else { - n_vrb_dl = 2*((n_gap < (n_rb_dl - n_gap)) ? n_gap : (n_rb_dl - n_gap)); /* expect: 46 */ - } - first_rb = 24; - break; - case 100: - n_gap = GAP_MAP[8][gap_index]; /* expect: 48 or 16 */ - if (gap_index > 0) { - n_vrb_dl = (n_rb_dl / (2*n_gap)) * (2*n_gap); /* expect: 96 */ - } else { - n_vrb_dl = 2*((n_gap < (n_rb_dl - n_gap)) ? n_gap : (n_rb_dl - n_gap)); /* expect: 96 */ - } - first_rb = 48; - break; - } - } else if (subframeP == 5 && ((frameP % 2) == 0 || (frameP % 8) == 1)) { // SIB + paging - switch (n_rb_dl) { - case 25: - n_gap = GAP_MAP[3][0]; /* expect: 12 */ - n_vrb_dl = 2*((n_gap < (n_rb_dl - n_gap)) ? n_gap : (n_rb_dl - n_gap)); /* expect: 24 */ - first_rb = 14; - break; - case 50: - n_gap = GAP_MAP[6][gap_index]; /* expect: 27 or 9 */ - if (gap_index > 0) { - n_vrb_dl = (n_rb_dl / (2*n_gap)) * (2*n_gap); /* 36 */ - } else { - n_vrb_dl = 2*((n_gap < (n_rb_dl - n_gap)) ? n_gap : (n_rb_dl - n_gap)); /* expect: 46 */ - } - first_rb = 28; - break; - case 100: - n_gap = GAP_MAP[8][gap_index]; /* expect: 48 or 16 */ - if (gap_index > 0) { - n_vrb_dl = (n_rb_dl / (2*n_gap)) * (2*n_gap); /* expect: 96 */ - } else { - n_vrb_dl = 2*((n_gap < (n_rb_dl - n_gap)) ? n_gap : (n_rb_dl - n_gap)); /* expect: 96 */ - } - first_rb = 52; - break; - } - } - /* Get MCS for length of PCH */ - if (pcch_sdu_length <= TBStable1C[0]) { - mcs=0; - } else if (pcch_sdu_length <= TBStable1C[1]) { - mcs=1; - } else if (pcch_sdu_length <= TBStable1C[2]) { - mcs=2; - } else if (pcch_sdu_length <= TBStable1C[3]) { - mcs=3; - } else if (pcch_sdu_length <= TBStable1C[4]) { - mcs=4; - } else if (pcch_sdu_length <= TBStable1C[5]) { - mcs=5; - } else if (pcch_sdu_length <= TBStable1C[6]) { - mcs=6; - } else if (pcch_sdu_length <= TBStable1C[7]) { - mcs=7; - } else if (pcch_sdu_length <= TBStable1C[8]) { - mcs=8; - } else if (pcch_sdu_length <= TBStable1C[9]) { - mcs=9; - } else { - /* unexpected: pcch sdb size is over max value*/ - LOG_E(MAC,"[eNB %d] Frame %d : PCCH->PCH CC_id %d, Received %d bytes is over max length(256) \n", - module_idP, frameP,CC_id, pcch_sdu_length); - return; - } - rb_num = TBStable1C[mcs] / rb_bit + ( (TBStable1C[mcs] % rb_bit == 0)? 0: 1) + 1; - /* calculate N_RB_STEP and Lcrbs */ - if (n_rb_dl < 50) { - n_rb_step = 2; - Lcrbs = rb_num / 2 + ((rb_num % 2 == 0) ? 0:2); - } else { - n_rb_step = 4; - Lcrbs = rb_num / 4 + ((rb_num % 4 == 0) ? 0:4); - } - for(i = 0;i < Lcrbs ;i++){ - vrb_map[first_rb+i] = 1; - } + + //NO SIB + if ((subframeP == 0 || subframeP == 1 || subframeP == 2 || subframeP == 4 || subframeP == 6 || subframeP == 9) || + (subframeP == 5 && ((frameP % 2) != 0 && (frameP % 8) != 1))) { + switch (n_rb_dl) { + case 25: + n_gap = GAP_MAP[3][0]; /* expect: 12 */ + n_vrb_dl = 2*((n_gap < (n_rb_dl - n_gap)) ? n_gap : (n_rb_dl - n_gap)); /* expect: 24 */ + first_rb = 10; + break; + + case 50: + n_gap = GAP_MAP[6][gap_index]; /* expect: 27 or 9 */ + + if (gap_index > 0) { + n_vrb_dl = (n_rb_dl / (2*n_gap)) * (2*n_gap); /* 36 */ + } else { + n_vrb_dl = 2*((n_gap < (n_rb_dl - n_gap)) ? n_gap : (n_rb_dl - n_gap)); /* expect: 46 */ + } + + first_rb = 24; + break; + + case 100: + n_gap = GAP_MAP[8][gap_index]; /* expect: 48 or 16 */ + + if (gap_index > 0) { + n_vrb_dl = (n_rb_dl / (2*n_gap)) * (2*n_gap); /* expect: 96 */ + } else { + n_vrb_dl = 2*((n_gap < (n_rb_dl - n_gap)) ? n_gap : (n_rb_dl - n_gap)); /* expect: 96 */ + } + + first_rb = 48; + break; + } + } else if (subframeP == 5 && ((frameP % 2) == 0 || (frameP % 8) == 1)) { // SIB + paging + switch (n_rb_dl) { + case 25: + n_gap = GAP_MAP[3][0]; /* expect: 12 */ + n_vrb_dl = 2*((n_gap < (n_rb_dl - n_gap)) ? n_gap : (n_rb_dl - n_gap)); /* expect: 24 */ + first_rb = 14; + break; + + case 50: + n_gap = GAP_MAP[6][gap_index]; /* expect: 27 or 9 */ + + if (gap_index > 0) { + n_vrb_dl = (n_rb_dl / (2*n_gap)) * (2*n_gap); /* 36 */ + } else { + n_vrb_dl = 2*((n_gap < (n_rb_dl - n_gap)) ? n_gap : (n_rb_dl - n_gap)); /* expect: 46 */ + } + + first_rb = 28; + break; + + case 100: + n_gap = GAP_MAP[8][gap_index]; /* expect: 48 or 16 */ + + if (gap_index > 0) { + n_vrb_dl = (n_rb_dl / (2*n_gap)) * (2*n_gap); /* expect: 96 */ + } else { + n_vrb_dl = 2*((n_gap < (n_rb_dl - n_gap)) ? n_gap : (n_rb_dl - n_gap)); /* expect: 96 */ + } + + first_rb = 52; + break; + } + } + + /* Get MCS for length of PCH */ + if (pcch_sdu_length <= TBStable1C[0]) { + mcs=0; + } else if (pcch_sdu_length <= TBStable1C[1]) { + mcs=1; + } else if (pcch_sdu_length <= TBStable1C[2]) { + mcs=2; + } else if (pcch_sdu_length <= TBStable1C[3]) { + mcs=3; + } else if (pcch_sdu_length <= TBStable1C[4]) { + mcs=4; + } else if (pcch_sdu_length <= TBStable1C[5]) { + mcs=5; + } else if (pcch_sdu_length <= TBStable1C[6]) { + mcs=6; + } else if (pcch_sdu_length <= TBStable1C[7]) { + mcs=7; + } else if (pcch_sdu_length <= TBStable1C[8]) { + mcs=8; + } else if (pcch_sdu_length <= TBStable1C[9]) { + mcs=9; + } else { + /* unexpected: pcch sdb size is over max value*/ + LOG_E(MAC,"[eNB %d] Frame %d : PCCH->PCH CC_id %d, Received %d bytes is over max length(256) \n", + module_idP, frameP,CC_id, pcch_sdu_length); + return; + } + + rb_num = TBStable1C[mcs] / rb_bit + ( (TBStable1C[mcs] % rb_bit == 0)? 0: 1) + 1; + + /* calculate N_RB_STEP and Lcrbs */ + if (n_rb_dl < 50) { + n_rb_step = 2; + Lcrbs = rb_num / 2 + ((rb_num % 2 == 0) ? 0:2); + } else { + n_rb_step = 4; + Lcrbs = rb_num / 4 + ((rb_num % 4 == 0) ? 0:4); + } + + for(i = 0; i < Lcrbs ; i++) { + vrb_map[first_rb+i] = 1; + } + #else - //NO SIB - if ((subframeP == 0 || subframeP == 1 || subframeP == 2 || subframeP == 4 || subframeP == 6 || subframeP == 9) || - (subframeP == 5 && ((frameP % 2) != 0 && (frameP % 8) != 1))) { - switch (n_rb_dl) { - case 25: - first_rb = 10; - break; - case 50: - first_rb = 24; - break; - case 100: - first_rb = 48; - break; - } - } else if (subframeP == 5 && ((frameP % 2) == 0 || (frameP % 8) == 1)) { // SIB + paging - switch (n_rb_dl) { - case 25: - first_rb = 14; - break; - case 50: - first_rb = 28; - break; - case 100: - first_rb = 52; - break; - } - } + + //NO SIB + if ((subframeP == 0 || subframeP == 1 || subframeP == 2 || subframeP == 4 || subframeP == 6 || subframeP == 9) || + (subframeP == 5 && ((frameP % 2) != 0 && (frameP % 8) != 1))) { + switch (n_rb_dl) { + case 25: + first_rb = 10; + break; + + case 50: + first_rb = 24; + break; + + case 100: + first_rb = 48; + break; + } + } else if (subframeP == 5 && ((frameP % 2) == 0 || (frameP % 8) == 1)) { // SIB + paging + switch (n_rb_dl) { + case 25: + first_rb = 14; + break; + + case 50: + first_rb = 28; + break; + + case 100: + first_rb = 52; + break; + } + } vrb_map[first_rb] = 1; vrb_map[first_rb + 1] = 1; vrb_map[first_rb + 2] = 1; vrb_map[first_rb + 3] = 1; + /* Get MCS for length of PCH */ if (pcch_sdu_length <= get_TBS_DL(0, 3)) { mcs = 0; @@ -2059,6 +2034,7 @@ void schedule_PCH(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP) } else if (pcch_sdu_length <= get_TBS_DL(9, 3)) { mcs = 9; } + #endif dl_config_pdu = &dl_req->dl_config_pdu_list[dl_req->number_pdu]; memset((void *) dl_config_pdu, 0, sizeof(nfapi_dl_config_request_pdu_t)); @@ -2083,20 +2059,19 @@ void schedule_PCH(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP) dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.transmission_power = 6000; // equal to RS power dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.mcs_1 = mcs; - if (!CCE_allocation_infeasible(module_idP, CC_id, 0, subframeP, dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level, P_RNTI)) { - LOG_D(MAC,"Frame %d: Subframe %d : Adding common DCI for P_RNTI\n", frameP,subframeP); - dl_req->number_dci++; - dl_req->number_pdu++; + if (!CCE_allocation_infeasible(module_idP, CC_id, 0, subframeP, dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level, P_RNTI)) { + LOG_D(MAC,"Frame %d: Subframe %d : Adding common DCI for P_RNTI\n", frameP,subframeP); + dl_req->number_dci++; + dl_req->number_pdu++; dl_req->tl.tag = NFAPI_DL_CONFIG_REQUEST_BODY_TAG; eNB->DL_req[CC_id].sfn_sf = frameP<<4 | subframeP; eNB->DL_req[CC_id].header.message_id = NFAPI_DL_CONFIG_REQUEST; - - dl_config_pdu = &dl_req->dl_config_pdu_list[dl_req->number_pdu]; - memset((void*)dl_config_pdu,0,sizeof(nfapi_dl_config_request_pdu_t)); - dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_DLSCH_PDU_TYPE; - dl_config_pdu->pdu_size = (uint8_t)(2+sizeof(nfapi_dl_config_dlsch_pdu)); - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pdu_index = eNB->pdu_index[CC_id]; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.rnti = 0xFFFE; + dl_config_pdu = &dl_req->dl_config_pdu_list[dl_req->number_pdu]; + memset((void *)dl_config_pdu,0,sizeof(nfapi_dl_config_request_pdu_t)); + dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_DLSCH_PDU_TYPE; + dl_config_pdu->pdu_size = (uint8_t)(2+sizeof(nfapi_dl_config_dlsch_pdu)); + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pdu_index = eNB->pdu_index[CC_id]; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.rnti = 0xFFFE; #ifdef FORMAT1C dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_allocation_type = 3; // format 1C dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_block_coding = getRIV(n_vrb_dl/n_rb_step, first_rb/n_rb_step, Lcrbs/n_rb_step); @@ -2105,86 +2080,83 @@ void schedule_PCH(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP) dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_block_coding = getRIV(n_rb_dl, first_rb, 4); dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.virtual_resource_block_assignment_flag = 0; // localized #endif - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.modulation = 2; //QPSK - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.redundancy_version = 1; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transport_blocks = 1;// first block - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transport_block_to_codeword_swap_flag = 0; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transmission_scheme = (cc->p_eNB==1 ) ? 0 : 1; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.number_of_layers = 1; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.number_of_subbands = 1; - // dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.codebook_index = ; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.ue_category_capacity = 1; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pa = 4; // 0 dB - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.delta_power_offset_index = 0; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.ngap = 0; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.nprb = get_subbandsize(cc->mib->message.dl_Bandwidth); // ignored - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transmission_mode = (cc->p_eNB==1 ) ? 1 : 2; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.num_bf_prb_per_subband = 1; - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.num_bf_vector = 1; - // dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.bf_vector = ; - - // Rel10 fields + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.modulation = 2; //QPSK + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.redundancy_version = 1; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transport_blocks = 1;// first block + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transport_block_to_codeword_swap_flag = 0; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transmission_scheme = (cc->p_eNB==1 ) ? 0 : 1; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.number_of_layers = 1; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.number_of_subbands = 1; + // dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.codebook_index = ; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.ue_category_capacity = 1; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.pa = 4; // 0 dB + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.delta_power_offset_index = 0; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.ngap = 0; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.nprb = get_subbandsize(cc->mib->message.dl_Bandwidth); // ignored + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transmission_mode = (cc->p_eNB==1 ) ? 1 : 2; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.num_bf_prb_per_subband = 1; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.num_bf_vector = 1; + // dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.bf_vector = ; + // Rel10 fields #if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel10.pdsch_start = 3; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel10.pdsch_start = 3; #endif - // Rel13 fields + // Rel13 fields #if (LTE_RRC_VERSION >= MAKE_VERSION(13, 0, 0)) - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.ue_type = 0; // regular UE - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.pdsch_payload_type = 2; // not BR - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.initial_transmission_sf_io = 0xFFFF; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.ue_type = 0; // regular UE + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.pdsch_payload_type = 2; // not BR + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.initial_transmission_sf_io = 0xFFFF; #endif - - dl_req->number_pdu++; - - eNB->TX_req[CC_id].sfn_sf = (frameP<<4)+subframeP; - TX_req = &eNB->TX_req[CC_id].tx_request_body.tx_pdu_list[eNB->TX_req[CC_id].tx_request_body.number_of_pdus]; - TX_req->pdu_length = pcch_sdu_length; - TX_req->pdu_index = eNB->pdu_index[CC_id]++; - TX_req->num_segments = 1; - TX_req->segments[0].segment_length = pcch_sdu_length; - TX_req->segments[0].segment_data = cc[CC_id].PCCH_pdu.payload; + dl_req->number_pdu++; + eNB->TX_req[CC_id].sfn_sf = (frameP<<4)+subframeP; + TX_req = &eNB->TX_req[CC_id].tx_request_body.tx_pdu_list[eNB->TX_req[CC_id].tx_request_body.number_of_pdus]; + TX_req->pdu_length = pcch_sdu_length; + TX_req->pdu_index = eNB->pdu_index[CC_id]++; + TX_req->num_segments = 1; + TX_req->segments[0].segment_length = pcch_sdu_length; + TX_req->segments[0].segment_data = cc[CC_id].PCCH_pdu.payload; eNB->TX_req[CC_id].tx_request_body.tl.tag = NFAPI_TX_REQUEST_BODY_TAG; - eNB->TX_req[CC_id].tx_request_body.number_of_pdus++; - } else { - LOG_E(MAC,"[eNB %d] CCid %d Frame %d, subframe %d : Cannot add DCI 1A/1C for Paging\n",module_idP, CC_id, frameP, subframeP); - continue; - } + eNB->TX_req[CC_id].tx_request_body.number_of_pdus++; + } else { + LOG_E(MAC,"[eNB %d] CCid %d Frame %d, subframe %d : Cannot add DCI 1A/1C for Paging\n",module_idP, CC_id, frameP, subframeP); + continue; + } - if (opt_enabled == 1) { - trace_pdu(DIRECTION_DOWNLINK, - &eNB->common_channels[CC_id].PCCH_pdu.payload[0], - pcch_sdu_length, - 0xffff, - PCCH, - P_RNTI, - eNB->frame, - eNB->subframe, - 0, - 0); - LOG_D(OPT,"[eNB %d][PCH] Frame %d trace pdu for CC_id %d rnti %x with size %d\n", - module_idP, frameP, CC_id, 0xffff, pcch_sdu_length); - } - eNB->eNB_stats[CC_id].total_num_pcch_pdu+=1; - eNB->eNB_stats[CC_id].pcch_buffer=pcch_sdu_length; - eNB->eNB_stats[CC_id].total_pcch_buffer+=pcch_sdu_length; - eNB->eNB_stats[CC_id].pcch_mcs=mcs; - //paging first_rb log - LOG_D(MAC,"[eNB %d] Frame %d subframe %d PCH: paging_ue_index %d pcch_sdu_length %d mcs %d first_rb %d\n", - module_idP, frameP, subframeP, UE_PF_PO[CC_id][i].ue_index_value, pcch_sdu_length, mcs, first_rb); + if (opt_enabled == 1) { + trace_pdu(DIRECTION_DOWNLINK, + &eNB->common_channels[CC_id].PCCH_pdu.payload[0], + pcch_sdu_length, + 0xffff, + PCCH, + P_RNTI, + eNB->frame, + eNB->subframe, + 0, + 0); + LOG_D(OPT,"[eNB %d][PCH] Frame %d trace pdu for CC_id %d rnti %x with size %d\n", + module_idP, frameP, CC_id, 0xffff, pcch_sdu_length); + } - pthread_mutex_lock(&ue_pf_po_mutex); - memset(&UE_PF_PO[CC_id][i], 0, sizeof(UE_PF_PO_t)); - pthread_mutex_unlock(&ue_pf_po_mutex); + eNB->eNB_stats[CC_id].total_num_pcch_pdu+=1; + eNB->eNB_stats[CC_id].pcch_buffer=pcch_sdu_length; + eNB->eNB_stats[CC_id].total_pcch_buffer+=pcch_sdu_length; + eNB->eNB_stats[CC_id].pcch_mcs=mcs; + //paging first_rb log + LOG_D(MAC,"[eNB %d] Frame %d subframe %d PCH: paging_ue_index %d pcch_sdu_length %d mcs %d first_rb %d\n", + module_idP, frameP, subframeP, UE_PF_PO[CC_id][i].ue_index_value, pcch_sdu_length, mcs, first_rb); + pthread_mutex_lock(&ue_pf_po_mutex); + memset(&UE_PF_PO[CC_id][i], 0, sizeof(UE_PF_PO_t)); + pthread_mutex_unlock(&ue_pf_po_mutex); } } } + /* this might be misleading when pcch is inactive */ stop_meas(&eNB->schedule_pch); return; } -static int slice_priority_compare(const void *_a, const void *_b, void *_c) -{ +static int slice_priority_compare(const void *_a, const void *_b, void *_c) { const int slice_id1 = *(const int *) _a; const int slice_id2 = *(const int *) _b; const module_id_t Mod_id = *(int *) _c; @@ -2193,12 +2165,13 @@ static int slice_priority_compare(const void *_a, const void *_b, void *_c) if (sli->dl[slice_id1].prio > sli->dl[slice_id2].prio) { return -1; } + return 1; } -void slice_priority_sort(module_id_t Mod_id, int slice_list[MAX_NUM_SLICES]) -{ +void slice_priority_sort(module_id_t Mod_id, int slice_list[MAX_NUM_SLICES]) { int i; + for (i = 0; i < RC.mac[Mod_id]->slice_info.n_dl; ++i) { slice_list[i] = i; } diff --git a/openair2/LAYER2/MAC/eNB_scheduler_fairRR.c b/openair2/LAYER2/MAC/eNB_scheduler_fairRR.c index 4e718456f5..61617f1bb9 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_fairRR.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_fairRR.c @@ -51,8 +51,8 @@ extern uint8_t nfapi_mode; #ifdef PHY_TX_THREAD -extern volatile int16_t phy_tx_txdataF_end; -extern int oai_exit; + extern volatile int16_t phy_tx_txdataF_end; + extern int oai_exit; #endif extern uint16_t sfnsf_add_subframe(uint16_t frameP, uint16_t subframeP, int offset); extern void add_subframe(uint16_t *frameP, uint16_t *subframeP, int offset); @@ -63,11 +63,11 @@ int last_dlsch_ue_id[MAX_NUM_CCs] = {-1}; int last_ulsch_ue_id[MAX_NUM_CCs] = {-1}; #if defined(PRE_SCD_THREAD) -uint16_t pre_nb_rbs_required[2][MAX_NUM_CCs][NUMBER_OF_UE_MAX]; -uint8_t dlsch_ue_select_tbl_in_use; -uint8_t new_dlsch_ue_select_tbl_in_use; -boolean_t pre_scd_activeUE[NUMBER_OF_UE_MAX]; -eNB_UE_STATS pre_scd_eNB_UE_stats[MAX_NUM_CCs][NUMBER_OF_UE_MAX]; + uint16_t pre_nb_rbs_required[2][MAX_NUM_CCs][NUMBER_OF_UE_MAX]; + uint8_t dlsch_ue_select_tbl_in_use; + uint8_t new_dlsch_ue_select_tbl_in_use; + boolean_t pre_scd_activeUE[NUMBER_OF_UE_MAX]; + eNB_UE_STATS pre_scd_eNB_UE_stats[MAX_NUM_CCs][NUMBER_OF_UE_MAX]; #endif #define DEBUG_eNB_SCHEDULER 1 @@ -89,92 +89,92 @@ void set_dl_ue_select_msg4(int CC_idP, uint16_t nb_rb, int UE_id, rnti_t rnti) { dlsch_ue_select[CC_idP].ue_num++; } #if defined(PRE_SCD_THREAD) -inline uint16_t search_rbs_required(uint16_t mcs, uint16_t TBS,uint16_t NB_RB, uint16_t step_size){ +inline uint16_t search_rbs_required(uint16_t mcs, uint16_t TBS,uint16_t NB_RB, uint16_t step_size) { uint16_t nb_rb,i_TBS,tmp_TBS; i_TBS=get_I_TBS(mcs); - for(nb_rb=step_size;nb_rb>3; + if(TBScommon_channels[CC_id].mib->message.dl_Bandwidth); - if(N_RB_DL==50) step_size=3; - if(N_RB_DL==100) step_size=4; - memset(nb_rbs_required, 0, sizeof(uint16_t)*MAX_NUM_CCs*NUMBER_OF_UE_MAX); - UE_list_t *UE_list = &RC.mac[module_idP]->UE_list; + uint16_t nb_rbs_required[MAX_NUM_CCs][NUMBER_OF_UE_MAX]) { + int CC_id=0,UE_id, lc_id, N_RB_DL; + UE_TEMPLATE UE_template; + eNB_UE_STATS *eNB_UE_stats; + rnti_t rnti; + mac_rlc_status_resp_t rlc_status; + uint16_t step_size=2; + N_RB_DL = to_prb(RC.mac[module_idP]->common_channels[CC_id].mib->message.dl_Bandwidth); - for (UE_id = 0; UE_id UE_list; - rnti = UE_RNTI(module_idP, UE_id); + for (UE_id = 0; UE_id = MAKE_VERSION(14, 0, 0)) - ,0, 0 + ,0, 0 #endif - ); - UE_template.dl_buffer_total += rlc_status.bytes_in_buffer; //storing the total dlsch buffer - } - // end of store dlsch buffer - - // assgin rbs required - // Calculate the number of RBs required by each UE on the basis of logical channel's buffer - //update CQI information across component carriers - eNB_UE_stats = &pre_scd_eNB_UE_stats[CC_id][UE_id]; - - eNB_UE_stats->dlsch_mcs1 = cqi_to_mcs[UE_list->UE_sched_ctrl[UE_id].dl_cqi[CC_id]]; - - - if (UE_template.dl_buffer_total > 0) { - nb_rbs_required[CC_id][UE_id] = search_rbs_required(eNB_UE_stats->dlsch_mcs1, UE_template.dl_buffer_total, N_RB_DL, step_size); - } + ); + UE_template.dl_buffer_total += rlc_status.bytes_in_buffer; //storing the total dlsch buffer } + + // end of store dlsch buffer + // assgin rbs required + // Calculate the number of RBs required by each UE on the basis of logical channel's buffer + //update CQI information across component carriers + eNB_UE_stats = &pre_scd_eNB_UE_stats[CC_id][UE_id]; + eNB_UE_stats->dlsch_mcs1 = cqi_to_mcs[UE_list->UE_sched_ctrl[UE_id].dl_cqi[CC_id]]; + + if (UE_template.dl_buffer_total > 0) { + nb_rbs_required[CC_id][UE_id] = search_rbs_required(eNB_UE_stats->dlsch_mcs1, UE_template.dl_buffer_total, N_RB_DL, step_size); + } + } } #endif -int cc_id_end(uint8_t *cc_id_flag ) -{ +int cc_id_end(uint8_t *cc_id_flag ) { int end_flag = 1; - for (int CC_id=0;CC_idcommon_channels; UE_list_t *UE_list = &eNB->UE_list; @@ -196,7 +196,6 @@ void dlsch_scheduler_pre_ue_select_fairRR( // Initialization for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { dlsch_ue_max_num[CC_id] = (uint16_t)RC.rrc[module_idP]->configuration.ue_multiple_max[CC_id]; - // save origin DL PDU number DL_req = &eNB->DL_req[CC_id].dl_config_request_body; saved_dlsch_dci[CC_id] = DL_req->number_pdu; @@ -209,60 +208,66 @@ void dlsch_scheduler_pre_ue_select_fairRR( } DL_req = &eNB->DL_req[CC_id].dl_config_request_body; + for (UE_id = 0; UE_id < NUMBER_OF_UE_MAX; UE_id++) { if (UE_list->active[UE_id] == FALSE) { continue; } rnti = UE_RNTI(module_idP, UE_id); + if (rnti == NOT_A_RNTI) { continue; } - if(mac_eNB_get_rrc_status(module_idP,rnti) < RRC_CONNECTED){ + if(mac_eNB_get_rrc_status(module_idP,rnti) < RRC_CONNECTED) { continue; } ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; - harq_pid = frame_subframe2_dl_harq_pid(cc[CC_id].tdd_Config,frameP ,subframeP); - + harq_pid = frame_subframe2_dl_harq_pid(cc[CC_id].tdd_Config,frameP,subframeP); round = ue_sched_ctl->round[CC_id][harq_pid]; + if (round != 8) { // retransmission - if(UE_list->UE_template[CC_id][UE_id].nb_rb[harq_pid] == 0){ + if(UE_list->UE_template[CC_id][UE_id].nb_rb[harq_pid] == 0) { continue; } + switch (get_tmode(module_idP, CC_id, UE_id)) { case 1: case 2: case 7: aggregation = get_aggregation(get_bw_index(module_idP, CC_id), - ue_sched_ctl->dl_cqi[CC_id], - format1); + ue_sched_ctl->dl_cqi[CC_id], + format1); break; + case 3: aggregation = get_aggregation(get_bw_index(module_idP,CC_id), - ue_sched_ctl->dl_cqi[CC_id], - format2A); + ue_sched_ctl->dl_cqi[CC_id], + format2A); break; + default: LOG_W(MAC,"Unsupported transmission mode %d\n", get_tmode(module_idP,CC_id,UE_id)); aggregation = 2; break; } + format_flag = 1; + if (!CCE_allocation_infeasible(module_idP, - CC_id, - format_flag, - subframeP, - aggregation, - rnti)) { + CC_id, + format_flag, + subframeP, + aggregation, + rnti)) { dl_config_pdu = &DL_req->dl_config_pdu_list[DL_req->number_pdu]; dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE; dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti = rnti; dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti_type = (format_flag == 0)?2:1; dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level = aggregation; DL_req->number_pdu++; - nb_rbs_required[CC_id][UE_id] = UE_list->UE_template[CC_id][UE_id].nb_rb[harq_pid]; // Insert DLSCH(retransmission) UE into selected UE list dlsch_ue_select[CC_id].list[dlsch_ue_select[CC_id].ue_num].UE_id = UE_id; @@ -270,6 +275,7 @@ void dlsch_scheduler_pre_ue_select_fairRR( dlsch_ue_select[CC_id].list[dlsch_ue_select[CC_id].ue_num].rnti = rnti; dlsch_ue_select[CC_id].list[dlsch_ue_select[CC_id].ue_num].nb_rb = nb_rbs_required[CC_id][UE_id]; dlsch_ue_select[CC_id].ue_num++; + if (dlsch_ue_select[CC_id].ue_num == dlsch_ue_max_num[CC_id]) { end_flag[CC_id] = 1; break; @@ -277,10 +283,10 @@ void dlsch_scheduler_pre_ue_select_fairRR( } else { if (cc[CC_id].tdd_Config != NULL) { //TDD set_ue_dai (subframeP, - UE_id, - CC_id, - cc[CC_id].tdd_Config->subframeAssignment, - UE_list); + UE_id, + CC_id, + cc[CC_id].tdd_Config->subframeAssignment, + UE_list); // update UL DAI after DLSCH scheduling set_ul_DAI(module_idP,UE_id,CC_id,frameP,subframeP); } @@ -296,227 +302,249 @@ void dlsch_scheduler_pre_ue_select_fairRR( } } } - if(cc_id_end(end_flag) == 1){ + + if(cc_id_end(end_flag) == 1) { for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { DL_req = &eNB->DL_req[CC_id].dl_config_request_body; DL_req->number_pdu = saved_dlsch_dci[CC_id]; } + return; } // Insert DLSCH(first transmission) UE into selected UE list (UE_id > last_dlsch_ue_id[CC_id]) for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { - if (mbsfn_flag[CC_id]>0) { + if (mbsfn_flag[CC_id]>0) { + continue; + } + + DL_req = &eNB->DL_req[CC_id].dl_config_request_body; + + for (UE_id = (last_dlsch_ue_id[CC_id]+1); UE_id active[UE_id] == FALSE) { continue; } - DL_req = &eNB->DL_req[CC_id].dl_config_request_body; - for (UE_id = (last_dlsch_ue_id[CC_id]+1); UE_id UE_sched_ctrl[UE_id]; + + for(i = 0; iactive[UE_id] == FALSE) { + if(i < dlsch_ue_select[CC_id].ue_num) + continue; + + harq_pid = frame_subframe2_dl_harq_pid(cc[CC_id].tdd_Config,frameP,subframeP); + round = ue_sched_ctl->round[CC_id][harq_pid]; + + if (round == 8) { + if (nb_rbs_required[CC_id][UE_id] == 0) { continue; } - rnti = UE_RNTI(module_idP,UE_id); - if (rnti == NOT_A_RNTI) - continue; + switch (get_tmode(module_idP, CC_id, UE_id)) { + case 1: + case 2: + case 7: + aggregation = get_aggregation(get_bw_index(module_idP, CC_id), + ue_sched_ctl->dl_cqi[CC_id], + format1); + break; - if(mac_eNB_get_rrc_status(module_idP,rnti) < RRC_CONNECTED){ - continue; + case 3: + aggregation = get_aggregation(get_bw_index(module_idP,CC_id), + ue_sched_ctl->dl_cqi[CC_id], + format2A); + break; + + default: + LOG_W(MAC,"Unsupported transmission mode %d\n", get_tmode(module_idP,CC_id,UE_id)); + aggregation = 2; + break; } - ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; - for(i = 0;iround[CC_id][harq_pid]; - if (round == 8) { - if (nb_rbs_required[CC_id][UE_id] == 0) { - continue; - } - switch (get_tmode(module_idP, CC_id, UE_id)) { - case 1: - case 2: - case 7: - aggregation = get_aggregation(get_bw_index(module_idP, CC_id), - ue_sched_ctl->dl_cqi[CC_id], - format1); - break; - case 3: - aggregation = get_aggregation(get_bw_index(module_idP,CC_id), - ue_sched_ctl->dl_cqi[CC_id], - format2A); - break; - default: - LOG_W(MAC,"Unsupported transmission mode %d\n", get_tmode(module_idP,CC_id,UE_id)); - aggregation = 2; - break; - } - format_flag = 1; - if (!CCE_allocation_infeasible(module_idP, - CC_id, - format_flag, - subframeP, - aggregation, - rnti)) { - dl_config_pdu = &DL_req->dl_config_pdu_list[DL_req->number_pdu]; - dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti = rnti; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti_type = (format_flag == 0)?2:1; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level = aggregation; - DL_req->number_pdu++; - - // Insert DLSCH(first transmission) UE into selected selected UE list - dlsch_ue_select[CC_id].list[dlsch_ue_select[CC_id].ue_num].ue_priority = SCH_DL_FIRST; - dlsch_ue_select[CC_id].list[dlsch_ue_select[CC_id].ue_num].nb_rb = nb_rbs_required[CC_id][UE_id]; - dlsch_ue_select[CC_id].list[dlsch_ue_select[CC_id].ue_num].UE_id = UE_id; - dlsch_ue_select[CC_id].list[dlsch_ue_select[CC_id].ue_num].rnti = rnti; - dlsch_ue_select[CC_id].ue_num++; + if (!CCE_allocation_infeasible(module_idP, + CC_id, + format_flag, + subframeP, + aggregation, + rnti)) { + dl_config_pdu = &DL_req->dl_config_pdu_list[DL_req->number_pdu]; + dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti = rnti; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti_type = (format_flag == 0)?2:1; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level = aggregation; + DL_req->number_pdu++; + // Insert DLSCH(first transmission) UE into selected selected UE list + dlsch_ue_select[CC_id].list[dlsch_ue_select[CC_id].ue_num].ue_priority = SCH_DL_FIRST; + dlsch_ue_select[CC_id].list[dlsch_ue_select[CC_id].ue_num].nb_rb = nb_rbs_required[CC_id][UE_id]; + dlsch_ue_select[CC_id].list[dlsch_ue_select[CC_id].ue_num].UE_id = UE_id; + dlsch_ue_select[CC_id].list[dlsch_ue_select[CC_id].ue_num].rnti = rnti; + dlsch_ue_select[CC_id].ue_num++; if (dlsch_ue_select[CC_id].ue_num == dlsch_ue_max_num[CC_id]) { - end_flag[CC_id] = 1; - break; - } - }else { - if (cc[CC_id].tdd_Config != NULL) { //TDD - set_ue_dai (subframeP, - UE_id, - CC_id, - cc[CC_id].tdd_Config->subframeAssignment, - UE_list); - // update UL DAI after DLSCH scheduling - set_ul_DAI(module_idP,UE_id,CC_id,frameP,subframeP); - } - add_ue_dlsch_info(module_idP, - CC_id, - UE_id, - subframeP, - S_DL_NONE); end_flag[CC_id] = 1; break; } - } - } - } - if(cc_id_end(end_flag) == 1){ - for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { - DL_req = &eNB->DL_req[CC_id].dl_config_request_body; - DL_req->number_pdu = saved_dlsch_dci[CC_id]; - } - return; - } - - // Insert DLSCH(first transmission) UE into selected UE list (UE_id <= last_dlsch_ue_id[CC_id]) - for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { - if (mbsfn_flag[CC_id]>0) { - continue; - } - - DL_req = &eNB->DL_req[CC_id].dl_config_request_body; - for (UE_id = 0; UE_id <= last_dlsch_ue_id[CC_id]; UE_id++) { - if(end_flag[CC_id] == 1){ - break; - } - - if (UE_list->active[UE_id] == FALSE) { - continue; - } - - rnti = UE_RNTI(module_idP,UE_id); - if (rnti == NOT_A_RNTI) - continue; - - if(mac_eNB_get_rrc_status(module_idP,rnti) < RRC_CONNECTED){ - continue; - } - - ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; - for(i = 0;isubframeAssignment, + UE_list); + // update UL DAI after DLSCH scheduling + set_ul_DAI(module_idP,UE_id,CC_id,frameP,subframeP); } - } - if(i < dlsch_ue_select[CC_id].ue_num) - continue; - harq_pid = frame_subframe2_dl_harq_pid(cc[CC_id].tdd_Config,frameP ,subframeP); - - round = ue_sched_ctl->round[CC_id][harq_pid]; - if (round == 8) { - if (nb_rbs_required[CC_id][UE_id] == 0) { - continue; - } - switch (get_tmode(module_idP, CC_id, UE_id)) { - case 1: - case 2: - case 7: - aggregation = get_aggregation(get_bw_index(module_idP, CC_id), - ue_sched_ctl->dl_cqi[CC_id], - format1); - break; - case 3: - aggregation = get_aggregation(get_bw_index(module_idP,CC_id), - ue_sched_ctl->dl_cqi[CC_id], - format2A); - break; - default: - LOG_W(MAC,"Unsupported transmission mode %d\n", get_tmode(module_idP,CC_id,UE_id)); - aggregation = 2; - break; - } - format_flag = 1; - if (!CCE_allocation_infeasible(module_idP, - CC_id, - format_flag, - subframeP, - aggregation, - rnti)) { - dl_config_pdu = &DL_req->dl_config_pdu_list[DL_req->number_pdu]; - dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti = rnti; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti_type = (format_flag == 0)?2:1; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level = aggregation; - DL_req->number_pdu++; - - // Insert DLSCH(first transmission) UE into selected selected UE list - dlsch_ue_select[CC_id].list[dlsch_ue_select[CC_id].ue_num].ue_priority = SCH_DL_FIRST; - dlsch_ue_select[CC_id].list[dlsch_ue_select[CC_id].ue_num].nb_rb = nb_rbs_required[CC_id][UE_id]; - dlsch_ue_select[CC_id].list[dlsch_ue_select[CC_id].ue_num].UE_id = UE_id; - dlsch_ue_select[CC_id].list[dlsch_ue_select[CC_id].ue_num].rnti = rnti; - dlsch_ue_select[CC_id].ue_num++; - - if (dlsch_ue_select[CC_id].ue_num == dlsch_ue_max_num[CC_id]) { - end_flag[CC_id] = 1; - break; - } - } else { - if (cc[CC_id].tdd_Config != NULL) { //TDD - set_ue_dai (subframeP, - UE_id, - CC_id, - cc[CC_id].tdd_Config->subframeAssignment, - UE_list); - // update UL DAI after DLSCH scheduling - set_ul_DAI(module_idP,UE_id,CC_id,frameP,subframeP); - } add_ue_dlsch_info(module_idP, CC_id, UE_id, subframeP, S_DL_NONE); - end_flag[CC_id] = 1; - break; - } + end_flag[CC_id] = 1; + break; + } + } + } + } + + if(cc_id_end(end_flag) == 1) { + for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { + DL_req = &eNB->DL_req[CC_id].dl_config_request_body; + DL_req->number_pdu = saved_dlsch_dci[CC_id]; + } + + return; + } + + // Insert DLSCH(first transmission) UE into selected UE list (UE_id <= last_dlsch_ue_id[CC_id]) + for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { + if (mbsfn_flag[CC_id]>0) { + continue; + } + + DL_req = &eNB->DL_req[CC_id].dl_config_request_body; + + for (UE_id = 0; UE_id <= last_dlsch_ue_id[CC_id]; UE_id++) { + if(end_flag[CC_id] == 1) { + break; + } + + if (UE_list->active[UE_id] == FALSE) { + continue; + } + + rnti = UE_RNTI(module_idP,UE_id); + + if (rnti == NOT_A_RNTI) + continue; + + if(mac_eNB_get_rrc_status(module_idP,rnti) < RRC_CONNECTED) { + continue; + } + + ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; + + for(i = 0; iround[CC_id][harq_pid]; + + if (round == 8) { + if (nb_rbs_required[CC_id][UE_id] == 0) { + continue; + } + + switch (get_tmode(module_idP, CC_id, UE_id)) { + case 1: + case 2: + case 7: + aggregation = get_aggregation(get_bw_index(module_idP, CC_id), + ue_sched_ctl->dl_cqi[CC_id], + format1); + break; + + case 3: + aggregation = get_aggregation(get_bw_index(module_idP,CC_id), + ue_sched_ctl->dl_cqi[CC_id], + format2A); + break; + + default: + LOG_W(MAC,"Unsupported transmission mode %d\n", get_tmode(module_idP,CC_id,UE_id)); + aggregation = 2; + break; + } + + format_flag = 1; + + if (!CCE_allocation_infeasible(module_idP, + CC_id, + format_flag, + subframeP, + aggregation, + rnti)) { + dl_config_pdu = &DL_req->dl_config_pdu_list[DL_req->number_pdu]; + dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti = rnti; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti_type = (format_flag == 0)?2:1; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level = aggregation; + DL_req->number_pdu++; + // Insert DLSCH(first transmission) UE into selected selected UE list + dlsch_ue_select[CC_id].list[dlsch_ue_select[CC_id].ue_num].ue_priority = SCH_DL_FIRST; + dlsch_ue_select[CC_id].list[dlsch_ue_select[CC_id].ue_num].nb_rb = nb_rbs_required[CC_id][UE_id]; + dlsch_ue_select[CC_id].list[dlsch_ue_select[CC_id].ue_num].UE_id = UE_id; + dlsch_ue_select[CC_id].list[dlsch_ue_select[CC_id].ue_num].rnti = rnti; + dlsch_ue_select[CC_id].ue_num++; + + if (dlsch_ue_select[CC_id].ue_num == dlsch_ue_max_num[CC_id]) { + end_flag[CC_id] = 1; + break; + } + } else { + if (cc[CC_id].tdd_Config != NULL) { //TDD + set_ue_dai (subframeP, + UE_id, + CC_id, + cc[CC_id].tdd_Config->subframeAssignment, + UE_list); + // update UL DAI after DLSCH scheduling + set_ul_DAI(module_idP,UE_id,CC_id,frameP,subframeP); + } + + add_ue_dlsch_info(module_idP, + CC_id, + UE_id, + subframeP, + S_DL_NONE); + end_flag[CC_id] = 1; + break; + } } } } @@ -525,6 +553,7 @@ void dlsch_scheduler_pre_ue_select_fairRR( DL_req = &eNB->DL_req[CC_id].dl_config_request_body; DL_req->number_pdu = saved_dlsch_dci[CC_id]; } + return; } @@ -532,88 +561,74 @@ void dlsch_scheduler_pre_ue_select_fairRR( // This function assigns pre-available RBS to each UE in specified sub-bands before scheduling is done void dlsch_scheduler_pre_processor_fairRR (module_id_t Mod_id, - frame_t frameP, - sub_frame_t subframeP, - int N_RBG[MAX_NUM_CCs], - int *mbsfn_flag) -{ - + frame_t frameP, + sub_frame_t subframeP, + int N_RBG[MAX_NUM_CCs], + int *mbsfn_flag) { unsigned char rballoc_sub[MAX_NUM_CCs][N_RBG_MAX],harq_pid=0,Round=0; uint16_t temp_total_rbs_count; unsigned char temp_total_ue_count; unsigned char MIMO_mode_indicator[MAX_NUM_CCs][N_RBG_MAX]; uint8_t slice_allocation[MAX_NUM_CCs][N_RBG_MAX]; - int UE_id, i; + int UE_id, i; uint16_t j,c; uint16_t nb_rbs_required[MAX_NUM_CCs][NUMBER_OF_UE_MAX]; uint16_t nb_rbs_required_remaining[MAX_NUM_CCs][NUMBER_OF_UE_MAX]; -// uint16_t nb_rbs_required_remaining_1[MAX_NUM_CCs][NUMBER_OF_UE_MAX]; + // uint16_t nb_rbs_required_remaining_1[MAX_NUM_CCs][NUMBER_OF_UE_MAX]; uint16_t average_rbs_per_user[MAX_NUM_CCs] = {0}; rnti_t rnti; int min_rb_unit[MAX_NUM_CCs]; -// uint16_t r1=0; + // uint16_t r1=0; uint8_t CC_id; UE_list_t *UE_list = &RC.mac[Mod_id]->UE_list; - UE_sched_ctrl *ue_sched_ctl; // int rrc_status = RRC_IDLE; COMMON_channels_t *cc; - #ifdef TM5 - int harq_pid1 = 0; - int round1 = 0, round2 = 0; - int UE_id2; - uint16_t i1, i2, i3; - rnti_t rnti1, rnti2; - LTE_eNB_UE_stats *eNB_UE_stats1 = NULL; - LTE_eNB_UE_stats *eNB_UE_stats2 = NULL; - UE_sched_ctrl *ue_sched_ctl1, *ue_sched_ctl2; + int harq_pid1 = 0; + int round1 = 0, round2 = 0; + int UE_id2; + uint16_t i1, i2, i3; + rnti_t rnti1, rnti2; + LTE_eNB_UE_stats *eNB_UE_stats1 = NULL; + LTE_eNB_UE_stats *eNB_UE_stats2 = NULL; + UE_sched_ctrl *ue_sched_ctl1, *ue_sched_ctl2; #endif memset(min_rb_unit,0,sizeof(min_rb_unit)); + for (CC_id=0; CC_id 0) // If this CC is allocated for MBSFN skip it here + continue; - if (mbsfn_flag[CC_id] > 0) // If this CC is allocated for MBSFN skip it here - continue; + min_rb_unit[CC_id] = get_min_rb_unit(Mod_id, CC_id); + for (i = 0; i < NUMBER_OF_UE_MAX; i++) { + if (UE_list->active[i] != TRUE) + continue; - - min_rb_unit[CC_id] = get_min_rb_unit(Mod_id, CC_id); - - for (i = 0; i < NUMBER_OF_UE_MAX; i++) { - if (UE_list->active[i] != TRUE) - continue; - - UE_id = i; - // Initialize scheduling information for all active UEs - - - - dlsch_scheduler_pre_processor_reset(Mod_id, - 0, - frameP, - subframeP, - min_rb_unit, - (uint16_t (*)[NUMBER_OF_UE_MAX])nb_rbs_required, - rballoc_sub, - MIMO_mode_indicator, - mbsfn_flag); - - } + UE_id = i; + // Initialize scheduling information for all active UEs + dlsch_scheduler_pre_processor_reset(Mod_id, + 0, + frameP, + subframeP, + min_rb_unit, + (uint16_t (*)[NUMBER_OF_UE_MAX])nb_rbs_required, + rballoc_sub, + MIMO_mode_indicator, + mbsfn_flag); } + } #if (!defined(PRE_SCD_THREAD)) - // Store the DLSCH buffer for each logical channel - store_dlsch_buffer(Mod_id,0, frameP, subframeP); - - - - // Calculate the number of RBs required by each UE on the basis of logical channel's buffer - assign_rbs_required(Mod_id, 0, frameP, subframeP, nb_rbs_required, - min_rb_unit); + // Store the DLSCH buffer for each logical channel + store_dlsch_buffer(Mod_id,0, frameP, subframeP); + // Calculate the number of RBs required by each UE on the basis of logical channel's buffer + assign_rbs_required(Mod_id, 0, frameP, subframeP, nb_rbs_required, + min_rb_unit); #else - memcpy(nb_rbs_required, pre_nb_rbs_required[dlsch_ue_select_tbl_in_use] , sizeof(uint16_t)*MAX_NUM_CCs*NUMBER_OF_UE_MAX); + memcpy(nb_rbs_required, pre_nb_rbs_required[dlsch_ue_select_tbl_in_use], sizeof(uint16_t)*MAX_NUM_CCs*NUMBER_OF_UE_MAX); #endif - dlsch_scheduler_pre_ue_select_fairRR(Mod_id,frameP,subframeP, mbsfn_flag,nb_rbs_required,dlsch_ue_select); for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { @@ -624,19 +639,21 @@ void dlsch_scheduler_pre_processor_fairRR (module_id_t Mod_id, temp_total_ue_count = dlsch_ue_select[CC_id].ue_num; for (i = 0; i < dlsch_ue_select[CC_id].ue_num; i++) { - if(dlsch_ue_select[CC_id].list[i].ue_priority == SCH_DL_MSG2){ - temp_total_ue_count--; - continue; + if(dlsch_ue_select[CC_id].list[i].ue_priority == SCH_DL_MSG2) { + temp_total_ue_count--; + continue; } - if(dlsch_ue_select[CC_id].list[i].ue_priority == SCH_DL_MSG4){ - temp_total_ue_count--; - continue; + + if(dlsch_ue_select[CC_id].list[i].ue_priority == SCH_DL_MSG4) { + temp_total_ue_count--; + continue; } + UE_id = dlsch_ue_select[CC_id].list[i].UE_id; nb_rbs_required[CC_id][UE_id] = dlsch_ue_select[CC_id].list[i].nb_rb; - average_rbs_per_user[CC_id] = (uint16_t)round((double)temp_total_rbs_count/(double)temp_total_ue_count); - if( average_rbs_per_user[CC_id] < min_rb_unit[CC_id] ){ + + if( average_rbs_per_user[CC_id] < min_rb_unit[CC_id] ) { temp_total_ue_count--; dlsch_ue_select[CC_id].ue_num--; i--; @@ -644,9 +661,8 @@ void dlsch_scheduler_pre_processor_fairRR (module_id_t Mod_id, } rnti = dlsch_ue_select[CC_id].list[i].rnti; - ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; - harq_pid = frame_subframe2_dl_harq_pid(cc->tdd_Config,frameP ,subframeP); + harq_pid = frame_subframe2_dl_harq_pid(cc->tdd_Config,frameP,subframeP); Round = ue_sched_ctl->round[CC_id][harq_pid]; //if (mac_eNB_get_rrc_status(Mod_id, rnti) < RRC_RECONFIGURED || round > 0) { @@ -685,9 +701,11 @@ void dlsch_scheduler_pre_processor_fairRR (module_id_t Mod_id, dlsch_ue_select[CC_id].ue_num = i+1; break; } - LOG_D(MAC,"DLSCH UE Select: frame %d subframe %d pre_nb_available_rbs %d(i %d UE_id %d nb_rbs_required %d nb_rbs_required_remaining %d average_rbs_per_user %d (temp_total rbs_count %d ue_num %d) available_prbs %d)\n", - frameP,subframeP,ue_sched_ctl->pre_nb_available_rbs[CC_id],i,UE_id,nb_rbs_required[CC_id][UE_id],nb_rbs_required_remaining[CC_id][UE_id], - average_rbs_per_user[CC_id],temp_total_rbs_count,temp_total_ue_count,RC.mac[Mod_id]->eNB_stats[CC_id].available_prbs); + + LOG_D(MAC, + "DLSCH UE Select: frame %d subframe %d pre_nb_available_rbs %d(i %d UE_id %d nb_rbs_required %d nb_rbs_required_remaining %d average_rbs_per_user %d (temp_total rbs_count %d ue_num %d) available_prbs %d)\n", + frameP,subframeP,ue_sched_ctl->pre_nb_available_rbs[CC_id],i,UE_id,nb_rbs_required[CC_id][UE_id],nb_rbs_required_remaining[CC_id][UE_id], + average_rbs_per_user[CC_id],temp_total_rbs_count,temp_total_ue_count,RC.mac[Mod_id]->eNB_stats[CC_id].available_prbs); #ifdef TM5 // TODO: data channel TM5: to be re-visited #endif @@ -696,231 +714,240 @@ void dlsch_scheduler_pre_processor_fairRR (module_id_t Mod_id, #ifdef TM5 - // This has to be revisited!!!! - for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { - i1 = 0; - i2 = 0; - i3 = 0; - - for (j = 0; j < N_RBG[CC_id]; j++) { - if (MIMO_mode_indicator[CC_id][j] == 2) { - i1 = i1 + 1; - } else if (MIMO_mode_indicator[CC_id][j] == 1) { - i2 = i2 + 1; - } else if (MIMO_mode_indicator[CC_id][j] == 0) { - i3 = i3 + 1; - } - } - - if ((i1 < N_RBG[CC_id]) && (i2 > 0) && (i3 == 0)) { - PHY_vars_eNB_g[Mod_id][CC_id]->check_for_SUMIMO_transmissions = - PHY_vars_eNB_g[Mod_id][CC_id]-> - check_for_SUMIMO_transmissions + 1; - } - - if (i3 == N_RBG[CC_id] && i1 == 0 && i2 == 0) { - PHY_vars_eNB_g[Mod_id][CC_id]->FULL_MUMIMO_transmissions = - PHY_vars_eNB_g[Mod_id][CC_id]->FULL_MUMIMO_transmissions + - 1; - } - - if((i1 < N_RBG[CC_id]) && (i3 > 0)) { - PHY_vars_eNB_g[Mod_id][CC_id]-> - check_for_MUMIMO_transmissions + 1; - } - - PHY_vars_eNB_g[Mod_id][CC_id]->check_for_total_transmissions = - PHY_vars_eNB_g[Mod_id][CC_id]->check_for_total_transmissions + - 1; + // This has to be revisited!!!! + for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { + i1 = 0; + i2 = 0; + i3 = 0; + for (j = 0; j < N_RBG[CC_id]; j++) { + if (MIMO_mode_indicator[CC_id][j] == 2) { + i1 = i1 + 1; + } else if (MIMO_mode_indicator[CC_id][j] == 1) { + i2 = i2 + 1; + } else if (MIMO_mode_indicator[CC_id][j] == 0) { + i3 = i3 + 1; + } } + if ((i1 < N_RBG[CC_id]) && (i2 > 0) && (i3 == 0)) { + PHY_vars_eNB_g[Mod_id][CC_id]->check_for_SUMIMO_transmissions = + PHY_vars_eNB_g[Mod_id][CC_id]-> + check_for_SUMIMO_transmissions + 1; + } + + if (i3 == N_RBG[CC_id] && i1 == 0 && i2 == 0) { + PHY_vars_eNB_g[Mod_id][CC_id]->FULL_MUMIMO_transmissions = + PHY_vars_eNB_g[Mod_id][CC_id]->FULL_MUMIMO_transmissions + + 1; + } + + if((i1 < N_RBG[CC_id]) && (i3 > 0)) { + PHY_vars_eNB_g[Mod_id][CC_id]-> + check_for_MUMIMO_transmissions + 1; + } + + PHY_vars_eNB_g[Mod_id][CC_id]->check_for_total_transmissions = + PHY_vars_eNB_g[Mod_id][CC_id]->check_for_total_transmissions + + 1; + } + #endif for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { - for (i = 0; i < dlsch_ue_select[CC_id].ue_num; i++) { - if(dlsch_ue_select[CC_id].list[i].ue_priority == SCH_DL_MSG2){ - continue; + for (i = 0; i < dlsch_ue_select[CC_id].ue_num; i++) { + if(dlsch_ue_select[CC_id].list[i].ue_priority == SCH_DL_MSG2) { + continue; + } + + if(dlsch_ue_select[CC_id].list[i].ue_priority == SCH_DL_MSG4) { + continue; + } + + UE_id = dlsch_ue_select[CC_id].list[i].UE_id; + ue_sched_ctl = &RC.mac[Mod_id]->UE_list.UE_sched_ctrl[UE_id]; + //PHY_vars_eNB_g[Mod_id]->mu_mimo_mode[UE_id].dl_pow_off = dl_pow_off[UE_id]; + + if (ue_sched_ctl->pre_nb_available_rbs[CC_id] > 0) { + LOG_D(MAC, + "******************DL Scheduling Information for UE%d ************************\n", + UE_id); + LOG_D(MAC, "dl power offset UE%d = %d \n", UE_id, + ue_sched_ctl->dl_pow_off[CC_id]); + LOG_D(MAC, + "***********RB Alloc for every subband for UE%d ***********\n", + UE_id); + + for (j = 0; j < N_RBG[CC_id]; j++) { + //PHY_vars_eNB_g[Mod_id]->mu_mimo_mode[UE_id].rballoc_sub[i] = rballoc_sub_UE[CC_id][UE_id][i]; + LOG_D(MAC, "RB Alloc for UE%d and Subband%d = %d\n", + UE_id, j, + ue_sched_ctl->rballoc_sub_UE[CC_id][j]); } - if(dlsch_ue_select[CC_id].list[i].ue_priority == SCH_DL_MSG4){ - continue; - } - UE_id = dlsch_ue_select[CC_id].list[i].UE_id; - ue_sched_ctl = &RC.mac[Mod_id]->UE_list.UE_sched_ctrl[UE_id]; - //PHY_vars_eNB_g[Mod_id]->mu_mimo_mode[UE_id].dl_pow_off = dl_pow_off[UE_id]; - if (ue_sched_ctl->pre_nb_available_rbs[CC_id] > 0) { - LOG_D(MAC, - "******************DL Scheduling Information for UE%d ************************\n", - UE_id); - LOG_D(MAC, "dl power offset UE%d = %d \n", UE_id, - ue_sched_ctl->dl_pow_off[CC_id]); - LOG_D(MAC, - "***********RB Alloc for every subband for UE%d ***********\n", - UE_id); - - for (j = 0; j < N_RBG[CC_id]; j++) { - //PHY_vars_eNB_g[Mod_id]->mu_mimo_mode[UE_id].rballoc_sub[i] = rballoc_sub_UE[CC_id][UE_id][i]; - LOG_D(MAC, "RB Alloc for UE%d and Subband%d = %d\n", - UE_id, j, - ue_sched_ctl->rballoc_sub_UE[CC_id][j]); - } - - //PHY_vars_eNB_g[Mod_id]->mu_mimo_mode[UE_id].pre_nb_available_rbs = pre_nb_available_rbs[CC_id][UE_id]; - LOG_D(MAC, "Total RBs allocated for UE%d = %d\n", UE_id, - ue_sched_ctl->pre_nb_available_rbs[CC_id]); - } - } + //PHY_vars_eNB_g[Mod_id]->mu_mimo_mode[UE_id].pre_nb_available_rbs = pre_nb_available_rbs[CC_id][UE_id]; + LOG_D(MAC, "Total RBs allocated for UE%d = %d\n", UE_id, + ue_sched_ctl->pre_nb_available_rbs[CC_id]); + } } + } } //------------------------------------------------------------------------------ void schedule_ue_spec_fairRR(module_id_t module_idP, - frame_t frameP, sub_frame_t subframeP, int *mbsfn_flag) + frame_t frameP, sub_frame_t subframeP, int *mbsfn_flag) //------------------------------------------------------------------------------ { - - - uint8_t CC_id; - int UE_id; -// unsigned char aggregation; - mac_rlc_status_resp_t rlc_status; - unsigned char header_len_dcch = 0, header_len_dcch_tmp = 0; - unsigned char header_len_dtch = 0, header_len_dtch_tmp = 0, header_len_dtch_last = 0; - unsigned char ta_len = 0; - unsigned char sdu_lcids[NB_RB_MAX], lcid, offset, num_sdus = 0; - uint16_t nb_rb, nb_rb_temp, nb_available_rb; - uint16_t TBS, j, sdu_lengths[NB_RB_MAX], rnti, padding = 0, post_padding = 0; - unsigned char dlsch_buffer[MAX_DLSCH_PAYLOAD_BYTES]; - unsigned char round = 0; - unsigned char harq_pid = 0; - eNB_UE_STATS *eNB_UE_stats = NULL; - uint16_t sdu_length_total = 0; - - eNB_MAC_INST *eNB = RC.mac[module_idP]; - COMMON_channels_t *cc = eNB->common_channels; - UE_list_t *UE_list = &eNB->UE_list; - // int continue_flag = 0; - int32_t normalized_rx_power, target_rx_power; - int32_t tpc = 1; - static int32_t tpc_accumulated = 0; - UE_sched_ctrl *ue_sched_ctl; - int mcs; - int i; - int min_rb_unit[MAX_NUM_CCs]; - int N_RB_DL[MAX_NUM_CCs]; - int total_nb_available_rb[MAX_NUM_CCs]; - int N_RBG[MAX_NUM_CCs]; - nfapi_dl_config_request_body_t *dl_req; - nfapi_dl_config_request_pdu_t *dl_config_pdu; - int tdd_sfa; - int ta_update; + uint8_t CC_id; + int UE_id; + // unsigned char aggregation; + mac_rlc_status_resp_t rlc_status; + unsigned char header_len_dcch = 0, header_len_dcch_tmp = 0; + unsigned char header_len_dtch = 0, header_len_dtch_tmp = 0, header_len_dtch_last = 0; + unsigned char ta_len = 0; + unsigned char sdu_lcids[NB_RB_MAX], lcid, offset, num_sdus = 0; + uint16_t nb_rb, nb_rb_temp, nb_available_rb; + uint16_t TBS, j, sdu_lengths[NB_RB_MAX], rnti, padding = 0, post_padding = 0; + unsigned char dlsch_buffer[MAX_DLSCH_PAYLOAD_BYTES]; + unsigned char round = 0; + unsigned char harq_pid = 0; + eNB_UE_STATS *eNB_UE_stats = NULL; + uint16_t sdu_length_total = 0; + eNB_MAC_INST *eNB = RC.mac[module_idP]; + COMMON_channels_t *cc = eNB->common_channels; + UE_list_t *UE_list = &eNB->UE_list; + // int continue_flag = 0; + int32_t normalized_rx_power, target_rx_power; + int32_t tpc = 1; + static int32_t tpc_accumulated = 0; + UE_sched_ctrl *ue_sched_ctl; + int mcs; + int i; + int min_rb_unit[MAX_NUM_CCs]; + int N_RB_DL[MAX_NUM_CCs]; + int total_nb_available_rb[MAX_NUM_CCs]; + int N_RBG[MAX_NUM_CCs]; + nfapi_dl_config_request_body_t *dl_req; + nfapi_dl_config_request_pdu_t *dl_config_pdu; + int tdd_sfa; + int ta_update; #ifdef DEBUG_eNB_SCHEDULER - int k; + int k; #endif - - start_meas(&eNB->schedule_dlsch); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME - (VCD_SIGNAL_DUMPER_FUNCTIONS_SCHEDULE_DLSCH, VCD_FUNCTION_IN); + start_meas(&eNB->schedule_dlsch); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME + (VCD_SIGNAL_DUMPER_FUNCTIONS_SCHEDULE_DLSCH, VCD_FUNCTION_IN); + // for TDD: check that we have to act here, otherwise return + if (cc[0].tdd_Config) { + tdd_sfa = cc[0].tdd_Config->subframeAssignment; - // for TDD: check that we have to act here, otherwise return - if (cc[0].tdd_Config) { - tdd_sfa = cc[0].tdd_Config->subframeAssignment; - switch (subframeP) { - case 0: - // always continue - break; - case 1: - return; - break; - case 2: - return; - break; - case 3: - if ((tdd_sfa != 2) && (tdd_sfa != 5)) - return; - break; - case 4: - if ((tdd_sfa != 1) && (tdd_sfa != 2) && (tdd_sfa != 4) - && (tdd_sfa != 5)) - return; - break; - case 5: - break; - case 6: - case 7: - if ((tdd_sfa != 3)&& (tdd_sfa != 4) && (tdd_sfa != 5)) - return; - break; - case 8: - if ((tdd_sfa != 2) && (tdd_sfa != 3) && (tdd_sfa != 4) - && (tdd_sfa != 5)) - return; - break; - case 9: - if (tdd_sfa == 0) - return; - break; + switch (subframeP) { + case 0: + // always continue + break; - } + case 1: + return; + break; + + case 2: + return; + break; + + case 3: + if ((tdd_sfa != 2) && (tdd_sfa != 5)) + return; + + break; + + case 4: + if ((tdd_sfa != 1) && (tdd_sfa != 2) && (tdd_sfa != 4) + && (tdd_sfa != 5)) + return; + + break; + + case 5: + break; + + case 6: + case 7: + if ((tdd_sfa != 3)&& (tdd_sfa != 4) && (tdd_sfa != 5)) + return; + + break; + + case 8: + if ((tdd_sfa != 2) && (tdd_sfa != 3) && (tdd_sfa != 4) + && (tdd_sfa != 5)) + return; + + break; + + case 9: + if (tdd_sfa == 0) + return; + + break; } + } - //weight = get_ue_weight(module_idP,UE_id); -// aggregation = 2; - for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { - N_RB_DL[CC_id] = to_prb(cc[CC_id].mib->message.dl_Bandwidth); - min_rb_unit[CC_id] = get_min_rb_unit(module_idP, CC_id); - // get number of PRBs less those used by common channels - total_nb_available_rb[CC_id] = N_RB_DL[CC_id]; - for (i = 0; i < N_RB_DL[CC_id]; i++) - if (cc[CC_id].vrb_map[i] != 0) - total_nb_available_rb[CC_id]--; + //weight = get_ue_weight(module_idP,UE_id); + // aggregation = 2; + for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { + N_RB_DL[CC_id] = to_prb(cc[CC_id].mib->message.dl_Bandwidth); + min_rb_unit[CC_id] = get_min_rb_unit(module_idP, CC_id); + // get number of PRBs less those used by common channels + total_nb_available_rb[CC_id] = N_RB_DL[CC_id]; - N_RBG[CC_id] = to_rbg(cc[CC_id].mib->message.dl_Bandwidth); + for (i = 0; i < N_RB_DL[CC_id]; i++) + if (cc[CC_id].vrb_map[i] != 0) + total_nb_available_rb[CC_id]--; - // store the global enb stats: - eNB->eNB_stats[CC_id].num_dlactive_UEs = UE_list->num_UEs; - eNB->eNB_stats[CC_id].available_prbs = - total_nb_available_rb[CC_id]; - eNB->eNB_stats[CC_id].total_available_prbs += - total_nb_available_rb[CC_id]; - eNB->eNB_stats[CC_id].dlsch_bytes_tx = 0; - eNB->eNB_stats[CC_id].dlsch_pdus_tx = 0; - } + N_RBG[CC_id] = to_rbg(cc[CC_id].mib->message.dl_Bandwidth); + // store the global enb stats: + eNB->eNB_stats[CC_id].num_dlactive_UEs = UE_list->num_UEs; + eNB->eNB_stats[CC_id].available_prbs = + total_nb_available_rb[CC_id]; + eNB->eNB_stats[CC_id].total_available_prbs += + total_nb_available_rb[CC_id]; + eNB->eNB_stats[CC_id].dlsch_bytes_tx = 0; + eNB->eNB_stats[CC_id].dlsch_pdus_tx = 0; + } /// CALLING Pre_Processor for downlink scheduling (Returns estimation of RBs required by each UE and the allocation on sub-band) - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_PREPROCESSOR,VCD_FUNCTION_IN); start_meas(&eNB->schedule_dlsch_preprocessor); dlsch_scheduler_pre_processor_fairRR(module_idP, - frameP, - subframeP, - N_RBG, - mbsfn_flag); + frameP, + subframeP, + N_RBG, + mbsfn_flag); stop_meas(&eNB->schedule_dlsch_preprocessor); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_PREPROCESSOR,VCD_FUNCTION_OUT); - for (CC_id=0; CC_idDL_req[CC_id].dl_config_request_body; if (mbsfn_flag[CC_id]>0) continue; for (i = 0; i < dlsch_ue_select[CC_id].ue_num; i++) { - if(dlsch_ue_select[CC_id].list[i].ue_priority == SCH_DL_MSG2){ + if(dlsch_ue_select[CC_id].list[i].ue_priority == SCH_DL_MSG2) { continue; } - if(dlsch_ue_select[CC_id].list[i].ue_priority == SCH_DL_MSG4){ + + if(dlsch_ue_select[CC_id].list[i].ue_priority == SCH_DL_MSG4) { continue; } + UE_id = dlsch_ue_select[CC_id].list[i].UE_id; rnti = UE_RNTI(module_idP,UE_id); + if (rnti==NOT_A_RNTI) { LOG_E(MAC,"Cannot find rnti for UE_id %d (num_UEs %d)\n",UE_id,UE_list->num_UEs); continue; @@ -928,387 +955,377 @@ schedule_ue_spec_fairRR(module_id_t module_idP, eNB_UE_stats = &UE_list->eNB_UE_stats[CC_id][UE_id]; ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; -/* - switch(get_tmode(module_idP,CC_id,UE_id)){ - case 1: - case 2: - case 7: - aggregation = get_aggregation(get_bw_index(module_idP,CC_id), - ue_sched_ctl->dl_cqi[CC_id], - format1); - break; - case 3: - aggregation = get_aggregation(get_bw_index(module_idP,CC_id), - ue_sched_ctl->dl_cqi[CC_id], - format2A); - break; - default: - LOG_W(MAC,"Unsupported transmission mode %d\n", get_tmode(module_idP,CC_id,UE_id)); - aggregation = 2; - break; - } -*/ + + /* + switch(get_tmode(module_idP,CC_id,UE_id)){ + case 1: + case 2: + case 7: + aggregation = get_aggregation(get_bw_index(module_idP,CC_id), + ue_sched_ctl->dl_cqi[CC_id], + format1); + break; + case 3: + aggregation = get_aggregation(get_bw_index(module_idP,CC_id), + ue_sched_ctl->dl_cqi[CC_id], + format2A); + break; + default: + LOG_W(MAC,"Unsupported transmission mode %d\n", get_tmode(module_idP,CC_id,UE_id)); + aggregation = 2; + break; + } + */ if (cc[CC_id].tdd_Config != NULL) { //TDD set_ue_dai (subframeP, UE_id, CC_id, - cc[CC_id].tdd_Config->subframeAssignment, + cc[CC_id].tdd_Config->subframeAssignment, UE_list); // update UL DAI after DLSCH scheduling set_ul_DAI(module_idP,UE_id,CC_id,frameP,subframeP); } - nb_available_rb = ue_sched_ctl->pre_nb_available_rbs[CC_id]; + nb_available_rb = ue_sched_ctl->pre_nb_available_rbs[CC_id]; + harq_pid = frame_subframe2_dl_harq_pid(cc->tdd_Config,frameP,subframeP); + round = ue_sched_ctl->round[CC_id][harq_pid]; + UE_list->eNB_UE_stats[CC_id][UE_id].crnti = rnti; + UE_list->eNB_UE_stats[CC_id][UE_id].rrc_status = + mac_eNB_get_rrc_status(module_idP, rnti); + UE_list->eNB_UE_stats[CC_id][UE_id].harq_pid = harq_pid; + UE_list->eNB_UE_stats[CC_id][UE_id].harq_round = round; - harq_pid = frame_subframe2_dl_harq_pid(cc->tdd_Config,frameP ,subframeP); + if (UE_list->eNB_UE_stats[CC_id][UE_id].rrc_status < + RRC_CONNECTED) + continue; - round = ue_sched_ctl->round[CC_id][harq_pid]; + sdu_length_total = 0; + num_sdus = 0; - UE_list->eNB_UE_stats[CC_id][UE_id].crnti = rnti; - UE_list->eNB_UE_stats[CC_id][UE_id].rrc_status = - mac_eNB_get_rrc_status(module_idP, rnti); - UE_list->eNB_UE_stats[CC_id][UE_id].harq_pid = harq_pid; - UE_list->eNB_UE_stats[CC_id][UE_id].harq_round = round; + /* + DevCheck(((eNB_UE_stats->dl_cqi < MIN_CQI_VALUE) || (eNB_UE_stats->dl_cqi > MAX_CQI_VALUE)), + eNB_UE_stats->dl_cqi, MIN_CQI_VALUE, MAX_CQI_VALUE); + */ + if (nfapi_mode) { + eNB_UE_stats->dlsch_mcs1 = 10;//cqi_to_mcs[ue_sched_ctl->dl_cqi[CC_id]]; + } else { + eNB_UE_stats->dlsch_mcs1 = cqi_to_mcs[ue_sched_ctl->dl_cqi[CC_id]]; + } + eNB_UE_stats->dlsch_mcs1 = eNB_UE_stats->dlsch_mcs1; //cmin(eNB_UE_stats->dlsch_mcs1, openair_daq_vars.target_ue_dl_mcs); - if (UE_list->eNB_UE_stats[CC_id][UE_id].rrc_status < - RRC_CONNECTED) - continue; + // store stats + //UE_list->eNB_UE_stats[CC_id][UE_id].dl_cqi= eNB_UE_stats->dl_cqi; - sdu_length_total = 0; - num_sdus = 0; + // initializing the rb allocation indicator for each UE + for (j = 0; j < N_RBG[CC_id]; j++) { + UE_list-> + UE_template[CC_id][UE_id].rballoc_subband[harq_pid][j] + = 0; + } - /* - DevCheck(((eNB_UE_stats->dl_cqi < MIN_CQI_VALUE) || (eNB_UE_stats->dl_cqi > MAX_CQI_VALUE)), - eNB_UE_stats->dl_cqi, MIN_CQI_VALUE, MAX_CQI_VALUE); - */ - if (nfapi_mode) { - eNB_UE_stats->dlsch_mcs1 = 10;//cqi_to_mcs[ue_sched_ctl->dl_cqi[CC_id]]; + LOG_D(MAC, + "[eNB %d] Frame %d: Scheduling UE %d on CC_id %d (rnti %x, harq_pid %d, round %d, rb %d, cqi %d, mcs %d, rrc %d)\n", + module_idP, frameP, UE_id, CC_id, rnti, harq_pid, round, + nb_available_rb, ue_sched_ctl->dl_cqi[CC_id], + eNB_UE_stats->dlsch_mcs1, + UE_list->eNB_UE_stats[CC_id][UE_id].rrc_status); + + /* process retransmission */ + + if (round != 8) { + // get freq_allocation + nb_rb = UE_list->UE_template[CC_id][UE_id].nb_rb[harq_pid]; + TBS = + get_TBS_DL(UE_list-> + UE_template[CC_id][UE_id].oldmcs1[harq_pid], + nb_rb); + + if (nb_rb <= nb_available_rb) { + if (cc[CC_id].tdd_Config != NULL) { + UE_list->UE_template[CC_id][UE_id].DAI++; + update_ul_dci(module_idP, CC_id, rnti, + UE_list->UE_template[CC_id][UE_id]. + DAI,subframeP); + LOG_D(MAC, + "DAI update: CC_id %d subframeP %d: UE %d, DAI %d\n", + CC_id, subframeP, UE_id, + UE_list->UE_template[CC_id][UE_id].DAI); + } + + if (nb_rb == ue_sched_ctl->pre_nb_available_rbs[CC_id]) { + for (j = 0; j < N_RBG[CC_id]; j++) { // for indicating the rballoc for each sub-band + UE_list->UE_template[CC_id][UE_id]. + rballoc_subband[harq_pid][j] = + ue_sched_ctl->rballoc_sub_UE[CC_id][j]; } - else { - eNB_UE_stats->dlsch_mcs1 = cqi_to_mcs[ue_sched_ctl->dl_cqi[CC_id]]; + } else { + nb_rb_temp = nb_rb; + j = 0; + + while ((nb_rb_temp > 0) && (j < N_RBG[CC_id])) { + if (ue_sched_ctl->rballoc_sub_UE[CC_id][j] == + 1) { + if (UE_list-> + UE_template[CC_id] + [UE_id].rballoc_subband[harq_pid][j]) + printf + ("WARN: rballoc_subband not free for retrans?\n"); + + UE_list-> + UE_template[CC_id] + [UE_id].rballoc_subband[harq_pid][j] = + ue_sched_ctl->rballoc_sub_UE[CC_id][j]; + + if ((j == N_RBG[CC_id] - 1) && + ((N_RB_DL[CC_id] == 25) || + (N_RB_DL[CC_id] == 50))) { + nb_rb_temp = + nb_rb_temp - min_rb_unit[CC_id] + + 1; + } else { + nb_rb_temp = + nb_rb_temp - min_rb_unit[CC_id]; + } + } + + j = j + 1; } - eNB_UE_stats->dlsch_mcs1 = eNB_UE_stats->dlsch_mcs1; //cmin(eNB_UE_stats->dlsch_mcs1, openair_daq_vars.target_ue_dl_mcs); + } + nb_available_rb -= nb_rb; + /* + eNB->mu_mimo_mode[UE_id].pre_nb_available_rbs = nb_rb; + eNB->mu_mimo_mode[UE_id].dl_pow_off = ue_sched_ctl->dl_pow_off[CC_id]; - // store stats - //UE_list->eNB_UE_stats[CC_id][UE_id].dl_cqi= eNB_UE_stats->dl_cqi; + for(j=0; jmu_mimo_mode[UE_id].rballoc_sub[j] = UE_list->UE_template[CC_id][UE_id].rballoc_subband[harq_pid][j]; + } + */ - // initializing the rb allocation indicator for each UE - for (j = 0; j < N_RBG[CC_id]; j++) { - UE_list-> - UE_template[CC_id][UE_id].rballoc_subband[harq_pid][j] - = 0; - } + switch (get_tmode(module_idP, CC_id, UE_id)) { + case 1: + case 2: + case 7: + default: + LOG_D(MAC,"retransmission DL_REQ: rnti:%x\n",rnti); + dl_config_pdu = + &dl_req->dl_config_pdu_list[dl_req-> + number_pdu]; + memset((void *) dl_config_pdu, 0, + sizeof(nfapi_dl_config_request_pdu_t)); + dl_config_pdu->pdu_type = + NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE; + dl_config_pdu->pdu_size = + (uint8_t) (2 + + sizeof(nfapi_dl_config_dci_dl_pdu)); + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tl.tag = NFAPI_DL_CONFIG_REQUEST_DCI_DL_PDU_REL8_TAG; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8. + dci_format = NFAPI_DL_DCI_FORMAT_1; + dl_config_pdu->dci_dl_pdu. + dci_dl_pdu_rel8.aggregation_level = + get_aggregation(get_bw_index + (module_idP, CC_id), + ue_sched_ctl->dl_cqi[CC_id], + format1); + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti = + rnti; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti_type = 1; // CRNTI : see Table 4-10 from SCF082 - nFAPI specifications + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.transmission_power = 6000; // equal to RS power + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8. + harq_process = harq_pid; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tpc = 1; // dont adjust power when retransmitting + dl_config_pdu->dci_dl_pdu. + dci_dl_pdu_rel8.new_data_indicator_1 = + UE_list->UE_template[CC_id][UE_id]. + oldNDI[harq_pid]; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.mcs_1 = + UE_list->UE_template[CC_id][UE_id]. + oldmcs1[harq_pid]; + dl_config_pdu->dci_dl_pdu. + dci_dl_pdu_rel8.redundancy_version_1 = + round & 3; - LOG_D(MAC, - "[eNB %d] Frame %d: Scheduling UE %d on CC_id %d (rnti %x, harq_pid %d, round %d, rb %d, cqi %d, mcs %d, rrc %d)\n", - module_idP, frameP, UE_id, CC_id, rnti, harq_pid, round, - nb_available_rb, ue_sched_ctl->dl_cqi[CC_id], - eNB_UE_stats->dlsch_mcs1, - UE_list->eNB_UE_stats[CC_id][UE_id].rrc_status); + if (cc[CC_id].tdd_Config != NULL) { //TDD + dl_config_pdu->dci_dl_pdu. + dci_dl_pdu_rel8.downlink_assignment_index = + (UE_list->UE_template[CC_id][UE_id].DAI - + 1) & 3; + LOG_D(MAC, + "[eNB %d] Retransmission CC_id %d : harq_pid %d, round %d, dai %d, mcs %d\n", + module_idP, CC_id, harq_pid, round, + (UE_list->UE_template[CC_id][UE_id].DAI - + 1), + UE_list-> + UE_template[CC_id][UE_id].oldmcs1 + [harq_pid]); + } else { + LOG_D(MAC, + "[eNB %d] Retransmission CC_id %d : harq_pid %d, round %d, mcs %d\n", + module_idP, CC_id, harq_pid, round, + UE_list-> + UE_template[CC_id][UE_id].oldmcs1 + [harq_pid]); + } + if (!CCE_allocation_infeasible + (module_idP, CC_id, 1, subframeP, + dl_config_pdu->dci_dl_pdu. + dci_dl_pdu_rel8.aggregation_level, rnti)) { + dl_req->number_dci++; + dl_req->number_pdu++; + dl_req->tl.tag = NFAPI_DL_CONFIG_REQUEST_BODY_TAG; + eNB->DL_req[CC_id].sfn_sf = frameP<<4 | subframeP; + eNB->DL_req[CC_id].header.message_id = NFAPI_DL_CONFIG_REQUEST; + fill_nfapi_dlsch_config(eNB, dl_req, TBS, -1 + /* retransmission, no pdu_index */ + , rnti, 0, // type 0 allocation from 7.1.6 in 36.213 + 0, // virtual_resource_block_assignment_flag, unused here + 0, // resource_block_coding, to be filled in later + getQm(UE_list->UE_template[CC_id][UE_id].oldmcs1[harq_pid]), round & 3, // redundancy version + 1, // transport blocks + 0, // transport block to codeword swap flag + cc[CC_id].p_eNB == 1 ? 0 : 1, // transmission_scheme + 1, // number of layers + 1, // number of subbands + // uint8_t codebook_index, + 4, // UE category capacity + UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->pdsch_ConfigDedicated->p_a, 0, // delta_power_offset for TM5 + 0, // ngap + 0, // nprb + cc[CC_id].p_eNB == 1 ? 1 : 2, // transmission mode + 0, //number of PRBs treated as one subband, not used here + 0 // number of beamforming vectors, not used here + ); + LOG_D(MAC, + "Filled NFAPI configuration for DCI/DLSCH %d, retransmission round %d\n", + eNB->pdu_index[CC_id], round); + program_dlsch_acknak(module_idP, CC_id, UE_id, + frameP, subframeP, + dl_config_pdu-> + dci_dl_pdu.dci_dl_pdu_rel8. + cce_idx); + // No TX request for retransmission (check if null request for FAPI) + } else { + LOG_W(MAC, + "Frame %d, Subframe %d: Dropping DLSCH allocation for UE %d\%x, infeasible CCE allocation\n", + frameP, subframeP, UE_id, rnti); + } + } + add_ue_dlsch_info(module_idP, + CC_id, UE_id, subframeP, + S_DL_SCHEDULED); + //eNB_UE_stats->dlsch_trials[round]++; + UE_list->eNB_UE_stats[CC_id][UE_id]. + num_retransmission += 1; + UE_list->eNB_UE_stats[CC_id][UE_id].rbs_used_retx = + nb_rb; + UE_list->eNB_UE_stats[CC_id][UE_id]. + total_rbs_used_retx += nb_rb; + UE_list->eNB_UE_stats[CC_id][UE_id].dlsch_mcs1 = + eNB_UE_stats->dlsch_mcs1; + UE_list->eNB_UE_stats[CC_id][UE_id].dlsch_mcs2 = + eNB_UE_stats->dlsch_mcs1; + } else { + LOG_D(MAC, + "[eNB %d] Frame %d CC_id %d : don't schedule UE %d, its retransmission takes more resources than we have\n", + module_idP, frameP, CC_id, UE_id); + } + } else { /* This is a potentially new SDU opportunity */ + rlc_status.bytes_in_buffer = 0; + // Now check RLC information to compute number of required RBs + // get maximum TBS size for RLC request + TBS = + get_TBS_DL(eNB_UE_stats->dlsch_mcs1, nb_available_rb); + // check first for RLC data on DCCH + // add the length for all the control elements (timing adv, drx, etc) : header + payload - /* process retransmission */ + if (ue_sched_ctl->ta_timer == 0) { + ta_update = ue_sched_ctl->ta_update; - if (round != 8) { + /* if we send TA then set timer to not send it for a while */ + if (ta_update != 31) + ue_sched_ctl->ta_timer = 20; - // get freq_allocation - nb_rb = UE_list->UE_template[CC_id][UE_id].nb_rb[harq_pid]; - TBS = - get_TBS_DL(UE_list-> - UE_template[CC_id][UE_id].oldmcs1[harq_pid], - nb_rb); + /* reset ta_update */ + ue_sched_ctl->ta_update = 31; + } else { + ta_update = 31; + } - if (nb_rb <= nb_available_rb) { - if (cc[CC_id].tdd_Config != NULL) { - UE_list->UE_template[CC_id][UE_id].DAI++; - update_ul_dci(module_idP, CC_id, rnti, - UE_list->UE_template[CC_id][UE_id]. - DAI,subframeP); - LOG_D(MAC, - "DAI update: CC_id %d subframeP %d: UE %d, DAI %d\n", - CC_id, subframeP, UE_id, - UE_list->UE_template[CC_id][UE_id].DAI); - } + ta_len = (ta_update != 31) ? 2 : 0; + header_len_dcch = 2; // 2 bytes DCCH SDU subheader - if (nb_rb == ue_sched_ctl->pre_nb_available_rbs[CC_id]) { - for (j = 0; j < N_RBG[CC_id]; j++) { // for indicating the rballoc for each sub-band - UE_list->UE_template[CC_id][UE_id]. - rballoc_subband[harq_pid][j] = - ue_sched_ctl->rballoc_sub_UE[CC_id][j]; - } - } else { - nb_rb_temp = nb_rb; - j = 0; - - while ((nb_rb_temp > 0) && (j < N_RBG[CC_id])) { - if (ue_sched_ctl->rballoc_sub_UE[CC_id][j] == - 1) { - if (UE_list-> - UE_template[CC_id] - [UE_id].rballoc_subband[harq_pid][j]) - printf - ("WARN: rballoc_subband not free for retrans?\n"); - UE_list-> - UE_template[CC_id] - [UE_id].rballoc_subband[harq_pid][j] = - ue_sched_ctl->rballoc_sub_UE[CC_id][j]; - - if ((j == N_RBG[CC_id] - 1) && - ((N_RB_DL[CC_id] == 25) || - (N_RB_DL[CC_id] == 50))) { - nb_rb_temp = - nb_rb_temp - min_rb_unit[CC_id] + - 1; - } else { - nb_rb_temp = - nb_rb_temp - min_rb_unit[CC_id]; - } - } - - j = j + 1; - } - } - - nb_available_rb -= nb_rb; - /* - eNB->mu_mimo_mode[UE_id].pre_nb_available_rbs = nb_rb; - eNB->mu_mimo_mode[UE_id].dl_pow_off = ue_sched_ctl->dl_pow_off[CC_id]; - - for(j=0; jmu_mimo_mode[UE_id].rballoc_sub[j] = UE_list->UE_template[CC_id][UE_id].rballoc_subband[harq_pid][j]; - } - */ - - switch (get_tmode(module_idP, CC_id, UE_id)) { - case 1: - case 2: - case 7: - default: - LOG_D(MAC,"retransmission DL_REQ: rnti:%x\n",rnti); - - dl_config_pdu = - &dl_req->dl_config_pdu_list[dl_req-> - number_pdu]; - memset((void *) dl_config_pdu, 0, - sizeof(nfapi_dl_config_request_pdu_t)); - dl_config_pdu->pdu_type = - NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE; - dl_config_pdu->pdu_size = - (uint8_t) (2 + - sizeof(nfapi_dl_config_dci_dl_pdu)); - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tl.tag = NFAPI_DL_CONFIG_REQUEST_DCI_DL_PDU_REL8_TAG; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8. - dci_format = NFAPI_DL_DCI_FORMAT_1; - dl_config_pdu->dci_dl_pdu. - dci_dl_pdu_rel8.aggregation_level = - get_aggregation(get_bw_index - (module_idP, CC_id), - ue_sched_ctl->dl_cqi[CC_id], - format1); - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti = - rnti; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti_type = 1; // CRNTI : see Table 4-10 from SCF082 - nFAPI specifications - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.transmission_power = 6000; // equal to RS power - - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8. - harq_process = harq_pid; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tpc = 1; // dont adjust power when retransmitting - dl_config_pdu->dci_dl_pdu. - dci_dl_pdu_rel8.new_data_indicator_1 = - UE_list->UE_template[CC_id][UE_id]. - oldNDI[harq_pid]; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.mcs_1 = - UE_list->UE_template[CC_id][UE_id]. - oldmcs1[harq_pid]; - dl_config_pdu->dci_dl_pdu. - dci_dl_pdu_rel8.redundancy_version_1 = - round & 3; - - if (cc[CC_id].tdd_Config != NULL) { //TDD - dl_config_pdu->dci_dl_pdu. - dci_dl_pdu_rel8.downlink_assignment_index = - (UE_list->UE_template[CC_id][UE_id].DAI - - 1) & 3; - LOG_D(MAC, - "[eNB %d] Retransmission CC_id %d : harq_pid %d, round %d, dai %d, mcs %d\n", - module_idP, CC_id, harq_pid, round, - (UE_list->UE_template[CC_id][UE_id].DAI - - 1), - UE_list-> - UE_template[CC_id][UE_id].oldmcs1 - [harq_pid]); - } else { - LOG_D(MAC, - "[eNB %d] Retransmission CC_id %d : harq_pid %d, round %d, mcs %d\n", - module_idP, CC_id, harq_pid, round, - UE_list-> - UE_template[CC_id][UE_id].oldmcs1 - [harq_pid]); - - } - if (!CCE_allocation_infeasible - (module_idP, CC_id, 1, subframeP, - dl_config_pdu->dci_dl_pdu. - dci_dl_pdu_rel8.aggregation_level, rnti)) { - dl_req->number_dci++; - dl_req->number_pdu++; - dl_req->tl.tag = NFAPI_DL_CONFIG_REQUEST_BODY_TAG; - - eNB->DL_req[CC_id].sfn_sf = frameP<<4 | subframeP; - eNB->DL_req[CC_id].header.message_id = NFAPI_DL_CONFIG_REQUEST; - - fill_nfapi_dlsch_config(eNB, dl_req, TBS, -1 - /* retransmission, no pdu_index */ - , rnti, 0, // type 0 allocation from 7.1.6 in 36.213 - 0, // virtual_resource_block_assignment_flag, unused here - 0, // resource_block_coding, to be filled in later - getQm(UE_list->UE_template[CC_id][UE_id].oldmcs1[harq_pid]), round & 3, // redundancy version - 1, // transport blocks - 0, // transport block to codeword swap flag - cc[CC_id].p_eNB == 1 ? 0 : 1, // transmission_scheme - 1, // number of layers - 1, // number of subbands - // uint8_t codebook_index, - 4, // UE category capacity - UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->pdsch_ConfigDedicated->p_a, 0, // delta_power_offset for TM5 - 0, // ngap - 0, // nprb - cc[CC_id].p_eNB == 1 ? 1 : 2, // transmission mode - 0, //number of PRBs treated as one subband, not used here - 0 // number of beamforming vectors, not used here - ); - - LOG_D(MAC, - "Filled NFAPI configuration for DCI/DLSCH %d, retransmission round %d\n", - eNB->pdu_index[CC_id], round); - - program_dlsch_acknak(module_idP, CC_id, UE_id, - frameP, subframeP, - dl_config_pdu-> - dci_dl_pdu.dci_dl_pdu_rel8. - cce_idx); - // No TX request for retransmission (check if null request for FAPI) - } else { - LOG_W(MAC, - "Frame %d, Subframe %d: Dropping DLSCH allocation for UE %d\%x, infeasible CCE allocation\n", - frameP, subframeP, UE_id, rnti); - } - } - - - add_ue_dlsch_info(module_idP, - CC_id, UE_id, subframeP, - S_DL_SCHEDULED); - - //eNB_UE_stats->dlsch_trials[round]++; - UE_list->eNB_UE_stats[CC_id][UE_id]. - num_retransmission += 1; - UE_list->eNB_UE_stats[CC_id][UE_id].rbs_used_retx = - nb_rb; - UE_list->eNB_UE_stats[CC_id][UE_id]. - total_rbs_used_retx += nb_rb; - UE_list->eNB_UE_stats[CC_id][UE_id].dlsch_mcs1 = - eNB_UE_stats->dlsch_mcs1; - UE_list->eNB_UE_stats[CC_id][UE_id].dlsch_mcs2 = - eNB_UE_stats->dlsch_mcs1; - } else { - LOG_D(MAC, - "[eNB %d] Frame %d CC_id %d : don't schedule UE %d, its retransmission takes more resources than we have\n", - module_idP, frameP, CC_id, UE_id); - } - } else { /* This is a potentially new SDU opportunity */ - - rlc_status.bytes_in_buffer = 0; - // Now check RLC information to compute number of required RBs - // get maximum TBS size for RLC request - TBS = - get_TBS_DL(eNB_UE_stats->dlsch_mcs1, nb_available_rb); - // check first for RLC data on DCCH - // add the length for all the control elements (timing adv, drx, etc) : header + payload - - if (ue_sched_ctl->ta_timer == 0) { - ta_update = ue_sched_ctl->ta_update; - /* if we send TA then set timer to not send it for a while */ - if (ta_update != 31) - ue_sched_ctl->ta_timer = 20; - /* reset ta_update */ - ue_sched_ctl->ta_update = 31; - } else { - ta_update = 31; - } - - ta_len = (ta_update != 31) ? 2 : 0; - - header_len_dcch = 2; // 2 bytes DCCH SDU subheader - - if (TBS - ta_len - header_len_dcch > 0) { - rlc_status = mac_rlc_status_ind(module_idP, rnti, module_idP, frameP, subframeP, ENB_FLAG_YES, MBMS_FLAG_NO, DCCH, (TBS - ta_len - header_len_dcch) + if (TBS - ta_len - header_len_dcch > 0) { + rlc_status = mac_rlc_status_ind(module_idP, rnti, module_idP, frameP, subframeP, ENB_FLAG_YES, MBMS_FLAG_NO, DCCH, (TBS - ta_len - header_len_dcch) #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - ,0, 0 + ,0, 0 #endif - ); // transport block set size + ); // transport block set size + sdu_lengths[0] = 0; - sdu_lengths[0] = 0; - - if (rlc_status.bytes_in_buffer > 0) { // There is DCCH to transmit - LOG_D(MAC, - "[eNB %d] SFN/SF %d.%d, DL-DCCH->DLSCH CC_id %d, Requesting %d bytes from RLC (RRC message)\n", - module_idP, frameP, subframeP, CC_id, - TBS - header_len_dcch); - sdu_lengths[0] = mac_rlc_data_req(module_idP, rnti, module_idP, frameP, ENB_FLAG_YES, MBMS_FLAG_NO, DCCH, TBS, //not used - (char *) - &dlsch_buffer - [0] + if (rlc_status.bytes_in_buffer > 0) { // There is DCCH to transmit + LOG_D(MAC, + "[eNB %d] SFN/SF %d.%d, DL-DCCH->DLSCH CC_id %d, Requesting %d bytes from RLC (RRC message)\n", + module_idP, frameP, subframeP, CC_id, + TBS - header_len_dcch); + sdu_lengths[0] = mac_rlc_data_req(module_idP, rnti, module_idP, frameP, ENB_FLAG_YES, MBMS_FLAG_NO, DCCH, TBS, //not used + (char *) + &dlsch_buffer + [0] #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - ,0, 0 + ,0, 0 #endif - ); + ); pthread_mutex_lock(&rrc_release_freelist); - if((rrc_release_info.num_UEs > 0) && (rlc_am_mui.rrc_mui_num > 0)){ + + if((rrc_release_info.num_UEs > 0) && (rlc_am_mui.rrc_mui_num > 0)) { uint16_t release_total = 0; - for(uint16_t release_num = 0;release_num < NUMBER_OF_UE_MAX;release_num++){ - if(rrc_release_info.RRC_release_ctrl[release_num].flag > 0){ + + for(uint16_t release_num = 0; release_num < NUMBER_OF_UE_MAX; release_num++) { + if(rrc_release_info.RRC_release_ctrl[release_num].flag > 0) { release_total++; - }else{ + } else { continue; } - if(rrc_release_info.RRC_release_ctrl[release_num].flag == 1){ - if(rrc_release_info.RRC_release_ctrl[release_num].rnti == rnti){ - for(uint16_t mui_num = 0;mui_num < rlc_am_mui.rrc_mui_num;mui_num++){ - if(rrc_release_info.RRC_release_ctrl[release_num].rrc_eNB_mui == rlc_am_mui.rrc_mui[mui_num]){ + if(rrc_release_info.RRC_release_ctrl[release_num].flag == 1) { + if(rrc_release_info.RRC_release_ctrl[release_num].rnti == rnti) { + for(uint16_t mui_num = 0; mui_num < rlc_am_mui.rrc_mui_num; mui_num++) { + if(rrc_release_info.RRC_release_ctrl[release_num].rrc_eNB_mui == rlc_am_mui.rrc_mui[mui_num]) { rrc_release_info.RRC_release_ctrl[release_num].flag = 3; LOG_D(MAC,"DLSCH Release send:index %d rnti %x mui %d mui_num %d flag 1->3\n",release_num,rnti,rlc_am_mui.rrc_mui[mui_num],mui_num); break; - } - } - } - } - if(rrc_release_info.RRC_release_ctrl[release_num].flag == 2){ - if(rrc_release_info.RRC_release_ctrl[release_num].rnti == rnti){ - for(uint16_t mui_num = 0;mui_num < rlc_am_mui.rrc_mui_num;mui_num++){ - if(rrc_release_info.RRC_release_ctrl[release_num].rrc_eNB_mui == rlc_am_mui.rrc_mui[mui_num]){ - rrc_release_info.RRC_release_ctrl[release_num].flag = 4; - LOG_D(MAC,"DLSCH Release send:index %d rnti %x mui %d mui_num %d flag 2->4\n",release_num,rnti,rlc_am_mui.rrc_mui[mui_num],mui_num); - break; } } } } + + if(rrc_release_info.RRC_release_ctrl[release_num].flag == 2) { + if(rrc_release_info.RRC_release_ctrl[release_num].rnti == rnti) { + for(uint16_t mui_num = 0; mui_num < rlc_am_mui.rrc_mui_num; mui_num++) { + if(rrc_release_info.RRC_release_ctrl[release_num].rrc_eNB_mui == rlc_am_mui.rrc_mui[mui_num]) { + rrc_release_info.RRC_release_ctrl[release_num].flag = 4; + LOG_D(MAC,"DLSCH Release send:index %d rnti %x mui %d mui_num %d flag 2->4\n",release_num,rnti,rlc_am_mui.rrc_mui[mui_num],mui_num); + break; + } + } + } + } + if(release_total >= rrc_release_info.num_UEs) break; } } - pthread_mutex_unlock(&rrc_release_freelist); + pthread_mutex_unlock(&rrc_release_freelist); RA_t *ra = &eNB->common_channels[CC_id].ra[0]; + for (uint8_t ra_ii = 0; ra_ii < NB_RA_PROC_MAX; ra_ii++) { - if((ra[ra_ii].rnti == rnti) && (ra[ra_ii].state == MSGCRNTI)){ - for(uint16_t mui_num = 0;mui_num < rlc_am_mui.rrc_mui_num;mui_num++){ - if(ra[ra_ii].crnti_rrc_mui == rlc_am_mui.rrc_mui[mui_num]){ + if((ra[ra_ii].rnti == rnti) && (ra[ra_ii].state == MSGCRNTI)) { + for(uint16_t mui_num = 0; mui_num < rlc_am_mui.rrc_mui_num; mui_num++) { + if(ra[ra_ii].crnti_rrc_mui == rlc_am_mui.rrc_mui[mui_num]) { ra[ra_ii].crnti_harq_pid = harq_pid; ra[ra_ii].state = MSGCRNTI_ACK; break; @@ -1316,347 +1333,339 @@ schedule_ue_spec_fairRR(module_id_t module_idP, } } } - T(T_ENB_MAC_UE_DL_SDU, T_INT(module_idP), - T_INT(CC_id), T_INT(rnti), T_INT(frameP), - T_INT(subframeP), T_INT(harq_pid), T_INT(DCCH), - T_INT(sdu_lengths[0])); - LOG_D(MAC, - "[eNB %d][DCCH] CC_id %d frame %d subframe %d UE_id %d/%x Got %d bytes bytes_in_buffer %d from release_num %d\n", - module_idP, CC_id, frameP, subframeP, UE_id, rnti, sdu_lengths[0],rlc_status.bytes_in_buffer,rrc_release_info.num_UEs); - - sdu_length_total = sdu_lengths[0]; - sdu_lcids[0] = DCCH; - UE_list->eNB_UE_stats[CC_id][UE_id]. - num_pdu_tx[DCCH] += 1; - UE_list-> - eNB_UE_stats[CC_id][UE_id].num_bytes_tx[DCCH] - += sdu_lengths[0]; - num_sdus = 1; + + T(T_ENB_MAC_UE_DL_SDU, T_INT(module_idP), + T_INT(CC_id), T_INT(rnti), T_INT(frameP), + T_INT(subframeP), T_INT(harq_pid), T_INT(DCCH), + T_INT(sdu_lengths[0])); + LOG_D(MAC, + "[eNB %d][DCCH] CC_id %d frame %d subframe %d UE_id %d/%x Got %d bytes bytes_in_buffer %d from release_num %d\n", + module_idP, CC_id, frameP, subframeP, UE_id, rnti, sdu_lengths[0],rlc_status.bytes_in_buffer,rrc_release_info.num_UEs); + sdu_length_total = sdu_lengths[0]; + sdu_lcids[0] = DCCH; + UE_list->eNB_UE_stats[CC_id][UE_id]. + num_pdu_tx[DCCH] += 1; + UE_list-> + eNB_UE_stats[CC_id][UE_id].num_bytes_tx[DCCH] + += sdu_lengths[0]; + num_sdus = 1; #ifdef DEBUG_eNB_SCHEDULER - LOG_T(MAC, - "[eNB %d][DCCH] CC_id %d Got %d bytes :", - module_idP, CC_id, sdu_lengths[0]); + LOG_T(MAC, + "[eNB %d][DCCH] CC_id %d Got %d bytes :", + module_idP, CC_id, sdu_lengths[0]); - for (k = 0; k < sdu_lengths[0]; k++) { - LOG_T(MAC, "%x ", dlsch_buffer[k]); - } + for (k = 0; k < sdu_lengths[0]; k++) { + LOG_T(MAC, "%x ", dlsch_buffer[k]); + } - LOG_T(MAC, "\n"); + LOG_T(MAC, "\n"); #endif - } else { - header_len_dcch = 0; - sdu_length_total = 0; - } - } - // check for DCCH1 and update header information (assume 2 byte sub-header) - if (TBS - ta_len - header_len_dcch - sdu_length_total > 0) { - rlc_status = mac_rlc_status_ind(module_idP, rnti, module_idP, frameP, subframeP, ENB_FLAG_YES, MBMS_FLAG_NO, DCCH + 1, (TBS - ta_len - header_len_dcch - sdu_length_total) -#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - ,0, 0 -#endif - ); // transport block set size less allocations for timing advance and - // DCCH SDU - sdu_lengths[num_sdus] = 0; - - if (rlc_status.bytes_in_buffer > 0) { - LOG_D(MAC, - "[eNB %d], Frame %d, DCCH1->DLSCH, CC_id %d, Requesting %d bytes from RLC (RRC message)\n", - module_idP, frameP, CC_id, - TBS - header_len_dcch - sdu_length_total); - sdu_lengths[num_sdus] += mac_rlc_data_req(module_idP, rnti, module_idP, frameP, ENB_FLAG_YES, MBMS_FLAG_NO, DCCH + 1, TBS, //not used - (char *) - &dlsch_buffer - [sdu_length_total] -#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - ,0, 0 -#endif - ); - - T(T_ENB_MAC_UE_DL_SDU, T_INT(module_idP), - T_INT(CC_id), T_INT(rnti), T_INT(frameP), - T_INT(subframeP), T_INT(harq_pid), - T_INT(DCCH + 1), T_INT(sdu_lengths[num_sdus])); - - sdu_lcids[num_sdus] = DCCH1; - sdu_length_total += sdu_lengths[num_sdus]; - header_len_dcch += 2; - UE_list->eNB_UE_stats[CC_id][UE_id]. - num_pdu_tx[DCCH1] += 1; - UE_list-> - eNB_UE_stats[CC_id][UE_id].num_bytes_tx[DCCH1] - += sdu_lengths[num_sdus]; - num_sdus++; -#ifdef DEBUG_eNB_SCHEDULER - LOG_T(MAC, - "[eNB %d][DCCH1] CC_id %d Got %d bytes :", - module_idP, CC_id, sdu_lengths[num_sdus]); - - for (k = 0; k < sdu_lengths[num_sdus]; k++) { - LOG_T(MAC, "%x ", dlsch_buffer[k]); - } - - LOG_T(MAC, "\n"); -#endif - - } - } - // assume the max dtch header size, and adjust it later - header_len_dtch = 0; - header_len_dtch_last = 0; // the header length of the last mac sdu - // lcid has to be sorted before the actual allocation (similar struct as ue_list). - /* TODO limited lcid for performance */ - for (lcid = DTCH; lcid >= DTCH; lcid--) { - // TBD: check if the lcid is active - header_len_dtch += 3; - header_len_dtch_last = 3; - - LOG_D(MAC, "[eNB %d], Frame %d, DTCH%d->DLSCH, Checking RLC status (tbs %d, len %d)\n", - module_idP, - frameP, - lcid, - TBS, - TBS - ta_len - header_len_dcch - sdu_length_total - header_len_dtch); - - if (TBS - ta_len - header_len_dcch - sdu_length_total - header_len_dtch > 0) { // NN: > 2 ? - rlc_status = mac_rlc_status_ind(module_idP, - rnti, - module_idP, - frameP, - subframeP, - ENB_FLAG_YES, - MBMS_FLAG_NO, - lcid, - TBS - ta_len - header_len_dcch - sdu_length_total - header_len_dtch -#ifdef Rel14 - , 0, 0 -#endif - ); - - - if (rlc_status.bytes_in_buffer > 0) { - LOG_D(MAC,"[eNB %d][USER-PLANE DEFAULT DRB] Frame %d : DTCH->DLSCH, Requesting %d bytes from RLC (lcid %d total hdr len %d)\n", - module_idP, - frameP, - TBS - header_len_dcch - sdu_length_total - header_len_dtch, - lcid, - header_len_dtch); - - sdu_lengths[num_sdus] = mac_rlc_data_req(module_idP, - rnti, - module_idP, - frameP, - ENB_FLAG_YES, - MBMS_FLAG_NO, - lcid, - TBS, //not used - (char *)&dlsch_buffer[sdu_length_total] -#ifdef Rel14 - , 0, 0 -#endif - ); - - T(T_ENB_MAC_UE_DL_SDU, - T_INT(module_idP), - T_INT(CC_id), - T_INT(rnti), - T_INT(frameP), - T_INT(subframeP), - T_INT(harq_pid), - T_INT(lcid), - T_INT(sdu_lengths[num_sdus])); - - LOG_D(MAC, "[eNB %d][USER-PLANE DEFAULT DRB] Got %d bytes for DTCH %d \n", - module_idP, - sdu_lengths[num_sdus], - lcid); - - sdu_lcids[num_sdus] = lcid; - sdu_length_total += sdu_lengths[num_sdus]; - UE_list->eNB_UE_stats[CC_id][UE_id].num_pdu_tx[lcid] += 1; - UE_list->eNB_UE_stats[CC_id][UE_id].num_bytes_tx[lcid] += sdu_lengths[num_sdus]; - - if (sdu_lengths[num_sdus] < 128) { - header_len_dtch--; - header_len_dtch_last--; - } - - num_sdus++; - - UE_list->UE_sched_ctrl[UE_id].uplane_inactivity_timer = 0; - - } else { // no data for this LCID - header_len_dtch -= 3; + } else { + header_len_dcch = 0; + sdu_length_total = 0; + } } - - } else { // no TBS left - header_len_dtch -= 3; - - break; - } - } - if (header_len_dtch == 0) - header_len_dtch_last = 0; - // there is at least one SDU - // if (num_sdus > 0 ){ - if ((sdu_length_total + header_len_dcch + - header_len_dtch) > 0) { - // Now compute number of required RBs for total sdu length - // Assume RAH format 2 - // adjust header lengths - header_len_dcch_tmp = header_len_dcch; - header_len_dtch_tmp = header_len_dtch; - if (header_len_dtch == 0) { - header_len_dcch = (header_len_dcch > 0) ? 1 : 0; //header_len_dcch; // remove length field - } else { - header_len_dtch_last -= 1; // now use it to find how many bytes has to be removed for the last MAC SDU - header_len_dtch = (header_len_dtch > 0) ? header_len_dtch - header_len_dtch_last : header_len_dtch; // remove length field for the last SDU - } - - mcs = eNB_UE_stats->dlsch_mcs1; - nb_rb = min_rb_unit[CC_id]; - TBS = get_TBS_DL(mcs, nb_rb); - - while (TBS < - (sdu_length_total + header_len_dcch + - header_len_dtch + ta_len)) { - nb_rb += min_rb_unit[CC_id]; // - - if (nb_rb > nb_available_rb) { // if we've gone beyond the maximum number of RBs - // (can happen if N_RB_DL is odd) - TBS = - get_TBS_DL(eNB_UE_stats->dlsch_mcs1, - nb_available_rb); - nb_rb = nb_available_rb; - break; - } - - TBS = get_TBS_DL(eNB_UE_stats->dlsch_mcs1, nb_rb); - } - - if (nb_rb == ue_sched_ctl->pre_nb_available_rbs[CC_id]) { - for (j = 0; j < N_RBG[CC_id]; j++) { // for indicating the rballoc for each sub-band - UE_list->UE_template[CC_id][UE_id]. - rballoc_subband[harq_pid][j] = - ue_sched_ctl->rballoc_sub_UE[CC_id][j]; - } - } else { - nb_rb_temp = nb_rb; - j = 0; - - while ((nb_rb_temp > 0) && (j < N_RBG[CC_id])) { - if (ue_sched_ctl->rballoc_sub_UE[CC_id][j] == - 1) { - UE_list-> - UE_template[CC_id] - [UE_id].rballoc_subband[harq_pid][j] = - ue_sched_ctl->rballoc_sub_UE[CC_id][j]; - - if ((j == N_RBG[CC_id] - 1) && - ((N_RB_DL[CC_id] == 25) || - (N_RB_DL[CC_id] == 50))) { - nb_rb_temp = - nb_rb_temp - min_rb_unit[CC_id] + - 1; - } else { - nb_rb_temp = - nb_rb_temp - min_rb_unit[CC_id]; - } - } - - j = j + 1; - } - } - - // decrease mcs until TBS falls below required length - while ((TBS > - (sdu_length_total + header_len_dcch + - header_len_dtch + ta_len)) && (mcs > 0)) { - mcs--; - TBS = get_TBS_DL(mcs, nb_rb); - } - - // if we have decreased too much or we don't have enough RBs, increase MCS - while ((TBS < - (sdu_length_total + header_len_dcch + - header_len_dtch + ta_len)) - && (((ue_sched_ctl->dl_pow_off[CC_id] > 0) - && (mcs < 28)) - || ((ue_sched_ctl->dl_pow_off[CC_id] == 0) - && (mcs <= 15)))) { - mcs++; - TBS = get_TBS_DL(mcs, nb_rb); - } - - LOG_D(MAC, - "dlsch_mcs before and after the rate matching = (%d, %d)\n", - eNB_UE_stats->dlsch_mcs1, mcs); + // check for DCCH1 and update header information (assume 2 byte sub-header) + if (TBS - ta_len - header_len_dcch - sdu_length_total > 0) { + rlc_status = mac_rlc_status_ind(module_idP, rnti, module_idP, frameP, subframeP, ENB_FLAG_YES, MBMS_FLAG_NO, DCCH + 1, (TBS - ta_len - header_len_dcch - sdu_length_total) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + ,0, 0 +#endif + ); // transport block set size less allocations for timing advance and + // DCCH SDU + sdu_lengths[num_sdus] = 0; + if (rlc_status.bytes_in_buffer > 0) { + LOG_D(MAC, + "[eNB %d], Frame %d, DCCH1->DLSCH, CC_id %d, Requesting %d bytes from RLC (RRC message)\n", + module_idP, frameP, CC_id, + TBS - header_len_dcch - sdu_length_total); + sdu_lengths[num_sdus] += mac_rlc_data_req(module_idP, rnti, module_idP, frameP, ENB_FLAG_YES, MBMS_FLAG_NO, DCCH + 1, TBS, //not used + (char *) + &dlsch_buffer + [sdu_length_total] +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + ,0, 0 +#endif + ); + T(T_ENB_MAC_UE_DL_SDU, T_INT(module_idP), + T_INT(CC_id), T_INT(rnti), T_INT(frameP), + T_INT(subframeP), T_INT(harq_pid), + T_INT(DCCH + 1), T_INT(sdu_lengths[num_sdus])); + sdu_lcids[num_sdus] = DCCH1; + sdu_length_total += sdu_lengths[num_sdus]; + header_len_dcch += 2; + UE_list->eNB_UE_stats[CC_id][UE_id]. + num_pdu_tx[DCCH1] += 1; + UE_list-> + eNB_UE_stats[CC_id][UE_id].num_bytes_tx[DCCH1] + += sdu_lengths[num_sdus]; + num_sdus++; #ifdef DEBUG_eNB_SCHEDULER - LOG_D(MAC, - "[eNB %d] CC_id %d Generated DLSCH header (mcs %d, TBS %d, nb_rb %d)\n", - module_idP, CC_id, mcs, TBS, nb_rb); - // msg("[MAC][eNB ] Reminder of DLSCH with random data %d %d %d %d \n", - // TBS, sdu_length_total, offset, TBS-sdu_length_total-offset); + LOG_T(MAC, + "[eNB %d][DCCH1] CC_id %d Got %d bytes :", + module_idP, CC_id, sdu_lengths[num_sdus]); + + for (k = 0; k < sdu_lengths[num_sdus]; k++) { + LOG_T(MAC, "%x ", dlsch_buffer[k]); + } + + LOG_T(MAC, "\n"); +#endif + } + } + + // assume the max dtch header size, and adjust it later + header_len_dtch = 0; + header_len_dtch_last = 0; // the header length of the last mac sdu + + // lcid has to be sorted before the actual allocation (similar struct as ue_list). + /* TODO limited lcid for performance */ + for (lcid = DTCH; lcid >= DTCH; lcid--) { + // TBD: check if the lcid is active + header_len_dtch += 3; + header_len_dtch_last = 3; + LOG_D(MAC, "[eNB %d], Frame %d, DTCH%d->DLSCH, Checking RLC status (tbs %d, len %d)\n", + module_idP, + frameP, + lcid, + TBS, + TBS - ta_len - header_len_dcch - sdu_length_total - header_len_dtch); + + if (TBS - ta_len - header_len_dcch - sdu_length_total - header_len_dtch > 0) { // NN: > 2 ? + rlc_status = mac_rlc_status_ind(module_idP, + rnti, + module_idP, + frameP, + subframeP, + ENB_FLAG_YES, + MBMS_FLAG_NO, + lcid, + TBS - ta_len - header_len_dcch - sdu_length_total - header_len_dtch +#ifdef Rel14 + , 0, 0 +#endif + ); + + if (rlc_status.bytes_in_buffer > 0) { + LOG_D(MAC,"[eNB %d][USER-PLANE DEFAULT DRB] Frame %d : DTCH->DLSCH, Requesting %d bytes from RLC (lcid %d total hdr len %d)\n", + module_idP, + frameP, + TBS - header_len_dcch - sdu_length_total - header_len_dtch, + lcid, + header_len_dtch); + sdu_lengths[num_sdus] = mac_rlc_data_req(module_idP, + rnti, + module_idP, + frameP, + ENB_FLAG_YES, + MBMS_FLAG_NO, + lcid, + TBS, //not used + (char *)&dlsch_buffer[sdu_length_total] +#ifdef Rel14 + , 0, 0 +#endif + ); + T(T_ENB_MAC_UE_DL_SDU, + T_INT(module_idP), + T_INT(CC_id), + T_INT(rnti), + T_INT(frameP), + T_INT(subframeP), + T_INT(harq_pid), + T_INT(lcid), + T_INT(sdu_lengths[num_sdus])); + LOG_D(MAC, "[eNB %d][USER-PLANE DEFAULT DRB] Got %d bytes for DTCH %d \n", + module_idP, + sdu_lengths[num_sdus], + lcid); + sdu_lcids[num_sdus] = lcid; + sdu_length_total += sdu_lengths[num_sdus]; + UE_list->eNB_UE_stats[CC_id][UE_id].num_pdu_tx[lcid] += 1; + UE_list->eNB_UE_stats[CC_id][UE_id].num_bytes_tx[lcid] += sdu_lengths[num_sdus]; + + if (sdu_lengths[num_sdus] < 128) { + header_len_dtch--; + header_len_dtch_last--; + } + + num_sdus++; + UE_list->UE_sched_ctrl[UE_id].uplane_inactivity_timer = 0; + } else { // no data for this LCID + header_len_dtch -= 3; + } + } else { // no TBS left + header_len_dtch -= 3; + break; + } + } + + if (header_len_dtch == 0) + header_len_dtch_last = 0; + + // there is at least one SDU + // if (num_sdus > 0 ){ + if ((sdu_length_total + header_len_dcch + + header_len_dtch) > 0) { + // Now compute number of required RBs for total sdu length + // Assume RAH format 2 + // adjust header lengths + header_len_dcch_tmp = header_len_dcch; + header_len_dtch_tmp = header_len_dtch; + + if (header_len_dtch == 0) { + header_len_dcch = (header_len_dcch > 0) ? 1 : 0; //header_len_dcch; // remove length field + } else { + header_len_dtch_last -= 1; // now use it to find how many bytes has to be removed for the last MAC SDU + header_len_dtch = (header_len_dtch > 0) ? header_len_dtch - header_len_dtch_last : header_len_dtch; // remove length field for the last SDU + } + + mcs = eNB_UE_stats->dlsch_mcs1; + nb_rb = min_rb_unit[CC_id]; + TBS = get_TBS_DL(mcs, nb_rb); + + while (TBS < + (sdu_length_total + header_len_dcch + + header_len_dtch + ta_len)) { + nb_rb += min_rb_unit[CC_id]; // + + if (nb_rb > nb_available_rb) { // if we've gone beyond the maximum number of RBs + // (can happen if N_RB_DL is odd) + TBS = + get_TBS_DL(eNB_UE_stats->dlsch_mcs1, + nb_available_rb); + nb_rb = nb_available_rb; + break; + } + + TBS = get_TBS_DL(eNB_UE_stats->dlsch_mcs1, nb_rb); + } + + if (nb_rb == ue_sched_ctl->pre_nb_available_rbs[CC_id]) { + for (j = 0; j < N_RBG[CC_id]; j++) { // for indicating the rballoc for each sub-band + UE_list->UE_template[CC_id][UE_id]. + rballoc_subband[harq_pid][j] = + ue_sched_ctl->rballoc_sub_UE[CC_id][j]; + } + } else { + nb_rb_temp = nb_rb; + j = 0; + + while ((nb_rb_temp > 0) && (j < N_RBG[CC_id])) { + if (ue_sched_ctl->rballoc_sub_UE[CC_id][j] == + 1) { + UE_list-> + UE_template[CC_id] + [UE_id].rballoc_subband[harq_pid][j] = + ue_sched_ctl->rballoc_sub_UE[CC_id][j]; + + if ((j == N_RBG[CC_id] - 1) && + ((N_RB_DL[CC_id] == 25) || + (N_RB_DL[CC_id] == 50))) { + nb_rb_temp = + nb_rb_temp - min_rb_unit[CC_id] + + 1; + } else { + nb_rb_temp = + nb_rb_temp - min_rb_unit[CC_id]; + } + } + + j = j + 1; + } + } + + // decrease mcs until TBS falls below required length + while ((TBS > + (sdu_length_total + header_len_dcch + + header_len_dtch + ta_len)) && (mcs > 0)) { + mcs--; + TBS = get_TBS_DL(mcs, nb_rb); + } + + // if we have decreased too much or we don't have enough RBs, increase MCS + while ((TBS < + (sdu_length_total + header_len_dcch + + header_len_dtch + ta_len)) + && (((ue_sched_ctl->dl_pow_off[CC_id] > 0) + && (mcs < 28)) + || ((ue_sched_ctl->dl_pow_off[CC_id] == 0) + && (mcs <= 15)))) { + mcs++; + TBS = get_TBS_DL(mcs, nb_rb); + } + + LOG_D(MAC, + "dlsch_mcs before and after the rate matching = (%d, %d)\n", + eNB_UE_stats->dlsch_mcs1, mcs); +#ifdef DEBUG_eNB_SCHEDULER + LOG_D(MAC, + "[eNB %d] CC_id %d Generated DLSCH header (mcs %d, TBS %d, nb_rb %d)\n", + module_idP, CC_id, mcs, TBS, nb_rb); + // msg("[MAC][eNB ] Reminder of DLSCH with random data %d %d %d %d \n", + // TBS, sdu_length_total, offset, TBS-sdu_length_total-offset); #endif - if ((TBS - header_len_dcch - header_len_dtch - - sdu_length_total - ta_len) <= 2) { - padding = - (TBS - header_len_dcch - header_len_dtch - - sdu_length_total - ta_len); - post_padding = 0; - } else { - padding = 0; + if ((TBS - header_len_dcch - header_len_dtch - + sdu_length_total - ta_len) <= 2) { + padding = + (TBS - header_len_dcch - header_len_dtch - + sdu_length_total - ta_len); + post_padding = 0; + } else { + padding = 0; - // adjust the header len - if (header_len_dtch == 0) { - header_len_dcch = header_len_dcch_tmp; - } else { //if (( header_len_dcch==0)&&((header_len_dtch==1)||(header_len_dtch==2))) - header_len_dtch = header_len_dtch_tmp; - } + // adjust the header len + if (header_len_dtch == 0) { + header_len_dcch = header_len_dcch_tmp; + } else { //if (( header_len_dcch==0)&&((header_len_dtch==1)||(header_len_dtch==2))) + header_len_dtch = header_len_dtch_tmp; + } - post_padding = TBS - sdu_length_total - header_len_dcch - header_len_dtch - ta_len; // 1 is for the postpadding header - } + post_padding = TBS - sdu_length_total - header_len_dcch - header_len_dtch - ta_len; // 1 is for the postpadding header + } #ifdef PHY_TX_THREAD - struct timespec time_req, time_rem; - time_req.tv_sec = 0; - time_req.tv_nsec = 10000; - while((!oai_exit)&&(phy_tx_txdataF_end == 0)){ - nanosleep(&time_req,&time_rem); - continue; - } + struct timespec time_req, time_rem; + time_req.tv_sec = 0; + time_req.tv_nsec = 10000; + + while((!oai_exit)&&(phy_tx_txdataF_end == 0)) { + nanosleep(&time_req,&time_rem); + continue; + } + #endif + offset = generate_dlsch_header((unsigned char *) UE_list->DLSCH_pdu[CC_id][0][UE_id].payload[0], num_sdus, //num_sdus + sdu_lengths, // + sdu_lcids, 255, // no drx + ta_update, // timing advance + NULL, // contention res id + padding, post_padding); - offset = generate_dlsch_header((unsigned char *) UE_list->DLSCH_pdu[CC_id][0][UE_id].payload[0], num_sdus, //num_sdus - sdu_lengths, // - sdu_lcids, 255, // no drx - ta_update, // timing advance - NULL, // contention res id - padding, post_padding); + //#ifdef DEBUG_eNB_SCHEDULER + if (ta_update != 31) { + LOG_D(MAC, + "[eNB %d][DLSCH] Frame %d Generate header for UE_id %d on CC_id %d: sdu_length_total %d, num_sdus %d, sdu_lengths[0] %d, sdu_lcids[0] %d => payload offset %d,timing advance value : %d, padding %d,post_padding %d,(mcs %d, TBS %d, nb_rb %d),header_dcch %d, header_dtch %d\n", + module_idP, frameP, UE_id, CC_id, + sdu_length_total, num_sdus, sdu_lengths[0], + sdu_lcids[0], offset, ta_update, padding, + post_padding, mcs, TBS, nb_rb, + header_len_dcch, header_len_dtch); + } - //#ifdef DEBUG_eNB_SCHEDULER - if (ta_update != 31) { - LOG_D(MAC, - "[eNB %d][DLSCH] Frame %d Generate header for UE_id %d on CC_id %d: sdu_length_total %d, num_sdus %d, sdu_lengths[0] %d, sdu_lcids[0] %d => payload offset %d,timing advance value : %d, padding %d,post_padding %d,(mcs %d, TBS %d, nb_rb %d),header_dcch %d, header_dtch %d\n", - module_idP, frameP, UE_id, CC_id, - sdu_length_total, num_sdus, sdu_lengths[0], - sdu_lcids[0], offset, ta_update, padding, - post_padding, mcs, TBS, nb_rb, - header_len_dcch, header_len_dtch); - } - //#endif + //#endif #ifdef DEBUG_eNB_SCHEDULER - LOG_T(MAC, "[eNB %d] First 16 bytes of DLSCH : \n",module_idP ); + LOG_T(MAC, "[eNB %d] First 16 bytes of DLSCH : \n",module_idP ); - for (k = 0; k < 16; k++) { - LOG_T(MAC, "%x.", dlsch_buffer[k]); - } + for (k = 0; k < 16; k++) { + LOG_T(MAC, "%x.", dlsch_buffer[k]); + } - LOG_T(MAC, "\n"); + LOG_T(MAC, "\n"); #endif - // cycle through SDUs and place in dlsch_buffer memcpy(&UE_list->DLSCH_pdu[CC_id][0][UE_id].payload[0][offset],dlsch_buffer,sdu_length_total); // memcpy(RC.mac[0].DLSCH_pdu[0][0].payload[0][offset],dcch_buffer,sdu_lengths[0]); @@ -1676,9 +1685,7 @@ schedule_ue_spec_fairRR(module_id_t module_idP, T(T_ENB_MAC_UE_DL_PDU_WITH_DATA, T_INT(module_idP), T_INT(CC_id), T_INT(rnti), T_INT(frameP), T_INT(subframeP), T_INT(harq_pid), T_BUFFER(UE_list->DLSCH_pdu[CC_id][0][UE_id].payload[0], TBS)); - - UE_list->UE_template[CC_id][UE_id].nb_rb[harq_pid] = nb_rb; - + UE_list->UE_template[CC_id][UE_id].nb_rb[harq_pid] = nb_rb; add_ue_dlsch_info(module_idP, CC_id, UE_id, @@ -1687,13 +1694,11 @@ schedule_ue_spec_fairRR(module_id_t module_idP, // store stats eNB->eNB_stats[CC_id].dlsch_bytes_tx+=sdu_length_total; eNB->eNB_stats[CC_id].dlsch_pdus_tx+=1; - UE_list->eNB_UE_stats[CC_id][UE_id].rbs_used = nb_rb; UE_list->eNB_UE_stats[CC_id][UE_id].total_rbs_used += nb_rb; UE_list->eNB_UE_stats[CC_id][UE_id].dlsch_mcs1=eNB_UE_stats->dlsch_mcs1; UE_list->eNB_UE_stats[CC_id][UE_id].dlsch_mcs2=mcs; UE_list->eNB_UE_stats[CC_id][UE_id].TBS = TBS; - UE_list->eNB_UE_stats[CC_id][UE_id].overhead_bytes= TBS- sdu_length_total; UE_list->eNB_UE_stats[CC_id][UE_id].total_sdu_bytes+= sdu_length_total; UE_list->eNB_UE_stats[CC_id][UE_id].total_pdu_bytes+= TBS; @@ -1704,168 +1709,152 @@ schedule_ue_spec_fairRR(module_id_t module_idP, update_ul_dci(module_idP,CC_id,rnti,UE_list->UE_template[CC_id][UE_id].DAI,subframeP); } - // do PUCCH power control + // do PUCCH power control // this is the normalized RX power - eNB_UE_stats = &UE_list->eNB_UE_stats[CC_id][UE_id]; - + eNB_UE_stats = &UE_list->eNB_UE_stats[CC_id][UE_id]; /* Unit is not dBm, it's special from nfapi */ - normalized_rx_power = (5*ue_sched_ctl->pucch1_snr[CC_id]-640)/10+30;//(+eNB->measurements.n0_power_dB[0]) - target_rx_power= eNB->puCch10xSnr/10 + 30;//(+eNB->measurements.n0_power_dB[0]) - + normalized_rx_power = (5*ue_sched_ctl->pucch1_snr[CC_id]-640)/10+30;//(+eNB->measurements.n0_power_dB[0]) + target_rx_power= eNB->puCch10xSnr/10 + 30;//(+eNB->measurements.n0_power_dB[0]) // this assumes accumulated tpc - // make sure that we are only sending a tpc update once a frame, otherwise the control loop will freak out - int32_t framex10psubframe = UE_list->UE_template[CC_id][UE_id].pucch_tpc_tx_frame*10+UE_list->UE_template[CC_id][UE_id].pucch_tpc_tx_subframe; + // make sure that we are only sending a tpc update once a frame, otherwise the control loop will freak out + int32_t framex10psubframe = UE_list->UE_template[CC_id][UE_id].pucch_tpc_tx_frame*10+UE_list->UE_template[CC_id][UE_id].pucch_tpc_tx_subframe; + if (((framex10psubframe+10)<=(frameP*10+subframeP)) || //normal case - ((framex10psubframe>(frameP*10+subframeP)) && (((10240-framex10psubframe+frameP*10+subframeP)>=10)))) //frame wrap-around - if (ue_sched_ctl->pucch1_cqi_update[CC_id] == 1) { - ue_sched_ctl->pucch1_cqi_update[CC_id] = 0; + ((framex10psubframe>(frameP*10+subframeP)) && (((10240-framex10psubframe+frameP*10+subframeP)>=10)))) //frame wrap-around + if (ue_sched_ctl->pucch1_cqi_update[CC_id] == 1) { + ue_sched_ctl->pucch1_cqi_update[CC_id] = 0; + UE_list->UE_template[CC_id][UE_id].pucch_tpc_tx_frame=frameP; + UE_list->UE_template[CC_id][UE_id].pucch_tpc_tx_subframe=subframeP; - UE_list->UE_template[CC_id][UE_id].pucch_tpc_tx_frame=frameP; - UE_list->UE_template[CC_id][UE_id].pucch_tpc_tx_subframe=subframeP; - - if (normalized_rx_power>(target_rx_power+4)) { - tpc = 0; //-1 - tpc_accumulated--; - } else if (normalized_rx_power<(target_rx_power-4)) { - tpc = 2; //+1 - tpc_accumulated++; - } else { - tpc = 1; //0 - } - - LOG_D(MAC,"[eNB %d] DLSCH scheduler: frame %d, subframe %d, harq_pid %d, tpc %d, accumulated %d, normalized/target rx power %d/%d\n", - module_idP,frameP, subframeP,harq_pid,tpc, - tpc_accumulated,normalized_rx_power,target_rx_power); + if (normalized_rx_power>(target_rx_power+4)) { + tpc = 0; //-1 + tpc_accumulated--; + } else if (normalized_rx_power<(target_rx_power-4)) { + tpc = 2; //+1 + tpc_accumulated++; + } else { + tpc = 1; //0 + } - } // Po_PUCCH has been updated - else { - tpc = 1; //0 - } // time to do TPC update - else { - tpc = 1; //0 - } + LOG_D(MAC,"[eNB %d] DLSCH scheduler: frame %d, subframe %d, harq_pid %d, tpc %d, accumulated %d, normalized/target rx power %d/%d\n", + module_idP,frameP, subframeP,harq_pid,tpc, + tpc_accumulated,normalized_rx_power,target_rx_power); + } // Po_PUCCH has been updated + else { + tpc = 1; //0 + } // time to do TPC update + else { + tpc = 1; //0 + } - dl_config_pdu = &dl_req->dl_config_pdu_list[dl_req->number_pdu]; - memset((void*)dl_config_pdu,0,sizeof(nfapi_dl_config_request_pdu_t)); - dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE; - dl_config_pdu->pdu_size = (uint8_t)(2+sizeof(nfapi_dl_config_dci_dl_pdu)); - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.dci_format = NFAPI_DL_DCI_FORMAT_1; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level = get_aggregation(get_bw_index(module_idP,CC_id),ue_sched_ctl->dl_cqi[CC_id],format1); - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti = rnti; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti_type = 1; // CRNTI : see Table 4-10 from SCF082 - nFAPI specifications - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.transmission_power = 6000; // equal to RS power - - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.harq_process = harq_pid; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tpc = tpc; // dont adjust power when retransmitting - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.new_data_indicator_1 = 1-UE_list->UE_template[CC_id][UE_id].oldNDI[harq_pid]; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.mcs_1 = mcs; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.redundancy_version_1 = 0; - //deactivate second codeword - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.mcs_2 = 0; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.redundancy_version_2 = 1; - if (cc[CC_id].tdd_Config != NULL) { //TDD - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.downlink_assignment_index = (UE_list->UE_template[CC_id][UE_id].DAI-1)&3; - LOG_D(MAC,"[eNB %d] Initial transmission CC_id %d : harq_pid %d, dai %d, mcs %d\n", - module_idP,CC_id,harq_pid, - (UE_list->UE_template[CC_id][UE_id].DAI-1), - mcs); - } else { - LOG_D(MAC,"[eNB %d] Initial transmission CC_id %d : harq_pid %d, mcs %d\n", - module_idP,CC_id,harq_pid,mcs); - - } - LOG_D(MAC,"Checking feasibility pdu %d (new sdu)\n",dl_req->number_pdu); - if (!CCE_allocation_infeasible(module_idP,CC_id,1,subframeP,dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level,rnti)) { + dl_config_pdu = &dl_req->dl_config_pdu_list[dl_req->number_pdu]; + memset((void *)dl_config_pdu,0,sizeof(nfapi_dl_config_request_pdu_t)); + dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE; + dl_config_pdu->pdu_size = (uint8_t)(2+sizeof(nfapi_dl_config_dci_dl_pdu)); + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.dci_format = NFAPI_DL_DCI_FORMAT_1; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level = get_aggregation(get_bw_index(module_idP,CC_id),ue_sched_ctl->dl_cqi[CC_id],format1); + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti = rnti; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti_type = 1; // CRNTI : see Table 4-10 from SCF082 - nFAPI specifications + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.transmission_power = 6000; // equal to RS power + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.harq_process = harq_pid; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tpc = tpc; // dont adjust power when retransmitting + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.new_data_indicator_1 = 1-UE_list->UE_template[CC_id][UE_id].oldNDI[harq_pid]; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.mcs_1 = mcs; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.redundancy_version_1 = 0; + //deactivate second codeword + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.mcs_2 = 0; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.redundancy_version_2 = 1; + if (cc[CC_id].tdd_Config != NULL) { //TDD + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.downlink_assignment_index = (UE_list->UE_template[CC_id][UE_id].DAI-1)&3; + LOG_D(MAC,"[eNB %d] Initial transmission CC_id %d : harq_pid %d, dai %d, mcs %d\n", + module_idP,CC_id,harq_pid, + (UE_list->UE_template[CC_id][UE_id].DAI-1), + mcs); + } else { + LOG_D(MAC,"[eNB %d] Initial transmission CC_id %d : harq_pid %d, mcs %d\n", + module_idP,CC_id,harq_pid,mcs); + } - ue_sched_ctl->round[CC_id][harq_pid] = 0; - dl_req->number_dci++; - dl_req->number_pdu++; - dl_req->tl.tag = NFAPI_DL_CONFIG_REQUEST_BODY_TAG; - - eNB->DL_req[CC_id].sfn_sf = frameP<<4 | subframeP; - eNB->DL_req[CC_id].header.message_id = NFAPI_DL_CONFIG_REQUEST; - // Toggle NDI for next time - LOG_D(MAC,"CC_id %d Frame %d, subframeP %d: Toggling Format1 NDI for UE %d (rnti %x/%d) oldNDI %d\n", - CC_id, frameP,subframeP,UE_id, - rnti,harq_pid,UE_list->UE_template[CC_id][UE_id].oldNDI[harq_pid]); - - UE_list->UE_template[CC_id][UE_id].oldNDI[harq_pid]=1-UE_list->UE_template[CC_id][UE_id].oldNDI[harq_pid]; - UE_list->UE_template[CC_id][UE_id].oldmcs1[harq_pid] = mcs; - UE_list->UE_template[CC_id][UE_id].oldmcs2[harq_pid] = 0; - AssertFatal(UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated!=NULL,"physicalConfigDedicated is NULL\n"); - AssertFatal(UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->pdsch_ConfigDedicated!=NULL,"physicalConfigDedicated->pdsch_ConfigDedicated is NULL\n"); - - fill_nfapi_dlsch_config(eNB,dl_req, - TBS, - eNB->pdu_index[CC_id], - rnti, - 0, // type 0 allocation from 7.1.6 in 36.213 - 0, // virtual_resource_block_assignment_flag, unused here - 0, // resource_block_coding, to be filled in later - getQm(mcs), - 0, // redundancy version - 1, // transport blocks - 0, // transport block to codeword swap flag - cc[CC_id].p_eNB == 1 ? 0 : 1, // transmission_scheme - 1, // number of layers - 1, // number of subbands - // uint8_t codebook_index, - 4, // UE category capacity - UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->pdsch_ConfigDedicated->p_a, - 0, // delta_power_offset for TM5 - 0, // ngap - 0, // nprb - cc[CC_id].p_eNB == 1 ? 1 : 2, // transmission mode - 0, //number of PRBs treated as one subband, not used here - 0 // number of beamforming vectors, not used here - ); - eNB->TX_req[CC_id].sfn_sf = fill_nfapi_tx_req(&eNB->TX_req[CC_id].tx_request_body, - (frameP*10)+subframeP, - TBS, - eNB->pdu_index[CC_id], - eNB->UE_list.DLSCH_pdu[CC_id][0][(unsigned char)UE_id].payload[0]); - - LOG_D(MAC,"Filled NFAPI configuration for DCI/DLSCH/TXREQ %d, new SDU\n",eNB->pdu_index[CC_id]); + LOG_D(MAC,"Checking feasibility pdu %d (new sdu)\n",dl_req->number_pdu); - eNB->pdu_index[CC_id]++; - program_dlsch_acknak(module_idP,CC_id,UE_id,frameP,subframeP,dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.cce_idx); - last_dlsch_ue_id[CC_id] = UE_id; - } - else { - LOG_W(MAC,"Frame %d, Subframe %d: Dropping DLSCH allocation for UE %d/%x, infeasible CCE allocations\n", - frameP,subframeP,UE_id,rnti); - } + if (!CCE_allocation_infeasible(module_idP,CC_id,1,subframeP,dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level,rnti)) { + ue_sched_ctl->round[CC_id][harq_pid] = 0; + dl_req->number_dci++; + dl_req->number_pdu++; + dl_req->tl.tag = NFAPI_DL_CONFIG_REQUEST_BODY_TAG; + eNB->DL_req[CC_id].sfn_sf = frameP<<4 | subframeP; + eNB->DL_req[CC_id].header.message_id = NFAPI_DL_CONFIG_REQUEST; + // Toggle NDI for next time + LOG_D(MAC,"CC_id %d Frame %d, subframeP %d: Toggling Format1 NDI for UE %d (rnti %x/%d) oldNDI %d\n", + CC_id, frameP,subframeP,UE_id, + rnti,harq_pid,UE_list->UE_template[CC_id][UE_id].oldNDI[harq_pid]); + UE_list->UE_template[CC_id][UE_id].oldNDI[harq_pid]=1-UE_list->UE_template[CC_id][UE_id].oldNDI[harq_pid]; + UE_list->UE_template[CC_id][UE_id].oldmcs1[harq_pid] = mcs; + UE_list->UE_template[CC_id][UE_id].oldmcs2[harq_pid] = 0; + AssertFatal(UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated!=NULL,"physicalConfigDedicated is NULL\n"); + AssertFatal(UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->pdsch_ConfigDedicated!=NULL,"physicalConfigDedicated->pdsch_ConfigDedicated is NULL\n"); + fill_nfapi_dlsch_config(eNB,dl_req, + TBS, + eNB->pdu_index[CC_id], + rnti, + 0, // type 0 allocation from 7.1.6 in 36.213 + 0, // virtual_resource_block_assignment_flag, unused here + 0, // resource_block_coding, to be filled in later + getQm(mcs), + 0, // redundancy version + 1, // transport blocks + 0, // transport block to codeword swap flag + cc[CC_id].p_eNB == 1 ? 0 : 1, // transmission_scheme + 1, // number of layers + 1, // number of subbands + // uint8_t codebook_index, + 4, // UE category capacity + UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->pdsch_ConfigDedicated->p_a, + 0, // delta_power_offset for TM5 + 0, // ngap + 0, // nprb + cc[CC_id].p_eNB == 1 ? 1 : 2, // transmission mode + 0, //number of PRBs treated as one subband, not used here + 0 // number of beamforming vectors, not used here + ); + eNB->TX_req[CC_id].sfn_sf = fill_nfapi_tx_req(&eNB->TX_req[CC_id].tx_request_body, + (frameP*10)+subframeP, + TBS, + eNB->pdu_index[CC_id], + eNB->UE_list.DLSCH_pdu[CC_id][0][(unsigned char)UE_id].payload[0]); + LOG_D(MAC,"Filled NFAPI configuration for DCI/DLSCH/TXREQ %d, new SDU\n",eNB->pdu_index[CC_id]); + eNB->pdu_index[CC_id]++; + program_dlsch_acknak(module_idP,CC_id,UE_id,frameP,subframeP,dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.cce_idx); + last_dlsch_ue_id[CC_id] = UE_id; + } else { + LOG_W(MAC,"Frame %d, Subframe %d: Dropping DLSCH allocation for UE %d/%x, infeasible CCE allocations\n", + frameP,subframeP,UE_id,rnti); + } } else { // There is no data from RLC or MAC header, so don't schedule - } } - if (cc[CC_id].tdd_Config != NULL){ // TDD + if (cc[CC_id].tdd_Config != NULL) { // TDD set_ul_DAI(module_idP,UE_id,CC_id,frameP,subframeP); } - } // UE_id loop } // CC_id loop - fill_DLSCH_dci_fairRR(module_idP,frameP,subframeP,mbsfn_flag); stop_meas(&eNB->schedule_dlsch); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_SCHEDULE_DLSCH,VCD_FUNCTION_OUT); - - } //------------------------------------------------------------------------------ void fill_DLSCH_dci_fairRR( - module_id_t module_idP, - frame_t frameP, - sub_frame_t subframeP, - int* mbsfn_flagP) + module_id_t module_idP, + frame_t frameP, + sub_frame_t subframeP, + int *mbsfn_flagP) //------------------------------------------------------------------------------ { - // loop over all allocated UEs and compute frequency allocations for PDSCH int UE_id = -1; uint8_t /* first_rb, */ nb_rb=3; @@ -1873,7 +1862,6 @@ fill_DLSCH_dci_fairRR( //unsigned char *vrb_map; uint8_t rballoc_sub[25]; //uint8_t number_of_subbands=13; - //unsigned char round; unsigned char harq_pid; int i; @@ -1899,65 +1887,63 @@ fill_DLSCH_dci_fairRR( // UE specific DCIs for (j = 0; j < dlsch_ue_select[CC_id].ue_num; j++) { - if(dlsch_ue_select[CC_id].list[j].ue_priority == SCH_DL_MSG2){ + if(dlsch_ue_select[CC_id].list[j].ue_priority == SCH_DL_MSG2) { continue; } - if(dlsch_ue_select[CC_id].list[j].ue_priority == SCH_DL_MSG4){ + + if(dlsch_ue_select[CC_id].list[j].ue_priority == SCH_DL_MSG4) { continue; } + UE_id = dlsch_ue_select[CC_id].list[j].UE_id; LOG_T(MAC,"CC_id %d, UE_id: %d => status %d\n",CC_id,UE_id,eNB_dlsch_info[module_idP][CC_id][UE_id].status); if (eNB_dlsch_info[module_idP][CC_id][UE_id].status == S_DL_SCHEDULED) { - // clear scheduling flag eNB_dlsch_info[module_idP][CC_id][UE_id].status = S_DL_WAITING; rnti = UE_RNTI(module_idP,UE_id); - harq_pid = frame_subframe2_dl_harq_pid(cc->tdd_Config,frameP ,subframeP); + harq_pid = frame_subframe2_dl_harq_pid(cc->tdd_Config,frameP,subframeP); nb_rb = UE_list->UE_template[CC_id][UE_id].nb_rb[harq_pid]; - - /// Synchronizing rballoc with rballoc_sub for(i=0; iUE_template[CC_id][UE_id].rballoc_subband[harq_pid][i]; } - nfapi_dl_config_request_t *DL_req = &RC.mac[module_idP]->DL_req[0]; - nfapi_dl_config_request_pdu_t* dl_config_pdu; + nfapi_dl_config_request_t *DL_req = &RC.mac[module_idP]->DL_req[0]; + nfapi_dl_config_request_pdu_t *dl_config_pdu; - for (i=0;ipdu_type == NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE)&& - (dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti == rnti) && - (dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.dci_format != 1)) { - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.resource_block_coding = allocate_prbs_sub(nb_rb,N_RB_DL,N_RBG,rballoc_sub); - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.resource_allocation_type = 0; - } - else if ((dl_config_pdu->pdu_type == NFAPI_DL_CONFIG_DLSCH_PDU_TYPE)&& - (dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.rnti == rnti) && - (dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_allocation_type==0)) { - dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_block_coding = allocate_prbs_sub(nb_rb,N_RB_DL,N_RBG,rballoc_sub); - } - } - } + for (i=0; ipdu_type == NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE)&& + (dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti == rnti) && + (dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.dci_format != 1)) { + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.resource_block_coding = allocate_prbs_sub(nb_rb,N_RB_DL,N_RBG,rballoc_sub); + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.resource_allocation_type = 0; + } else if ((dl_config_pdu->pdu_type == NFAPI_DL_CONFIG_DLSCH_PDU_TYPE)&& + (dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.rnti == rnti) && + (dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_allocation_type==0)) { + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.resource_block_coding = allocate_prbs_sub(nb_rb,N_RB_DL,N_RBG,rballoc_sub); + } + } } } + } - stop_meas(&eNB->fill_DLSCH_dci); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME - (VCD_SIGNAL_DUMPER_FUNCTIONS_FILL_DLSCH_DCI, VCD_FUNCTION_OUT); + stop_meas(&eNB->fill_DLSCH_dci); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME + (VCD_SIGNAL_DUMPER_FUNCTIONS_FILL_DLSCH_DCI, VCD_FUNCTION_OUT); } void ulsch_scheduler_pre_ue_select_fairRR( - module_id_t module_idP, - frame_t frameP, - sub_frame_t subframeP, - sub_frame_t sched_subframeP, - ULSCH_UE_SELECT ulsch_ue_select[MAX_NUM_CCs]) -{ + module_id_t module_idP, + frame_t frameP, + sub_frame_t subframeP, + sub_frame_t sched_subframeP, + ULSCH_UE_SELECT ulsch_ue_select[MAX_NUM_CCs]) { eNB_MAC_INST *eNB=RC.mac[module_idP]; COMMON_channels_t *cc; int CC_id,UE_id; @@ -1968,7 +1954,7 @@ void ulsch_scheduler_pre_ue_select_fairRR( uint8_t first_ue_id[MAX_NUM_CCs][20]; uint8_t ul_inactivity_num[MAX_NUM_CCs]; uint8_t ul_inactivity_id[MAX_NUM_CCs][20]; -// LTE_DL_FRAME_PARMS *frame_parms; + // LTE_DL_FRAME_PARMS *frame_parms; uint8_t ulsch_ue_max_num[MAX_NUM_CCs]; uint16_t saved_ulsch_dci[MAX_NUM_CCs]; rnti_t rnti; @@ -1976,127 +1962,134 @@ void ulsch_scheduler_pre_ue_select_fairRR( uint8_t cc_id_flag[MAX_NUM_CCs]; uint8_t harq_pid = 0,round = 0; UE_list_t *UE_list= &eNB->UE_list; - - uint8_t aggregation = 2; int format_flag; nfapi_hi_dci0_request_body_t *HI_DCI0_req; nfapi_hi_dci0_request_pdu_t *hi_dci0_pdu; - for ( CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++ ) { - //save ulsch dci number - saved_ulsch_dci[CC_id] = eNB->HI_DCI0_req[CC_id][subframeP].hi_dci0_request_body.number_of_dci; - // maximum multiplicity number - ulsch_ue_max_num[CC_id] =RC.rrc[module_idP]->configuration.ue_multiple_max[CC_id]; - - cc_id_flag[CC_id] = 0; - ue_first_num[CC_id] = 0; - ul_inactivity_num[CC_id] = 0; - + //save ulsch dci number + saved_ulsch_dci[CC_id] = eNB->HI_DCI0_req[CC_id][subframeP].hi_dci0_request_body.number_of_dci; + // maximum multiplicity number + ulsch_ue_max_num[CC_id] =RC.rrc[module_idP]->configuration.ue_multiple_max[CC_id]; + cc_id_flag[CC_id] = 0; + ue_first_num[CC_id] = 0; + ul_inactivity_num[CC_id] = 0; } + // UE round >0 for ( UE_id = 0; UE_id < NUMBER_OF_UE_MAX; UE_id++ ) { - if (UE_list->active[UE_id] == FALSE) - continue; + if (UE_list->active[UE_id] == FALSE) + continue; - rnti = UE_RNTI(module_idP,UE_id); - if (rnti ==NOT_A_RNTI) + rnti = UE_RNTI(module_idP,UE_id); + + if (rnti ==NOT_A_RNTI) + continue; + + CC_id = UE_PCCID(module_idP,UE_id); + + if (UE_list->UE_template[CC_id][UE_id].configured == FALSE) + continue; + + if (UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync == 1) + continue; + + // UL DCI + HI_DCI0_req = &eNB->HI_DCI0_req[CC_id][subframeP].hi_dci0_request_body; + + if ( (ulsch_ue_select[CC_id].ue_num >= ulsch_ue_max_num[CC_id]) || (cc_id_flag[CC_id] == 1) ) { + cc_id_flag[CC_id] = 1; + HI_DCI0_req->number_of_dci = saved_ulsch_dci[CC_id]; + ret = cc_id_end(cc_id_flag); + + if ( ret == 0 ) { continue; + } - CC_id = UE_PCCID(module_idP,UE_id); - if (UE_list->UE_template[CC_id][UE_id].configured == FALSE) - continue; + if ( ret == 1 ) { + return; + } + } - if (UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync == 1) - continue; + cc = &eNB->common_channels[CC_id]; + //harq_pid + harq_pid = subframe2harqpid(cc,(frameP+(sched_subframePUE_sched_ctrl[UE_id].round_UL[CC_id][harq_pid]; - // UL DCI - HI_DCI0_req = &eNB->HI_DCI0_req[CC_id][subframeP].hi_dci0_request_body; - if ( (ulsch_ue_select[CC_id].ue_num >= ulsch_ue_max_num[CC_id]) || (cc_id_flag[CC_id] == 1) ) { + if ( round > 0 ) { + hi_dci0_pdu = &HI_DCI0_req->hi_dci0_pdu_list[HI_DCI0_req->number_of_dci+HI_DCI0_req->number_of_hi]; + format_flag = 2; + + if (CCE_allocation_infeasible(module_idP,CC_id,format_flag,subframeP,aggregation,rnti) == 1) { cc_id_flag[CC_id] = 1; - HI_DCI0_req->number_of_dci = saved_ulsch_dci[CC_id]; - ret = cc_id_end(cc_id_flag); - if ( ret == 0 ) { - continue; - } - if ( ret == 1 ) { - return; - } + continue; + } else { + hi_dci0_pdu->pdu_type = NFAPI_HI_DCI0_DCI_PDU_TYPE; + hi_dci0_pdu->dci_pdu.dci_pdu_rel8.rnti = rnti; + hi_dci0_pdu->dci_pdu.dci_pdu_rel8.aggregation_level = aggregation; + HI_DCI0_req->number_of_dci++; + ulsch_ue_select[CC_id].list[ulsch_ue_select[CC_id].ue_num].ue_priority = SCH_UL_RETRANS; + ulsch_ue_select[CC_id].list[ulsch_ue_select[CC_id].ue_num].start_rb = eNB->UE_list.UE_template[CC_id][UE_id].first_rb_ul[harq_pid]; + ulsch_ue_select[CC_id].list[ulsch_ue_select[CC_id].ue_num].nb_rb = eNB->UE_list.UE_template[CC_id][UE_id].nb_rb_ul[harq_pid]; + ulsch_ue_select[CC_id].list[ulsch_ue_select[CC_id].ue_num].UE_id = UE_id; + ulsch_ue_select[CC_id].ue_num++; + continue; + } + } + + // + int bytes_to_schedule = UE_list->UE_template[CC_id][UE_id].estimated_ul_buffer - UE_list->UE_template[CC_id][UE_id].scheduled_ul_bytes; + + if (bytes_to_schedule < 0) bytes_to_schedule = 0; + + if ( UE_id > last_ulsch_ue_id[CC_id] && ((ulsch_ue_select[CC_id].ue_num+ue_first_num[CC_id]) < ulsch_ue_max_num[CC_id]) ) { + if ( bytes_to_schedule > 0 ) { + first_ue_id[CC_id][ue_first_num[CC_id]]= UE_id; + first_ue_total[CC_id][ue_first_num[CC_id]] = bytes_to_schedule; + ue_first_num[CC_id]++; + continue; } - cc = &eNB->common_channels[CC_id]; - //harq_pid - harq_pid = subframe2harqpid(cc,(frameP+(sched_subframePUE_sched_ctrl[UE_id].round_UL[CC_id][harq_pid]; + if ( UE_list->UE_template[CC_id][UE_id].ul_SR > 0 ) { + first_ue_id[CC_id][ue_first_num[CC_id]]= UE_id; + first_ue_total[CC_id] [ue_first_num[CC_id]] = 0; + ue_first_num[CC_id]++; + continue; + } - if ( round > 0 ) { - hi_dci0_pdu = &HI_DCI0_req->hi_dci0_pdu_list[HI_DCI0_req->number_of_dci+HI_DCI0_req->number_of_hi]; - format_flag = 2; - if (CCE_allocation_infeasible(module_idP,CC_id,format_flag,subframeP,aggregation,rnti) == 1) { - cc_id_flag[CC_id] = 1; - continue; + UE_sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; + + if ( ((UE_sched_ctl->ul_inactivity_timer>20)&&(UE_sched_ctl->ul_scheduled==0)) || + ((UE_sched_ctl->ul_inactivity_timer>10)&&(UE_sched_ctl->ul_scheduled==0)&&(mac_eNB_get_rrc_status(module_idP,UE_RNTI(module_idP,UE_id)) < RRC_CONNECTED))) { + first_ue_id[CC_id][ue_first_num[CC_id]]= UE_id; + first_ue_total[CC_id] [ue_first_num[CC_id]] = 0; + ue_first_num[CC_id]++; + continue; + } + + /*if ( (ulsch_ue_select[CC_id].ue_num+ul_inactivity_num[CC_id] ) < ulsch_ue_max_num[CC_id] ) { + UE_sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; + uint8_t ul_period = 0; + if (cc->tdd_Config) { + ul_period = 50; } else { - hi_dci0_pdu->pdu_type = NFAPI_HI_DCI0_DCI_PDU_TYPE; - hi_dci0_pdu->dci_pdu.dci_pdu_rel8.rnti = rnti; - hi_dci0_pdu->dci_pdu.dci_pdu_rel8.aggregation_level = aggregation; - HI_DCI0_req->number_of_dci++; - - ulsch_ue_select[CC_id].list[ulsch_ue_select[CC_id].ue_num].ue_priority = SCH_UL_RETRANS; - ulsch_ue_select[CC_id].list[ulsch_ue_select[CC_id].ue_num].start_rb = eNB->UE_list.UE_template[CC_id][UE_id].first_rb_ul[harq_pid]; - ulsch_ue_select[CC_id].list[ulsch_ue_select[CC_id].ue_num].nb_rb = eNB->UE_list.UE_template[CC_id][UE_id].nb_rb_ul[harq_pid]; - ulsch_ue_select[CC_id].list[ulsch_ue_select[CC_id].ue_num].UE_id = UE_id; - ulsch_ue_select[CC_id].ue_num++; - continue; + ul_period = 20; } - } - // - int bytes_to_schedule = UE_list->UE_template[CC_id][UE_id].estimated_ul_buffer - UE_list->UE_template[CC_id][UE_id].scheduled_ul_bytes; - if (bytes_to_schedule < 0) bytes_to_schedule = 0; - - if ( UE_id > last_ulsch_ue_id[CC_id] && ((ulsch_ue_select[CC_id].ue_num+ue_first_num[CC_id]) < ulsch_ue_max_num[CC_id]) ) { - if ( bytes_to_schedule > 0 ) { - first_ue_id[CC_id][ue_first_num[CC_id]]= UE_id; - first_ue_total[CC_id][ue_first_num[CC_id]] = bytes_to_schedule; - ue_first_num[CC_id]++; - continue; - } - if ( UE_list->UE_template[CC_id][UE_id].ul_SR > 0 ) { - first_ue_id[CC_id][ue_first_num[CC_id]]= UE_id; - first_ue_total[CC_id] [ue_first_num[CC_id]] = 0; - ue_first_num[CC_id]++; - continue; - } - UE_sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; - if ( ((UE_sched_ctl->ul_inactivity_timer>20)&&(UE_sched_ctl->ul_scheduled==0)) || + if ( ((UE_sched_ctl->ul_inactivity_timer>ul_period)&&(UE_sched_ctl->ul_scheduled==0)) || ((UE_sched_ctl->ul_inactivity_timer>10)&&(UE_sched_ctl->ul_scheduled==0)&&(mac_eNB_get_rrc_status(module_idP,UE_RNTI(module_idP,UE_id)) < RRC_CONNECTED))) { - first_ue_id[CC_id][ue_first_num[CC_id]]= UE_id; - first_ue_total[CC_id] [ue_first_num[CC_id]] = 0; - ue_first_num[CC_id]++; + ul_inactivity_id[CC_id][ul_inactivity_num[CC_id]]= UE_id; + ul_inactivity_num[CC_id] ++; continue; } - /*if ( (ulsch_ue_select[CC_id].ue_num+ul_inactivity_num[CC_id] ) < ulsch_ue_max_num[CC_id] ) { - UE_sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; - uint8_t ul_period = 0; - if (cc->tdd_Config) { - ul_period = 50; - } else { - ul_period = 20; - } - if ( ((UE_sched_ctl->ul_inactivity_timer>ul_period)&&(UE_sched_ctl->ul_scheduled==0)) || - ((UE_sched_ctl->ul_inactivity_timer>10)&&(UE_sched_ctl->ul_scheduled==0)&&(mac_eNB_get_rrc_status(module_idP,UE_RNTI(module_idP,UE_id)) < RRC_CONNECTED))) { - ul_inactivity_id[CC_id][ul_inactivity_num[CC_id]]= UE_id; - ul_inactivity_num[CC_id] ++; - continue; - } - }*/ - } - + }*/ + } } for ( CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++ ) { HI_DCI0_req = &eNB->HI_DCI0_req[CC_id][subframeP].hi_dci0_request_body; + for ( int temp = 0; temp < ue_first_num[CC_id]; temp++ ) { if ( (ulsch_ue_select[CC_id].ue_num >= ulsch_ue_max_num[CC_id]) || (cc_id_flag[CC_id] == 1) ) { cc_id_flag[CC_id] = 1; @@ -2107,113 +2100,121 @@ void ulsch_scheduler_pre_ue_select_fairRR( hi_dci0_pdu = &HI_DCI0_req->hi_dci0_pdu_list[HI_DCI0_req->number_of_dci+HI_DCI0_req->number_of_hi]; format_flag = 2; rnti = UE_RNTI(module_idP,first_ue_id[CC_id][temp]); - if (CCE_allocation_infeasible(module_idP,CC_id,format_flag,subframeP,aggregation,rnti) == 1) { - cc_id_flag[CC_id] = 1; - break; - } else { - hi_dci0_pdu->pdu_type = NFAPI_HI_DCI0_DCI_PDU_TYPE; - hi_dci0_pdu->dci_pdu.dci_pdu_rel8.rnti = rnti; - hi_dci0_pdu->dci_pdu.dci_pdu_rel8.aggregation_level = aggregation; - HI_DCI0_req->number_of_dci++; - ulsch_ue_select[CC_id].list[ulsch_ue_select[CC_id].ue_num].ue_priority = SCH_UL_FIRST; - ulsch_ue_select[CC_id].list[ulsch_ue_select[CC_id].ue_num].ul_total_buffer = first_ue_total[CC_id][temp]; - ulsch_ue_select[CC_id].list[ulsch_ue_select[CC_id].ue_num].UE_id = first_ue_id[CC_id][temp]; - ulsch_ue_select[CC_id].ue_num++; + if (CCE_allocation_infeasible(module_idP,CC_id,format_flag,subframeP,aggregation,rnti) == 1) { + cc_id_flag[CC_id] = 1; + break; + } else { + hi_dci0_pdu->pdu_type = NFAPI_HI_DCI0_DCI_PDU_TYPE; + hi_dci0_pdu->dci_pdu.dci_pdu_rel8.rnti = rnti; + hi_dci0_pdu->dci_pdu.dci_pdu_rel8.aggregation_level = aggregation; + HI_DCI0_req->number_of_dci++; + ulsch_ue_select[CC_id].list[ulsch_ue_select[CC_id].ue_num].ue_priority = SCH_UL_FIRST; + ulsch_ue_select[CC_id].list[ulsch_ue_select[CC_id].ue_num].ul_total_buffer = first_ue_total[CC_id][temp]; + ulsch_ue_select[CC_id].list[ulsch_ue_select[CC_id].ue_num].UE_id = first_ue_id[CC_id][temp]; + ulsch_ue_select[CC_id].ue_num++; } } } for ( UE_id = 0; UE_id < NUMBER_OF_UE_MAX; UE_id++ ) { if (UE_list->active[UE_id] == FALSE) - continue; + continue; rnti = UE_RNTI(module_idP,UE_id); + if (rnti ==NOT_A_RNTI) - continue; + continue; CC_id = UE_PCCID(module_idP,UE_id); if (UE_id > last_ulsch_ue_id[CC_id]) - continue; + continue; if (UE_list->UE_template[CC_id][UE_id].configured == FALSE) - continue; + continue; if (UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync == 1) - continue; + continue; if ( (ulsch_ue_select[CC_id].ue_num >= ulsch_ue_max_num[CC_id]) || (cc_id_flag[CC_id] == 1) ) { - cc_id_flag[CC_id] = 1; - HI_DCI0_req->number_of_dci = saved_ulsch_dci[CC_id]; - ret = cc_id_end(cc_id_flag); - if ( ret == 0 ) { - continue; - } - if ( ret == 1 ) { - return; - } - } + cc_id_flag[CC_id] = 1; + HI_DCI0_req->number_of_dci = saved_ulsch_dci[CC_id]; + ret = cc_id_end(cc_id_flag); - for(i = 0;iHI_DCI0_req[CC_id][subframeP].hi_dci0_request_body; //SR BSR - UE_sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; - + UE_sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; int bytes_to_schedule = UE_list->UE_template[CC_id][UE_id].estimated_ul_buffer - UE_list->UE_template[CC_id][UE_id].scheduled_ul_bytes; + if (bytes_to_schedule < 0) bytes_to_schedule = 0; if ( (bytes_to_schedule > 0) || (UE_list->UE_template[CC_id][UE_id].ul_SR > 0) || - ((UE_sched_ctl->ul_inactivity_timer>20)&&(UE_sched_ctl->ul_scheduled==0)) || - ((UE_sched_ctl->ul_inactivity_timer>10)&&(UE_sched_ctl->ul_scheduled==0)&&(mac_eNB_get_rrc_status(module_idP,UE_RNTI(module_idP,UE_id)) < RRC_CONNECTED)) ){ - hi_dci0_pdu = &HI_DCI0_req->hi_dci0_pdu_list[HI_DCI0_req->number_of_dci+HI_DCI0_req->number_of_hi]; - format_flag = 2; - if (CCE_allocation_infeasible(module_idP,CC_id,format_flag,subframeP,aggregation,rnti) == 1) { - cc_id_flag[CC_id] = 1; - continue; - } else { - hi_dci0_pdu->pdu_type = NFAPI_HI_DCI0_DCI_PDU_TYPE; - hi_dci0_pdu->dci_pdu.dci_pdu_rel8.rnti = rnti; - hi_dci0_pdu->dci_pdu.dci_pdu_rel8.aggregation_level = aggregation; - HI_DCI0_req->number_of_dci++; + ((UE_sched_ctl->ul_inactivity_timer>20)&&(UE_sched_ctl->ul_scheduled==0)) || + ((UE_sched_ctl->ul_inactivity_timer>10)&&(UE_sched_ctl->ul_scheduled==0)&&(mac_eNB_get_rrc_status(module_idP,UE_RNTI(module_idP,UE_id)) < RRC_CONNECTED)) ) { + hi_dci0_pdu = &HI_DCI0_req->hi_dci0_pdu_list[HI_DCI0_req->number_of_dci+HI_DCI0_req->number_of_hi]; + format_flag = 2; - ulsch_ue_select[CC_id].list[ulsch_ue_select[CC_id].ue_num].ue_priority = SCH_UL_FIRST; - if(bytes_to_schedule > 0) - ulsch_ue_select[CC_id].list[ulsch_ue_select[CC_id].ue_num].ul_total_buffer = bytes_to_schedule; - else if(UE_list->UE_template[CC_id][UE_id].ul_SR > 0) - ulsch_ue_select[CC_id].list[ulsch_ue_select[CC_id].ue_num].ul_total_buffer = 0; - ulsch_ue_select[CC_id].list[ulsch_ue_select[CC_id].ue_num].UE_id = UE_id; - ulsch_ue_select[CC_id].ue_num++; - continue; - } + if (CCE_allocation_infeasible(module_idP,CC_id,format_flag,subframeP,aggregation,rnti) == 1) { + cc_id_flag[CC_id] = 1; + continue; + } else { + hi_dci0_pdu->pdu_type = NFAPI_HI_DCI0_DCI_PDU_TYPE; + hi_dci0_pdu->dci_pdu.dci_pdu_rel8.rnti = rnti; + hi_dci0_pdu->dci_pdu.dci_pdu_rel8.aggregation_level = aggregation; + HI_DCI0_req->number_of_dci++; + ulsch_ue_select[CC_id].list[ulsch_ue_select[CC_id].ue_num].ue_priority = SCH_UL_FIRST; + + if(bytes_to_schedule > 0) + ulsch_ue_select[CC_id].list[ulsch_ue_select[CC_id].ue_num].ul_total_buffer = bytes_to_schedule; + else if(UE_list->UE_template[CC_id][UE_id].ul_SR > 0) + ulsch_ue_select[CC_id].list[ulsch_ue_select[CC_id].ue_num].ul_total_buffer = 0; + + ulsch_ue_select[CC_id].list[ulsch_ue_select[CC_id].ue_num].UE_id = UE_id; + ulsch_ue_select[CC_id].ue_num++; + continue; + } } + //inactivity UE -/* if ( (ulsch_ue_select[CC_id].ue_num+ul_inactivity_num[CC_id]) < ulsch_ue_max_num[CC_id] ) { - UE_sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; - uint8_t ul_period = 0; - if (cc->tdd_Config) { - ul_period = 50; - } else { - ul_period = 20; - } - if ( ((UE_sched_ctl->ul_inactivity_timer>ul_period)&&(UE_sched_ctl->ul_scheduled==0)) || - ((UE_sched_ctl->ul_inactivity_timer>10)&&(UE_sched_ctl->ul_scheduled==0)&&(mac_eNB_get_rrc_status(module_idP,UE_RNTI(module_idP,UE_id)) < RRC_CONNECTED))) { - ul_inactivity_id[CC_id][ul_inactivity_num[CC_id]]= UE_id; - ul_inactivity_num[CC_id]++; - continue; - } - }*/ + /* if ( (ulsch_ue_select[CC_id].ue_num+ul_inactivity_num[CC_id]) < ulsch_ue_max_num[CC_id] ) { + UE_sched_ctl = &UE_list->UE_sched_ctrl[UE_id]; + uint8_t ul_period = 0; + if (cc->tdd_Config) { + ul_period = 50; + } else { + ul_period = 20; + } + if ( ((UE_sched_ctl->ul_inactivity_timer>ul_period)&&(UE_sched_ctl->ul_scheduled==0)) || + ((UE_sched_ctl->ul_inactivity_timer>10)&&(UE_sched_ctl->ul_scheduled==0)&&(mac_eNB_get_rrc_status(module_idP,UE_RNTI(module_idP,UE_id)) < RRC_CONNECTED))) { + ul_inactivity_id[CC_id][ul_inactivity_num[CC_id]]= UE_id; + ul_inactivity_num[CC_id]++; + continue; + } + }*/ } for ( CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++ ) { HI_DCI0_req = &eNB->HI_DCI0_req[CC_id][subframeP].hi_dci0_request_body; + for ( int temp = 0; temp < ul_inactivity_num[CC_id]; temp++ ) { if ( (ulsch_ue_select[CC_id].ue_num >= ulsch_ue_max_num[CC_id]) || (cc_id_flag[CC_id] == 1) ) { HI_DCI0_req = &eNB->HI_DCI0_req[CC_id][subframeP].hi_dci0_request_body; @@ -2224,43 +2225,45 @@ void ulsch_scheduler_pre_ue_select_fairRR( hi_dci0_pdu = &HI_DCI0_req->hi_dci0_pdu_list[HI_DCI0_req->number_of_dci+HI_DCI0_req->number_of_hi]; format_flag = 2; rnti = UE_RNTI(module_idP,ul_inactivity_id[CC_id][temp]); - if (CCE_allocation_infeasible(module_idP,CC_id,format_flag,subframeP,aggregation,rnti) == 1) { - cc_id_flag[CC_id] = 1; - continue; - } else { - hi_dci0_pdu->pdu_type = NFAPI_HI_DCI0_DCI_PDU_TYPE; - hi_dci0_pdu->dci_pdu.dci_pdu_rel8.rnti = rnti; - hi_dci0_pdu->dci_pdu.dci_pdu_rel8.aggregation_level = aggregation; - HI_DCI0_req->number_of_dci++; - ulsch_ue_select[CC_id].list[ulsch_ue_select[CC_id].ue_num].ue_priority = SCH_UL_INACTIVE; - ulsch_ue_select[CC_id].list[ulsch_ue_select[CC_id].ue_num].ul_total_buffer = 0; - ulsch_ue_select[CC_id].list[ulsch_ue_select[CC_id].ue_num].UE_id = ul_inactivity_id[CC_id][temp]; - ulsch_ue_select[CC_id].ue_num++; + if (CCE_allocation_infeasible(module_idP,CC_id,format_flag,subframeP,aggregation,rnti) == 1) { + cc_id_flag[CC_id] = 1; + continue; + } else { + hi_dci0_pdu->pdu_type = NFAPI_HI_DCI0_DCI_PDU_TYPE; + hi_dci0_pdu->dci_pdu.dci_pdu_rel8.rnti = rnti; + hi_dci0_pdu->dci_pdu.dci_pdu_rel8.aggregation_level = aggregation; + HI_DCI0_req->number_of_dci++; + ulsch_ue_select[CC_id].list[ulsch_ue_select[CC_id].ue_num].ue_priority = SCH_UL_INACTIVE; + ulsch_ue_select[CC_id].list[ulsch_ue_select[CC_id].ue_num].ul_total_buffer = 0; + ulsch_ue_select[CC_id].list[ulsch_ue_select[CC_id].ue_num].UE_id = ul_inactivity_id[CC_id][temp]; + ulsch_ue_select[CC_id].ue_num++; } } + HI_DCI0_req->number_of_dci = saved_ulsch_dci[CC_id]; } + return; } -uint8_t find_rb_table_index(uint8_t average_rbs) -{ +uint8_t find_rb_table_index(uint8_t average_rbs) { int i; + for ( i = 0; i < 34; i++ ) { if ( rb_table[i] > average_rbs ) { return (i-1); } } + return i; } void ulsch_scheduler_pre_processor_fairRR(module_id_t module_idP, - frame_t frameP, - sub_frame_t subframeP, - sub_frame_t sched_subframeP, - ULSCH_UE_SELECT ulsch_ue_select[MAX_NUM_CCs]) -{ + frame_t frameP, + sub_frame_t subframeP, + sub_frame_t sched_subframeP, + ULSCH_UE_SELECT ulsch_ue_select[MAX_NUM_CCs]) { int CC_id,ulsch_ue_num; eNB_MAC_INST *eNB = RC.mac[module_idP]; UE_list_t *UE_list= &eNB->UE_list; @@ -2285,26 +2288,27 @@ void ulsch_scheduler_pre_processor_fairRR(module_id_t module_idP, for ( CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++ ) { cc = &RC.mac[module_idP]->common_channels[CC_id]; frame_parms = &(RC.eNB[module_idP][CC_id]->frame_parms); + if (cc->tdd_Config) { //TDD if (frame_parms->N_RB_UL == 25) { - num_pucch_rb = 1; + num_pucch_rb = 1; } else if (frame_parms->N_RB_UL == 50) { - num_pucch_rb = 2; + num_pucch_rb = 2; } else { - num_pucch_rb = 3; + num_pucch_rb = 3; } } else {//FDD if (frame_parms->N_RB_UL == 25) { - num_pucch_rb = 1; + num_pucch_rb = 1; } else { - num_pucch_rb = 2; + num_pucch_rb = 2; } } first_rb[CC_id] = num_pucch_rb; ue_num_temp = ulsch_ue_select[CC_id].ue_num; - for ( ulsch_ue_num = 0; ulsch_ue_num < ulsch_ue_select[CC_id].ue_num; ulsch_ue_num++ ) { + for ( ulsch_ue_num = 0; ulsch_ue_num < ulsch_ue_select[CC_id].ue_num; ulsch_ue_num++ ) { UE_id = ulsch_ue_select[CC_id].list[ulsch_ue_num].UE_id; if (ulsch_ue_select[CC_id].list[ulsch_ue_num].ue_priority == SCH_UL_MSG3) { @@ -2319,52 +2323,59 @@ void ulsch_scheduler_pre_processor_fairRR(module_id_t module_idP, continue; } - if (first_rb[CC_id] >= frame_parms->N_RB_UL-num_pucch_rb ) { - LOG_W(MAC,"[eNB %d] frame %d subframe %d, UE %d/%x CC %d: dropping, not enough RBs\n", - module_idP,frameP,subframeP,UE_id,UE_RNTI(CC_id,UE_id),CC_id); - break; + LOG_W(MAC,"[eNB %d] frame %d subframe %d, UE %d/%x CC %d: dropping, not enough RBs\n", + module_idP,frameP,subframeP,UE_id,UE_RNTI(CC_id,UE_id),CC_id); + break; } - total_rbs = frame_parms->N_RB_UL-num_pucch_rb-first_rb[CC_id]; + total_rbs = frame_parms->N_RB_UL-num_pucch_rb-first_rb[CC_id]; average_rbs = (int)round((double)total_rbs/(double)ue_num_temp); + if ( average_rbs < 3 ) { ue_num_temp--; ulsch_ue_num--; ulsch_ue_select[CC_id].ue_num--; continue; } + if ( ulsch_ue_select[CC_id].list[ulsch_ue_num].ue_priority == SCH_UL_RETRANS ) { if ( ulsch_ue_select[CC_id].list[ulsch_ue_num].nb_rb <= average_rbs ) { - // assigne RBS(nb_rb) - ulsch_ue_select[CC_id].list[ulsch_ue_num].start_rb = first_rb[CC_id]; - first_rb[CC_id] = first_rb[CC_id] + ulsch_ue_select[CC_id].list[ulsch_ue_num].nb_rb; + // assigne RBS(nb_rb) + ulsch_ue_select[CC_id].list[ulsch_ue_num].start_rb = first_rb[CC_id]; + first_rb[CC_id] = first_rb[CC_id] + ulsch_ue_select[CC_id].list[ulsch_ue_num].nb_rb; } + if ( ulsch_ue_select[CC_id].list[ulsch_ue_num].nb_rb > average_rbs ) { if ( ulsch_ue_select[CC_id].list[ulsch_ue_num].nb_rb <= total_rbs ) { - // assigne RBS(average_rbs) - ulsch_ue_select[CC_id].list[ulsch_ue_num].start_rb = first_rb[CC_id]; - first_rb[CC_id] = first_rb[CC_id] + ulsch_ue_select[CC_id].list[ulsch_ue_num].nb_rb; + // assigne RBS(average_rbs) + ulsch_ue_select[CC_id].list[ulsch_ue_num].start_rb = first_rb[CC_id]; + first_rb[CC_id] = first_rb[CC_id] + ulsch_ue_select[CC_id].list[ulsch_ue_num].nb_rb; } else { - // assigne RBS(remain rbs) - ulsch_ue_select[CC_id].list[ulsch_ue_num].start_rb = first_rb[CC_id]; - rb_table_index = 2; - while(rb_table[rb_table_index] <= total_rbs){ - rb_table_index++; - } - ulsch_ue_select[CC_id].list[ulsch_ue_num].nb_rb = rb_table[rb_table_index-1]; - first_rb[CC_id] = first_rb[CC_id] + rb_table[rb_table_index-1]; + // assigne RBS(remain rbs) + ulsch_ue_select[CC_id].list[ulsch_ue_num].start_rb = first_rb[CC_id]; + rb_table_index = 2; + + while(rb_table[rb_table_index] <= total_rbs) { + rb_table_index++; + } + + ulsch_ue_select[CC_id].list[ulsch_ue_num].nb_rb = rb_table[rb_table_index-1]; + first_rb[CC_id] = first_rb[CC_id] + rb_table[rb_table_index-1]; } } - }else{ + } else { UE_template = &UE_list->UE_template[CC_id][UE_id]; + if ( UE_list->UE_sched_ctrl[UE_id].phr_received == 1 ) { mcs = 20; } else { mcs = 10; } + if ( ulsch_ue_select[CC_id].list[ulsch_ue_num].ue_priority == SCH_UL_FIRST ) { int bytes_to_schedule = UE_template->estimated_ul_buffer - UE_template->scheduled_ul_bytes; + if (bytes_to_schedule < 0) bytes_to_schedule = 0; if ( ulsch_ue_select[CC_id].list[ulsch_ue_num].ul_total_buffer > 0 ) { @@ -2379,7 +2390,7 @@ void ulsch_scheduler_pre_processor_fairRR(module_id_t module_idP, } while ( (tbs < bytes_to_schedule) && (rb_table[rb_table_index]<(frame_parms->N_RB_UL-num_pucch_rb-first_rb[CC_id])) && - ((UE_template->phr_info - tx_power) > 0) && (rb_table_index < 32 )) { + ((UE_template->phr_info - tx_power) > 0) && (rb_table_index < 32 )) { rb_table_index++; tbs = get_TBS_UL(mcs,rb_table[rb_table_index])<<3; tx_power= estimate_ue_tx_power(tbs,rb_table[rb_table_index],0,frame_parms->Ncp,0); @@ -2388,6 +2399,7 @@ void ulsch_scheduler_pre_processor_fairRR(module_id_t module_idP, if ( rb_table[rb_table_index]<3 ) { rb_table_index=2; } + if ( rb_table[rb_table_index] <= average_rbs ) { // assigne RBS( nb_rb) first_rb[CC_id] = first_rb[CC_id] + rb_table[rb_table_index]; @@ -2395,27 +2407,30 @@ void ulsch_scheduler_pre_processor_fairRR(module_id_t module_idP, UE_list->UE_template[CC_id][UE_id].pre_allocated_rb_table_index_ul = rb_table_index; UE_list->UE_template[CC_id][UE_id].pre_assigned_mcs_ul = mcs; } + if ( rb_table[rb_table_index] > average_rbs ) { // assigne RBS(average_rbs) rb_table_index = find_rb_table_index(average_rbs); - if (rb_table_index>=34){ - LOG_W(MAC,"[eNB %d] frame %d subframe %d, UE %d/%x CC %d: average RBs %d > 100\n", - module_idP,frameP,subframeP,UE_id,UE_RNTI(CC_id,UE_id),CC_id,average_rbs); - break; + + if (rb_table_index>=34) { + LOG_W(MAC,"[eNB %d] frame %d subframe %d, UE %d/%x CC %d: average RBs %d > 100\n", + module_idP,frameP,subframeP,UE_id,UE_RNTI(CC_id,UE_id),CC_id,average_rbs); + break; } + first_rb[CC_id] = first_rb[CC_id] + rb_table[rb_table_index]; UE_list->UE_template[CC_id][UE_id].pre_allocated_nb_rb_ul[0] = rb_table[rb_table_index]; UE_list->UE_template[CC_id][UE_id].pre_allocated_rb_table_index_ul = rb_table_index; UE_list->UE_template[CC_id][UE_id].pre_assigned_mcs_ul = mcs; } - }else { + } else { // assigne RBS( 3 RBs) first_rb[CC_id] = first_rb[CC_id] + 3; UE_list->UE_template[CC_id][UE_id].pre_allocated_nb_rb_ul[0] = 3; UE_list->UE_template[CC_id][UE_id].pre_allocated_rb_table_index_ul = 2; UE_list->UE_template[CC_id][UE_id].pre_assigned_mcs_ul = 10; } - }else if ( ulsch_ue_select[CC_id].list[ulsch_ue_num].ue_priority == SCH_UL_INACTIVE ) { + } else if ( ulsch_ue_select[CC_id].list[ulsch_ue_num].ue_priority == SCH_UL_INACTIVE ) { // assigne RBS( 3 RBs) first_rb[CC_id] = first_rb[CC_id] + 3; UE_list->UE_template[CC_id][UE_id].pre_allocated_nb_rb_ul[0] = 3; @@ -2423,6 +2438,7 @@ void ulsch_scheduler_pre_processor_fairRR(module_id_t module_idP, UE_list->UE_template[CC_id][UE_id].pre_assigned_mcs_ul = 10; } } + ue_num_temp--; } } @@ -2431,105 +2447,126 @@ void ulsch_scheduler_pre_processor_fairRR(module_id_t module_idP, void schedule_ulsch_fairRR(module_id_t module_idP, frame_t frameP, - sub_frame_t subframeP) -{ + sub_frame_t subframeP) { uint16_t i; int CC_id; eNB_MAC_INST *mac = RC.mac[module_idP]; COMMON_channels_t *cc; int sched_frame=frameP; - start_meas(&mac->schedule_ulsch); - int sched_subframe = (subframeP+4)%10; - cc = &mac->common_channels[0]; int tdd_sfa; + // for TDD: check subframes where we have to act and return if nothing should be done now if (cc->tdd_Config) { tdd_sfa = cc->tdd_Config->subframeAssignment; + switch (subframeP) { - case 0: - if ((tdd_sfa == 0)|| - (tdd_sfa == 3)) sched_subframe = 4; - else if (tdd_sfa==6) sched_subframe = 7; - else return; - break; - case 1: - if ((tdd_sfa==0)|| - (tdd_sfa==1)) sched_subframe = 7; - else if (tdd_sfa==6) sched_subframe = 8; - else return; - break; - case 2: // Don't schedule UL in subframe 2 for TDD - return; - case 3: - if (tdd_sfa==2) sched_subframe = 7; - else return; - break; - case 4: - if (tdd_sfa==1) sched_subframe = 8; - else return; - break; - case 5: - if (tdd_sfa==0) sched_subframe = 9; - else if (tdd_sfa==6) sched_subframe = 2; - else return; - break; - case 6: - if (tdd_sfa==0 || tdd_sfa==1) sched_subframe = 2; - else if (tdd_sfa==6) sched_subframe = 3; - else return; - break; - case 7: - return; - case 8: - if ((tdd_sfa>=2) && (tdd_sfa<=5)) sched_subframe=2; - else return; - break; - case 9: - if ((tdd_sfa==1) || (tdd_sfa==3) || (tdd_sfa==4)) sched_subframe=3; - else if (tdd_sfa==6) sched_subframe=4; - else return; - break; + case 0: + if ((tdd_sfa == 0)|| + (tdd_sfa == 3)) sched_subframe = 4; + else if (tdd_sfa==6) sched_subframe = 7; + else return; + + break; + + case 1: + if ((tdd_sfa==0)|| + (tdd_sfa==1)) sched_subframe = 7; + else if (tdd_sfa==6) sched_subframe = 8; + else return; + + break; + + case 2: // Don't schedule UL in subframe 2 for TDD + return; + + case 3: + if (tdd_sfa==2) sched_subframe = 7; + else return; + + break; + + case 4: + if (tdd_sfa==1) sched_subframe = 8; + else return; + + break; + + case 5: + if (tdd_sfa==0) sched_subframe = 9; + else if (tdd_sfa==6) sched_subframe = 2; + else return; + + break; + + case 6: + if (tdd_sfa==0 || tdd_sfa==1) sched_subframe = 2; + else if (tdd_sfa==6) sched_subframe = 3; + else return; + + break; + + case 7: + return; + + case 8: + if ((tdd_sfa>=2) && (tdd_sfa<=5)) sched_subframe=2; + else return; + + break; + + case 9: + if ((tdd_sfa==1) || (tdd_sfa==3) || (tdd_sfa==4)) sched_subframe=3; + else if (tdd_sfa==6) sched_subframe=4; + else return; + + break; } } + if (sched_subframe < subframeP) sched_frame++; + ULSCH_UE_SELECT ulsch_ue_select[MAX_NUM_CCs]; memset(ulsch_ue_select, 0, sizeof(ulsch_ue_select)); - LTE_DL_FRAME_PARMS *frame_parms ; for (CC_id=0; CC_idcommon_channels[CC_id]; frame_parms= &RC.eNB[module_idP][CC_id]->frame_parms; + // output of scheduling, the UE numbers in RBs, where it is in the code??? // check if RA (Msg3) is active in this subframeP, if so skip the PRBs used for Msg3 // Msg3 is using 1 PRB so we need to increase first_rb accordingly // not sure about the break (can there be more than 1 active RA procedure?) for (i=0; ira[i].state == WAITMSG3) &&(cc->ra[i].Msg3_subframe == sched_subframe)) { + if ((cc->ra[i].state == WAITMSG3) &&(cc->ra[i].Msg3_subframe == sched_subframe)) { ulsch_ue_select[CC_id].list[ulsch_ue_select[CC_id].ue_num].ue_priority = SCH_UL_MSG3; + if (cc->tdd_Config == NULL) { - if(frame_parms->N_RB_UL == 25){ - ulsch_ue_select[CC_id].list[ulsch_ue_select[CC_id].ue_num].start_rb = 1; - }else{ - ulsch_ue_select[CC_id].list[ulsch_ue_select[CC_id].ue_num].start_rb = 2; - } + if(frame_parms->N_RB_UL == 25) { + ulsch_ue_select[CC_id].list[ulsch_ue_select[CC_id].ue_num].start_rb = 1; + } else { + ulsch_ue_select[CC_id].list[ulsch_ue_select[CC_id].ue_num].start_rb = 2; + } } else { - switch(frame_parms->N_RB_UL){ + switch(frame_parms->N_RB_UL) { case 25: default: ulsch_ue_select[CC_id].list[ulsch_ue_select[CC_id].ue_num].start_rb = 1; break; + case 50: ulsch_ue_select[CC_id].list[ulsch_ue_select[CC_id].ue_num].start_rb = 2; break; + case 100: ulsch_ue_select[CC_id].list[ulsch_ue_select[CC_id].ue_num].start_rb = 3; break; - } + } } + ulsch_ue_select[CC_id].list[ulsch_ue_select[CC_id].ue_num].nb_rb = 1; ulsch_ue_select[CC_id].list[ulsch_ue_select[CC_id].ue_num].UE_id = -1; ulsch_ue_select[CC_id].ue_num++; @@ -2541,11 +2578,11 @@ schedule_ulsch_fairRR(module_id_t module_idP, frame_t frameP, if (is_prach_subframe(frame_parms,sched_frame,sched_subframe)==1) { ulsch_ue_select[CC_id].list[ulsch_ue_select[CC_id].ue_num].ue_priority = SCH_UL_PRACH; ulsch_ue_select[CC_id].list[ulsch_ue_select[CC_id].ue_num].start_rb = get_prach_prb_offset( - frame_parms, - frame_parms->prach_config_common.prach_ConfigInfo.prach_ConfigIndex, - frame_parms->prach_config_common.prach_ConfigInfo.prach_FreqOffset, - 0,//tdd_mapindex - frameP); //Nf + frame_parms, + frame_parms->prach_config_common.prach_ConfigInfo.prach_ConfigIndex, + frame_parms->prach_config_common.prach_ConfigInfo.prach_FreqOffset, + 0,//tdd_mapindex + frameP); //Nf ulsch_ue_select[CC_id].list[ulsch_ue_select[CC_id].ue_num].nb_rb = 6; ulsch_ue_select[CC_id].list[ulsch_ue_select[CC_id].ue_num].UE_id = -1; ulsch_ue_select[CC_id].ue_num++; @@ -2557,11 +2594,10 @@ schedule_ulsch_fairRR(module_id_t module_idP, frame_t frameP, } void schedule_ulsch_rnti_fairRR(module_id_t module_idP, - frame_t frameP, - sub_frame_t subframeP, - unsigned char sched_subframeP, - ULSCH_UE_SELECT ulsch_ue_select[MAX_NUM_CCs]) -{ + frame_t frameP, + sub_frame_t subframeP, + unsigned char sched_subframeP, + ULSCH_UE_SELECT ulsch_ue_select[MAX_NUM_CCs]) { int16_t UE_id; uint8_t aggregation = 2; uint16_t first_rb[MAX_NUM_CCs]; @@ -2570,7 +2606,7 @@ void schedule_ulsch_rnti_fairRR(module_id_t module_idP, uint8_t round = 0; uint8_t harq_pid = 0; uint8_t status = 0; - uint8_t rb_table_index = -1; + uint8_t rb_table_index = -1; uint32_t cqi_req,cshift,ndi,tpc; int32_t normalized_rx_power; int32_t target_rx_power=-90; @@ -2586,99 +2622,102 @@ void schedule_ulsch_rnti_fairRR(module_id_t module_idP, int rvidx_tab[4] = {0,2,3,1}; uint16_t ul_req_index; uint8_t dlsch_flag; + if (sched_subframeP < subframeP) sched_frame++; nfapi_hi_dci0_request_body_t *hi_dci0_req; nfapi_hi_dci0_request_pdu_t *hi_dci0_pdu; - nfapi_ul_config_request_body_t *ul_req_tmp; nfapi_ul_config_ulsch_harq_information *ulsch_harq_information; LOG_D(MAC,"entering ulsch preprocesor\n"); ulsch_scheduler_pre_processor_fairRR(module_idP, - frameP, - subframeP, - sched_subframeP, - ulsch_ue_select); - + frameP, + subframeP, + sched_subframeP, + ulsch_ue_select); LOG_D(MAC,"exiting ulsch preprocesor\n"); - - // loop over all active UEs for (CC_id=0; CC_idHI_DCI0_req[CC_id][subframeP].hi_dci0_request_body; - eNB->HI_DCI0_req[CC_id][subframeP].sfn_sf = (frameP<<4)+subframeP; - ul_req_tmp = &eNB->UL_req_tmp[CC_id][sched_subframeP].ul_config_request_body; - nfapi_ul_config_request_t *ul_req = &eNB->UL_req_tmp[CC_id][sched_subframeP]; - + hi_dci0_req = &eNB->HI_DCI0_req[CC_id][subframeP].hi_dci0_request_body; + eNB->HI_DCI0_req[CC_id][subframeP].sfn_sf = (frameP<<4)+subframeP; + ul_req_tmp = &eNB->UL_req_tmp[CC_id][sched_subframeP].ul_config_request_body; + nfapi_ul_config_request_t *ul_req = &eNB->UL_req_tmp[CC_id][sched_subframeP]; ULSCH_first_end = 0; cc = &eNB->common_channels[CC_id]; // This is the actual CC_id in the list N_RB_UL = to_prb(cc->mib->message.dl_Bandwidth); + //leave out first RB for PUCCH if (cc->tdd_Config == NULL) { - if(N_RB_UL == 25){ - first_rb[CC_id] = 1; - }else{ - first_rb[CC_id] = 2; - } - }else { - switch(N_RB_UL){ + if(N_RB_UL == 25) { + first_rb[CC_id] = 1; + } else { + first_rb[CC_id] = 2; + } + } else { + switch(N_RB_UL) { case 25: default: - first_rb[CC_id] = 1; + first_rb[CC_id] = 1; break; + case 50: - first_rb[CC_id] = 2; + first_rb[CC_id] = 2; break; + case 100: - first_rb[CC_id] = 3; + first_rb[CC_id] = 3; break; - } + } } + for ( ulsch_ue_num = 0; ulsch_ue_num < ulsch_ue_select[CC_id].ue_num; ulsch_ue_num++ ) { UE_id = ulsch_ue_select[CC_id].list[ulsch_ue_num].UE_id; + /* be sure that there are some free RBs */ - if (cc->tdd_Config == NULL){ - if(N_RB_UL == 25){ - if (first_rb[CC_id] >= N_RB_UL-1) { - LOG_W(MAC,"[eNB %d] frame %d subframe %d, UE %d/%x CC %d: dropping, not enough RBs\n", - module_idP,frameP,subframeP,UE_id,rnti,CC_id); - break; - } - }else{ - if (first_rb[CC_id] >= N_RB_UL-2) { - LOG_W(MAC,"[eNB %d] frame %d subframe %d, UE %d/%x CC %d: dropping, not enough RBs\n", - module_idP,frameP,subframeP,UE_id,rnti,CC_id); - break; - } + if (cc->tdd_Config == NULL) { + if(N_RB_UL == 25) { + if (first_rb[CC_id] >= N_RB_UL-1) { + LOG_W(MAC,"[eNB %d] frame %d subframe %d, UE %d/%x CC %d: dropping, not enough RBs\n", + module_idP,frameP,subframeP,UE_id,rnti,CC_id); + break; } + } else { + if (first_rb[CC_id] >= N_RB_UL-2) { + LOG_W(MAC,"[eNB %d] frame %d subframe %d, UE %d/%x CC %d: dropping, not enough RBs\n", + module_idP,frameP,subframeP,UE_id,rnti,CC_id); + break; + } + } } else { - if(N_RB_UL == 25){ - if (first_rb[CC_id] >= N_RB_UL-1) { - LOG_W(MAC,"[eNB %d] frame %d subframe %d, UE %d/%x CC %d N_RB_UL %d first_rb %d: dropping, not enough RBs\n", - module_idP,frameP,subframeP,UE_id,rnti,CC_id, N_RB_UL, first_rb[CC_id]); - break; - } - }else if(N_RB_UL == 50){ - if (first_rb[CC_id] >= N_RB_UL-2) { - LOG_W(MAC,"[eNB %d] frame %d subframe %d, UE %d/%x CC %d N_RB_UL %d first_rb %d: dropping, not enough RBs\n", - module_idP,frameP,subframeP,UE_id,rnti,CC_id, N_RB_UL, first_rb[CC_id]); - break; - } - }else if(N_RB_UL == 100){ - if (first_rb[CC_id] >= N_RB_UL-3) { - LOG_W(MAC,"[eNB %d] frame %d subframe %d, UE %d/%x CC %d N_RB_UL %d first_rb %d: dropping, not enough RBs\n", - module_idP,frameP,subframeP,UE_id,rnti,CC_id, N_RB_UL, first_rb[CC_id]); - break; - } + if(N_RB_UL == 25) { + if (first_rb[CC_id] >= N_RB_UL-1) { + LOG_W(MAC,"[eNB %d] frame %d subframe %d, UE %d/%x CC %d N_RB_UL %d first_rb %d: dropping, not enough RBs\n", + module_idP,frameP,subframeP,UE_id,rnti,CC_id, N_RB_UL, first_rb[CC_id]); + break; } + } else if(N_RB_UL == 50) { + if (first_rb[CC_id] >= N_RB_UL-2) { + LOG_W(MAC,"[eNB %d] frame %d subframe %d, UE %d/%x CC %d N_RB_UL %d first_rb %d: dropping, not enough RBs\n", + module_idP,frameP,subframeP,UE_id,rnti,CC_id, N_RB_UL, first_rb[CC_id]); + break; + } + } else if(N_RB_UL == 100) { + if (first_rb[CC_id] >= N_RB_UL-3) { + LOG_W(MAC,"[eNB %d] frame %d subframe %d, UE %d/%x CC %d N_RB_UL %d first_rb %d: dropping, not enough RBs\n", + module_idP,frameP,subframeP,UE_id,rnti,CC_id, N_RB_UL, first_rb[CC_id]); + break; + } + } } + //MSG3 if (ulsch_ue_select[CC_id].list[ulsch_ue_num].ue_priority == SCH_UL_MSG3) { first_rb[CC_id] ++; continue; } + //PRACH if (ulsch_ue_select[CC_id].list[ulsch_ue_num].ue_priority == SCH_UL_PRACH) { first_rb[CC_id] = ulsch_ue_select[CC_id].list[ulsch_ue_num].start_rb+ulsch_ue_select[CC_id].list[ulsch_ue_num].nb_rb; @@ -2691,376 +2730,389 @@ void schedule_ulsch_rnti_fairRR(module_id_t module_idP, rnti = UE_RNTI(CC_id,UE_id); LOG_D(MAC,"[eNB %d] frame %d subframe %d,Checking PUSCH %d for UE %d/%x CC %d : aggregation level %d, N_RB_UL %d\n", module_idP,frameP,subframeP,harq_pid,UE_id,rnti,CC_id, aggregation,N_RB_UL); - int bytes_to_schedule = UE_template->estimated_ul_buffer - UE_template->scheduled_ul_bytes; + if (bytes_to_schedule < 0) bytes_to_schedule = 0; RC.eNB[module_idP][CC_id]->pusch_stats_BO[UE_id][(frameP*10)+subframeP] = bytes_to_schedule; VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_UE0_BO,RC.eNB[module_idP][CC_id]->pusch_stats_BO[UE_id][(frameP*10)+subframeP]); - status = mac_eNB_get_rrc_status(module_idP,rnti); + if (status < RRC_CONNECTED) cqi_req = 0; else if (UE_sched_ctrl->cqi_req_timer>30) { - cqi_req = 1; - // To be safe , do not ask CQI in special SFs:36.213/7.2.3 CQI definition - if (cc->tdd_Config) { - switch (cc->tdd_Config->subframeAssignment) { - case 1: - if( subframeP == 1 || subframeP == 6 ) cqi_req=0; - break; - case 3: - if( subframeP == 1 ) cqi_req=0; - break; - default: - LOG_E(MAC," TDD config not supported\n"); - break; - } - } - if(cqi_req == 1){ - UE_sched_ctrl->cqi_req_timer=0; - UE_sched_ctrl->cqi_req_flag |= 1 << sched_subframeP; - } - } - else + cqi_req = 1; + + // To be safe , do not ask CQI in special SFs:36.213/7.2.3 CQI definition + if (cc->tdd_Config) { + switch (cc->tdd_Config->subframeAssignment) { + case 1: + if( subframeP == 1 || subframeP == 6 ) cqi_req=0; + + break; + + case 3: + if( subframeP == 1 ) cqi_req=0; + + break; + + default: + LOG_E(MAC," TDD config not supported\n"); + break; + } + } + + if(cqi_req == 1) { + UE_sched_ctrl->cqi_req_timer=0; + UE_sched_ctrl->cqi_req_flag |= 1 << sched_subframeP; + } + } else cqi_req = 0; //power control //compute the expected ULSCH RX power (for the stats) - // this is the normalized RX power and this should be constant (regardless of mcs normalized_rx_power = (5*UE_sched_ctrl->pusch_snr[CC_id]-640)/10+30; //(+eNB->measurements.n0_power_dB[0]) target_rx_power= eNB->puSch10xSnr/10 + 30; //(+eNB->measurements.n0_power_dB[0]) - // this assumes accumulated tpc // make sure that we are only sending a tpc update once a frame, otherwise the control loop will freak out int32_t framex10psubframe = UE_template->pusch_tpc_tx_frame*10+UE_template->pusch_tpc_tx_subframe; + if (((framex10psubframe+10)<=(frameP*10+subframeP)) || //normal case - ((framex10psubframe>(frameP*10+subframeP)) && (((10240-framex10psubframe+frameP*10+subframeP)>=10)))) //frame wrap-around - { - UE_template->pusch_tpc_tx_frame=frameP; - UE_template->pusch_tpc_tx_subframe=subframeP; - if (normalized_rx_power>(target_rx_power+4)) { - tpc = 0; //-1 - tpc_accumulated--; - } else if (normalized_rx_power<(target_rx_power-4)) { - tpc = 2; //+1 - tpc_accumulated++; - } else { - tpc = 1; //0 - } + ((framex10psubframe>(frameP*10+subframeP)) && (((10240-framex10psubframe+frameP*10+subframeP)>=10)))) { //frame wrap-around + UE_template->pusch_tpc_tx_frame=frameP; + UE_template->pusch_tpc_tx_subframe=subframeP; + + if (normalized_rx_power>(target_rx_power+4)) { + tpc = 0; //-1 + tpc_accumulated--; + } else if (normalized_rx_power<(target_rx_power-4)) { + tpc = 2; //+1 + tpc_accumulated++; } else { tpc = 1; //0 } - if (tpc!=1) { - LOG_D(MAC,"[eNB %d] ULSCH scheduler: frame %d, subframe %d, harq_pid %d, tpc %d, accumulated %d, normalized/target rx power %d/%d\n", + } else { + tpc = 1; //0 + } + + if (tpc!=1) { + LOG_D(MAC,"[eNB %d] ULSCH scheduler: frame %d, subframe %d, harq_pid %d, tpc %d, accumulated %d, normalized/target rx power %d/%d\n", module_idP,frameP,subframeP,harq_pid,tpc, tpc_accumulated,normalized_rx_power,target_rx_power); + } + + // new transmission + if ((ulsch_ue_select[CC_id].list[ulsch_ue_num].ue_priority == SCH_UL_FIRST) || + (ulsch_ue_select[CC_id].list[ulsch_ue_num].ue_priority == SCH_UL_INACTIVE)) { + LOG_D(MAC,"[eNB %d][PUSCH %d] Frame %d subframe %d Scheduling UE %d/%x (SR %d,UL_inactivity timer %d,UL_failure timer %d,cqi_req_timer %d)\n", + module_idP,harq_pid,frameP,subframeP,UE_id,rnti,UE_template->ul_SR, + UE_sched_ctrl->ul_inactivity_timer, + UE_sched_ctrl->ul_failure_timer, + UE_sched_ctrl->cqi_req_timer); + ndi = 1-UE_template->oldNDI_UL[harq_pid]; + UE_template->oldNDI_UL[harq_pid]=ndi; + UE_list->eNB_UE_stats[CC_id][UE_id].normalized_rx_power=normalized_rx_power; + UE_list->eNB_UE_stats[CC_id][UE_id].target_rx_power=target_rx_power; + UE_list->eNB_UE_stats[CC_id][UE_id].ulsch_mcs1=UE_template->pre_assigned_mcs_ul; + UE_template->mcs_UL[harq_pid] = UE_template->pre_assigned_mcs_ul;//cmin (UE_template->pre_assigned_mcs_ul, openair_daq_vars.target_ue_ul_mcs); // adjust, based on user-defined MCS + + if (UE_template->pre_allocated_rb_table_index_ul >=0) { + rb_table_index=UE_template->pre_allocated_rb_table_index_ul; + } else { + UE_template->mcs_UL[harq_pid]=10;//cmin (10, openair_daq_vars.target_ue_ul_mcs); + rb_table_index=5; // for PHR } - // new transmission - if ((ulsch_ue_select[CC_id].list[ulsch_ue_num].ue_priority == SCH_UL_FIRST) || - (ulsch_ue_select[CC_id].list[ulsch_ue_num].ue_priority == SCH_UL_INACTIVE)) { - LOG_D(MAC,"[eNB %d][PUSCH %d] Frame %d subframe %d Scheduling UE %d/%x (SR %d,UL_inactivity timer %d,UL_failure timer %d,cqi_req_timer %d)\n", - module_idP,harq_pid,frameP,subframeP,UE_id,rnti,UE_template->ul_SR, - UE_sched_ctrl->ul_inactivity_timer, - UE_sched_ctrl->ul_failure_timer, - UE_sched_ctrl->cqi_req_timer); - ndi = 1-UE_template->oldNDI_UL[harq_pid]; - UE_template->oldNDI_UL[harq_pid]=ndi; - UE_list->eNB_UE_stats[CC_id][UE_id].normalized_rx_power=normalized_rx_power; - UE_list->eNB_UE_stats[CC_id][UE_id].target_rx_power=target_rx_power; - UE_list->eNB_UE_stats[CC_id][UE_id].ulsch_mcs1=UE_template->pre_assigned_mcs_ul; - UE_template->mcs_UL[harq_pid] = UE_template->pre_assigned_mcs_ul;//cmin (UE_template->pre_assigned_mcs_ul, openair_daq_vars.target_ue_ul_mcs); // adjust, based on user-defined MCS - if (UE_template->pre_allocated_rb_table_index_ul >=0) { - rb_table_index=UE_template->pre_allocated_rb_table_index_ul; - } else { - UE_template->mcs_UL[harq_pid]=10;//cmin (10, openair_daq_vars.target_ue_ul_mcs); - rb_table_index=5; // for PHR - } - UE_list->eNB_UE_stats[CC_id][UE_id].ulsch_mcs2=UE_template->mcs_UL[harq_pid]; + UE_list->eNB_UE_stats[CC_id][UE_id].ulsch_mcs2=UE_template->mcs_UL[harq_pid]; + UE_template->TBS_UL[harq_pid] = get_TBS_UL(UE_template->mcs_UL[harq_pid],rb_table[rb_table_index]); + UE_list->eNB_UE_stats[CC_id][UE_id].total_rbs_used_rx+=rb_table[rb_table_index]; + UE_list->eNB_UE_stats[CC_id][UE_id].ulsch_TBS=UE_template->TBS_UL[harq_pid]; + T(T_ENB_MAC_UE_UL_SCHEDULE, T_INT(module_idP), T_INT(CC_id), T_INT(rnti), T_INT(frameP), + T_INT(subframeP), T_INT(harq_pid), T_INT(UE_template->mcs_UL[harq_pid]), T_INT(first_rb[CC_id]), T_INT(rb_table[rb_table_index]), + T_INT(UE_template->TBS_UL[harq_pid]), T_INT(ndi)); - UE_template->TBS_UL[harq_pid] = get_TBS_UL(UE_template->mcs_UL[harq_pid],rb_table[rb_table_index]); - UE_list->eNB_UE_stats[CC_id][UE_id].total_rbs_used_rx+=rb_table[rb_table_index]; - UE_list->eNB_UE_stats[CC_id][UE_id].ulsch_TBS=UE_template->TBS_UL[harq_pid]; + if (mac_eNB_get_rrc_status(module_idP,rnti) < RRC_CONNECTED) + LOG_D(MAC,"[eNB %d][PUSCH %d/%x] CC_id %d Frame %d subframeP %d Scheduled UE %d (mcs %d, first rb %d, nb_rb %d, rb_table_index %d, TBS %d, harq_pid %d)\n", + module_idP,harq_pid,rnti,CC_id,frameP,subframeP,UE_id,UE_template->mcs_UL[harq_pid], + first_rb[CC_id],rb_table[rb_table_index], + rb_table_index,UE_template->TBS_UL[harq_pid],harq_pid); - T(T_ENB_MAC_UE_UL_SCHEDULE, T_INT(module_idP), T_INT(CC_id), T_INT(rnti), T_INT(frameP), - T_INT(subframeP), T_INT(harq_pid), T_INT(UE_template->mcs_UL[harq_pid]), T_INT(first_rb[CC_id]), T_INT(rb_table[rb_table_index]), - T_INT(UE_template->TBS_UL[harq_pid]), T_INT(ndi)); + // bad indices : 20 (40 PRB), 21 (45 PRB), 22 (48 PRB) + //store for possible retransmission + UE_template->nb_rb_ul[harq_pid] = rb_table[rb_table_index]; + UE_template->first_rb_ul[harq_pid] = first_rb[CC_id]; + UE_sched_ctrl->ul_scheduled |= (1<mcs_UL[harq_pid], - first_rb[CC_id],rb_table[rb_table_index], - rb_table_index,UE_template->TBS_UL[harq_pid],harq_pid); + if (UE_id == UE_list->head) + VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_UE0_SCHEDULED,UE_sched_ctrl->ul_scheduled); - // bad indices : 20 (40 PRB), 21 (45 PRB), 22 (48 PRB) - //store for possible retransmission - UE_template->nb_rb_ul[harq_pid] = rb_table[rb_table_index]; - UE_template->first_rb_ul[harq_pid] = first_rb[CC_id]; + // adjust total UL buffer status by TBS, wait for UL sdus to do final update + /*LOG_D(MAC,"[eNB %d] CC_id %d UE %d/%x : adjusting ul_total_buffer, old %d, TBS %d\n", module_idP,CC_id,UE_id,rnti,UE_template->ul_total_buffer,UE_template->TBS_UL[harq_pid]); + if (UE_template->ul_total_buffer > UE_template->TBS_UL[harq_pid]) + UE_template->ul_total_buffer -= UE_template->TBS_UL[harq_pid]; + else + UE_template->ul_total_buffer = 0; + LOG_D(MAC,"ul_total_buffer, new %d\n", UE_template->ul_total_buffer);*/ + // Cyclic shift for DM RS + cshift = 0;// values from 0 to 7 can be used for mapping the cyclic shift (36.211 , Table 5.5.2.1.1-1) + // save it for a potential retransmission + UE_template->cshift[harq_pid] = cshift; + hi_dci0_pdu = &hi_dci0_req->hi_dci0_pdu_list[hi_dci0_req->number_of_dci+hi_dci0_req->number_of_hi]; + memset((void *)hi_dci0_pdu,0,sizeof(nfapi_hi_dci0_request_pdu_t)); + hi_dci0_pdu->pdu_type = NFAPI_HI_DCI0_DCI_PDU_TYPE; + hi_dci0_pdu->pdu_size = 2+sizeof(nfapi_hi_dci0_dci_pdu); + hi_dci0_pdu->dci_pdu.dci_pdu_rel8.dci_format = NFAPI_UL_DCI_FORMAT_0; + hi_dci0_pdu->dci_pdu.dci_pdu_rel8.aggregation_level = aggregation; + hi_dci0_pdu->dci_pdu.dci_pdu_rel8.rnti = rnti; + hi_dci0_pdu->dci_pdu.dci_pdu_rel8.transmission_power = 6000; + hi_dci0_pdu->dci_pdu.dci_pdu_rel8.resource_block_start = first_rb[CC_id]; + hi_dci0_pdu->dci_pdu.dci_pdu_rel8.number_of_resource_block = rb_table[rb_table_index]; + hi_dci0_pdu->dci_pdu.dci_pdu_rel8.mcs_1 = UE_template->mcs_UL[harq_pid]; + hi_dci0_pdu->dci_pdu.dci_pdu_rel8.cyclic_shift_2_for_drms = cshift; + hi_dci0_pdu->dci_pdu.dci_pdu_rel8.frequency_hopping_enabled_flag = 0; + hi_dci0_pdu->dci_pdu.dci_pdu_rel8.new_data_indication_1 = ndi; + hi_dci0_pdu->dci_pdu.dci_pdu_rel8.tpc = tpc; + hi_dci0_pdu->dci_pdu.dci_pdu_rel8.cqi_csi_request = cqi_req; + hi_dci0_pdu->dci_pdu.dci_pdu_rel8.dl_assignment_index = UE_template->DAI_ul[sched_subframeP]; + hi_dci0_pdu->dci_pdu.dci_pdu_rel8.harq_pid = harq_pid; + hi_dci0_req->number_of_dci++; + hi_dci0_req->sfnsf = sfnsf_add_subframe(sched_frame, sched_subframeP, 0); //(frameP, subframeP, 4) + hi_dci0_req->tl.tag = NFAPI_HI_DCI0_REQUEST_BODY_TAG; + nfapi_hi_dci0_request_t *nfapi_hi_dci0_req = &eNB->HI_DCI0_req[CC_id][subframeP]; + nfapi_hi_dci0_req->sfn_sf = frameP<<4|subframeP; // sfnsf_add_subframe(sched_frame, sched_subframeP, 0); // sunday! + nfapi_hi_dci0_req->header.message_id = NFAPI_HI_DCI0_REQUEST; + LOG_D(MAC,"[PUSCH %d] Frame %d, Subframe %d: Adding UL CONFIG.Request for UE %d/%x, ulsch_frame %d, ulsch_subframe %d\n", + harq_pid,frameP,subframeP,UE_id,rnti,sched_frame,sched_subframeP); + ul_req_index = 0; + dlsch_flag = 0; - UE_sched_ctrl->ul_scheduled |= (1<head) - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_UE0_SCHEDULED,UE_sched_ctrl->ul_scheduled); - - // adjust total UL buffer status by TBS, wait for UL sdus to do final update - /*LOG_D(MAC,"[eNB %d] CC_id %d UE %d/%x : adjusting ul_total_buffer, old %d, TBS %d\n", module_idP,CC_id,UE_id,rnti,UE_template->ul_total_buffer,UE_template->TBS_UL[harq_pid]); - if (UE_template->ul_total_buffer > UE_template->TBS_UL[harq_pid]) - UE_template->ul_total_buffer -= UE_template->TBS_UL[harq_pid]; - else - UE_template->ul_total_buffer = 0; - LOG_D(MAC,"ul_total_buffer, new %d\n", UE_template->ul_total_buffer);*/ - // Cyclic shift for DM RS - cshift = 0;// values from 0 to 7 can be used for mapping the cyclic shift (36.211 , Table 5.5.2.1.1-1) - // save it for a potential retransmission - UE_template->cshift[harq_pid] = cshift; - - hi_dci0_pdu = &hi_dci0_req->hi_dci0_pdu_list[hi_dci0_req->number_of_dci+hi_dci0_req->number_of_hi]; - memset((void*)hi_dci0_pdu,0,sizeof(nfapi_hi_dci0_request_pdu_t)); - hi_dci0_pdu->pdu_type = NFAPI_HI_DCI0_DCI_PDU_TYPE; - hi_dci0_pdu->pdu_size = 2+sizeof(nfapi_hi_dci0_dci_pdu); - hi_dci0_pdu->dci_pdu.dci_pdu_rel8.dci_format = NFAPI_UL_DCI_FORMAT_0; - hi_dci0_pdu->dci_pdu.dci_pdu_rel8.aggregation_level = aggregation; - hi_dci0_pdu->dci_pdu.dci_pdu_rel8.rnti = rnti; - hi_dci0_pdu->dci_pdu.dci_pdu_rel8.transmission_power = 6000; - hi_dci0_pdu->dci_pdu.dci_pdu_rel8.resource_block_start = first_rb[CC_id]; - hi_dci0_pdu->dci_pdu.dci_pdu_rel8.number_of_resource_block = rb_table[rb_table_index]; - hi_dci0_pdu->dci_pdu.dci_pdu_rel8.mcs_1 = UE_template->mcs_UL[harq_pid]; - hi_dci0_pdu->dci_pdu.dci_pdu_rel8.cyclic_shift_2_for_drms = cshift; - hi_dci0_pdu->dci_pdu.dci_pdu_rel8.frequency_hopping_enabled_flag = 0; - hi_dci0_pdu->dci_pdu.dci_pdu_rel8.new_data_indication_1 = ndi; - hi_dci0_pdu->dci_pdu.dci_pdu_rel8.tpc = tpc; - hi_dci0_pdu->dci_pdu.dci_pdu_rel8.cqi_csi_request = cqi_req; - hi_dci0_pdu->dci_pdu.dci_pdu_rel8.dl_assignment_index = UE_template->DAI_ul[sched_subframeP]; - hi_dci0_pdu->dci_pdu.dci_pdu_rel8.harq_pid = harq_pid; - - hi_dci0_req->number_of_dci++; - hi_dci0_req->sfnsf = sfnsf_add_subframe(sched_frame, sched_subframeP, 0); //(frameP, subframeP, 4) - hi_dci0_req->tl.tag = NFAPI_HI_DCI0_REQUEST_BODY_TAG; - nfapi_hi_dci0_request_t *nfapi_hi_dci0_req = &eNB->HI_DCI0_req[CC_id][subframeP]; - nfapi_hi_dci0_req->sfn_sf = frameP<<4|subframeP; // sfnsf_add_subframe(sched_frame, sched_subframeP, 0); // sunday! - nfapi_hi_dci0_req->header.message_id = NFAPI_HI_DCI0_REQUEST; - - LOG_D(MAC,"[PUSCH %d] Frame %d, Subframe %d: Adding UL CONFIG.Request for UE %d/%x, ulsch_frame %d, ulsch_subframe %d\n", - harq_pid,frameP,subframeP,UE_id,rnti,sched_frame,sched_subframeP); - - ul_req_index = 0; - dlsch_flag = 0; - for(ul_req_index = 0;ul_req_index < ul_req_tmp->number_of_pdus;ul_req_index++){ - if((ul_req_tmp->ul_config_pdu_list[ul_req_index].pdu_type == NFAPI_UL_CONFIG_UCI_HARQ_PDU_TYPE) && - (ul_req_tmp->ul_config_pdu_list[ul_req_index].uci_harq_pdu.ue_information.ue_information_rel8.rnti == rnti)){ - dlsch_flag = 1; - LOG_D(MAC,"Frame %d, Subframe %d:rnti %x ul_req_index %d Switched UCI HARQ to ULSCH HARQ(first)\n",frameP,subframeP,rnti,ul_req_index); - break; - } - } - // Add UL_config PDUs - fill_nfapi_ulsch_config_request_rel8(&ul_req_tmp->ul_config_pdu_list[ul_req_index], - cqi_req, - cc, - UE_template->physicalConfigDedicated, - get_tmode(module_idP,CC_id,UE_id), - eNB->ul_handle, - rnti, - first_rb[CC_id], // resource_block_start - rb_table[rb_table_index], // number_of_resource_blocks - UE_template->mcs_UL[harq_pid], - cshift, // cyclic_shift_2_for_drms - 0, // frequency_hopping_enabled_flag - 0, // frequency_hopping_bits - ndi, // new_data_indication - 0, // redundancy_version - harq_pid, // harq_process_number - 0, // ul_tx_mode - 0, // current_tx_nb - 0, // n_srs - get_TBS_UL(UE_template->mcs_UL[harq_pid], - rb_table[rb_table_index]) - ); -#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - if (UE_template->rach_resource_type>0) { // This is a BL/CE UE allocation - fill_nfapi_ulsch_config_request_emtc(&ul_req_tmp->ul_config_pdu_list[ul_req_index], - UE_template->rach_resource_type>2 ? 2 : 1, - 1, //total_number_of_repetitions - 1, //repetition_number - (frameP*10)+subframeP); - } -#endif - if(dlsch_flag == 1){ - if(cqi_req == 1){ - ul_req_tmp->ul_config_pdu_list[ul_req_index].pdu_type = NFAPI_UL_CONFIG_ULSCH_CQI_HARQ_RI_PDU_TYPE; - ulsch_harq_information = &ul_req_tmp->ul_config_pdu_list[ul_req_index].ulsch_cqi_harq_ri_pdu.harq_information; - ul_req_tmp->ul_config_pdu_list[ul_req_index].ulsch_cqi_harq_ri_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.tl.tag=NFAPI_UL_CONFIG_REQUEST_INITIAL_TRANSMISSION_PARAMETERS_REL8_TAG; - ul_req_tmp->ul_config_pdu_list[ul_req_index].ulsch_cqi_harq_ri_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.n_srs_initial = 0; // last symbol not punctured - ul_req_tmp->ul_config_pdu_list[ul_req_index].ulsch_cqi_harq_ri_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.initial_number_of_resource_blocks = rb_table[rb_table_index]; - - }else{ - ul_req_tmp->ul_config_pdu_list[ul_req_index].pdu_type = NFAPI_UL_CONFIG_ULSCH_HARQ_PDU_TYPE; - ulsch_harq_information = &ul_req_tmp->ul_config_pdu_list[ul_req_index].ulsch_harq_pdu.harq_information; - ul_req_tmp->ul_config_pdu_list[ul_req_index].ulsch_harq_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.tl.tag = NFAPI_UL_CONFIG_REQUEST_INITIAL_TRANSMISSION_PARAMETERS_REL8_TAG; - ul_req_tmp->ul_config_pdu_list[ul_req_index].ulsch_harq_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.n_srs_initial = 0; // last symbol not punctured - ul_req_tmp->ul_config_pdu_list[ul_req_index].ulsch_harq_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.initial_number_of_resource_blocks = rb_table[rb_table_index]; - } - fill_nfapi_ulsch_harq_information(module_idP, CC_id,rnti, ulsch_harq_information,subframeP); - }else{ - ul_req_tmp->number_of_pdus++; - } - eNB->ul_handle++; - ul_req->header.message_id = NFAPI_UL_CONFIG_REQUEST; - ul_req_tmp->tl.tag = NFAPI_UL_CONFIG_REQUEST_BODY_TAG; - uint16_t ul_sched_frame = sched_frame; - uint16_t ul_sched_subframeP = sched_subframeP; - add_subframe(&ul_sched_frame, &ul_sched_subframeP, 2); - ul_req->sfn_sf = ul_sched_frame<<4|ul_sched_subframeP; - - add_ue_ulsch_info(module_idP, - CC_id, - UE_id, - subframeP, - S_UL_SCHEDULED); - - LOG_D(MAC,"[eNB %d] CC_id %d Frame %d, subframeP %d: Generated ULSCH DCI for next UE_id %d, format 0\n", module_idP,CC_id,frameP,subframeP,UE_id); - - // increment first rb for next UE allocation - first_rb[CC_id]+=rb_table[rb_table_index]; - if(ulsch_ue_select[CC_id].list[ulsch_ue_num].ue_priority == SCH_UL_FIRST) { - UE_template->scheduled_ul_bytes += get_TBS_UL(UE_template->mcs_UL[harq_pid],rb_table[rb_table_index]); - UE_template->ul_SR = 0; - } - if((ulsch_ue_select[CC_id].list[ulsch_ue_num].ue_priority == SCH_UL_INACTIVE) && (ULSCH_first_end == 0)) { - ULSCH_first_end = 1; - last_ulsch_ue_id[CC_id] = ulsch_ue_select[CC_id].list[ulsch_ue_num-1].UE_id; - } - if((ulsch_ue_num == ulsch_ue_select[CC_id].ue_num-1) && (ULSCH_first_end == 0)) { - ULSCH_first_end = 1; - last_ulsch_ue_id[CC_id] = ulsch_ue_select[CC_id].list[ulsch_ue_num].UE_id; - } + for(ul_req_index = 0; ul_req_index < ul_req_tmp->number_of_pdus; ul_req_index++) { + if((ul_req_tmp->ul_config_pdu_list[ul_req_index].pdu_type == NFAPI_UL_CONFIG_UCI_HARQ_PDU_TYPE) && + (ul_req_tmp->ul_config_pdu_list[ul_req_index].uci_harq_pdu.ue_information.ue_information_rel8.rnti == rnti)) { + dlsch_flag = 1; + LOG_D(MAC,"Frame %d, Subframe %d:rnti %x ul_req_index %d Switched UCI HARQ to ULSCH HARQ(first)\n",frameP,subframeP,rnti,ul_req_index); + break; } - else if (ulsch_ue_select[CC_id].list[ulsch_ue_num].ue_priority == SCH_UL_RETRANS) { // round > 0 => retransmission - T(T_ENB_MAC_UE_UL_SCHEDULE_RETRANSMISSION, T_INT(module_idP), T_INT(CC_id), T_INT(rnti), T_INT(frameP), - T_INT(subframeP), T_INT(harq_pid), T_INT(UE_template->mcs_UL[harq_pid]), T_INT(first_rb[CC_id]), T_INT(rb_table[rb_table_index]), - T_INT(round)); + } - round = UE_sched_ctrl->round_UL[CC_id][harq_pid]; - UE_list->eNB_UE_stats[CC_id][UE_id].normalized_rx_power=normalized_rx_power; - UE_list->eNB_UE_stats[CC_id][UE_id].target_rx_power=target_rx_power; - uint8_t mcs_rv = 0; - if(rvidx_tab[round&3]==1){ - mcs_rv = 29; - }else if(rvidx_tab[round&3]==2){ - mcs_rv = 30; - }else if(rvidx_tab[round&3]==3){ - mcs_rv = 31; - } - UE_template->TBS_UL[harq_pid] = get_TBS_UL(UE_template->mcs_UL[harq_pid],ulsch_ue_select[CC_id].list[ulsch_ue_num].nb_rb); - UE_list->eNB_UE_stats[CC_id][UE_id].ulsch_TBS=UE_template->TBS_UL[harq_pid]; - - - if (mac_eNB_get_rrc_status(module_idP,rnti) < RRC_CONNECTED) - LOG_D(MAC,"[eNB %d][PUSCH %d/%x] CC_id %d Frame %d subframeP %d Scheduled UE %d (mcs %d, first rb %d, nb_rb %d, rb_table_index %d, TBS %d, harq_pid %d)\n", - module_idP,harq_pid,rnti,CC_id,frameP,subframeP,UE_id,mcs_rv,first_rb[CC_id],rb_table[rb_table_index],rb_table_index,UE_template->TBS_UL[harq_pid],harq_pid); - - // bad indices : 20 (40 PRB), 21 (45 PRB), 22 (48 PRB) - //store for possible retransmission - UE_template->nb_rb_ul[harq_pid] = ulsch_ue_select[CC_id].list[ulsch_ue_num].nb_rb; - UE_template->first_rb_ul[harq_pid] = ulsch_ue_select[CC_id].list[ulsch_ue_num].start_rb; - - UE_sched_ctrl->ul_scheduled |= (1<hi_dci0_pdu_list[hi_dci0_req->number_of_dci+hi_dci0_req->number_of_hi]; - memset((void*)hi_dci0_pdu,0,sizeof(nfapi_hi_dci0_request_pdu_t)); - hi_dci0_pdu->pdu_type = NFAPI_HI_DCI0_DCI_PDU_TYPE; - hi_dci0_pdu->pdu_size = 2+sizeof(nfapi_hi_dci0_dci_pdu); - hi_dci0_pdu->dci_pdu.dci_pdu_rel8.dci_format = NFAPI_UL_DCI_FORMAT_0; - hi_dci0_pdu->dci_pdu.dci_pdu_rel8.aggregation_level = aggregation; - hi_dci0_pdu->dci_pdu.dci_pdu_rel8.rnti = rnti; - hi_dci0_pdu->dci_pdu.dci_pdu_rel8.transmission_power = 6000; - hi_dci0_pdu->dci_pdu.dci_pdu_rel8.resource_block_start = ulsch_ue_select[CC_id].list[ulsch_ue_num].start_rb; - hi_dci0_pdu->dci_pdu.dci_pdu_rel8.number_of_resource_block = ulsch_ue_select[CC_id].list[ulsch_ue_num].nb_rb; - hi_dci0_pdu->dci_pdu.dci_pdu_rel8.mcs_1 = mcs_rv; - hi_dci0_pdu->dci_pdu.dci_pdu_rel8.cyclic_shift_2_for_drms = cshift; - hi_dci0_pdu->dci_pdu.dci_pdu_rel8.frequency_hopping_enabled_flag = 0; - hi_dci0_pdu->dci_pdu.dci_pdu_rel8.new_data_indication_1 = UE_template->oldNDI_UL[harq_pid]; - hi_dci0_pdu->dci_pdu.dci_pdu_rel8.tpc = tpc; - hi_dci0_pdu->dci_pdu.dci_pdu_rel8.cqi_csi_request = cqi_req; - hi_dci0_pdu->dci_pdu.dci_pdu_rel8.dl_assignment_index = UE_template->DAI_ul[sched_subframeP]; - hi_dci0_pdu->dci_pdu.dci_pdu_rel8.harq_pid = harq_pid; - - hi_dci0_req->number_of_dci++; - // Add UL_config PDUs - LOG_D(MAC,"[PUSCH %d] Frame %d, Subframe %d: Adding UL CONFIG.Request for UE %d/%x, ulsch_frame %d, ulsch_subframe %d\n", - harq_pid,frameP,subframeP,UE_id,rnti,sched_frame,sched_subframeP); - ul_req_index = 0; - dlsch_flag = 0; - for(ul_req_index = 0;ul_req_index < ul_req_tmp->number_of_pdus;ul_req_index++){ - if((ul_req_tmp->ul_config_pdu_list[ul_req_index].pdu_type == NFAPI_UL_CONFIG_UCI_HARQ_PDU_TYPE) && - (ul_req_tmp->ul_config_pdu_list[ul_req_index].uci_harq_pdu.ue_information.ue_information_rel8.rnti == rnti)){ - dlsch_flag = 1; - LOG_D(MAC,"Frame %d, Subframe %d:rnti %x ul_req_index %d Switched UCI HARQ to ULSCH HARQ(phich)\n",frameP,subframeP,rnti,ul_req_index); - break; - } - } - fill_nfapi_ulsch_config_request_rel8(&ul_req_tmp->ul_config_pdu_list[ul_req_index], - cqi_req, - cc, - UE_template->physicalConfigDedicated, - get_tmode(module_idP,CC_id,UE_id), - eNB->ul_handle, - rnti, - ulsch_ue_select[CC_id].list[ulsch_ue_num].start_rb, // resource_block_start - ulsch_ue_select[CC_id].list[ulsch_ue_num].nb_rb, // number_of_resource_blocks - UE_template->mcs_UL[harq_pid], - cshift, // cyclic_shift_2_for_drms - 0, // frequency_hopping_enabled_flag - 0, // frequency_hopping_bits - UE_template->oldNDI_UL[harq_pid], // new_data_indication - rvidx_tab[round&3], // redundancy_version - harq_pid, // harq_process_number - 0, // ul_tx_mode - 0, // current_tx_nb - 0, // n_srs - UE_template->TBS_UL[harq_pid] - ); + // Add UL_config PDUs + fill_nfapi_ulsch_config_request_rel8(&ul_req_tmp->ul_config_pdu_list[ul_req_index], + cqi_req, + cc, + UE_template->physicalConfigDedicated, + get_tmode(module_idP,CC_id,UE_id), + eNB->ul_handle, + rnti, + first_rb[CC_id], // resource_block_start + rb_table[rb_table_index], // number_of_resource_blocks + UE_template->mcs_UL[harq_pid], + cshift, // cyclic_shift_2_for_drms + 0, // frequency_hopping_enabled_flag + 0, // frequency_hopping_bits + ndi, // new_data_indication + 0, // redundancy_version + harq_pid, // harq_process_number + 0, // ul_tx_mode + 0, // current_tx_nb + 0, // n_srs + get_TBS_UL(UE_template->mcs_UL[harq_pid], + rb_table[rb_table_index]) + ); #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - if (UE_template->rach_resource_type>0) { // This is a BL/CE UE allocation - fill_nfapi_ulsch_config_request_emtc(&ul_req_tmp->ul_config_pdu_list[ul_req_index], - UE_template->rach_resource_type>2 ? 2 : 1, - 1, //total_number_of_repetitions - 1, //repetition_number - (frameP*10)+subframeP); - } + + if (UE_template->rach_resource_type>0) { // This is a BL/CE UE allocation + fill_nfapi_ulsch_config_request_emtc(&ul_req_tmp->ul_config_pdu_list[ul_req_index], + UE_template->rach_resource_type>2 ? 2 : 1, + 1, //total_number_of_repetitions + 1, //repetition_number + (frameP*10)+subframeP); + } + #endif - if(dlsch_flag == 1){ - if(cqi_req == 1){ - ul_req_tmp->ul_config_pdu_list[ul_req_index].pdu_type = NFAPI_UL_CONFIG_ULSCH_CQI_HARQ_RI_PDU_TYPE; - ulsch_harq_information = &ul_req_tmp->ul_config_pdu_list[ul_req_index].ulsch_cqi_harq_ri_pdu.harq_information; - ul_req_tmp->ul_config_pdu_list[ul_req_index].ulsch_cqi_harq_ri_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.tl.tag=NFAPI_UL_CONFIG_REQUEST_INITIAL_TRANSMISSION_PARAMETERS_REL8_TAG; - ul_req_tmp->ul_config_pdu_list[ul_req_index].ulsch_cqi_harq_ri_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.n_srs_initial = 0; // last symbol not punctured - ul_req_tmp->ul_config_pdu_list[ul_req_index].ulsch_cqi_harq_ri_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.initial_number_of_resource_blocks = ulsch_ue_select[CC_id].list[ulsch_ue_num].nb_rb; - }else{ - ul_req_tmp->ul_config_pdu_list[ul_req_index].pdu_type = NFAPI_UL_CONFIG_ULSCH_HARQ_PDU_TYPE; - ulsch_harq_information = &ul_req_tmp->ul_config_pdu_list[ul_req_index].ulsch_harq_pdu.harq_information; - ul_req_tmp->ul_config_pdu_list[ul_req_index].ulsch_harq_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.tl.tag = NFAPI_UL_CONFIG_REQUEST_INITIAL_TRANSMISSION_PARAMETERS_REL8_TAG; - ul_req_tmp->ul_config_pdu_list[ul_req_index].ulsch_harq_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.n_srs_initial = 0; // last symbol not punctured - ul_req_tmp->ul_config_pdu_list[ul_req_index].ulsch_harq_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.initial_number_of_resource_blocks = ulsch_ue_select[CC_id].list[ulsch_ue_num].nb_rb; - } - fill_nfapi_ulsch_harq_information(module_idP, CC_id,rnti, ulsch_harq_information,subframeP); - }else{ - ul_req_tmp->number_of_pdus++; - } - eNB->ul_handle++; - ul_req->header.message_id = NFAPI_UL_CONFIG_REQUEST; - ul_req_tmp->tl.tag = NFAPI_UL_CONFIG_REQUEST_BODY_TAG; - ul_req->sfn_sf = sched_frame<<4|sched_subframeP; - - LOG_D(MAC,"[eNB %d] CC_id %d Frame %d, subframeP %d: Generated ULSCH DCI for next UE_id %d, format 0(round >0)\n", module_idP,CC_id,frameP,subframeP,UE_id); - - // increment first rb for next UE allocation - first_rb[CC_id]+=ulsch_ue_select[CC_id].list[ulsch_ue_num].nb_rb; + if(dlsch_flag == 1) { + if(cqi_req == 1) { + ul_req_tmp->ul_config_pdu_list[ul_req_index].pdu_type = NFAPI_UL_CONFIG_ULSCH_CQI_HARQ_RI_PDU_TYPE; + ulsch_harq_information = &ul_req_tmp->ul_config_pdu_list[ul_req_index].ulsch_cqi_harq_ri_pdu.harq_information; + ul_req_tmp->ul_config_pdu_list[ul_req_index].ulsch_cqi_harq_ri_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.tl.tag= + NFAPI_UL_CONFIG_REQUEST_INITIAL_TRANSMISSION_PARAMETERS_REL8_TAG; + ul_req_tmp->ul_config_pdu_list[ul_req_index].ulsch_cqi_harq_ri_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.n_srs_initial = 0; // last symbol not punctured + ul_req_tmp->ul_config_pdu_list[ul_req_index].ulsch_cqi_harq_ri_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.initial_number_of_resource_blocks = rb_table[rb_table_index]; + } else { + ul_req_tmp->ul_config_pdu_list[ul_req_index].pdu_type = NFAPI_UL_CONFIG_ULSCH_HARQ_PDU_TYPE; + ulsch_harq_information = &ul_req_tmp->ul_config_pdu_list[ul_req_index].ulsch_harq_pdu.harq_information; + ul_req_tmp->ul_config_pdu_list[ul_req_index].ulsch_harq_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.tl.tag = + NFAPI_UL_CONFIG_REQUEST_INITIAL_TRANSMISSION_PARAMETERS_REL8_TAG; + ul_req_tmp->ul_config_pdu_list[ul_req_index].ulsch_harq_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.n_srs_initial = 0; // last symbol not punctured + ul_req_tmp->ul_config_pdu_list[ul_req_index].ulsch_harq_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.initial_number_of_resource_blocks = rb_table[rb_table_index]; } + + fill_nfapi_ulsch_harq_information(module_idP, CC_id,rnti, ulsch_harq_information,subframeP); + } else { + ul_req_tmp->number_of_pdus++; + } + + eNB->ul_handle++; + ul_req->header.message_id = NFAPI_UL_CONFIG_REQUEST; + ul_req_tmp->tl.tag = NFAPI_UL_CONFIG_REQUEST_BODY_TAG; + uint16_t ul_sched_frame = sched_frame; + uint16_t ul_sched_subframeP = sched_subframeP; + add_subframe(&ul_sched_frame, &ul_sched_subframeP, 2); + ul_req->sfn_sf = ul_sched_frame<<4|ul_sched_subframeP; + add_ue_ulsch_info(module_idP, + CC_id, + UE_id, + subframeP, + S_UL_SCHEDULED); + LOG_D(MAC,"[eNB %d] CC_id %d Frame %d, subframeP %d: Generated ULSCH DCI for next UE_id %d, format 0\n", module_idP,CC_id,frameP,subframeP,UE_id); + // increment first rb for next UE allocation + first_rb[CC_id]+=rb_table[rb_table_index]; + + if(ulsch_ue_select[CC_id].list[ulsch_ue_num].ue_priority == SCH_UL_FIRST) { + UE_template->scheduled_ul_bytes += get_TBS_UL(UE_template->mcs_UL[harq_pid],rb_table[rb_table_index]); + UE_template->ul_SR = 0; + } + + if((ulsch_ue_select[CC_id].list[ulsch_ue_num].ue_priority == SCH_UL_INACTIVE) && (ULSCH_first_end == 0)) { + ULSCH_first_end = 1; + last_ulsch_ue_id[CC_id] = ulsch_ue_select[CC_id].list[ulsch_ue_num-1].UE_id; + } + + if((ulsch_ue_num == ulsch_ue_select[CC_id].ue_num-1) && (ULSCH_first_end == 0)) { + ULSCH_first_end = 1; + last_ulsch_ue_id[CC_id] = ulsch_ue_select[CC_id].list[ulsch_ue_num].UE_id; + } + } else if (ulsch_ue_select[CC_id].list[ulsch_ue_num].ue_priority == SCH_UL_RETRANS) { // round > 0 => retransmission + T(T_ENB_MAC_UE_UL_SCHEDULE_RETRANSMISSION, T_INT(module_idP), T_INT(CC_id), T_INT(rnti), T_INT(frameP), + T_INT(subframeP), T_INT(harq_pid), T_INT(UE_template->mcs_UL[harq_pid]), T_INT(first_rb[CC_id]), T_INT(rb_table[rb_table_index]), + T_INT(round)); + round = UE_sched_ctrl->round_UL[CC_id][harq_pid]; + UE_list->eNB_UE_stats[CC_id][UE_id].normalized_rx_power=normalized_rx_power; + UE_list->eNB_UE_stats[CC_id][UE_id].target_rx_power=target_rx_power; + uint8_t mcs_rv = 0; + + if(rvidx_tab[round&3]==1) { + mcs_rv = 29; + } else if(rvidx_tab[round&3]==2) { + mcs_rv = 30; + } else if(rvidx_tab[round&3]==3) { + mcs_rv = 31; + } + + UE_template->TBS_UL[harq_pid] = get_TBS_UL(UE_template->mcs_UL[harq_pid],ulsch_ue_select[CC_id].list[ulsch_ue_num].nb_rb); + UE_list->eNB_UE_stats[CC_id][UE_id].ulsch_TBS=UE_template->TBS_UL[harq_pid]; + + if (mac_eNB_get_rrc_status(module_idP,rnti) < RRC_CONNECTED) + LOG_D(MAC,"[eNB %d][PUSCH %d/%x] CC_id %d Frame %d subframeP %d Scheduled UE %d (mcs %d, first rb %d, nb_rb %d, rb_table_index %d, TBS %d, harq_pid %d)\n", + module_idP,harq_pid,rnti,CC_id,frameP,subframeP,UE_id,mcs_rv,first_rb[CC_id],rb_table[rb_table_index],rb_table_index,UE_template->TBS_UL[harq_pid],harq_pid); + + // bad indices : 20 (40 PRB), 21 (45 PRB), 22 (48 PRB) + //store for possible retransmission + UE_template->nb_rb_ul[harq_pid] = ulsch_ue_select[CC_id].list[ulsch_ue_num].nb_rb; + UE_template->first_rb_ul[harq_pid] = ulsch_ue_select[CC_id].list[ulsch_ue_num].start_rb; + UE_sched_ctrl->ul_scheduled |= (1<hi_dci0_pdu_list[hi_dci0_req->number_of_dci+hi_dci0_req->number_of_hi]; + memset((void *)hi_dci0_pdu,0,sizeof(nfapi_hi_dci0_request_pdu_t)); + hi_dci0_pdu->pdu_type = NFAPI_HI_DCI0_DCI_PDU_TYPE; + hi_dci0_pdu->pdu_size = 2+sizeof(nfapi_hi_dci0_dci_pdu); + hi_dci0_pdu->dci_pdu.dci_pdu_rel8.dci_format = NFAPI_UL_DCI_FORMAT_0; + hi_dci0_pdu->dci_pdu.dci_pdu_rel8.aggregation_level = aggregation; + hi_dci0_pdu->dci_pdu.dci_pdu_rel8.rnti = rnti; + hi_dci0_pdu->dci_pdu.dci_pdu_rel8.transmission_power = 6000; + hi_dci0_pdu->dci_pdu.dci_pdu_rel8.resource_block_start = ulsch_ue_select[CC_id].list[ulsch_ue_num].start_rb; + hi_dci0_pdu->dci_pdu.dci_pdu_rel8.number_of_resource_block = ulsch_ue_select[CC_id].list[ulsch_ue_num].nb_rb; + hi_dci0_pdu->dci_pdu.dci_pdu_rel8.mcs_1 = mcs_rv; + hi_dci0_pdu->dci_pdu.dci_pdu_rel8.cyclic_shift_2_for_drms = cshift; + hi_dci0_pdu->dci_pdu.dci_pdu_rel8.frequency_hopping_enabled_flag = 0; + hi_dci0_pdu->dci_pdu.dci_pdu_rel8.new_data_indication_1 = UE_template->oldNDI_UL[harq_pid]; + hi_dci0_pdu->dci_pdu.dci_pdu_rel8.tpc = tpc; + hi_dci0_pdu->dci_pdu.dci_pdu_rel8.cqi_csi_request = cqi_req; + hi_dci0_pdu->dci_pdu.dci_pdu_rel8.dl_assignment_index = UE_template->DAI_ul[sched_subframeP]; + hi_dci0_pdu->dci_pdu.dci_pdu_rel8.harq_pid = harq_pid; + hi_dci0_req->number_of_dci++; + // Add UL_config PDUs + LOG_D(MAC,"[PUSCH %d] Frame %d, Subframe %d: Adding UL CONFIG.Request for UE %d/%x, ulsch_frame %d, ulsch_subframe %d\n", + harq_pid,frameP,subframeP,UE_id,rnti,sched_frame,sched_subframeP); + ul_req_index = 0; + dlsch_flag = 0; + + for(ul_req_index = 0; ul_req_index < ul_req_tmp->number_of_pdus; ul_req_index++) { + if((ul_req_tmp->ul_config_pdu_list[ul_req_index].pdu_type == NFAPI_UL_CONFIG_UCI_HARQ_PDU_TYPE) && + (ul_req_tmp->ul_config_pdu_list[ul_req_index].uci_harq_pdu.ue_information.ue_information_rel8.rnti == rnti)) { + dlsch_flag = 1; + LOG_D(MAC,"Frame %d, Subframe %d:rnti %x ul_req_index %d Switched UCI HARQ to ULSCH HARQ(phich)\n",frameP,subframeP,rnti,ul_req_index); + break; + } + } + + fill_nfapi_ulsch_config_request_rel8(&ul_req_tmp->ul_config_pdu_list[ul_req_index], + cqi_req, + cc, + UE_template->physicalConfigDedicated, + get_tmode(module_idP,CC_id,UE_id), + eNB->ul_handle, + rnti, + ulsch_ue_select[CC_id].list[ulsch_ue_num].start_rb, // resource_block_start + ulsch_ue_select[CC_id].list[ulsch_ue_num].nb_rb, // number_of_resource_blocks + UE_template->mcs_UL[harq_pid], + cshift, // cyclic_shift_2_for_drms + 0, // frequency_hopping_enabled_flag + 0, // frequency_hopping_bits + UE_template->oldNDI_UL[harq_pid], // new_data_indication + rvidx_tab[round&3], // redundancy_version + harq_pid, // harq_process_number + 0, // ul_tx_mode + 0, // current_tx_nb + 0, // n_srs + UE_template->TBS_UL[harq_pid] + ); +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + + if (UE_template->rach_resource_type>0) { // This is a BL/CE UE allocation + fill_nfapi_ulsch_config_request_emtc(&ul_req_tmp->ul_config_pdu_list[ul_req_index], + UE_template->rach_resource_type>2 ? 2 : 1, + 1, //total_number_of_repetitions + 1, //repetition_number + (frameP*10)+subframeP); + } + +#endif + + if(dlsch_flag == 1) { + if(cqi_req == 1) { + ul_req_tmp->ul_config_pdu_list[ul_req_index].pdu_type = NFAPI_UL_CONFIG_ULSCH_CQI_HARQ_RI_PDU_TYPE; + ulsch_harq_information = &ul_req_tmp->ul_config_pdu_list[ul_req_index].ulsch_cqi_harq_ri_pdu.harq_information; + ul_req_tmp->ul_config_pdu_list[ul_req_index].ulsch_cqi_harq_ri_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.tl.tag= + NFAPI_UL_CONFIG_REQUEST_INITIAL_TRANSMISSION_PARAMETERS_REL8_TAG; + ul_req_tmp->ul_config_pdu_list[ul_req_index].ulsch_cqi_harq_ri_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.n_srs_initial = 0; // last symbol not punctured + ul_req_tmp->ul_config_pdu_list[ul_req_index].ulsch_cqi_harq_ri_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.initial_number_of_resource_blocks = + ulsch_ue_select[CC_id].list[ulsch_ue_num].nb_rb; + } else { + ul_req_tmp->ul_config_pdu_list[ul_req_index].pdu_type = NFAPI_UL_CONFIG_ULSCH_HARQ_PDU_TYPE; + ulsch_harq_information = &ul_req_tmp->ul_config_pdu_list[ul_req_index].ulsch_harq_pdu.harq_information; + ul_req_tmp->ul_config_pdu_list[ul_req_index].ulsch_harq_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.tl.tag = + NFAPI_UL_CONFIG_REQUEST_INITIAL_TRANSMISSION_PARAMETERS_REL8_TAG; + ul_req_tmp->ul_config_pdu_list[ul_req_index].ulsch_harq_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.n_srs_initial = 0; // last symbol not punctured + ul_req_tmp->ul_config_pdu_list[ul_req_index].ulsch_harq_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.initial_number_of_resource_blocks = + ulsch_ue_select[CC_id].list[ulsch_ue_num].nb_rb; + } + + fill_nfapi_ulsch_harq_information(module_idP, CC_id,rnti, ulsch_harq_information,subframeP); + } else { + ul_req_tmp->number_of_pdus++; + } + + eNB->ul_handle++; + ul_req->header.message_id = NFAPI_UL_CONFIG_REQUEST; + ul_req_tmp->tl.tag = NFAPI_UL_CONFIG_REQUEST_BODY_TAG; + ul_req->sfn_sf = sched_frame<<4|sched_subframeP; + LOG_D(MAC,"[eNB %d] CC_id %d Frame %d, subframeP %d: Generated ULSCH DCI for next UE_id %d, format 0(round >0)\n", module_idP,CC_id,frameP,subframeP,UE_id); + // increment first rb for next UE allocation + first_rb[CC_id]+=ulsch_ue_select[CC_id].list[ulsch_ue_num].nb_rb; + } } // loop over UE_id } // loop of CC_id } diff --git a/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c b/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c index 997877d7a8..e67ddb6aae 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c @@ -51,7 +51,7 @@ #include "pdcp.h" #if defined(ENABLE_ITTI) -#include "intertask_interface.h" + #include "intertask_interface.h" #endif #include "ENB_APP/flexran_agent_defs.h" @@ -76,10 +76,10 @@ extern int oai_nfapi_ul_config_req(nfapi_ul_config_request_t *ul_config_req); extern uint8_t nfapi_mode; // This table holds the allowable PRB sizes for ULSCH transmissions -uint8_t rb_table[34] = - { 1, 2, 3, 4, 5, 6, 8, 9, 10, 12, 15, 16, 18, 20, 24, 25, 27, 30, 32, - 36, 40, 45, 48, 50, 54, 60, 64, 72, 75, 80, 81, 90, 96, 100 - }; +uint8_t rb_table[34] = { + 1, 2, 3, 4, 5, 6, 8, 9, 10, 12, 15, 16, 18, 20, 24, 25, 27, 30, 32, + 36, 40, 45, 48, 50, 54, 60, 64, 72, 75, 80, 81, 90, 96, 100 +}; extern mui_t rrc_eNB_mui; @@ -89,10 +89,9 @@ rx_sdu(const module_id_t enb_mod_idP, const frame_t frameP, const sub_frame_t subframeP, const rnti_t rntiP, - uint8_t * sduP, + uint8_t *sduP, const uint16_t sdu_lenP, - const uint16_t timing_advance, const uint8_t ul_cqi) -{ + const uint16_t timing_advance, const uint8_t ul_cqi) { int current_rnti = rntiP; unsigned char rx_ces[MAX_NUM_CE], num_ce, num_sdu, i, *payload_ptr; unsigned char rx_lcids[NB_RB_MAX]; @@ -104,15 +103,12 @@ rx_sdu(const module_id_t enb_mod_idP, int harq_pid = subframe2harqpid(&mac->common_channels[CC_idP], frameP, subframeP); int lcgid_updated[4] = {0, 0, 0, 0}; - UE_list_t *UE_list = &mac->UE_list; int crnti_rx = 0; RA_t *ra = (RA_t *) & RC.mac[enb_mod_idP]->common_channels[CC_idP].ra[0]; int first_rb = 0; - rrc_eNB_ue_context_t *ue_contextP = NULL; - start_meas(&mac->rx_ulsch_sdu); if ((UE_id > MAX_MOBILES_PER_ENB) || (UE_id == -1)) @@ -121,23 +117,24 @@ rx_sdu(const module_id_t enb_mod_idP, } VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME - (VCD_SIGNAL_DUMPER_FUNCTIONS_RX_SDU, 1); + (VCD_SIGNAL_DUMPER_FUNCTIONS_RX_SDU, 1); + if (opt_enabled == 1) { trace_pdu(DIRECTION_UPLINK, sduP, sdu_lenP, 0, WS_C_RNTI, current_rnti, frameP, subframeP, - 0, 0); + 0, 0); LOG_D(OPT, "[eNB %d][ULSCH] Frame %d rnti %x with size %d\n", - enb_mod_idP, frameP, current_rnti, sdu_lenP); + enb_mod_idP, frameP, current_rnti, sdu_lenP); } if (UE_id != -1) { LOG_D(MAC, - "[eNB %d][PUSCH %d] CC_id %d %d.%d Received ULSCH sdu round %d from PHY (rnti %x, UE_id %d) ul_cqi %d\n", - enb_mod_idP, harq_pid, CC_idP,frameP,subframeP, - UE_list->UE_sched_ctrl[UE_id].round_UL[CC_idP][harq_pid], - current_rnti, UE_id, ul_cqi); - + "[eNB %d][PUSCH %d] CC_id %d %d.%d Received ULSCH sdu round %d from PHY (rnti %x, UE_id %d) ul_cqi %d\n", + enb_mod_idP, harq_pid, CC_idP,frameP,subframeP, + UE_list->UE_sched_ctrl[UE_id].round_UL[CC_idP][harq_pid], + current_rnti, UE_id, ul_cqi); AssertFatal(UE_list->UE_sched_ctrl[UE_id]. - round_UL[CC_idP][harq_pid] < 8, "round >= 8\n"); + round_UL[CC_idP][harq_pid] < 8, "round >= 8\n"); + if (sduP != NULL) { UE_list->UE_sched_ctrl[UE_id].ul_inactivity_timer = 0; UE_list->UE_sched_ctrl[UE_id].ul_failure_timer = 0; @@ -147,58 +144,60 @@ rx_sdu(const module_id_t enb_mod_idP, * lte_est_timing_advance_pusch, maybe it's not necessary? * maybe it's even not correct at all? */ - UE_list->UE_sched_ctrl[UE_id].ta_update = (UE_list->UE_sched_ctrl[UE_id].ta_update * 3 + timing_advance) / 4; + UE_list->UE_sched_ctrl[UE_id].ta_update = (UE_list->UE_sched_ctrl[UE_id].ta_update * 3 + timing_advance) / 4; UE_list->UE_sched_ctrl[UE_id].pusch_snr[CC_idP] = ul_cqi; UE_list->UE_sched_ctrl[UE_id].ul_consecutive_errors = 0; first_rb = UE_list->UE_template[CC_idP][UE_id].first_rb_ul[harq_pid]; if (UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync > 0) { - UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync = 0; - mac_eNB_rrc_ul_in_sync(enb_mod_idP, CC_idP, frameP, - subframeP, UE_RNTI(enb_mod_idP, - UE_id)); + UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync = 0; + mac_eNB_rrc_ul_in_sync(enb_mod_idP, CC_idP, frameP, + subframeP, UE_RNTI(enb_mod_idP, + UE_id)); } /* update scheduled bytes */ UE_list->UE_template[CC_idP][UE_id].scheduled_ul_bytes -= UE_list->UE_template[CC_idP][UE_id].TBS_UL[harq_pid]; + if (UE_list->UE_template[CC_idP][UE_id].scheduled_ul_bytes < 0) UE_list->UE_template[CC_idP][UE_id].scheduled_ul_bytes = 0; - } else { // we've got an error + } else { // we've got an error LOG_I(MAC, - "[eNB %d][PUSCH %d] CC_id %d %d.%d ULSCH in error in round %d, ul_cqi %d\n", - enb_mod_idP, harq_pid, CC_idP,frameP,subframeP, - UE_list->UE_sched_ctrl[UE_id].round_UL[CC_idP][harq_pid], - ul_cqi); + "[eNB %d][PUSCH %d] CC_id %d %d.%d ULSCH in error in round %d, ul_cqi %d\n", + enb_mod_idP, harq_pid, CC_idP,frameP,subframeP, + UE_list->UE_sched_ctrl[UE_id].round_UL[CC_idP][harq_pid], + ul_cqi); - if(ul_cqi>200){ // too high energy pattern + if(ul_cqi>200) { // too high energy pattern UE_list->UE_sched_ctrl[UE_id].pusch_snr[CC_idP] = ul_cqi; } // AssertFatal(1==0,"ulsch in error\n"); if (UE_list->UE_sched_ctrl[UE_id].round_UL[CC_idP][harq_pid] == 3) { - UE_list->UE_sched_ctrl[UE_id].ul_scheduled &= (~(1 << harq_pid)); - UE_list->UE_sched_ctrl[UE_id].round_UL[CC_idP][harq_pid] = 0; - if (UE_list->UE_sched_ctrl[UE_id].ul_consecutive_errors++ == 10) - UE_list->UE_sched_ctrl[UE_id].ul_failure_timer = 1; + UE_list->UE_sched_ctrl[UE_id].ul_scheduled &= (~(1 << harq_pid)); + UE_list->UE_sched_ctrl[UE_id].round_UL[CC_idP][harq_pid] = 0; + + if (UE_list->UE_sched_ctrl[UE_id].ul_consecutive_errors++ == 10) + UE_list->UE_sched_ctrl[UE_id].ul_failure_timer = 1; /* update scheduled bytes */ UE_list->UE_template[CC_idP][UE_id].scheduled_ul_bytes -= UE_list->UE_template[CC_idP][UE_id].TBS_UL[harq_pid]; + if (UE_list->UE_template[CC_idP][UE_id].scheduled_ul_bytes < 0) UE_list->UE_template[CC_idP][UE_id].scheduled_ul_bytes = 0; if (find_RA_id(enb_mod_idP, CC_idP, current_rnti) != -1) cancel_ra_proc(enb_mod_idP, CC_idP, frameP, current_rnti); } else - UE_list->UE_sched_ctrl[UE_id].round_UL[CC_idP][harq_pid]++; + UE_list->UE_sched_ctrl[UE_id].round_UL[CC_idP][harq_pid]++; first_rb = UE_list->UE_template[CC_idP][UE_id].first_rb_ul[harq_pid]; - // Program NACK for PHICH LOG_D(MAC, - "Programming PHICH NACK for rnti %x harq_pid %d (first_rb %d)\n", - current_rnti, harq_pid, first_rb); + "Programming PHICH NACK for rnti %x harq_pid %d (first_rb %d)\n", + current_rnti, harq_pid, first_rb); nfapi_hi_dci0_request_t *hi_dci0_req; - uint8_t sf_ahead_dl = ul_subframe2_k_phich(&mac->common_channels[CC_idP] , subframeP); + uint8_t sf_ahead_dl = ul_subframe2_k_phich(&mac->common_channels[CC_idP], subframeP); hi_dci0_req = &mac->HI_DCI0_req[CC_idP][(subframeP+sf_ahead_dl)%10]; nfapi_hi_dci0_request_body_t *hi_dci0_req_body = &hi_dci0_req->hi_dci0_request_body; nfapi_hi_dci0_request_pdu_t *hi_dci0_pdu = @@ -215,64 +214,59 @@ rx_sdu(const module_id_t enb_mod_idP, hi_dci0_req_body->tl.tag = NFAPI_HI_DCI0_REQUEST_BODY_TAG; hi_dci0_req->sfn_sf = sfnsf_add_subframe(frameP,subframeP, sf_ahead_dl); hi_dci0_req->header.message_id = NFAPI_HI_DCI0_REQUEST; - return; - } - } else if ((RA_id = find_RA_id(enb_mod_idP, CC_idP, current_rnti)) != -1) { // Check if this is an RA process for the rnti + } else if ((RA_id = find_RA_id(enb_mod_idP, CC_idP, current_rnti)) != -1) { // Check if this is an RA process for the rnti AssertFatal(mac->common_channels[CC_idP]. - radioResourceConfigCommon->rach_ConfigCommon. - maxHARQ_Msg3Tx > 1, - "maxHARQ %d should be greater than 1\n", - (int) mac->common_channels[CC_idP]. - radioResourceConfigCommon->rach_ConfigCommon. - maxHARQ_Msg3Tx); - + radioResourceConfigCommon->rach_ConfigCommon. + maxHARQ_Msg3Tx > 1, + "maxHARQ %d should be greater than 1\n", + (int) mac->common_channels[CC_idP]. + radioResourceConfigCommon->rach_ConfigCommon. + maxHARQ_Msg3Tx); LOG_D(MAC, - "[eNB %d][PUSCH %d] CC_id %d [RAPROC Msg3] Received ULSCH sdu round %d from PHY (rnti %x, RA_id %d) ul_cqi %d\n", - enb_mod_idP, harq_pid, CC_idP, ra[RA_id].msg3_round, - current_rnti, RA_id, ul_cqi); - + "[eNB %d][PUSCH %d] CC_id %d [RAPROC Msg3] Received ULSCH sdu round %d from PHY (rnti %x, RA_id %d) ul_cqi %d\n", + enb_mod_idP, harq_pid, CC_idP, ra[RA_id].msg3_round, + current_rnti, RA_id, ul_cqi); first_rb = ra->msg3_first_rb; - if (sduP == NULL) { // we've got an error on Msg3 + if (sduP == NULL) { // we've got an error on Msg3 LOG_D(MAC, - "[eNB %d] CC_id %d, RA %d ULSCH in error in round %d/%d\n", - enb_mod_idP, CC_idP, RA_id, - ra[RA_id].msg3_round, - (int) mac->common_channels[CC_idP]. - radioResourceConfigCommon->rach_ConfigCommon. - maxHARQ_Msg3Tx); - if (ra[RA_id].msg3_round >= mac->common_channels[CC_idP].radioResourceConfigCommon->rach_ConfigCommon.maxHARQ_Msg3Tx - 1) { - cancel_ra_proc(enb_mod_idP, CC_idP, frameP, current_rnti); - } + "[eNB %d] CC_id %d, RA %d ULSCH in error in round %d/%d\n", + enb_mod_idP, CC_idP, RA_id, + ra[RA_id].msg3_round, + (int) mac->common_channels[CC_idP]. + radioResourceConfigCommon->rach_ConfigCommon. + maxHARQ_Msg3Tx); - else { - first_rb = UE_list->UE_template[CC_idP][UE_id].first_rb_ul[harq_pid]; - ra[RA_id].msg3_round++; - // prepare handling of retransmission + if (ra[RA_id].msg3_round >= mac->common_channels[CC_idP].radioResourceConfigCommon->rach_ConfigCommon.maxHARQ_Msg3Tx - 1) { + cancel_ra_proc(enb_mod_idP, CC_idP, frameP, current_rnti); + } else { + first_rb = UE_list->UE_template[CC_idP][UE_id].first_rb_ul[harq_pid]; + ra[RA_id].msg3_round++; + // prepare handling of retransmission get_Msg3allocret(&mac->common_channels[CC_idP], - ra[RA_id].Msg3_subframe, ra[RA_id].Msg3_frame, - &ra[RA_id].Msg3_frame, &ra[RA_id].Msg3_subframe); - add_msg3(enb_mod_idP, CC_idP, &ra[RA_id], frameP, subframeP); + ra[RA_id].Msg3_subframe, ra[RA_id].Msg3_frame, + &ra[RA_id].Msg3_frame, &ra[RA_id].Msg3_subframe); + add_msg3(enb_mod_idP, CC_idP, &ra[RA_id], frameP, subframeP); } /* TODO: program NACK for PHICH? */ - return; } } else { LOG_W(MAC, - "Cannot find UE or RA corresponding to ULSCH rnti %x, dropping it\n", - current_rnti); + "Cannot find UE or RA corresponding to ULSCH rnti %x, dropping it\n", + current_rnti); return; } + payload_ptr = parse_ulsch_header(sduP, &num_ce, &num_sdu, rx_ces, rx_lcids, rx_lengths, sdu_lenP); - if(payload_ptr == NULL){ - LOG_E(MAC,"[eNB %d][PUSCH %d] CC_id %d ulsch header unknown lcid(rnti %x, UE_id %d)\n", - enb_mod_idP, harq_pid, CC_idP,current_rnti, UE_id); - return; + if(payload_ptr == NULL) { + LOG_E(MAC,"[eNB %d][PUSCH %d] CC_id %d ulsch header unknown lcid(rnti %x, UE_id %d)\n", + enb_mod_idP, harq_pid, CC_idP,current_rnti, UE_id); + return; } T(T_ENB_MAC_UE_UL_PDU, T_INT(enb_mod_idP), T_INT(CC_idP), @@ -282,65 +276,65 @@ rx_sdu(const module_id_t enb_mod_idP, T_INT(current_rnti), T_INT(frameP), T_INT(subframeP), T_INT(harq_pid), T_INT(sdu_lenP), T_INT(num_ce), T_INT(num_sdu), T_BUFFER(sduP, sdu_lenP)); - mac->eNB_stats[CC_idP].ulsch_bytes_rx = sdu_lenP; mac->eNB_stats[CC_idP].total_ulsch_bytes_rx += sdu_lenP; mac->eNB_stats[CC_idP].total_ulsch_pdus_rx += 1; - UE_list->UE_sched_ctrl[UE_id].round_UL[CC_idP][harq_pid] = 0; // control element for (i = 0; i < num_ce; i++) { - T(T_ENB_MAC_UE_UL_CE, T_INT(enb_mod_idP), T_INT(CC_idP), T_INT(current_rnti), T_INT(frameP), T_INT(subframeP), T_INT(rx_ces[i])); - switch (rx_ces[i]) { // implement and process BSR + CRNTI + - case POWER_HEADROOM: - if (UE_id != -1) { - UE_list->UE_template[CC_idP][UE_id].phr_info = - (payload_ptr[0] & 0x3f) - PHR_MAPPING_OFFSET + (int8_t)(hundred_times_log10_NPRB[UE_list->UE_template[CC_idP][UE_id].nb_rb_ul[harq_pid]-1]/100); - if(UE_list->UE_template[CC_idP][UE_id].phr_info > 40) - UE_list->UE_template[CC_idP][UE_id].phr_info = 40; + switch (rx_ces[i]) { // implement and process BSR + CRNTI + + case POWER_HEADROOM: + if (UE_id != -1) { + UE_list->UE_template[CC_idP][UE_id].phr_info = + (payload_ptr[0] & 0x3f) - PHR_MAPPING_OFFSET + (int8_t)(hundred_times_log10_NPRB[UE_list->UE_template[CC_idP][UE_id].nb_rb_ul[harq_pid]-1]/100); - LOG_D(MAC, - "[eNB %d] CC_id %d MAC CE_LCID %d : Received PHR PH = %d (db)\n", - enb_mod_idP, CC_idP, rx_ces[i], - UE_list->UE_template[CC_idP][UE_id].phr_info); - UE_list->UE_template[CC_idP][UE_id].phr_info_configured = - 1; - UE_list->UE_sched_ctrl[UE_id].phr_received = 1; - } - payload_ptr += sizeof(POWER_HEADROOM_CMD); - break; + if(UE_list->UE_template[CC_idP][UE_id].phr_info > 40) + UE_list->UE_template[CC_idP][UE_id].phr_info = 40; - case CRNTI: - { - int old_rnti = - (((uint16_t) payload_ptr[0]) << 8) + payload_ptr[1]; - int old_UE_id = find_UE_id(enb_mod_idP, old_rnti); - LOG_D(MAC, - "[eNB %d] Frame %d, Subframe %d CC_id %d MAC CE_LCID %d (ce %d/%d): CRNTI %x (UE_id %d) in Msg3\n", - enb_mod_idP, frameP, subframeP, CC_idP, rx_ces[i], i, - num_ce, old_rnti, old_UE_id); - /* receiving CRNTI means that the current rnti has to go away */ - //cancel_ra_proc(enb_mod_idP, CC_idP, frameP, - // current_rnti); - if (old_UE_id != -1) { - /* TODO: if the UE did random access (followed by a MAC uplink with - * CRNTI) because none of its scheduling request was granted, then - * according to 36.321 5.4.4 the UE's MAC will notify RRC to release - * PUCCH/SRS. According to 36.331 5.3.13 the UE will then apply - * default configuration for CQI reporting and scheduling requests, - * which basically means that the CQI requests won't work anymore and - * that the UE won't do any scheduling request anymore as long as the - * eNB doesn't reconfigure the UE. - * We have to take care of this. As the code is, nothing is done and - * the UE state in the eNB is wrong. - */ + LOG_D(MAC, + "[eNB %d] CC_id %d MAC CE_LCID %d : Received PHR PH = %d (db)\n", + enb_mod_idP, CC_idP, rx_ces[i], + UE_list->UE_template[CC_idP][UE_id].phr_info); + UE_list->UE_template[CC_idP][UE_id].phr_info_configured = + 1; + UE_list->UE_sched_ctrl[UE_id].phr_received = 1; + } + + payload_ptr += sizeof(POWER_HEADROOM_CMD); + break; + + case CRNTI: { + int old_rnti = + (((uint16_t) payload_ptr[0]) << 8) + payload_ptr[1]; + int old_UE_id = find_UE_id(enb_mod_idP, old_rnti); + LOG_D(MAC, + "[eNB %d] Frame %d, Subframe %d CC_id %d MAC CE_LCID %d (ce %d/%d): CRNTI %x (UE_id %d) in Msg3\n", + enb_mod_idP, frameP, subframeP, CC_idP, rx_ces[i], i, + num_ce, old_rnti, old_UE_id); + + /* receiving CRNTI means that the current rnti has to go away */ + //cancel_ra_proc(enb_mod_idP, CC_idP, frameP, + // current_rnti); + if (old_UE_id != -1) { + /* TODO: if the UE did random access (followed by a MAC uplink with + * CRNTI) because none of its scheduling request was granted, then + * according to 36.321 5.4.4 the UE's MAC will notify RRC to release + * PUCCH/SRS. According to 36.331 5.3.13 the UE will then apply + * default configuration for CQI reporting and scheduling requests, + * which basically means that the CQI requests won't work anymore and + * that the UE won't do any scheduling request anymore as long as the + * eNB doesn't reconfigure the UE. + * We have to take care of this. As the code is, nothing is done and + * the UE state in the eNB is wrong. + */ for (ii = 0; ii < NB_RA_PROC_MAX; ii++) { ra = &mac->common_channels[CC_idP].ra[ii]; + if ((ra->rnti == current_rnti) && (ra->state != IDLE)) { mac_rrc_data_ind(enb_mod_idP, CC_idP, @@ -355,7 +349,6 @@ rx_sdu(const module_id_t enb_mod_idP, LOG_I(MAC, "[eNB %d] Frame %d, Subframe %d CC_id %d : (rnti %x UE_id %d) RRCConnectionReconfiguration(Msg4)\n", enb_mod_idP, frameP, subframeP, CC_idP, old_rnti, old_UE_id); - UE_id = old_UE_id; current_rnti = old_rnti; ra->rnti = old_rnti; @@ -365,11 +358,13 @@ rx_sdu(const module_id_t enb_mod_idP, UE_list->UE_sched_ctrl[UE_id].uplane_inactivity_timer = 0; UE_list->UE_sched_ctrl[UE_id].ul_inactivity_timer = 0; UE_list->UE_sched_ctrl[UE_id].ul_failure_timer = 0; + if (UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync > 0) { UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync = 0; mac_eNB_rrc_ul_in_sync(enb_mod_idP, CC_idP, frameP, subframeP, old_rnti); } + UE_list->UE_template[CC_idP][UE_id].ul_SR = 1; UE_list->UE_sched_ctrl[UE_id].crnti_reconfigurationcomplete_flag = 1; break; @@ -378,391 +373,371 @@ rx_sdu(const module_id_t enb_mod_idP, } else { cancel_ra_proc(enb_mod_idP, CC_idP, frameP,current_rnti); } - crnti_rx = 1; - payload_ptr += 2; - break; + + crnti_rx = 1; + payload_ptr += 2; + break; } - case TRUNCATED_BSR: - case SHORT_BSR: - { - uint8_t lcgid; - lcgid = (payload_ptr[0] >> 6); + case TRUNCATED_BSR: + case SHORT_BSR: { + uint8_t lcgid; + lcgid = (payload_ptr[0] >> 6); + LOG_D(MAC, + "[eNB %d] CC_id %d MAC CE_LCID %d : Received short BSR LCGID = %u bsr = %d\n", + enb_mod_idP, CC_idP, rx_ces[i], lcgid, + payload_ptr[0] & 0x3f); - LOG_D(MAC, - "[eNB %d] CC_id %d MAC CE_LCID %d : Received short BSR LCGID = %u bsr = %d\n", - enb_mod_idP, CC_idP, rx_ces[i], lcgid, - payload_ptr[0] & 0x3f); + if (crnti_rx == 1) + LOG_D(MAC, + "[eNB %d] CC_id %d MAC CE_LCID %d : Received short BSR LCGID = %u bsr = %d\n", + enb_mod_idP, CC_idP, rx_ces[i], lcgid, + payload_ptr[0] & 0x3f); - if (crnti_rx == 1) - LOG_D(MAC, - "[eNB %d] CC_id %d MAC CE_LCID %d : Received short BSR LCGID = %u bsr = %d\n", - enb_mod_idP, CC_idP, rx_ces[i], lcgid, - payload_ptr[0] & 0x3f); - if (UE_id != -1) { + if (UE_id != -1) { int bsr = payload_ptr[0] & 0x3f; - lcgid_updated[lcgid] = 1; - // update buffer info UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[lcgid] = BSR_TABLE[bsr]; - UE_list->UE_template[CC_idP][UE_id].estimated_ul_buffer = - UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID0] + - UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID1] + - UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID2] + - UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID3]; - //UE_list->UE_template[CC_idP][UE_id].estimated_ul_buffer += UE_list->UE_template[CC_idP][UE_id].estimated_ul_buffer / 4; - - RC.eNB[enb_mod_idP][CC_idP]->pusch_stats_bsr[UE_id][(frameP * 10) + subframeP] = (payload_ptr[0] & 0x3f); - if (UE_id == UE_list->head) - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_UE0_BSR, - RC.eNB[enb_mod_idP][CC_idP]->pusch_stats_bsr - [UE_id][(frameP * 10) + subframeP]); - if (UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[lcgid] == 0) { - UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[lcgid] = frameP; - } - if (mac_eNB_get_rrc_status(enb_mod_idP,UE_RNTI(enb_mod_idP, UE_id)) < RRC_CONNECTED) - LOG_D(MAC, - "[eNB %d] CC_id %d MAC CE_LCID %d : estimated_ul_buffer = %d (lcg increment %d)\n", - enb_mod_idP, CC_idP, rx_ces[i], - UE_list->UE_template[CC_idP][UE_id].estimated_ul_buffer, - UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[lcgid]); - } else { - - } - payload_ptr += 1; //sizeof(SHORT_BSR); // fixme - } - break; - - case LONG_BSR: - if (UE_id != -1) { - int bsr0 = (payload_ptr[0] & 0xFC) >> 2; - int bsr1 = ((payload_ptr[0] & 0x03) << 4) | ((payload_ptr[1] & 0xF0) >> 4); - int bsr2 = ((payload_ptr[1] & 0x0F) << 2) | ((payload_ptr[2] & 0xC0) >> 6); - int bsr3 = payload_ptr[2] & 0x3F; - - lcgid_updated[LCGID0] = 1; - lcgid_updated[LCGID1] = 1; - lcgid_updated[LCGID2] = 1; - lcgid_updated[LCGID3] = 1; - - // update buffer info - UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID0] = BSR_TABLE[bsr0]; - UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID1] = BSR_TABLE[bsr1]; - UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID2] = BSR_TABLE[bsr2]; - UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID3] = BSR_TABLE[bsr3]; - - UE_list->UE_template[CC_idP][UE_id].estimated_ul_buffer = UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID0] + UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID1] + UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID2] + UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID3]; - //UE_list->UE_template[CC_idP][UE_id].estimated_ul_buffer += UE_list->UE_template[CC_idP][UE_id].estimated_ul_buffer / 4; + //UE_list->UE_template[CC_idP][UE_id].estimated_ul_buffer += UE_list->UE_template[CC_idP][UE_id].estimated_ul_buffer / 4; + RC.eNB[enb_mod_idP][CC_idP]->pusch_stats_bsr[UE_id][(frameP * 10) + subframeP] = (payload_ptr[0] & 0x3f); - LOG_D(MAC, - "[eNB %d] CC_id %d MAC CE_LCID %d: Received long BSR. Size is LCGID0 = %u LCGID1 = " - "%u LCGID2 = %u LCGID3 = %u\n", enb_mod_idP, CC_idP, - rx_ces[i], - UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID0], - UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID1], - UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID2], - UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID3]); - if (crnti_rx == 1) + if (UE_id == UE_list->head) + VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_UE0_BSR, + RC.eNB[enb_mod_idP][CC_idP]->pusch_stats_bsr + [UE_id][(frameP * 10) + subframeP]); + + if (UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[lcgid] == 0) { + UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[lcgid] = frameP; + } + + if (mac_eNB_get_rrc_status(enb_mod_idP,UE_RNTI(enb_mod_idP, UE_id)) < RRC_CONNECTED) + LOG_D(MAC, + "[eNB %d] CC_id %d MAC CE_LCID %d : estimated_ul_buffer = %d (lcg increment %d)\n", + enb_mod_idP, CC_idP, rx_ces[i], + UE_list->UE_template[CC_idP][UE_id].estimated_ul_buffer, + UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[lcgid]); + } else { + } + + payload_ptr += 1; //sizeof(SHORT_BSR); // fixme + } + break; + + case LONG_BSR: + if (UE_id != -1) { + int bsr0 = (payload_ptr[0] & 0xFC) >> 2; + int bsr1 = ((payload_ptr[0] & 0x03) << 4) | ((payload_ptr[1] & 0xF0) >> 4); + int bsr2 = ((payload_ptr[1] & 0x0F) << 2) | ((payload_ptr[2] & 0xC0) >> 6); + int bsr3 = payload_ptr[2] & 0x3F; + lcgid_updated[LCGID0] = 1; + lcgid_updated[LCGID1] = 1; + lcgid_updated[LCGID2] = 1; + lcgid_updated[LCGID3] = 1; + // update buffer info + UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID0] = BSR_TABLE[bsr0]; + UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID1] = BSR_TABLE[bsr1]; + UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID2] = BSR_TABLE[bsr2]; + UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID3] = BSR_TABLE[bsr3]; + UE_list->UE_template[CC_idP][UE_id].estimated_ul_buffer = + UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID0] + + UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID1] + + UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID2] + + UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID3]; + //UE_list->UE_template[CC_idP][UE_id].estimated_ul_buffer += UE_list->UE_template[CC_idP][UE_id].estimated_ul_buffer / 4; LOG_D(MAC, "[eNB %d] CC_id %d MAC CE_LCID %d: Received long BSR. Size is LCGID0 = %u LCGID1 = " - "%u LCGID2 = %u LCGID3 = %u\n", enb_mod_idP, - CC_idP, rx_ces[i], + "%u LCGID2 = %u LCGID3 = %u\n", enb_mod_idP, CC_idP, + rx_ces[i], UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID0], UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID1], UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID2], UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID3]); - if (UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID0] == 0) { - UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID0] = 0; - } else if (UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID0] == 0) { - UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID0] = frameP; - } + if (crnti_rx == 1) + LOG_D(MAC, + "[eNB %d] CC_id %d MAC CE_LCID %d: Received long BSR. Size is LCGID0 = %u LCGID1 = " + "%u LCGID2 = %u LCGID3 = %u\n", enb_mod_idP, + CC_idP, rx_ces[i], + UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID0], + UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID1], + UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID2], + UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID3]); - if (UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID1] == 0) { - UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID1] = 0; - } else if (UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID1] == 0) { - UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID1] = frameP; - } + if (UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID0] == 0) { + UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID0] = 0; + } else if (UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID0] == 0) { + UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID0] = frameP; + } - if (UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID2] == 0) { - UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID2] = 0; - } else if (UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID2] == 0) { - UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID2] = frameP; - } + if (UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID1] == 0) { + UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID1] = 0; + } else if (UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID1] == 0) { + UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID1] = frameP; + } - if (UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID3] == 0) { - UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID3] = 0; - } else if (UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID3] == 0) { - UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID3] = frameP; + if (UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID2] == 0) { + UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID2] = 0; + } else if (UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID2] == 0) { + UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID2] = frameP; + } - } - } + if (UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID3] == 0) { + UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID3] = 0; + } else if (UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID3] == 0) { + UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID3] = frameP; + } + } - payload_ptr += 3; ////sizeof(LONG_BSR); - break; + payload_ptr += 3; ////sizeof(LONG_BSR); + break; - default: - LOG_E(MAC, - "[eNB %d] CC_id %d Received unknown MAC header (0x%02x)\n", - enb_mod_idP, CC_idP, rx_ces[i]); - break; + default: + LOG_E(MAC, + "[eNB %d] CC_id %d Received unknown MAC header (0x%02x)\n", + enb_mod_idP, CC_idP, rx_ces[i]); + break; } } for (i = 0; i < num_sdu; i++) { LOG_D(MAC, "SDU Number %d MAC Subheader SDU_LCID %d, length %d\n", - i, rx_lcids[i], rx_lengths[i]); - + i, rx_lcids[i], rx_lengths[i]); T(T_ENB_MAC_UE_UL_SDU, T_INT(enb_mod_idP), T_INT(CC_idP), T_INT(current_rnti), T_INT(frameP), T_INT(subframeP), T_INT(rx_lcids[i]), T_INT(rx_lengths[i])); T(T_ENB_MAC_UE_UL_SDU_WITH_DATA, T_INT(enb_mod_idP), T_INT(CC_idP), T_INT(current_rnti), T_INT(frameP), T_INT(subframeP), T_INT(rx_lcids[i]), T_INT(rx_lengths[i]), T_BUFFER(payload_ptr, - rx_lengths - [i])); + rx_lengths + [i])); switch (rx_lcids[i]) { - case CCCH: - if (rx_lengths[i] > CCCH_PAYLOAD_SIZE_MAX) { - LOG_E(MAC, - "[eNB %d/%d] frame %d received CCCH of size %d (too big, maximum allowed is %d, sdu_len %d), dropping packet\n", - enb_mod_idP, CC_idP, frameP, rx_lengths[i], - CCCH_PAYLOAD_SIZE_MAX, sdu_lenP); - break; - } - LOG_D(MAC, - "[eNB %d][RAPROC] CC_id %d Frame %d, Received CCCH: %x.%x.%x.%x.%x.%x, Terminating RA procedure for UE rnti %x\n", - enb_mod_idP, CC_idP, frameP, payload_ptr[0], - payload_ptr[1], payload_ptr[2], payload_ptr[3], - payload_ptr[4], payload_ptr[5], current_rnti); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_TERMINATE_RA_PROC, 1); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_TERMINATE_RA_PROC, 0); - for (ii = 0; ii < NB_RA_PROC_MAX; ii++) { - RA_t *ra = &mac->common_channels[CC_idP].ra[ii]; - - LOG_D(MAC, - "[mac %d][RAPROC] CC_id %d Checking proc %d : rnti (%x, %x), state %d\n", - enb_mod_idP, CC_idP, ii, ra->rnti, - current_rnti, ra->state); - - if ((ra->rnti == current_rnti) && (ra->state != IDLE)) { - - //payload_ptr = parse_ulsch_header(msg3,&num_ce,&num_sdu,rx_ces,rx_lcids,rx_lengths,msg3_len); - - if (UE_id < 0) { - memcpy(&ra->cont_res_id[0], payload_ptr, 6); - LOG_D(MAC, - "[eNB %d][RAPROC] CC_id %d Frame %d CCCH: Received Msg3: length %d, offset %ld\n", - enb_mod_idP, CC_idP, frameP, rx_lengths[i], - payload_ptr - sduP); - - if ((UE_id = add_new_ue(enb_mod_idP, CC_idP, - mac->common_channels[CC_idP]. - ra[ii].rnti, harq_pid -#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - , - mac->common_channels[CC_idP]. - ra[ii].rach_resource_type -#endif - )) == -1) { - LOG_E(MAC,"[MAC][eNB] Max user count reached\n"); - cancel_ra_proc(enb_mod_idP, CC_idP, frameP,current_rnti); - break; - // kill RA procedure - } else - LOG_D(MAC, - "[eNB %d][RAPROC] CC_id %d Frame %d Added user with rnti %x => UE %d\n", - enb_mod_idP, CC_idP, frameP, ra->rnti, - UE_id); - } else { - LOG_D(MAC, - "[eNB %d][RAPROC] CC_id %d Frame %d CCCH: Received Msg3 from already registered UE %d: length %d, offset %ld\n", - enb_mod_idP, CC_idP, frameP, UE_id, - rx_lengths[i], payload_ptr - sduP); - // kill RA procedure - } - - mac_rrc_data_ind(enb_mod_idP, - CC_idP, - frameP, subframeP, - current_rnti, - CCCH, - (uint8_t *) payload_ptr, - rx_lengths[i], - 0); - - - if (num_ce > 0) { // handle msg3 which is not RRCConnectionRequest - // process_ra_message(msg3,num_ce,rx_lcids,rx_ces); - } - // prepare transmission of Msg4 - ra->state = MSG4; - - - - if(mac->common_channels[CC_idP].tdd_Config!=NULL){ - switch(mac->common_channels[CC_idP].tdd_Config->subframeAssignment){ - case 1: - ra->Msg4_frame = frameP + ((subframeP > 2) ? 1 : 0); - ra->Msg4_subframe = (subframeP + 7) % 10; - break; - default: printf("%s:%d: TODO\n", __FILE__, __LINE__); abort(); - // TODO need to be complete for other tdd configs. - } - }else{ - // Program Msg4 PDCCH+DLSCH/MPDCCH transmission 4 subframes from now, // Check if this is ok for BL/CE, or if the rule is different - ra->Msg4_frame = frameP + ((subframeP > 5) ? 1 : 0); - ra->Msg4_subframe = (subframeP + 4) % 10; - } - - UE_list->UE_sched_ctrl[UE_id].crnti_reconfigurationcomplete_flag = 0; - } // if process is active - } // loop on RA processes - - break; - - case DCCH: - case DCCH1: - // if(eNB_mac_inst[module_idP][CC_idP].Dcch_lchan[UE_id].Active==1){ - - -#if defined(ENABLE_MAC_PAYLOAD_DEBUG) - LOG_T(MAC, "offset: %d\n", - (unsigned char) ((unsigned char *) payload_ptr - sduP)); - for (j = 0; j < 32; j++) { - LOG_T(MAC, "%x ", payload_ptr[j]); - } - LOG_T(MAC, "\n"); -#endif - - if (UE_id != -1) { - if (lcgid_updated[UE_list->UE_template[CC_idP][UE_id].lcgidmap[rx_lcids[i]]] == 0) { - // adjust buffer occupancy of the correponding logical channel group - if (UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[UE_list->UE_template[CC_idP][UE_id].lcgidmap[rx_lcids[i]]] >= rx_lengths[i]) - UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[UE_list->UE_template[CC_idP][UE_id].lcgidmap[rx_lcids[i]]] -= rx_lengths[i]; - else - UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[UE_list->UE_template[CC_idP][UE_id].lcgidmap[rx_lcids[i]]] = 0; - - UE_list->UE_template[CC_idP][UE_id].estimated_ul_buffer = - UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[0] + - UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[1] + - UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[2] + - UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[3]; - //UE_list->UE_template[CC_idP][UE_id].estimated_ul_buffer += UE_list->UE_template[CC_idP][UE_id].estimated_ul_buffer / 4; + case CCCH: + if (rx_lengths[i] > CCCH_PAYLOAD_SIZE_MAX) { + LOG_E(MAC, + "[eNB %d/%d] frame %d received CCCH of size %d (too big, maximum allowed is %d, sdu_len %d), dropping packet\n", + enb_mod_idP, CC_idP, frameP, rx_lengths[i], + CCCH_PAYLOAD_SIZE_MAX, sdu_lenP); + break; } - LOG_D(MAC, - "[eNB %d] CC_id %d Frame %d : ULSCH -> UL-DCCH, received %d bytes form UE %d on LCID %d \n", - enb_mod_idP, CC_idP, frameP, rx_lengths[i], UE_id, - rx_lcids[i]); + LOG_D(MAC, + "[eNB %d][RAPROC] CC_id %d Frame %d, Received CCCH: %x.%x.%x.%x.%x.%x, Terminating RA procedure for UE rnti %x\n", + enb_mod_idP, CC_idP, frameP, payload_ptr[0], + payload_ptr[1], payload_ptr[2], payload_ptr[3], + payload_ptr[4], payload_ptr[5], current_rnti); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_TERMINATE_RA_PROC, 1); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_TERMINATE_RA_PROC, 0); - mac_rlc_data_ind(enb_mod_idP, current_rnti, enb_mod_idP, frameP, ENB_FLAG_YES, MBMS_FLAG_NO, rx_lcids[i], (char *) payload_ptr, rx_lengths[i], 1, NULL); //(unsigned int*)crc_status); - UE_list->eNB_UE_stats[CC_idP][UE_id].num_pdu_rx[rx_lcids[i]] += 1; - UE_list->eNB_UE_stats[CC_idP][UE_id].num_bytes_rx[rx_lcids[i]] += rx_lengths[i]; + for (ii = 0; ii < NB_RA_PROC_MAX; ii++) { + RA_t *ra = &mac->common_channels[CC_idP].ra[ii]; + LOG_D(MAC, + "[mac %d][RAPROC] CC_id %d Checking proc %d : rnti (%x, %x), state %d\n", + enb_mod_idP, CC_idP, ii, ra->rnti, + current_rnti, ra->state); + if ((ra->rnti == current_rnti) && (ra->state != IDLE)) { + //payload_ptr = parse_ulsch_header(msg3,&num_ce,&num_sdu,rx_ces,rx_lcids,rx_lengths,msg3_len); + if (UE_id < 0) { + memcpy(&ra->cont_res_id[0], payload_ptr, 6); + LOG_D(MAC, + "[eNB %d][RAPROC] CC_id %d Frame %d CCCH: Received Msg3: length %d, offset %ld\n", + enb_mod_idP, CC_idP, frameP, rx_lengths[i], + payload_ptr - sduP); - } + if ((UE_id = add_new_ue(enb_mod_idP, CC_idP, + mac->common_channels[CC_idP]. + ra[ii].rnti, harq_pid +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + , + mac->common_channels[CC_idP]. + ra[ii].rach_resource_type +#endif + )) == -1) { + LOG_E(MAC,"[MAC][eNB] Max user count reached\n"); + cancel_ra_proc(enb_mod_idP, CC_idP, frameP,current_rnti); + break; + // kill RA procedure + } else + LOG_D(MAC, + "[eNB %d][RAPROC] CC_id %d Frame %d Added user with rnti %x => UE %d\n", + enb_mod_idP, CC_idP, frameP, ra->rnti, + UE_id); + } else { + LOG_D(MAC, + "[eNB %d][RAPROC] CC_id %d Frame %d CCCH: Received Msg3 from already registered UE %d: length %d, offset %ld\n", + enb_mod_idP, CC_idP, frameP, UE_id, + rx_lengths[i], payload_ptr - sduP); + // kill RA procedure + } - /* UE_id != -1 */ - // } - break; + mac_rrc_data_ind(enb_mod_idP, + CC_idP, + frameP, subframeP, + current_rnti, + CCCH, + (uint8_t *) payload_ptr, + rx_lengths[i], + 0); - // all the DRBS - case DTCH: - - default: + if (num_ce > 0) { // handle msg3 which is not RRCConnectionRequest + // process_ra_message(msg3,num_ce,rx_lcids,rx_ces); + } + // prepare transmission of Msg4 + ra->state = MSG4; + + if(mac->common_channels[CC_idP].tdd_Config!=NULL) { + switch(mac->common_channels[CC_idP].tdd_Config->subframeAssignment) { + case 1: + ra->Msg4_frame = frameP + ((subframeP > 2) ? 1 : 0); + ra->Msg4_subframe = (subframeP + 7) % 10; + break; + + default: + printf("%s:%d: TODO\n", __FILE__, __LINE__); + abort(); + // TODO need to be complete for other tdd configs. + } + } else { + // Program Msg4 PDCCH+DLSCH/MPDCCH transmission 4 subframes from now, // Check if this is ok for BL/CE, or if the rule is different + ra->Msg4_frame = frameP + ((subframeP > 5) ? 1 : 0); + ra->Msg4_subframe = (subframeP + 4) % 10; + } + + UE_list->UE_sched_ctrl[UE_id].crnti_reconfigurationcomplete_flag = 0; + } // if process is active + } // loop on RA processes + + break; + + case DCCH: + case DCCH1: + // if(eNB_mac_inst[module_idP][CC_idP].Dcch_lchan[UE_id].Active==1){ #if defined(ENABLE_MAC_PAYLOAD_DEBUG) - - LOG_T(MAC, "offset: %d\n", - (unsigned char) ((unsigned char *) payload_ptr - sduP)); - - for (j = 0; j < 32; j++) { - LOG_T(MAC, "%x ", payload_ptr[j]); - } - - LOG_T(MAC, "\n"); + LOG_T(MAC, "offset: %d\n", + (unsigned char) ((unsigned char *) payload_ptr - sduP)); + for (j = 0; j < 32; j++) { + LOG_T(MAC, "%x ", payload_ptr[j]); + } + + LOG_T(MAC, "\n"); #endif - if (rx_lcids[i] < NB_RB_MAX) { - - LOG_D(MAC, "[eNB %d] CC_id %d Frame %d : ULSCH -> UL-DTCH, received %d bytes from UE %d for lcid %d\n", - enb_mod_idP, - CC_idP, - frameP, - rx_lengths[i], - UE_id, - rx_lcids[i]); - - if (UE_id != -1) { - // adjust buffer occupancy of the correponding logical channel group - LOG_D(MAC, "[eNB %d] CC_id %d Frame %d : ULSCH -> UL-DTCH, received %d bytes from UE %d for lcid %d, removing from LCGID %ld, %d\n", - enb_mod_idP, - CC_idP, - frameP, - rx_lengths[i], - UE_id, - rx_lcids[i], - UE_list->UE_template[CC_idP][UE_id].lcgidmap[rx_lcids[i]], - UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[UE_list->UE_template[CC_idP][UE_id].lcgidmap[rx_lcids[i]]]); - + if (UE_id != -1) { if (lcgid_updated[UE_list->UE_template[CC_idP][UE_id].lcgidmap[rx_lcids[i]]] == 0) { - if (UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[UE_list->UE_template[CC_idP][UE_id].lcgidmap[rx_lcids[i]]] >= rx_lengths[i]) { + // adjust buffer occupancy of the correponding logical channel group + if (UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[UE_list->UE_template[CC_idP][UE_id].lcgidmap[rx_lcids[i]]] >= rx_lengths[i]) UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[UE_list->UE_template[CC_idP][UE_id].lcgidmap[rx_lcids[i]]] -= rx_lengths[i]; - } else { - UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[UE_list->UE_template[CC_idP][UE_id].lcgidmap[rx_lcids[i]]] = 0; - } + else + UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[UE_list->UE_template[CC_idP][UE_id].lcgidmap[rx_lcids[i]]] = 0; UE_list->UE_template[CC_idP][UE_id].estimated_ul_buffer = UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[0] + UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[1] + UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[2] + UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[3]; + //UE_list->UE_template[CC_idP][UE_id].estimated_ul_buffer += UE_list->UE_template[CC_idP][UE_id].estimated_ul_buffer / 4; } - if ((rx_lengths[i] < SCH_PAYLOAD_SIZE_MAX) && (rx_lengths[i] > 0)) { // MAX SIZE OF transport block - mac_rlc_data_ind(enb_mod_idP, current_rnti, enb_mod_idP, frameP, ENB_FLAG_YES, MBMS_FLAG_NO, rx_lcids[i], (char *) payload_ptr, rx_lengths[i], 1, NULL); + LOG_D(MAC, + "[eNB %d] CC_id %d Frame %d : ULSCH -> UL-DCCH, received %d bytes form UE %d on LCID %d \n", + enb_mod_idP, CC_idP, frameP, rx_lengths[i], UE_id, + rx_lcids[i]); + mac_rlc_data_ind(enb_mod_idP, current_rnti, enb_mod_idP, frameP, ENB_FLAG_YES, MBMS_FLAG_NO, rx_lcids[i], (char *) payload_ptr, rx_lengths[i], 1, NULL); //(unsigned int*)crc_status); + UE_list->eNB_UE_stats[CC_idP][UE_id].num_pdu_rx[rx_lcids[i]] += 1; + UE_list->eNB_UE_stats[CC_idP][UE_id].num_bytes_rx[rx_lcids[i]] += rx_lengths[i]; + } - UE_list->eNB_UE_stats[CC_idP][UE_id].num_pdu_rx[rx_lcids[i]] += 1; - UE_list->eNB_UE_stats[CC_idP][UE_id].num_bytes_rx[rx_lcids[i]] += rx_lengths[i]; + /* UE_id != -1 */ + // } + break; - //clear uplane_inactivity_timer - UE_list->UE_sched_ctrl[UE_id].uplane_inactivity_timer = 0; + // all the DRBS + case DTCH: + default: +#if defined(ENABLE_MAC_PAYLOAD_DEBUG) + LOG_T(MAC, "offset: %d\n", + (unsigned char) ((unsigned char *) payload_ptr - sduP)); - // reset RRC inactivity timer after uplane activity - ue_contextP = rrc_eNB_get_ue_context(RC.rrc[enb_mod_idP], rntiP); - ue_contextP->ue_context.ue_rrc_inactivity_timer = 1; + for (j = 0; j < 32; j++) { + LOG_T(MAC, "%x ", payload_ptr[j]); + } - } else { /* rx_length[i] */ - UE_list->eNB_UE_stats[CC_idP][UE_id].num_errors_rx += 1; - - LOG_E(MAC, "[eNB %d] CC_id %d Frame %d : Max size of transport block reached LCID %d from UE %d ", - enb_mod_idP, - CC_idP, - frameP, - rx_lcids[i], - UE_id); + LOG_T(MAC, "\n"); +#endif + + if (rx_lcids[i] < NB_RB_MAX) { + LOG_D(MAC, "[eNB %d] CC_id %d Frame %d : ULSCH -> UL-DTCH, received %d bytes from UE %d for lcid %d\n", + enb_mod_idP, + CC_idP, + frameP, + rx_lengths[i], + UE_id, + rx_lcids[i]); + + if (UE_id != -1) { + // adjust buffer occupancy of the correponding logical channel group + LOG_D(MAC, "[eNB %d] CC_id %d Frame %d : ULSCH -> UL-DTCH, received %d bytes from UE %d for lcid %d, removing from LCGID %ld, %d\n", + enb_mod_idP, + CC_idP, + frameP, + rx_lengths[i], + UE_id, + rx_lcids[i], + UE_list->UE_template[CC_idP][UE_id].lcgidmap[rx_lcids[i]], + UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[UE_list->UE_template[CC_idP][UE_id].lcgidmap[rx_lcids[i]]]); + + if (lcgid_updated[UE_list->UE_template[CC_idP][UE_id].lcgidmap[rx_lcids[i]]] == 0) { + if (UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[UE_list->UE_template[CC_idP][UE_id].lcgidmap[rx_lcids[i]]] >= rx_lengths[i]) { + UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[UE_list->UE_template[CC_idP][UE_id].lcgidmap[rx_lcids[i]]] -= rx_lengths[i]; + } else { + UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[UE_list->UE_template[CC_idP][UE_id].lcgidmap[rx_lcids[i]]] = 0; + } + + UE_list->UE_template[CC_idP][UE_id].estimated_ul_buffer = + UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[0] + + UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[1] + + UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[2] + + UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[3]; + } + + if ((rx_lengths[i] < SCH_PAYLOAD_SIZE_MAX) && (rx_lengths[i] > 0)) { // MAX SIZE OF transport block + mac_rlc_data_ind(enb_mod_idP, current_rnti, enb_mod_idP, frameP, ENB_FLAG_YES, MBMS_FLAG_NO, rx_lcids[i], (char *) payload_ptr, rx_lengths[i], 1, NULL); + UE_list->eNB_UE_stats[CC_idP][UE_id].num_pdu_rx[rx_lcids[i]] += 1; + UE_list->eNB_UE_stats[CC_idP][UE_id].num_bytes_rx[rx_lcids[i]] += rx_lengths[i]; + //clear uplane_inactivity_timer + UE_list->UE_sched_ctrl[UE_id].uplane_inactivity_timer = 0; + // reset RRC inactivity timer after uplane activity + ue_contextP = rrc_eNB_get_ue_context(RC.rrc[enb_mod_idP], rntiP); + ue_contextP->ue_context.ue_rrc_inactivity_timer = 1; + } else { /* rx_length[i] */ + UE_list->eNB_UE_stats[CC_idP][UE_id].num_errors_rx += 1; + LOG_E(MAC, "[eNB %d] CC_id %d Frame %d : Max size of transport block reached LCID %d from UE %d ", + enb_mod_idP, + CC_idP, + frameP, + rx_lcids[i], + UE_id); + } + } else { // end if (UE_id != -1) + LOG_E(MAC,"[eNB %d] CC_id %d Frame %d : received unsupported or unknown LCID %d from UE %d ", + enb_mod_idP, + CC_idP, + frameP, + rx_lcids[i], + UE_id); } + } - } else { // end if (UE_id != -1) - LOG_E(MAC,"[eNB %d] CC_id %d Frame %d : received unsupported or unknown LCID %d from UE %d ", - enb_mod_idP, - CC_idP, - frameP, - rx_lcids[i], - UE_id); - } - } - - break; + break; } payload_ptr += rx_lengths[i]; @@ -770,12 +745,11 @@ rx_sdu(const module_id_t enb_mod_idP, // Program ACK for PHICH LOG_D(MAC, - "Programming PHICH ACK for rnti %x harq_pid %d (first_rb %d)\n", - current_rnti, harq_pid, first_rb); + "Programming PHICH ACK for rnti %x harq_pid %d (first_rb %d)\n", + current_rnti, harq_pid, first_rb); nfapi_hi_dci0_request_t *hi_dci0_req; - uint8_t sf_ahead_dl = ul_subframe2_k_phich(&mac->common_channels[CC_idP] , subframeP); + uint8_t sf_ahead_dl = ul_subframe2_k_phich(&mac->common_channels[CC_idP], subframeP); hi_dci0_req = &mac->HI_DCI0_req[CC_idP][(subframeP+sf_ahead_dl)%10]; - nfapi_hi_dci0_request_body_t *hi_dci0_req_body = &hi_dci0_req->hi_dci0_request_body; nfapi_hi_dci0_request_pdu_t *hi_dci0_pdu = &hi_dci0_req_body->hi_dci0_pdu_list[hi_dci0_req_body->number_of_dci + hi_dci0_req_body->number_of_hi]; @@ -796,6 +770,7 @@ rx_sdu(const module_id_t enb_mod_idP, if ((num_sdu == 0) && (num_ce == 0)) { if (UE_id != -1) UE_list->eNB_UE_stats[CC_idP][UE_id].total_num_errors_rx += 1; + /* if (msg3_flagP != NULL) { if( *msg3_flagP == 1 ) { @@ -815,8 +790,7 @@ rx_sdu(const module_id_t enb_mod_idP, stop_meas(&mac->rx_ulsch_sdu); } -uint32_t bytes_to_bsr_index(int32_t nbytes) -{ +uint32_t bytes_to_bsr_index(int32_t nbytes) { uint32_t i = 0; if (nbytes < 0) { @@ -832,30 +806,26 @@ uint32_t bytes_to_bsr_index(int32_t nbytes) void add_ue_ulsch_info(module_id_t module_idP, int CC_id, int UE_id, - sub_frame_t subframeP, UE_ULSCH_STATUS status) -{ + sub_frame_t subframeP, UE_ULSCH_STATUS status) { eNB_ulsch_info[module_idP][CC_id][UE_id].rnti = UE_RNTI(module_idP, UE_id); eNB_ulsch_info[module_idP][CC_id][UE_id].subframe = subframeP; eNB_ulsch_info[module_idP][CC_id][UE_id].status = status; - eNB_ulsch_info[module_idP][CC_id][UE_id].serving_num++; } unsigned char *parse_ulsch_header(unsigned char *mac_header, - unsigned char *num_ce, - unsigned char *num_sdu, - unsigned char *rx_ces, - unsigned char *rx_lcids, - unsigned short *rx_lengths, - unsigned short tb_length) -{ + unsigned char *num_ce, + unsigned char *num_sdu, + unsigned char *rx_ces, + unsigned char *rx_lcids, + unsigned short *rx_lengths, + unsigned short tb_length) { unsigned char not_done = 1, num_ces = 0, num_sdus = - 0, lcid, num_sdu_cnt; + 0, lcid, num_sdu_cnt; unsigned char *mac_header_ptr = mac_header; unsigned short length, ce_len = 0; while (not_done == 1) { - if (((SCH_SUBHEADER_FIXED *) mac_header_ptr)->E == 0) { not_done = 0; } @@ -863,62 +833,61 @@ unsigned char *parse_ulsch_header(unsigned char *mac_header, lcid = ((SCH_SUBHEADER_FIXED *) mac_header_ptr)->LCID; if (lcid < EXTENDED_POWER_HEADROOM) { - if (not_done == 0) { // last MAC SDU, length is implicit - mac_header_ptr++; - length = tb_length - (mac_header_ptr - mac_header) - ce_len; + if (not_done == 0) { // last MAC SDU, length is implicit + mac_header_ptr++; + length = tb_length - (mac_header_ptr - mac_header) - ce_len; - for (num_sdu_cnt = 0; num_sdu_cnt < num_sdus; - num_sdu_cnt++) { - length -= rx_lengths[num_sdu_cnt]; - } + for (num_sdu_cnt = 0; num_sdu_cnt < num_sdus; + num_sdu_cnt++) { + length -= rx_lengths[num_sdu_cnt]; + } } else { - if (((SCH_SUBHEADER_SHORT *) mac_header_ptr)->F == 0) { - length = ((SCH_SUBHEADER_SHORT *) mac_header_ptr)->L; - mac_header_ptr += 2; //sizeof(SCH_SUBHEADER_SHORT); - } else { // F = 1 - length = - ((((SCH_SUBHEADER_LONG *) mac_header_ptr)->L_MSB & - 0x7f) << 8) | (((SCH_SUBHEADER_LONG *) - mac_header_ptr)->L_LSB & 0xff); - mac_header_ptr += 3; //sizeof(SCH_SUBHEADER_LONG); - } + if (((SCH_SUBHEADER_SHORT *) mac_header_ptr)->F == 0) { + length = ((SCH_SUBHEADER_SHORT *) mac_header_ptr)->L; + mac_header_ptr += 2; //sizeof(SCH_SUBHEADER_SHORT); + } else { // F = 1 + length = + ((((SCH_SUBHEADER_LONG *) mac_header_ptr)->L_MSB & + 0x7f) << 8) | (((SCH_SUBHEADER_LONG *) + mac_header_ptr)->L_LSB & 0xff); + mac_header_ptr += 3; //sizeof(SCH_SUBHEADER_LONG); + } } LOG_D(MAC, - "[eNB] sdu %d lcid %d tb_length %d length %d (offset now %ld)\n", - num_sdus, lcid, tb_length, length, - mac_header_ptr - mac_header); + "[eNB] sdu %d lcid %d tb_length %d length %d (offset now %ld)\n", + num_sdus, lcid, tb_length, length, + mac_header_ptr - mac_header); rx_lcids[num_sdus] = lcid; rx_lengths[num_sdus] = length; num_sdus++; - } else { // This is a control element subheader POWER_HEADROOM, BSR and CRNTI + } else { // This is a control element subheader POWER_HEADROOM, BSR and CRNTI if (lcid == SHORT_PADDING) { - mac_header_ptr++; + mac_header_ptr++; } else { - rx_ces[num_ces] = lcid; - num_ces++; - mac_header_ptr++; + rx_ces[num_ces] = lcid; + num_ces++; + mac_header_ptr++; - if (lcid == LONG_BSR) { - ce_len += 3; - } else if (lcid == CRNTI) { - ce_len += 2; - } else if ((lcid == POWER_HEADROOM) - || (lcid == TRUNCATED_BSR) - || (lcid == SHORT_BSR)) { - ce_len++; - } else { - LOG_E(MAC, "unknown CE %d \n", lcid); - //AssertFatal(1 == 0, "unknown CE"); + if (lcid == LONG_BSR) { + ce_len += 3; + } else if (lcid == CRNTI) { + ce_len += 2; + } else if ((lcid == POWER_HEADROOM) + || (lcid == TRUNCATED_BSR) + || (lcid == SHORT_BSR)) { + ce_len++; + } else { + LOG_E(MAC, "unknown CE %d \n", lcid); + //AssertFatal(1 == 0, "unknown CE"); return NULL; - } + } } } } *num_ce = num_ces; *num_sdu = num_sdus; - return (mac_header_ptr); } @@ -929,18 +898,18 @@ unsigned char *parse_ulsch_header(unsigned char *mac_header, */ void set_msg3_subframe(module_id_t mod_id, - int CC_id, - int frame, - int subframe, int rnti, int Msg3_frame, - int Msg3_subframe) -{ + int CC_id, + int frame, + int subframe, int rnti, int Msg3_frame, + int Msg3_subframe) { eNB_MAC_INST *mac = RC.mac[mod_id]; int i; + for (i = 0; i < NB_RA_PROC_MAX; i++) { if (mac->common_channels[CC_id].ra[i].state != IDLE && - mac->common_channels[CC_id].ra[i].rnti == rnti) { + mac->common_channels[CC_id].ra[i].rnti == rnti) { mac->common_channels[CC_id].ra[i].Msg3_subframe = - Msg3_subframe; + Msg3_subframe; break; } } @@ -948,90 +917,105 @@ set_msg3_subframe(module_id_t mod_id, void schedule_ulsch(module_id_t module_idP, frame_t frameP, - sub_frame_t subframeP) -{ + sub_frame_t subframeP) { uint16_t first_rb[NFAPI_CC_MAX], i; int CC_id; eNB_MAC_INST *mac = RC.mac[module_idP]; slice_info_t *sli = &RC.mac[module_idP]->slice_info; COMMON_channels_t *cc; - start_meas(&mac->schedule_ulsch); - int sched_frame=frameP; int sched_subframe = (subframeP + 4) % 10; - cc = &mac->common_channels[0]; int tdd_sfa; + // for TDD: check subframes where we have to act and return if nothing should be done now if (cc->tdd_Config) { tdd_sfa = cc->tdd_Config->subframeAssignment; - switch (subframeP) { - case 0: - if ((tdd_sfa == 0) || (tdd_sfa == 3)) - sched_subframe = 4; - else if (tdd_sfa == 6) - sched_subframe = 7; - else - return; - break; - case 1: - if ((tdd_sfa == 0) || (tdd_sfa == 1)) - sched_subframe = 7; - else if (tdd_sfa == 6) - sched_subframe = 8; - else - return; - break; - default: - return; - case 2: // Don't schedule UL in subframe 2 for TDD - return; - case 3: - if (tdd_sfa == 2) - sched_subframe = 7; - else - return; - break; - case 4: - if (tdd_sfa == 1) - sched_subframe = 8; - else - return; - break; - case 5: - if (tdd_sfa == 0) - sched_subframe = 9; - else if (tdd_sfa == 6) - sched_subframe = 2; - else - return; - break; - case 6: - if (tdd_sfa == 0 || tdd_sfa == 1) - sched_subframe = 2; - else if (tdd_sfa == 6) - sched_subframe = 3; - else - return; - break; - case 7: - return; - case 8: - if ((tdd_sfa >= 2) && (tdd_sfa <= 5)) - sched_subframe = 2; - else + switch (subframeP) { + case 0: + if ((tdd_sfa == 0) || (tdd_sfa == 3)) + sched_subframe = 4; + else if (tdd_sfa == 6) + sched_subframe = 7; + else + return; + + break; + + case 1: + if ((tdd_sfa == 0) || (tdd_sfa == 1)) + sched_subframe = 7; + else if (tdd_sfa == 6) + sched_subframe = 8; + else + return; + + break; + + default: return; - break; - case 9: - if ((tdd_sfa == 1) || (tdd_sfa == 3) || (tdd_sfa == 4)) - sched_subframe = 3; - else if (tdd_sfa == 6) - sched_subframe = 4; - else + + case 2: // Don't schedule UL in subframe 2 for TDD return; - break; + + case 3: + if (tdd_sfa == 2) + sched_subframe = 7; + else + return; + + break; + + case 4: + if (tdd_sfa == 1) + sched_subframe = 8; + else + return; + + break; + + case 5: + if (tdd_sfa == 0) + sched_subframe = 9; + else if (tdd_sfa == 6) + sched_subframe = 2; + else + return; + + break; + + case 6: + if (tdd_sfa == 0 || tdd_sfa == 1) + sched_subframe = 2; + else if (tdd_sfa == 6) + sched_subframe = 3; + else + return; + + break; + + case 7: + return; + + case 8: + if ((tdd_sfa >= 2) && (tdd_sfa <= 5)) + sched_subframe = 2; + else + return; + + break; + + case 9: + if ((tdd_sfa == 1) || (tdd_sfa == 3) || (tdd_sfa == 4)) + sched_subframe = 3; + else if (tdd_sfa == 6) + sched_subframe = 4; + else + return; + + break; } } @@ -1056,11 +1040,12 @@ schedule_ulsch(module_id_t module_idP, frame_t frameP, for (i = 0; i < NB_RA_PROC_MAX; i++) { if ((cc->ra[i].state == WAITMSG3) && - (cc->ra[i].Msg3_subframe == sched_subframe)) { + (cc->ra[i].Msg3_subframe == sched_subframe)) { if (first_rb[CC_id] < cc->ra[i].msg3_first_rb + cc->ra[i].msg3_nb_rb) first_rb[CC_id] = cc->ra[i].msg3_first_rb + cc->ra[i].msg3_nb_rb; - // cc->ray[i].Msg3_subframe = -1; - break; + + // cc->ray[i].Msg3_subframe = -1; + break; } } } @@ -1075,11 +1060,10 @@ schedule_ulsch(module_id_t module_idP, frame_t frameP, void schedule_ulsch_rnti(module_id_t module_idP, - int slice_idx, - frame_t frameP, - sub_frame_t subframeP, - unsigned char sched_subframeP, uint16_t * first_rb) -{ + int slice_idx, + frame_t frameP, + sub_frame_t subframeP, + unsigned char sched_subframeP, uint16_t *first_rb) { int UE_id; uint8_t aggregation = 2; rnti_t rnti = -1; @@ -1107,56 +1091,55 @@ schedule_ulsch_rnti(module_id_t module_idP, int first_rb_slice[NFAPI_CC_MAX]; if (sched_subframeP < subframeP) - sched_frame++; + sched_frame++; nfapi_hi_dci0_request_t *hi_dci0_req = &mac->HI_DCI0_req[CC_id][subframeP]; nfapi_hi_dci0_request_body_t *hi_dci0_req_body = &hi_dci0_req->hi_dci0_request_body; nfapi_hi_dci0_request_pdu_t *hi_dci0_pdu; - nfapi_ul_config_request_t *ul_req_tmp = &mac->UL_req_tmp[CC_id][sched_subframeP]; nfapi_ul_config_request_body_t *ul_req_tmp_body = &ul_req_tmp->ul_config_request_body; nfapi_ul_config_ulsch_harq_information *ulsch_harq_information; - for (CC_id = 0; CC_id < RC.nb_mac_CC[module_idP]; ++CC_id) { + for (CC_id = 0; CC_id < RC.nb_mac_CC[module_idP]; ++CC_id) { N_RB_UL = to_prb(cc[CC_id].ul_Bandwidth); - UE_list->first_rb_offset[CC_id][slice_idx] = cmin(N_RB_UL, sli->ul[slice_idx].first_rb); - } + UE_list->first_rb_offset[CC_id][slice_idx] = cmin(N_RB_UL, sli->ul[slice_idx].first_rb); + } //LOG_D(MAC, "entering ulsch preprocesor\n"); ulsch_scheduler_pre_processor(module_idP, slice_idx, frameP, subframeP, sched_subframeP, first_rb); - for (CC_id = 0; CC_id < RC.nb_mac_CC[module_idP]; ++CC_id) { + for (CC_id = 0; CC_id < RC.nb_mac_CC[module_idP]; ++CC_id) { first_rb_slice[CC_id] = first_rb[CC_id] + UE_list->first_rb_offset[CC_id][slice_idx]; } - //LOG_D(MAC, "exiting ulsch preprocesor\n"); + //LOG_D(MAC, "exiting ulsch preprocesor\n"); hi_dci0_req->sfn_sf = (frameP << 4) + subframeP; // loop over all active UEs for (UE_id = UE_list->head_ul; UE_id >= 0; UE_id = UE_list->next_ul[UE_id]) { - if (!ue_ul_slice_membership(module_idP, UE_id, slice_idx)) - continue; + continue; // don't schedule if Msg4 is not received yet if (UE_list->UE_template[UE_PCCID(module_idP, UE_id)][UE_id]. configured == FALSE) { - LOG_D(MAC, - "[eNB %d] frame %d subfarme %d, UE %d: not configured, skipping UE scheduling \n", - module_idP, frameP, subframeP, UE_id); - continue; + LOG_D(MAC, + "[eNB %d] frame %d subfarme %d, UE %d: not configured, skipping UE scheduling \n", + module_idP, frameP, subframeP, UE_id); + continue; } rnti = UE_RNTI(module_idP, UE_id); if (rnti == NOT_A_RNTI) { LOG_W(MAC, "[eNB %d] frame %d subfarme %d, UE %d: no RNTI \n", - module_idP, frameP, subframeP, UE_id); + module_idP, frameP, subframeP, UE_id); continue; } drop_ue = 0; + /* let's drop the UE if get_eNB_UE_stats returns NULL when calling it with any of the UE's active UL CCs */ /* TODO: refine? @@ -1172,6 +1155,7 @@ schedule_ulsch_rnti(module_id_t module_idP, if (drop_ue == 1) { /* we can't come here, ulsch_scheduler_pre_processor won't put in the list a UE with no PHY context */ abort(); + /* TODO: this is a hack. Sometimes the UE has no PHY context but * is still present in the MAC with 'ul_failure_timer' = 0 and * 'ul_out_of_sync' = 0. It seems wrong and the UE stays there forever. Let's @@ -1180,18 +1164,20 @@ schedule_ulsch_rnti(module_id_t module_idP, * In the meantime, this hack... */ if (UE_list->UE_sched_ctrl[UE_id].ul_failure_timer == 0 && - UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync == 0) { - LOG_W(MAC, - "[eNB %d] frame %d subframe %d, UE %d/%x CC %d: UE in weird state, let's put it 'out of sync'\n", - module_idP, frameP, subframeP, UE_id, rnti, CC_id); - // inform RRC of failure and clear timer - mac_eNB_rrc_ul_failure(module_idP, CC_id, frameP, - subframeP, rnti); - UE_list->UE_sched_ctrl[UE_id].ul_failure_timer = 0; - UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync = 1; + UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync == 0) { + LOG_W(MAC, + "[eNB %d] frame %d subframe %d, UE %d/%x CC %d: UE in weird state, let's put it 'out of sync'\n", + module_idP, frameP, subframeP, UE_id, rnti, CC_id); + // inform RRC of failure and clear timer + mac_eNB_rrc_ul_failure(module_idP, CC_id, frameP, + subframeP, rnti); + UE_list->UE_sched_ctrl[UE_id].ul_failure_timer = 0; + UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync = 1; } + continue; } + // loop over all active UL CC_ids for this UE for (n = 0; n < UE_list->numactiveULCCs[UE_id]; n++) { // This is the actual CC_id in the list @@ -1199,416 +1185,421 @@ schedule_ulsch_rnti(module_id_t module_idP, N_RB_UL = to_prb(cc[CC_id].ul_Bandwidth); /* - aggregation=get_aggregation(get_bw_index(module_idP,CC_id), - eNB_UE_stats->dl_cqi, - format0); + aggregation=get_aggregation(get_bw_index(module_idP,CC_id), + eNB_UE_stats->dl_cqi, + format0); */ if (CCE_allocation_infeasible - (module_idP, CC_id, 1, subframeP, aggregation, rnti)) { - LOG_W(MAC, - "[eNB %d] frame %d subframe %d, UE %d/%x CC %d: not enough nCCE\n", - module_idP, frameP, subframeP, UE_id, rnti, CC_id); - continue; // break; + (module_idP, CC_id, 1, subframeP, aggregation, rnti)) { + LOG_W(MAC, + "[eNB %d] frame %d subframe %d, UE %d/%x CC %d: not enough nCCE\n", + module_idP, frameP, subframeP, UE_id, rnti, CC_id); + continue; // break; } /* be sure that there are some free RBs */ if (first_rb_slice[CC_id] >= N_RB_UL - 1) { - LOG_W(MAC, - "[eNB %d] frame %d subframe %d, UE %d/%x CC %d: dropping, not enough RBs\n", - module_idP, frameP, subframeP, UE_id, rnti, CC_id); - continue; + LOG_W(MAC, + "[eNB %d] frame %d subframe %d, UE %d/%x CC %d: dropping, not enough RBs\n", + module_idP, frameP, subframeP, UE_id, rnti, CC_id); + continue; } - // if (eNB_UE_stats->mode == PUSCH) { // ue has a ulsch channel + // if (eNB_UE_stats->mode == PUSCH) { // ue has a ulsch channel UE_template = &UE_list->UE_template[CC_id][UE_id]; UE_sched_ctrl = &UE_list->UE_sched_ctrl[UE_id]; harq_pid = subframe2harqpid(&cc[CC_id], sched_frame, sched_subframeP); round = UE_sched_ctrl->round_UL[CC_id][harq_pid]; AssertFatal(round < 8, "round %d > 7 for UE %d/%x\n", round, - UE_id, rnti); + UE_id, rnti); LOG_D(MAC, - "[eNB %d] frame %d subframe %d (sched_frame %d, sched_subframe %d), Checking PUSCH %d for UE %d/%x CC %d : aggregation level %d, N_RB_UL %d\n", - module_idP, frameP, subframeP, sched_frame, sched_subframeP, harq_pid, UE_id, rnti, - CC_id, aggregation, N_RB_UL); - + "[eNB %d] frame %d subframe %d (sched_frame %d, sched_subframe %d), Checking PUSCH %d for UE %d/%x CC %d : aggregation level %d, N_RB_UL %d\n", + module_idP, frameP, subframeP, sched_frame, sched_subframeP, harq_pid, UE_id, rnti, + CC_id, aggregation, N_RB_UL); RC.eNB[module_idP][CC_id]->pusch_stats_BO[UE_id][(frameP * 10) + subframeP] = UE_template->estimated_ul_buffer; VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_UE0_BO,RC.eNB[module_idP][CC_id]->pusch_stats_BO[UE_id][(frameP * - 10) + - subframeP]); - if (UE_is_to_be_scheduled(module_idP, CC_id, UE_id) > 0 || round > 0) // || ((frameP%10)==0)) - // if there is information on bsr of DCCH, DTCH or if there is UL_SR, or if there is a packet to retransmit, or we want to schedule a periodic feedback every 10 frames - { - LOG_D(MAC, - "[eNB %d][PUSCH %d] Frame %d subframe %d Scheduling UE %d/%x in round %d(SR %d,UL_inactivity timer %d,UL_failure timer %d,cqi_req_timer %d)\n", - module_idP, harq_pid, frameP, subframeP, UE_id, rnti, - round, UE_template->ul_SR, - UE_sched_ctrl->ul_inactivity_timer, - UE_sched_ctrl->ul_failure_timer, - UE_sched_ctrl->cqi_req_timer); - // reset the scheduling request - UE_template->ul_SR = 0; - status = mac_eNB_get_rrc_status(module_idP, rnti); - cqi_req = 0; + 10) + + subframeP]); - if (status >= RRC_CONNECTED && UE_sched_ctrl->cqi_req_timer > 30) { - if (UE_sched_ctrl->cqi_received == 0) { - if (nfapi_mode) { - cqi_req = 0; - } else { - cqi_req = 1; - // To be safe , do not ask CQI in special Subframes:36.213/7.2.3 CQI definition - if (cc[CC_id].tdd_Config) { - switch (cc[CC_id].tdd_Config->subframeAssignment) { - case 1: - if( subframeP == 1 || subframeP == 6 ) cqi_req=0; - break; - case 3: - if( subframeP == 1 ) cqi_req=0; - break; - default: - LOG_E(MAC," TDD config not supported\n"); - break; - } - } - if(cqi_req == 1) UE_sched_ctrl->cqi_req_flag |= 1 << sched_subframeP; - } - } - else if (UE_sched_ctrl->cqi_received == 1) { - UE_sched_ctrl->cqi_req_flag = 0; - UE_sched_ctrl->cqi_received = 0; - UE_sched_ctrl->cqi_req_timer = 0; - } - } + if (UE_is_to_be_scheduled(module_idP, CC_id, UE_id) > 0 || round > 0) // || ((frameP%10)==0)) + // if there is information on bsr of DCCH, DTCH or if there is UL_SR, or if there is a packet to retransmit, or we want to schedule a periodic feedback every 10 frames + { + LOG_D(MAC, + "[eNB %d][PUSCH %d] Frame %d subframe %d Scheduling UE %d/%x in round %d(SR %d,UL_inactivity timer %d,UL_failure timer %d,cqi_req_timer %d)\n", + module_idP, harq_pid, frameP, subframeP, UE_id, rnti, + round, UE_template->ul_SR, + UE_sched_ctrl->ul_inactivity_timer, + UE_sched_ctrl->ul_failure_timer, + UE_sched_ctrl->cqi_req_timer); + // reset the scheduling request + UE_template->ul_SR = 0; + status = mac_eNB_get_rrc_status(module_idP, rnti); + cqi_req = 0; - //power control - //compute the expected ULSCH RX power (for the stats) + if (status >= RRC_CONNECTED && UE_sched_ctrl->cqi_req_timer > 30) { + if (UE_sched_ctrl->cqi_received == 0) { + if (nfapi_mode) { + cqi_req = 0; + } else { + cqi_req = 1; - // this is the normalized RX power and this should be constant (regardless of mcs - //is not in dBm, unit from nfapi, converting to dBm: ToDo: Noise power hard coded to 30 - normalized_rx_power = (5*UE_sched_ctrl->pusch_snr[CC_id]-640)/10+30; - target_rx_power= mac->puSch10xSnr/10 + 30; - //printf("\n mac->puSch10xSnr = %d, normalized_rx_power = %d, target_rx_power = %d \n",mac->puSch10xSnr,normalized_rx_power,target_rx_power); - // this assumes accumulated tpc - // make sure that we are only sending a tpc update once a frame, otherwise the control loop will freak out - int32_t framex10psubframe = UE_template->pusch_tpc_tx_frame * 10 + UE_template->pusch_tpc_tx_subframe; - if (((framex10psubframe + 10) <= (frameP * 10 + subframeP)) || //normal case - ((framex10psubframe > (frameP * 10 + subframeP)) && (((10240 - framex10psubframe + frameP * 10 + subframeP) >= 10)))) //frame wrap-around - { - UE_template->pusch_tpc_tx_frame = frameP; - UE_template->pusch_tpc_tx_subframe = subframeP; - if (normalized_rx_power > (target_rx_power + 4)) { - tpc = 0; //-1 - tpc_accumulated--; - } else if (normalized_rx_power < (target_rx_power - 4)) { - tpc = 2; //+1 - tpc_accumulated++; - } else { - tpc = 1; //0 - } - } else { - tpc = 1; //0 - } - //tpc = 1; - if (tpc != 1) { - LOG_D(MAC, - "[eNB %d] ULSCH scheduler: frame %d, subframe %d, harq_pid %d, tpc %d, accumulated %d, normalized/target rx power %d/%d\n", - module_idP, frameP, subframeP, harq_pid, tpc, - tpc_accumulated, normalized_rx_power, - target_rx_power); - } - // new transmission - if (round == 0) { + // To be safe , do not ask CQI in special Subframes:36.213/7.2.3 CQI definition + if (cc[CC_id].tdd_Config) { + switch (cc[CC_id].tdd_Config->subframeAssignment) { + case 1: + if( subframeP == 1 || subframeP == 6 ) cqi_req=0; - ndi = 1 - UE_template->oldNDI_UL[harq_pid]; - UE_template->oldNDI_UL[harq_pid] = ndi; - UE_list->eNB_UE_stats[CC_id][UE_id].normalized_rx_power = normalized_rx_power; - UE_list->eNB_UE_stats[CC_id][UE_id].target_rx_power = target_rx_power; - UE_template->mcs_UL[harq_pid] = cmin(UE_template->pre_assigned_mcs_ul, sli->ul[slice_idx].maxmcs); - UE_list->eNB_UE_stats[CC_id][UE_id].ulsch_mcs1= UE_template->mcs_UL[harq_pid]; - //cmin (UE_template->pre_assigned_mcs_ul, openair_daq_vars.target_ue_ul_mcs); // adjust, based on user-defined MCS - if (UE_template->pre_allocated_rb_table_index_ul >= 0) { - rb_table_index = UE_template->pre_allocated_rb_table_index_ul; - } else { - UE_template->mcs_UL[harq_pid] = 10; //cmin (10, openair_daq_vars.target_ue_ul_mcs); - rb_table_index = 5; // for PHR - } + break; - UE_list->eNB_UE_stats[CC_id][UE_id].ulsch_mcs2 = UE_template->mcs_UL[harq_pid]; - // buffer_occupancy = UE_template->ul_total_buffer; + case 3: + if( subframeP == 1 ) cqi_req=0; + break; - while (((rb_table[rb_table_index] > (N_RB_UL - first_rb_slice[CC_id])) - || (rb_table[rb_table_index] > 45)) - && (rb_table_index > 0)) { - rb_table_index--; - } - - UE_template->TBS_UL[harq_pid] = get_TBS_UL(UE_template->mcs_UL[harq_pid], - rb_table[rb_table_index]); - UE_list->eNB_UE_stats[CC_id][UE_id].total_rbs_used_rx += rb_table[rb_table_index]; - UE_list->eNB_UE_stats[CC_id][UE_id].ulsch_TBS = UE_template->TBS_UL[harq_pid]; - UE_list->eNB_UE_stats[CC_id][UE_id].total_ulsch_TBS += UE_template->TBS_UL[harq_pid]; - // buffer_occupancy -= TBS; - - T(T_ENB_MAC_UE_UL_SCHEDULE, T_INT(module_idP), - T_INT(CC_id), T_INT(rnti), T_INT(frameP), - T_INT(subframeP), T_INT(harq_pid), - T_INT(UE_template->mcs_UL[harq_pid]), - T_INT(first_rb_slice[CC_id]), - T_INT(rb_table[rb_table_index]), - T_INT(UE_template->TBS_UL[harq_pid]), T_INT(ndi)); - - if (mac_eNB_get_rrc_status(module_idP, rnti) < RRC_CONNECTED) - LOG_D(MAC, - "[eNB %d][PUSCH %d/%x] CC_id %d Frame %d subframeP %d Scheduled UE %d (mcs %d, first rb %d, nb_rb %d, rb_table_index %d, TBS %d, harq_pid %d)\n", - module_idP, harq_pid, rnti, CC_id, frameP, - subframeP, UE_id, - UE_template->mcs_UL[harq_pid], - first_rb_slice[CC_id], rb_table[rb_table_index], - rb_table_index, - UE_template->TBS_UL[harq_pid], harq_pid); - - // bad indices : 20 (40 PRB), 21 (45 PRB), 22 (48 PRB) - //store for possible retransmission - UE_template->nb_rb_ul[harq_pid] = rb_table[rb_table_index]; - UE_template->first_rb_ul[harq_pid] = first_rb_slice[CC_id]; - - UE_sched_ctrl->ul_scheduled |= (1 << harq_pid); - if (UE_id == UE_list->head) - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_UE0_SCHEDULED, - UE_sched_ctrl->ul_scheduled); - - // adjust scheduled UL bytes by TBS, wait for UL sdus to do final update - LOG_D(MAC, - "[eNB %d] CC_id %d UE %d/%x : adjusting scheduled_ul_bytes, old %d, TBS %d\n", - module_idP, CC_id, UE_id, rnti, - UE_template->scheduled_ul_bytes, - UE_template->TBS_UL[harq_pid]); - - UE_template->scheduled_ul_bytes += UE_template->TBS_UL[harq_pid]; - - LOG_D(MAC, "scheduled_ul_bytes, new %d\n", UE_template->scheduled_ul_bytes); - - // Cyclic shift for DM RS - cshift = 0; // values from 0 to 7 can be used for mapping the cyclic shift (36.211 , Table 5.5.2.1.1-1) - // save it for a potential retransmission - UE_template->cshift[harq_pid] = cshift; - - hi_dci0_pdu = &hi_dci0_req_body->hi_dci0_pdu_list[hi_dci0_req_body->number_of_dci + hi_dci0_req_body->number_of_hi]; - memset((void *) hi_dci0_pdu, 0,sizeof(nfapi_hi_dci0_request_pdu_t)); - hi_dci0_pdu->pdu_type = NFAPI_HI_DCI0_DCI_PDU_TYPE; - hi_dci0_pdu->pdu_size = 2 + sizeof(nfapi_hi_dci0_dci_pdu); - hi_dci0_pdu->dci_pdu.dci_pdu_rel8.tl.tag = NFAPI_HI_DCI0_REQUEST_DCI_PDU_REL8_TAG; - hi_dci0_pdu->dci_pdu.dci_pdu_rel8.dci_format = NFAPI_UL_DCI_FORMAT_0; - hi_dci0_pdu->dci_pdu.dci_pdu_rel8.aggregation_level = aggregation; - hi_dci0_pdu->dci_pdu.dci_pdu_rel8.rnti = rnti; - hi_dci0_pdu->dci_pdu.dci_pdu_rel8.transmission_power = 6000; - hi_dci0_pdu->dci_pdu.dci_pdu_rel8.resource_block_start = first_rb_slice[CC_id]; - hi_dci0_pdu->dci_pdu.dci_pdu_rel8.number_of_resource_block = rb_table[rb_table_index]; - hi_dci0_pdu->dci_pdu.dci_pdu_rel8.mcs_1 = UE_template->mcs_UL[harq_pid]; - hi_dci0_pdu->dci_pdu.dci_pdu_rel8.cyclic_shift_2_for_drms = cshift; - hi_dci0_pdu->dci_pdu.dci_pdu_rel8.frequency_hopping_enabled_flag = 0; - hi_dci0_pdu->dci_pdu.dci_pdu_rel8.new_data_indication_1 = ndi; - hi_dci0_pdu->dci_pdu.dci_pdu_rel8.tpc = tpc; - hi_dci0_pdu->dci_pdu.dci_pdu_rel8.cqi_csi_request = cqi_req; - hi_dci0_pdu->dci_pdu.dci_pdu_rel8.dl_assignment_index = UE_template->DAI_ul[sched_subframeP]; - hi_dci0_pdu->dci_pdu.dci_pdu_rel8.harq_pid = harq_pid; - - hi_dci0_req_body->number_of_dci++; - hi_dci0_req_body->sfnsf = sfnsf_add_subframe(sched_frame, sched_subframeP, 0); //(frameP, subframeP, 4); - hi_dci0_req_body->tl.tag = NFAPI_HI_DCI0_REQUEST_BODY_TAG; - - hi_dci0_req->sfn_sf = frameP<<4|subframeP; // sfnsf_add_subframe(sched_frame, sched_subframeP, 0); // sunday! - hi_dci0_req->header.message_id = NFAPI_HI_DCI0_REQUEST; - - - LOG_D(MAC, - "[PUSCH %d] Frame %d, Subframe %d: Adding UL CONFIG.Request for UE %d/%x, ulsch_frame %d, ulsch_subframe %d\n", - harq_pid, frameP, subframeP, UE_id, rnti, - sched_frame, sched_subframeP); - - ul_req_index = 0; - dlsch_flag = 0; - for(ul_req_index = 0;ul_req_index < ul_req_tmp_body->number_of_pdus;ul_req_index++){ - if(ul_req_tmp_body->ul_config_pdu_list[ul_req_index].pdu_type == NFAPI_UL_CONFIG_UCI_HARQ_PDU_TYPE && - ul_req_tmp_body->ul_config_pdu_list[ul_req_index].uci_harq_pdu.ue_information.ue_information_rel8.rnti == rnti){ - dlsch_flag = 1; - LOG_D(MAC,"Frame %d, Subframe %d:rnti %x ul_req_index %d Switched UCI HARQ to ULSCH HARQ(first)\n",frameP,subframeP,rnti,ul_req_index); - break; + default: + LOG_E(MAC," TDD config not supported\n"); + break; + } } - } - // Add UL_config PDUs - fill_nfapi_ulsch_config_request_rel8(&ul_req_tmp_body->ul_config_pdu_list[ul_req_index], cqi_req, cc, UE_template->physicalConfigDedicated, get_tmode(module_idP, CC_id, UE_id), mac->ul_handle, rnti, first_rb_slice[CC_id], // resource_block_start - rb_table[rb_table_index], // number_of_resource_blocks - UE_template->mcs_UL[harq_pid], cshift, // cyclic_shift_2_for_drms - 0, // frequency_hopping_enabled_flag - 0, // frequency_hopping_bits - ndi, // new_data_indication - 0, // redundancy_version - harq_pid, // harq_process_number - 0, // ul_tx_mode - 0, // current_tx_nb - 0, // n_srs - get_TBS_UL - (UE_template-> - mcs_UL[harq_pid], - rb_table - [rb_table_index])); + if(cqi_req == 1) UE_sched_ctrl->cqi_req_flag |= 1 << sched_subframeP; + } + } else if (UE_sched_ctrl->cqi_received == 1) { + UE_sched_ctrl->cqi_req_flag = 0; + UE_sched_ctrl->cqi_received = 0; + UE_sched_ctrl->cqi_req_timer = 0; + } + } + + //power control + //compute the expected ULSCH RX power (for the stats) + // this is the normalized RX power and this should be constant (regardless of mcs + //is not in dBm, unit from nfapi, converting to dBm: ToDo: Noise power hard coded to 30 + normalized_rx_power = (5*UE_sched_ctrl->pusch_snr[CC_id]-640)/10+30; + target_rx_power= mac->puSch10xSnr/10 + 30; + //printf("\n mac->puSch10xSnr = %d, normalized_rx_power = %d, target_rx_power = %d \n",mac->puSch10xSnr,normalized_rx_power,target_rx_power); + // this assumes accumulated tpc + // make sure that we are only sending a tpc update once a frame, otherwise the control loop will freak out + int32_t framex10psubframe = UE_template->pusch_tpc_tx_frame * 10 + UE_template->pusch_tpc_tx_subframe; + + if (((framex10psubframe + 10) <= (frameP * 10 + subframeP)) || //normal case + ((framex10psubframe > (frameP * 10 + subframeP)) && (((10240 - framex10psubframe + frameP * 10 + subframeP) >= 10)))) { //frame wrap-around + UE_template->pusch_tpc_tx_frame = frameP; + UE_template->pusch_tpc_tx_subframe = subframeP; + + if (normalized_rx_power > (target_rx_power + 4)) { + tpc = 0; //-1 + tpc_accumulated--; + } else if (normalized_rx_power < (target_rx_power - 4)) { + tpc = 2; //+1 + tpc_accumulated++; + } else { + tpc = 1; //0 + } + } else { + tpc = 1; //0 + } + + //tpc = 1; + if (tpc != 1) { + LOG_D(MAC, + "[eNB %d] ULSCH scheduler: frame %d, subframe %d, harq_pid %d, tpc %d, accumulated %d, normalized/target rx power %d/%d\n", + module_idP, frameP, subframeP, harq_pid, tpc, + tpc_accumulated, normalized_rx_power, + target_rx_power); + } + + // new transmission + if (round == 0) { + ndi = 1 - UE_template->oldNDI_UL[harq_pid]; + UE_template->oldNDI_UL[harq_pid] = ndi; + UE_list->eNB_UE_stats[CC_id][UE_id].normalized_rx_power = normalized_rx_power; + UE_list->eNB_UE_stats[CC_id][UE_id].target_rx_power = target_rx_power; + UE_template->mcs_UL[harq_pid] = cmin(UE_template->pre_assigned_mcs_ul, sli->ul[slice_idx].maxmcs); + UE_list->eNB_UE_stats[CC_id][UE_id].ulsch_mcs1= UE_template->mcs_UL[harq_pid]; + + //cmin (UE_template->pre_assigned_mcs_ul, openair_daq_vars.target_ue_ul_mcs); // adjust, based on user-defined MCS + if (UE_template->pre_allocated_rb_table_index_ul >= 0) { + rb_table_index = UE_template->pre_allocated_rb_table_index_ul; + } else { + UE_template->mcs_UL[harq_pid] = 10; //cmin (10, openair_daq_vars.target_ue_ul_mcs); + rb_table_index = 5; // for PHR + } + + UE_list->eNB_UE_stats[CC_id][UE_id].ulsch_mcs2 = UE_template->mcs_UL[harq_pid]; + // buffer_occupancy = UE_template->ul_total_buffer; + + while (((rb_table[rb_table_index] > (N_RB_UL - first_rb_slice[CC_id])) + || (rb_table[rb_table_index] > 45)) + && (rb_table_index > 0)) { + rb_table_index--; + } + + UE_template->TBS_UL[harq_pid] = get_TBS_UL(UE_template->mcs_UL[harq_pid], + rb_table[rb_table_index]); + UE_list->eNB_UE_stats[CC_id][UE_id].total_rbs_used_rx += rb_table[rb_table_index]; + UE_list->eNB_UE_stats[CC_id][UE_id].ulsch_TBS = UE_template->TBS_UL[harq_pid]; + UE_list->eNB_UE_stats[CC_id][UE_id].total_ulsch_TBS += UE_template->TBS_UL[harq_pid]; + // buffer_occupancy -= TBS; + T(T_ENB_MAC_UE_UL_SCHEDULE, T_INT(module_idP), + T_INT(CC_id), T_INT(rnti), T_INT(frameP), + T_INT(subframeP), T_INT(harq_pid), + T_INT(UE_template->mcs_UL[harq_pid]), + T_INT(first_rb_slice[CC_id]), + T_INT(rb_table[rb_table_index]), + T_INT(UE_template->TBS_UL[harq_pid]), T_INT(ndi)); + + if (mac_eNB_get_rrc_status(module_idP, rnti) < RRC_CONNECTED) + LOG_D(MAC, + "[eNB %d][PUSCH %d/%x] CC_id %d Frame %d subframeP %d Scheduled UE %d (mcs %d, first rb %d, nb_rb %d, rb_table_index %d, TBS %d, harq_pid %d)\n", + module_idP, harq_pid, rnti, CC_id, frameP, + subframeP, UE_id, + UE_template->mcs_UL[harq_pid], + first_rb_slice[CC_id], rb_table[rb_table_index], + rb_table_index, + UE_template->TBS_UL[harq_pid], harq_pid); + + // bad indices : 20 (40 PRB), 21 (45 PRB), 22 (48 PRB) + //store for possible retransmission + UE_template->nb_rb_ul[harq_pid] = rb_table[rb_table_index]; + UE_template->first_rb_ul[harq_pid] = first_rb_slice[CC_id]; + UE_sched_ctrl->ul_scheduled |= (1 << harq_pid); + + if (UE_id == UE_list->head) + VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_UE0_SCHEDULED, + UE_sched_ctrl->ul_scheduled); + + // adjust scheduled UL bytes by TBS, wait for UL sdus to do final update + LOG_D(MAC, + "[eNB %d] CC_id %d UE %d/%x : adjusting scheduled_ul_bytes, old %d, TBS %d\n", + module_idP, CC_id, UE_id, rnti, + UE_template->scheduled_ul_bytes, + UE_template->TBS_UL[harq_pid]); + UE_template->scheduled_ul_bytes += UE_template->TBS_UL[harq_pid]; + LOG_D(MAC, "scheduled_ul_bytes, new %d\n", UE_template->scheduled_ul_bytes); + // Cyclic shift for DM RS + cshift = 0; // values from 0 to 7 can be used for mapping the cyclic shift (36.211 , Table 5.5.2.1.1-1) + // save it for a potential retransmission + UE_template->cshift[harq_pid] = cshift; + hi_dci0_pdu = &hi_dci0_req_body->hi_dci0_pdu_list[hi_dci0_req_body->number_of_dci + hi_dci0_req_body->number_of_hi]; + memset((void *) hi_dci0_pdu, 0,sizeof(nfapi_hi_dci0_request_pdu_t)); + hi_dci0_pdu->pdu_type = NFAPI_HI_DCI0_DCI_PDU_TYPE; + hi_dci0_pdu->pdu_size = 2 + sizeof(nfapi_hi_dci0_dci_pdu); + hi_dci0_pdu->dci_pdu.dci_pdu_rel8.tl.tag = NFAPI_HI_DCI0_REQUEST_DCI_PDU_REL8_TAG; + hi_dci0_pdu->dci_pdu.dci_pdu_rel8.dci_format = NFAPI_UL_DCI_FORMAT_0; + hi_dci0_pdu->dci_pdu.dci_pdu_rel8.aggregation_level = aggregation; + hi_dci0_pdu->dci_pdu.dci_pdu_rel8.rnti = rnti; + hi_dci0_pdu->dci_pdu.dci_pdu_rel8.transmission_power = 6000; + hi_dci0_pdu->dci_pdu.dci_pdu_rel8.resource_block_start = first_rb_slice[CC_id]; + hi_dci0_pdu->dci_pdu.dci_pdu_rel8.number_of_resource_block = rb_table[rb_table_index]; + hi_dci0_pdu->dci_pdu.dci_pdu_rel8.mcs_1 = UE_template->mcs_UL[harq_pid]; + hi_dci0_pdu->dci_pdu.dci_pdu_rel8.cyclic_shift_2_for_drms = cshift; + hi_dci0_pdu->dci_pdu.dci_pdu_rel8.frequency_hopping_enabled_flag = 0; + hi_dci0_pdu->dci_pdu.dci_pdu_rel8.new_data_indication_1 = ndi; + hi_dci0_pdu->dci_pdu.dci_pdu_rel8.tpc = tpc; + hi_dci0_pdu->dci_pdu.dci_pdu_rel8.cqi_csi_request = cqi_req; + hi_dci0_pdu->dci_pdu.dci_pdu_rel8.dl_assignment_index = UE_template->DAI_ul[sched_subframeP]; + hi_dci0_pdu->dci_pdu.dci_pdu_rel8.harq_pid = harq_pid; + hi_dci0_req_body->number_of_dci++; + hi_dci0_req_body->sfnsf = sfnsf_add_subframe(sched_frame, sched_subframeP, 0); //(frameP, subframeP, 4); + hi_dci0_req_body->tl.tag = NFAPI_HI_DCI0_REQUEST_BODY_TAG; + hi_dci0_req->sfn_sf = frameP<<4|subframeP; // sfnsf_add_subframe(sched_frame, sched_subframeP, 0); // sunday! + hi_dci0_req->header.message_id = NFAPI_HI_DCI0_REQUEST; + LOG_D(MAC, + "[PUSCH %d] Frame %d, Subframe %d: Adding UL CONFIG.Request for UE %d/%x, ulsch_frame %d, ulsch_subframe %d\n", + harq_pid, frameP, subframeP, UE_id, rnti, + sched_frame, sched_subframeP); + ul_req_index = 0; + dlsch_flag = 0; + + for(ul_req_index = 0; ul_req_index < ul_req_tmp_body->number_of_pdus; ul_req_index++) { + if(ul_req_tmp_body->ul_config_pdu_list[ul_req_index].pdu_type == NFAPI_UL_CONFIG_UCI_HARQ_PDU_TYPE && + ul_req_tmp_body->ul_config_pdu_list[ul_req_index].uci_harq_pdu.ue_information.ue_information_rel8.rnti == rnti) { + dlsch_flag = 1; + LOG_D(MAC,"Frame %d, Subframe %d:rnti %x ul_req_index %d Switched UCI HARQ to ULSCH HARQ(first)\n",frameP,subframeP,rnti,ul_req_index); + break; + } + } + + // Add UL_config PDUs + fill_nfapi_ulsch_config_request_rel8(&ul_req_tmp_body->ul_config_pdu_list[ul_req_index], cqi_req, cc, UE_template->physicalConfigDedicated, get_tmode(module_idP, CC_id, UE_id), mac->ul_handle, rnti, + first_rb_slice[CC_id], // resource_block_start + rb_table[rb_table_index], // number_of_resource_blocks + UE_template->mcs_UL[harq_pid], cshift, // cyclic_shift_2_for_drms + 0, // frequency_hopping_enabled_flag + 0, // frequency_hopping_bits + ndi, // new_data_indication + 0, // redundancy_version + harq_pid, // harq_process_number + 0, // ul_tx_mode + 0, // current_tx_nb + 0, // n_srs + get_TBS_UL + (UE_template-> + mcs_UL[harq_pid], + rb_table + [rb_table_index])); #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - if (UE_template->rach_resource_type > 0) { // This is a BL/CE UE allocation - fill_nfapi_ulsch_config_request_emtc(&ul_req_tmp_body->ul_config_pdu_list[ul_req_index], UE_template->rach_resource_type > 2 ? 2 : 1, 1, //total_number_of_repetitions - 1, //repetition_number - (frameP * - 10) + - subframeP); - } + + if (UE_template->rach_resource_type > 0) { // This is a BL/CE UE allocation + fill_nfapi_ulsch_config_request_emtc(&ul_req_tmp_body->ul_config_pdu_list[ul_req_index], UE_template->rach_resource_type > 2 ? 2 : 1, 1, //total_number_of_repetitions + 1, //repetition_number + (frameP * + 10) + + subframeP); + } + #endif - if(dlsch_flag == 1){ - if(cqi_req == 1){ - ul_req_tmp_body->ul_config_pdu_list[ul_req_index].pdu_type = NFAPI_UL_CONFIG_ULSCH_CQI_HARQ_RI_PDU_TYPE; - ulsch_harq_information = &ul_req_tmp_body->ul_config_pdu_list[ul_req_index].ulsch_cqi_harq_ri_pdu.harq_information; - ul_req_tmp_body->ul_config_pdu_list[ul_req_index].ulsch_cqi_harq_ri_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.tl.tag=NFAPI_UL_CONFIG_REQUEST_INITIAL_TRANSMISSION_PARAMETERS_REL8_TAG; - ul_req_tmp_body->ul_config_pdu_list[ul_req_index].ulsch_cqi_harq_ri_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.n_srs_initial = 0; // last symbol not punctured - ul_req_tmp_body->ul_config_pdu_list[ul_req_index].ulsch_cqi_harq_ri_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.initial_number_of_resource_blocks = rb_table[rb_table_index]; - }else{ - ul_req_tmp_body->ul_config_pdu_list[ul_req_index].pdu_type = NFAPI_UL_CONFIG_ULSCH_HARQ_PDU_TYPE; - ulsch_harq_information = &ul_req_tmp_body->ul_config_pdu_list[ul_req_index].ulsch_harq_pdu.harq_information; - ul_req_tmp_body->ul_config_pdu_list[ul_req_index].ulsch_harq_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.tl.tag = NFAPI_UL_CONFIG_REQUEST_INITIAL_TRANSMISSION_PARAMETERS_REL8_TAG; - ul_req_tmp_body->ul_config_pdu_list[ul_req_index].ulsch_harq_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.n_srs_initial = 0; // last symbol not punctured - ul_req_tmp_body->ul_config_pdu_list[ul_req_index].ulsch_harq_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.initial_number_of_resource_blocks = rb_table[rb_table_index]; - } - fill_nfapi_ulsch_harq_information(module_idP, CC_id,rnti, ulsch_harq_information,subframeP); - }else{ - ul_req_tmp_body->number_of_pdus++; + if(dlsch_flag == 1) { + if(cqi_req == 1) { + ul_req_tmp_body->ul_config_pdu_list[ul_req_index].pdu_type = NFAPI_UL_CONFIG_ULSCH_CQI_HARQ_RI_PDU_TYPE; + ulsch_harq_information = &ul_req_tmp_body->ul_config_pdu_list[ul_req_index].ulsch_cqi_harq_ri_pdu.harq_information; + ul_req_tmp_body->ul_config_pdu_list[ul_req_index].ulsch_cqi_harq_ri_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.tl.tag= + NFAPI_UL_CONFIG_REQUEST_INITIAL_TRANSMISSION_PARAMETERS_REL8_TAG; + ul_req_tmp_body->ul_config_pdu_list[ul_req_index].ulsch_cqi_harq_ri_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.n_srs_initial = 0; // last symbol not punctured + ul_req_tmp_body->ul_config_pdu_list[ul_req_index].ulsch_cqi_harq_ri_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.initial_number_of_resource_blocks = + rb_table[rb_table_index]; + } else { + ul_req_tmp_body->ul_config_pdu_list[ul_req_index].pdu_type = NFAPI_UL_CONFIG_ULSCH_HARQ_PDU_TYPE; + ulsch_harq_information = &ul_req_tmp_body->ul_config_pdu_list[ul_req_index].ulsch_harq_pdu.harq_information; + ul_req_tmp_body->ul_config_pdu_list[ul_req_index].ulsch_harq_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.tl.tag = + NFAPI_UL_CONFIG_REQUEST_INITIAL_TRANSMISSION_PARAMETERS_REL8_TAG; + ul_req_tmp_body->ul_config_pdu_list[ul_req_index].ulsch_harq_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.n_srs_initial = 0; // last symbol not punctured + ul_req_tmp_body->ul_config_pdu_list[ul_req_index].ulsch_harq_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.initial_number_of_resource_blocks = rb_table[rb_table_index]; } - ul_req_tmp->header.message_id = NFAPI_UL_CONFIG_REQUEST; - ul_req_tmp_body->tl.tag = NFAPI_UL_CONFIG_REQUEST_BODY_TAG; - mac->ul_handle++; + fill_nfapi_ulsch_harq_information(module_idP, CC_id,rnti, ulsch_harq_information,subframeP); + } else { + ul_req_tmp_body->number_of_pdus++; + } - uint16_t ul_sched_frame = sched_frame; - uint16_t ul_sched_subframeP = sched_subframeP; + ul_req_tmp->header.message_id = NFAPI_UL_CONFIG_REQUEST; + ul_req_tmp_body->tl.tag = NFAPI_UL_CONFIG_REQUEST_BODY_TAG; + mac->ul_handle++; + uint16_t ul_sched_frame = sched_frame; + uint16_t ul_sched_subframeP = sched_subframeP; + //add_subframe(&ul_sched_frame, &ul_sched_subframeP, 2); + ul_req_tmp->sfn_sf = ul_sched_frame<<4|ul_sched_subframeP; + add_ue_ulsch_info(module_idP, + CC_id, UE_id, subframeP, + S_UL_SCHEDULED); + LOG_D(MAC, "[eNB %d] CC_id %d Frame %d, subframeP %d: Generated ULSCH DCI for next UE_id %d, format 0\n", module_idP, CC_id, frameP, subframeP, UE_id); + LOG_D(MAC,"[PUSCH %d] SFN/SF:%04d%d UL_CFG:SFN/SF:%04d%d CQI:%d for UE %d/%x\n", harq_pid,frameP,subframeP,ul_sched_frame,ul_sched_subframeP,cqi_req,UE_id,rnti); + // increment first rb for next UE allocation + first_rb_slice[CC_id] += rb_table[rb_table_index]; + } else { // round > 0 => retransmission + T(T_ENB_MAC_UE_UL_SCHEDULE_RETRANSMISSION, + T_INT(module_idP), T_INT(CC_id), T_INT(rnti), + T_INT(frameP), T_INT(subframeP), T_INT(harq_pid), + T_INT(UE_template->mcs_UL[harq_pid]), + T_INT(first_rb_slice[CC_id]), + T_INT(rb_table[rb_table_index]), T_INT(round)); + // Add UL_config PDUs + LOG_D(MAC, + "[PUSCH %d] Frame %d, Subframe %d: Adding UL CONFIG.Request for UE %d/%x, ulsch_frame %d, ulsch_subframe %d\n", + harq_pid, frameP, subframeP, UE_id, rnti, + sched_frame, sched_subframeP); + ul_req_index = 0; + dlsch_flag = 0; - //add_subframe(&ul_sched_frame, &ul_sched_subframeP, 2); - ul_req_tmp->sfn_sf = ul_sched_frame<<4|ul_sched_subframeP; - - add_ue_ulsch_info(module_idP, - CC_id, UE_id, subframeP, - S_UL_SCHEDULED); - - LOG_D(MAC, "[eNB %d] CC_id %d Frame %d, subframeP %d: Generated ULSCH DCI for next UE_id %d, format 0\n", module_idP, CC_id, frameP, subframeP, UE_id); - LOG_D(MAC,"[PUSCH %d] SFN/SF:%04d%d UL_CFG:SFN/SF:%04d%d CQI:%d for UE %d/%x\n", harq_pid,frameP,subframeP,ul_sched_frame,ul_sched_subframeP,cqi_req,UE_id,rnti); - - // increment first rb for next UE allocation - first_rb_slice[CC_id] += rb_table[rb_table_index]; - } else { // round > 0 => retransmission - T(T_ENB_MAC_UE_UL_SCHEDULE_RETRANSMISSION, - T_INT(module_idP), T_INT(CC_id), T_INT(rnti), - T_INT(frameP), T_INT(subframeP), T_INT(harq_pid), - T_INT(UE_template->mcs_UL[harq_pid]), - T_INT(first_rb_slice[CC_id]), - T_INT(rb_table[rb_table_index]), T_INT(round)); - - // Add UL_config PDUs - LOG_D(MAC, - "[PUSCH %d] Frame %d, Subframe %d: Adding UL CONFIG.Request for UE %d/%x, ulsch_frame %d, ulsch_subframe %d\n", - harq_pid, frameP, subframeP, UE_id, rnti, - sched_frame, sched_subframeP); - ul_req_index = 0; - dlsch_flag = 0; - for(ul_req_index = 0;ul_req_index < ul_req_tmp_body->number_of_pdus;ul_req_index++){ - if(ul_req_tmp_body->ul_config_pdu_list[ul_req_index].pdu_type == NFAPI_UL_CONFIG_UCI_HARQ_PDU_TYPE && - ul_req_tmp_body->ul_config_pdu_list[ul_req_index].uci_harq_pdu.ue_information.ue_information_rel8.rnti == rnti){ - dlsch_flag = 1; - LOG_D(MAC,"Frame %d, Subframe %d:rnti %x ul_req_index %d Switched UCI HARQ to ULSCH HARQ(first)\n",frameP,subframeP,rnti,ul_req_index); - break; - } + for(ul_req_index = 0; ul_req_index < ul_req_tmp_body->number_of_pdus; ul_req_index++) { + if(ul_req_tmp_body->ul_config_pdu_list[ul_req_index].pdu_type == NFAPI_UL_CONFIG_UCI_HARQ_PDU_TYPE && + ul_req_tmp_body->ul_config_pdu_list[ul_req_index].uci_harq_pdu.ue_information.ue_information_rel8.rnti == rnti) { + dlsch_flag = 1; + LOG_D(MAC,"Frame %d, Subframe %d:rnti %x ul_req_index %d Switched UCI HARQ to ULSCH HARQ(first)\n",frameP,subframeP,rnti,ul_req_index); + break; } - fill_nfapi_ulsch_config_request_rel8(&ul_req_tmp_body->ul_config_pdu_list[ul_req_index], cqi_req, cc, UE_template->physicalConfigDedicated, get_tmode(module_idP, CC_id, UE_id), mac->ul_handle, rnti, UE_template->first_rb_ul[harq_pid], // resource_block_start - UE_template->nb_rb_ul[harq_pid], // number_of_resource_blocks - UE_template->mcs_UL[harq_pid], cshift, // cyclic_shift_2_for_drms - 0, // frequency_hopping_enabled_flag - 0, // frequency_hopping_bits - UE_template->oldNDI_UL[harq_pid], // new_data_indication - rvidx_tab[round & 3], // redundancy_version - harq_pid, // harq_process_number - 0, // ul_tx_mode - 0, // current_tx_nb - 0, // n_srs - UE_template-> - TBS_UL[harq_pid]); + } + + fill_nfapi_ulsch_config_request_rel8(&ul_req_tmp_body->ul_config_pdu_list[ul_req_index], cqi_req, cc, UE_template->physicalConfigDedicated, get_tmode(module_idP, CC_id, UE_id), mac->ul_handle, rnti, + UE_template->first_rb_ul[harq_pid], // resource_block_start + UE_template->nb_rb_ul[harq_pid], // number_of_resource_blocks + UE_template->mcs_UL[harq_pid], cshift, // cyclic_shift_2_for_drms + 0, // frequency_hopping_enabled_flag + 0, // frequency_hopping_bits + UE_template->oldNDI_UL[harq_pid], // new_data_indication + rvidx_tab[round & 3], // redundancy_version + harq_pid, // harq_process_number + 0, // ul_tx_mode + 0, // current_tx_nb + 0, // n_srs + UE_template-> + TBS_UL[harq_pid]); #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - if (UE_template->rach_resource_type > 0) { // This is a BL/CE UE allocation - fill_nfapi_ulsch_config_request_emtc(&ul_req_tmp_body->ul_config_pdu_list[ul_req_index], UE_template->rach_resource_type > 2 ? 2 : 1, 1, //total_number_of_repetitions - 1, //repetition_number - (frameP * - 10) + - subframeP); - } -#endif - if(dlsch_flag == 1){ - if(cqi_req == 1){ - ul_req_tmp_body->ul_config_pdu_list[ul_req_index].pdu_type = NFAPI_UL_CONFIG_ULSCH_CQI_HARQ_RI_PDU_TYPE; - ulsch_harq_information = &ul_req_tmp_body->ul_config_pdu_list[ul_req_index].ulsch_cqi_harq_ri_pdu.harq_information; - ul_req_tmp_body->ul_config_pdu_list[ul_req_index].ulsch_cqi_harq_ri_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.tl.tag=NFAPI_UL_CONFIG_REQUEST_INITIAL_TRANSMISSION_PARAMETERS_REL8_TAG; - ul_req_tmp_body->ul_config_pdu_list[ul_req_index].ulsch_cqi_harq_ri_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.n_srs_initial = 0; // last symbol not punctured - ul_req_tmp_body->ul_config_pdu_list[ul_req_index].ulsch_cqi_harq_ri_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.initial_number_of_resource_blocks = UE_template->nb_rb_ul[harq_pid]; - }else{ - ul_req_tmp_body->ul_config_pdu_list[ul_req_index].pdu_type = NFAPI_UL_CONFIG_ULSCH_HARQ_PDU_TYPE; - ulsch_harq_information = &ul_req_tmp_body->ul_config_pdu_list[ul_req_index].ulsch_harq_pdu.harq_information; - ul_req_tmp_body->ul_config_pdu_list[ul_req_index].ulsch_harq_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.tl.tag = NFAPI_UL_CONFIG_REQUEST_INITIAL_TRANSMISSION_PARAMETERS_REL8_TAG; - ul_req_tmp_body->ul_config_pdu_list[ul_req_index].ulsch_harq_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.n_srs_initial = 0; // last symbol not punctured - ul_req_tmp_body->ul_config_pdu_list[ul_req_index].ulsch_harq_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.initial_number_of_resource_blocks = UE_template->nb_rb_ul[harq_pid]; - } - fill_nfapi_ulsch_harq_information(module_idP, CC_id,rnti, ulsch_harq_information,subframeP); - }else{ - ul_req_tmp_body->number_of_pdus++; + if (UE_template->rach_resource_type > 0) { // This is a BL/CE UE allocation + fill_nfapi_ulsch_config_request_emtc(&ul_req_tmp_body->ul_config_pdu_list[ul_req_index], UE_template->rach_resource_type > 2 ? 2 : 1, 1, //total_number_of_repetitions + 1, //repetition_number + (frameP * + 10) + + subframeP); + } + +#endif + + if(dlsch_flag == 1) { + if(cqi_req == 1) { + ul_req_tmp_body->ul_config_pdu_list[ul_req_index].pdu_type = NFAPI_UL_CONFIG_ULSCH_CQI_HARQ_RI_PDU_TYPE; + ulsch_harq_information = &ul_req_tmp_body->ul_config_pdu_list[ul_req_index].ulsch_cqi_harq_ri_pdu.harq_information; + ul_req_tmp_body->ul_config_pdu_list[ul_req_index].ulsch_cqi_harq_ri_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.tl.tag= + NFAPI_UL_CONFIG_REQUEST_INITIAL_TRANSMISSION_PARAMETERS_REL8_TAG; + ul_req_tmp_body->ul_config_pdu_list[ul_req_index].ulsch_cqi_harq_ri_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.n_srs_initial = 0; // last symbol not punctured + ul_req_tmp_body->ul_config_pdu_list[ul_req_index].ulsch_cqi_harq_ri_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.initial_number_of_resource_blocks = + UE_template->nb_rb_ul[harq_pid]; + } else { + ul_req_tmp_body->ul_config_pdu_list[ul_req_index].pdu_type = NFAPI_UL_CONFIG_ULSCH_HARQ_PDU_TYPE; + ulsch_harq_information = &ul_req_tmp_body->ul_config_pdu_list[ul_req_index].ulsch_harq_pdu.harq_information; + ul_req_tmp_body->ul_config_pdu_list[ul_req_index].ulsch_harq_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.tl.tag = + NFAPI_UL_CONFIG_REQUEST_INITIAL_TRANSMISSION_PARAMETERS_REL8_TAG; + ul_req_tmp_body->ul_config_pdu_list[ul_req_index].ulsch_harq_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.n_srs_initial = 0; // last symbol not punctured + ul_req_tmp_body->ul_config_pdu_list[ul_req_index].ulsch_harq_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.initial_number_of_resource_blocks = + UE_template->nb_rb_ul[harq_pid]; } - mac->ul_handle++; + fill_nfapi_ulsch_harq_information(module_idP, CC_id,rnti, ulsch_harq_information,subframeP); + } else { + ul_req_tmp_body->number_of_pdus++; + } - ul_req_tmp_body->tl.tag = NFAPI_UL_CONFIG_REQUEST_BODY_TAG; + mac->ul_handle++; + ul_req_tmp_body->tl.tag = NFAPI_UL_CONFIG_REQUEST_BODY_TAG; + ul_req_tmp->sfn_sf = sched_frame<<4|sched_subframeP; + ul_req_tmp->header.message_id = NFAPI_UL_CONFIG_REQUEST; + LOG_D(MAC,"[PUSCH %d] Frame %d, Subframe %d: Adding UL CONFIG.Request for UE %d/%x, ulsch_frame %d, ulsch_subframe %d cqi_req %d\n", + harq_pid,frameP,subframeP,UE_id,rnti,sched_frame,sched_subframeP,cqi_req); + } /* - ul_req_tmp->sfn_sf = sched_frame<<4|sched_subframeP; - ul_req_tmp->header.message_id = NFAPI_UL_CONFIG_REQUEST; + else if (round > 0) { //we schedule a retransmission - LOG_D(MAC,"[PUSCH %d] Frame %d, Subframe %d: Adding UL CONFIG.Request for UE %d/%x, ulsch_frame %d, ulsch_subframe %d cqi_req %d\n", - harq_pid,frameP,subframeP,UE_id,rnti,sched_frame,sched_subframeP,cqi_req); - } /* - else if (round > 0) { //we schedule a retransmission + ndi = UE_template->oldNDI_UL[harq_pid]; - ndi = UE_template->oldNDI_UL[harq_pid]; + if ((round&3)==0) { + mcs = openair_daq_vars.target_ue_ul_mcs; + } else { + mcs = rvidx_tab[round&3] + 28; //not correct for round==4! - if ((round&3)==0) { - mcs = openair_daq_vars.target_ue_ul_mcs; - } else { - mcs = rvidx_tab[round&3] + 28; //not correct for round==4! + } - } + LOG_I(MAC,"[eNB %d][PUSCH %d/%x] CC_id %d Frame %d subframeP %d Scheduled UE retransmission (mcs %d, first rb %d, nb_rb %d, harq_pid %d, round %d)\n", + module_idP,UE_id,rnti,CC_id,frameP,subframeP,mcs, + first_rb[CC_id],UE_template->nb_rb_ul[harq_pid], + harq_pid, round); - LOG_I(MAC,"[eNB %d][PUSCH %d/%x] CC_id %d Frame %d subframeP %d Scheduled UE retransmission (mcs %d, first rb %d, nb_rb %d, harq_pid %d, round %d)\n", - module_idP,UE_id,rnti,CC_id,frameP,subframeP,mcs, - first_rb[CC_id],UE_template->nb_rb_ul[harq_pid], - harq_pid, round); + rballoc = mac_xface->computeRIV(frame_parms->N_RB_UL, + first_rb[CC_id], + UE_template->nb_rb_ul[harq_pid]); + first_rb[CC_id]+=UE_template->nb_rb_ul[harq_pid]; // increment for next UE allocation - rballoc = mac_xface->computeRIV(frame_parms->N_RB_UL, - first_rb[CC_id], - UE_template->nb_rb_ul[harq_pid]); - first_rb[CC_id]+=UE_template->nb_rb_ul[harq_pid]; // increment for next UE allocation - - UE_list->eNB_UE_stats[CC_id][UE_id].num_retransmission_rx+=1; - UE_list->eNB_UE_stats[CC_id][UE_id].rbs_used_retx_rx=UE_template->nb_rb_ul[harq_pid]; - UE_list->eNB_UE_stats[CC_id][UE_id].total_rbs_used_rx+=UE_template->nb_rb_ul[harq_pid]; - UE_list->eNB_UE_stats[CC_id][UE_id].ulsch_mcs1=mcs; - UE_list->eNB_UE_stats[CC_id][UE_id].ulsch_mcs2=mcs; - } - */ - - } // UE_is_to_be_scheduled - } // loop over UE_id - } // loop of CC_id + UE_list->eNB_UE_stats[CC_id][UE_id].num_retransmission_rx+=1; + UE_list->eNB_UE_stats[CC_id][UE_id].rbs_used_retx_rx=UE_template->nb_rb_ul[harq_pid]; + UE_list->eNB_UE_stats[CC_id][UE_id].total_rbs_used_rx+=UE_template->nb_rb_ul[harq_pid]; + UE_list->eNB_UE_stats[CC_id][UE_id].ulsch_mcs1=mcs; + UE_list->eNB_UE_stats[CC_id][UE_id].ulsch_mcs2=mcs; + } + */ + } // UE_is_to_be_scheduled + } // loop over UE_id + } // loop of CC_id } diff --git a/openair2/RRC/LTE/L2_interface.c b/openair2/RRC/LTE/L2_interface.c index db3d7947fb..4265a841e9 100644 --- a/openair2/RRC/LTE/L2_interface.c +++ b/openair2/RRC/LTE/L2_interface.c @@ -38,7 +38,7 @@ #include "common/ran_context.h" #if defined(ENABLE_ITTI) -# include "intertask_interface.h" + #include "intertask_interface.h" #endif #include "flexran_agent_extern.h" @@ -54,7 +54,7 @@ mac_rrc_data_req( const frame_t frameP, const rb_id_t Srb_id, const uint8_t Nb_tb, - uint8_t* const buffer_pP, + uint8_t *const buffer_pP, const uint8_t mbsfn_sync_area ) //-------------------------------------------------------------------------- @@ -64,7 +64,6 @@ mac_rrc_data_req( uint8_t Sdu_size = 0; uint8_t sfn = (uint8_t)((frameP>>2)&0xff); - if (LOG_DEBUGFLAG(DEBUG_RRC)) { LOG_D(RRC,"[eNB %d] mac_rrc_data_req to SRB ID=%d\n",Mod_idP,Srb_id); } @@ -72,156 +71,151 @@ mac_rrc_data_req( eNB_RRC_INST *rrc; rrc_eNB_carrier_data_t *carrier; LTE_BCCH_BCH_Message_t *mib; + rrc = RC.rrc[Mod_idP]; + carrier = &rrc->carrier[0]; + mib = &carrier->mib; - - rrc = RC.rrc[Mod_idP]; - carrier = &rrc->carrier[0]; - mib = &carrier->mib; - - if((Srb_id & RAB_OFFSET) == BCCH) { - if(RC.rrc[Mod_idP]->carrier[CC_id].SI.Active==0) { - return 0; - } - - // All even frames transmit SIB in SF 5 - AssertFatal(RC.rrc[Mod_idP]->carrier[CC_id].sizeof_SIB1 != 255, - "[eNB %d] MAC Request for SIB1 and SIB1 not initialized\n",Mod_idP); - - if ((frameP%2) == 0) { - memcpy(&buffer_pP[0], - RC.rrc[Mod_idP]->carrier[CC_id].SIB1, - RC.rrc[Mod_idP]->carrier[CC_id].sizeof_SIB1); - - if (LOG_DEBUGFLAG(DEBUG_RRC)) { - LOG_T(RRC,"[eNB %d] Frame %d : BCCH request => SIB 1\n",Mod_idP,frameP); - - for (int i=0; icarrier[CC_id].sizeof_SIB1; i++) { - LOG_T(RRC,"%x.",buffer_pP[i]); - } - - LOG_T(RRC,"\n"); - } /* LOG_DEBUGFLAG(DEBUG_RRC) */ - - return (RC.rrc[Mod_idP]->carrier[CC_id].sizeof_SIB1); - } // All RFN mod 8 transmit SIB2-3 in SF 5 - else if ((frameP%8) == 1) { - memcpy(&buffer_pP[0], - RC.rrc[Mod_idP]->carrier[CC_id].SIB23, - RC.rrc[Mod_idP]->carrier[CC_id].sizeof_SIB23); - - if (LOG_DEBUGFLAG(DEBUG_RRC)) { - LOG_T(RRC,"[eNB %d] Frame %d BCCH request => SIB 2-3\n",Mod_idP,frameP); - - for (int i=0; icarrier[CC_id].sizeof_SIB23; i++) { - LOG_T(RRC,"%x.",buffer_pP[i]); - } - - LOG_T(RRC,"\n"); - } /* LOG_DEBUGFLAG(DEBUG_RRC) */ - return(RC.rrc[Mod_idP]->carrier[CC_id].sizeof_SIB23); - } else { - return(0); - } - } - if( (Srb_id & RAB_OFFSET ) == MIBCH) { - - mib->message.systemFrameNumber.buf = &sfn; - enc_rval = uper_encode_to_buffer(&asn_DEF_LTE_BCCH_BCH_Message, - NULL, - (void*)mib, - carrier->MIB, - 24); - LOG_D(RRC,"Encoded MIB for frame %d (%p), bits %lu\n",sfn,carrier->MIB,enc_rval.encoded); - buffer_pP[0]=carrier->MIB[0]; - buffer_pP[1]=carrier->MIB[1]; - buffer_pP[2]=carrier->MIB[2]; - AssertFatal (enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %lu)!\n", - enc_rval.failed_type->name, enc_rval.encoded); - return(3); + if((Srb_id & RAB_OFFSET) == BCCH) { + if(RC.rrc[Mod_idP]->carrier[CC_id].SI.Active==0) { + return 0; } - if( (Srb_id & RAB_OFFSET ) == CCCH) { - LOG_T(RRC,"[eNB %d] Frame %d CCCH request (Srb_id %d)\n",Mod_idP,frameP, Srb_id); + // All even frames transmit SIB in SF 5 + AssertFatal(RC.rrc[Mod_idP]->carrier[CC_id].sizeof_SIB1 != 255, + "[eNB %d] MAC Request for SIB1 and SIB1 not initialized\n",Mod_idP); - if(RC.rrc[Mod_idP]->carrier[CC_id].Srb0.Active==0) { - LOG_E(RRC,"[eNB %d] CCCH Not active\n",Mod_idP); - return -1; - } + if ((frameP%2) == 0) { + memcpy(&buffer_pP[0], + RC.rrc[Mod_idP]->carrier[CC_id].SIB1, + RC.rrc[Mod_idP]->carrier[CC_id].sizeof_SIB1); - Srb_info=&RC.rrc[Mod_idP]->carrier[CC_id].Srb0; + if (LOG_DEBUGFLAG(DEBUG_RRC)) { + LOG_T(RRC,"[eNB %d] Frame %d : BCCH request => SIB 1\n",Mod_idP,frameP); - // check if data is there for MAC - if(Srb_info->Tx_buffer.payload_size>0) { //Fill buffer - LOG_D(RRC,"[eNB %d] CCCH (%p) has %d bytes (dest: %p, src %p)\n",Mod_idP,Srb_info,Srb_info->Tx_buffer.payload_size,buffer_pP,Srb_info->Tx_buffer.Payload); + for (int i=0; icarrier[CC_id].sizeof_SIB1; i++) { + LOG_T(RRC,"%x.",buffer_pP[i]); + } - memcpy(buffer_pP,Srb_info->Tx_buffer.Payload,Srb_info->Tx_buffer.payload_size); - Sdu_size = Srb_info->Tx_buffer.payload_size; - Srb_info->Tx_buffer.payload_size=0; - } + LOG_T(RRC,"\n"); + } /* LOG_DEBUGFLAG(DEBUG_RRC) */ - return (Sdu_size); + return (RC.rrc[Mod_idP]->carrier[CC_id].sizeof_SIB1); + } // All RFN mod 8 transmit SIB2-3 in SF 5 + else if ((frameP%8) == 1) { + memcpy(&buffer_pP[0], + RC.rrc[Mod_idP]->carrier[CC_id].SIB23, + RC.rrc[Mod_idP]->carrier[CC_id].sizeof_SIB23); + + if (LOG_DEBUGFLAG(DEBUG_RRC)) { + LOG_T(RRC,"[eNB %d] Frame %d BCCH request => SIB 2-3\n",Mod_idP,frameP); + + for (int i=0; icarrier[CC_id].sizeof_SIB23; i++) { + LOG_T(RRC,"%x.",buffer_pP[i]); + } + + LOG_T(RRC,"\n"); + } /* LOG_DEBUGFLAG(DEBUG_RRC) */ + + return(RC.rrc[Mod_idP]->carrier[CC_id].sizeof_SIB23); + } else { + return(0); + } + } + + if( (Srb_id & RAB_OFFSET ) == MIBCH) { + mib->message.systemFrameNumber.buf = &sfn; + enc_rval = uper_encode_to_buffer(&asn_DEF_LTE_BCCH_BCH_Message, + NULL, + (void *)mib, + carrier->MIB, + 24); + LOG_D(RRC,"Encoded MIB for frame %d (%p), bits %lu\n",sfn,carrier->MIB,enc_rval.encoded); + buffer_pP[0]=carrier->MIB[0]; + buffer_pP[1]=carrier->MIB[1]; + buffer_pP[2]=carrier->MIB[2]; + AssertFatal (enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %lu)!\n", + enc_rval.failed_type->name, enc_rval.encoded); + return(3); + } + + if( (Srb_id & RAB_OFFSET ) == CCCH) { + LOG_T(RRC,"[eNB %d] Frame %d CCCH request (Srb_id %d)\n",Mod_idP,frameP, Srb_id); + + if(RC.rrc[Mod_idP]->carrier[CC_id].Srb0.Active==0) { + LOG_E(RRC,"[eNB %d] CCCH Not active\n",Mod_idP); + return -1; } - if( (Srb_id & RAB_OFFSET ) == PCCH) { - LOG_T(RRC,"[eNB %d] Frame %d PCCH request (Srb_id %d)\n",Mod_idP,frameP, Srb_id); + Srb_info=&RC.rrc[Mod_idP]->carrier[CC_id].Srb0; - // check if data is there for MAC - if(RC.rrc[Mod_idP]->carrier[CC_id].sizeof_paging[mbsfn_sync_area] > 0) { //Fill buffer - LOG_D(RRC,"[eNB %d] PCCH (%p) has %d bytes\n",Mod_idP,&RC.rrc[Mod_idP]->carrier[CC_id].paging[mbsfn_sync_area], - RC.rrc[Mod_idP]->carrier[CC_id].sizeof_paging[mbsfn_sync_area]); - - memcpy(buffer_pP, RC.rrc[Mod_idP]->carrier[CC_id].paging[mbsfn_sync_area], RC.rrc[Mod_idP]->carrier[CC_id].sizeof_paging[mbsfn_sync_area]); - Sdu_size = RC.rrc[Mod_idP]->carrier[CC_id].sizeof_paging[mbsfn_sync_area]; - RC.rrc[Mod_idP]->carrier[CC_id].sizeof_paging[mbsfn_sync_area] = 0; - } - - return (Sdu_size); + // check if data is there for MAC + if(Srb_info->Tx_buffer.payload_size>0) { //Fill buffer + LOG_D(RRC,"[eNB %d] CCCH (%p) has %d bytes (dest: %p, src %p)\n",Mod_idP,Srb_info,Srb_info->Tx_buffer.payload_size,buffer_pP,Srb_info->Tx_buffer.Payload); + memcpy(buffer_pP,Srb_info->Tx_buffer.Payload,Srb_info->Tx_buffer.payload_size); + Sdu_size = Srb_info->Tx_buffer.payload_size; + Srb_info->Tx_buffer.payload_size=0; } + return (Sdu_size); + } + + if( (Srb_id & RAB_OFFSET ) == PCCH) { + LOG_T(RRC,"[eNB %d] Frame %d PCCH request (Srb_id %d)\n",Mod_idP,frameP, Srb_id); + + // check if data is there for MAC + if(RC.rrc[Mod_idP]->carrier[CC_id].sizeof_paging[mbsfn_sync_area] > 0) { //Fill buffer + LOG_D(RRC,"[eNB %d] PCCH (%p) has %d bytes\n",Mod_idP,&RC.rrc[Mod_idP]->carrier[CC_id].paging[mbsfn_sync_area], + RC.rrc[Mod_idP]->carrier[CC_id].sizeof_paging[mbsfn_sync_area]); + memcpy(buffer_pP, RC.rrc[Mod_idP]->carrier[CC_id].paging[mbsfn_sync_area], RC.rrc[Mod_idP]->carrier[CC_id].sizeof_paging[mbsfn_sync_area]); + Sdu_size = RC.rrc[Mod_idP]->carrier[CC_id].sizeof_paging[mbsfn_sync_area]; + RC.rrc[Mod_idP]->carrier[CC_id].sizeof_paging[mbsfn_sync_area] = 0; + } + + return (Sdu_size); + } + #if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) - if((Srb_id & RAB_OFFSET) == MCCH) { - if(RC.rrc[Mod_idP]->carrier[CC_id].MCCH_MESS[mbsfn_sync_area].Active==0) { - return 0; // this parameter is set in function init_mcch in rrc_eNB.c + if((Srb_id & RAB_OFFSET) == MCCH) { + if(RC.rrc[Mod_idP]->carrier[CC_id].MCCH_MESS[mbsfn_sync_area].Active==0) { + return 0; // this parameter is set in function init_mcch in rrc_eNB.c + } + + memcpy(&buffer_pP[0], + RC.rrc[Mod_idP]->carrier[CC_id].MCCH_MESSAGE[mbsfn_sync_area], + RC.rrc[Mod_idP]->carrier[CC_id].sizeof_MCCH_MESSAGE[mbsfn_sync_area]); + + if (LOG_DEBUGFLAG(DEBUG_RRC)) { + LOG_D(RRC,"[eNB %d] Frame %d : MCCH request => MCCH_MESSAGE \n",Mod_idP,frameP); + + for (int i=0; icarrier[CC_id].sizeof_MCCH_MESSAGE[mbsfn_sync_area]; i++) { + LOG_T(RRC,"%x.",buffer_pP[i]); } - memcpy(&buffer_pP[0], - RC.rrc[Mod_idP]->carrier[CC_id].MCCH_MESSAGE[mbsfn_sync_area], - RC.rrc[Mod_idP]->carrier[CC_id].sizeof_MCCH_MESSAGE[mbsfn_sync_area]); + LOG_T(RRC,"\n"); + } /* LOG_DEBUGFLAG(DEBUG_RRC) */ - if (LOG_DEBUGFLAG(DEBUG_RRC)) { - LOG_D(RRC,"[eNB %d] Frame %d : MCCH request => MCCH_MESSAGE \n",Mod_idP,frameP); - - for (int i=0; icarrier[CC_id].sizeof_MCCH_MESSAGE[mbsfn_sync_area]; i++) { - LOG_T(RRC,"%x.",buffer_pP[i]); - } - - LOG_T(RRC,"\n"); - } /* LOG_DEBUGFLAG(DEBUG_RRC) */ - - return (RC.rrc[Mod_idP]->carrier[CC_id].sizeof_MCCH_MESSAGE[mbsfn_sync_area]); - } + return (RC.rrc[Mod_idP]->carrier[CC_id].sizeof_MCCH_MESSAGE[mbsfn_sync_area]); + } #endif // #if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) - #if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) - if ((Srb_id & RAB_OFFSET) == BCCH_SIB1_BR){ - memcpy(&buffer_pP[0], - RC.rrc[Mod_idP]->carrier[CC_id].SIB1_BR, - RC.rrc[Mod_idP]->carrier[CC_id].sizeof_SIB1_BR); - return (RC.rrc[Mod_idP]->carrier[CC_id].sizeof_SIB1_BR); - } - if ((Srb_id & RAB_OFFSET) == BCCH_SI_BR){ // First SI message with SIB2/3 - memcpy(&buffer_pP[0], - RC.rrc[Mod_idP]->carrier[CC_id].SIB23_BR, - RC.rrc[Mod_idP]->carrier[CC_id].sizeof_SIB23_BR); - return (RC.rrc[Mod_idP]->carrier[CC_id].sizeof_SIB23_BR); - } + if ((Srb_id & RAB_OFFSET) == BCCH_SIB1_BR) { + memcpy(&buffer_pP[0], + RC.rrc[Mod_idP]->carrier[CC_id].SIB1_BR, + RC.rrc[Mod_idP]->carrier[CC_id].sizeof_SIB1_BR); + return (RC.rrc[Mod_idP]->carrier[CC_id].sizeof_SIB1_BR); + } + + if ((Srb_id & RAB_OFFSET) == BCCH_SI_BR) { // First SI message with SIB2/3 + memcpy(&buffer_pP[0], + RC.rrc[Mod_idP]->carrier[CC_id].SIB23_BR, + RC.rrc[Mod_idP]->carrier[CC_id].sizeof_SIB23_BR); + return (RC.rrc[Mod_idP]->carrier[CC_id].sizeof_SIB23_BR); + } #endif - - return(0); } @@ -234,7 +228,7 @@ mac_rrc_data_ind( const sub_frame_t sub_frameP, const rnti_t rntiP, const rb_id_t srb_idP, - const uint8_t* sduP, + const uint8_t *sduP, const sdu_size_t sdu_lenP, const uint8_t mbsfn_sync_areaP ) @@ -243,39 +237,38 @@ mac_rrc_data_ind( SRB_INFO *Srb_info; protocol_ctxt_t ctxt; sdu_size_t sdu_size = 0; - /* for no gcc warnings */ (void)sdu_size; - /* int si_window; */ PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, module_idP, ENB_FLAG_YES, rntiP, frameP, sub_frameP,0); - if((srb_idP & RAB_OFFSET) == CCCH) { + if((srb_idP & RAB_OFFSET) == CCCH) { Srb_info = &RC.rrc[module_idP]->carrier[CC_id].Srb0; LOG_D(RRC,"[eNB %d] Received SDU for CCCH on SRB %d\n",module_idP,Srb_info->Srb_id); - + // msg("\n******INST %d Srb_info %p, Srb_id=%d****\n\n",Mod_id,Srb_info,Srb_info->Srb_id); if (sdu_lenP > 0) { memcpy(Srb_info->Rx_buffer.Payload,sduP,sdu_lenP); Srb_info->Rx_buffer.payload_size = sdu_lenP; rrc_eNB_decode_ccch(&ctxt, Srb_info, CC_id); } + } + + if((srb_idP & RAB_OFFSET) == DCCH) { + struct rrc_eNB_ue_context_s *ue_context_p = NULL; + ue_context_p = rrc_eNB_get_ue_context(RC.rrc[ctxt.module_id],rntiP); + + if(ue_context_p) { + rrc_eNB_generate_defaultRRCConnectionReconfiguration(&ctxt, + ue_context_p, + 0); + ue_context_p->ue_context.Status = RRC_RECONFIGURED; } - if((srb_idP & RAB_OFFSET) == DCCH) { - struct rrc_eNB_ue_context_s* ue_context_p = NULL; - ue_context_p = rrc_eNB_get_ue_context(RC.rrc[ctxt.module_id],rntiP); - if(ue_context_p){ - rrc_eNB_generate_defaultRRCConnectionReconfiguration(&ctxt, - ue_context_p, - 0); - ue_context_p->ue_context.Status = RRC_RECONFIGURED; - } - } + } return(0); - } //------------------------------------------------------------------------------ @@ -289,7 +282,7 @@ mac_eNB_get_rrc_status( ) //------------------------------------------------------------------------------ { - struct rrc_eNB_ue_context_s* ue_context_p = NULL; + struct rrc_eNB_ue_context_s *ue_context_p = NULL; ue_context_p = rrc_eNB_get_ue_context(RC.rrc[Mod_idP], rntiP); if (ue_context_p != NULL) { @@ -300,60 +293,59 @@ mac_eNB_get_rrc_status( } void mac_eNB_rrc_ul_failure(const module_id_t Mod_instP, - const int CC_idP, - const frame_t frameP, - const sub_frame_t subframeP, - const rnti_t rntiP) -{ - struct rrc_eNB_ue_context_s* ue_context_p = NULL; + const int CC_idP, + const frame_t frameP, + const sub_frame_t subframeP, + const rnti_t rntiP) { + struct rrc_eNB_ue_context_s *ue_context_p = NULL; ue_context_p = rrc_eNB_get_ue_context( RC.rrc[Mod_instP], rntiP); if (ue_context_p != NULL) { LOG_I(RRC,"Frame %d, Subframe %d: UE %x UL failure, activating timer\n",frameP,subframeP,rntiP); + if(ue_context_p->ue_context.ul_failure_timer == 0) ue_context_p->ue_context.ul_failure_timer=1; - } - else { + } else { LOG_W(RRC,"Frame %d, Subframe %d: UL failure: UE %x unknown \n",frameP,subframeP,rntiP); } + if (rrc_agent_registered[Mod_instP]) { agent_rrc_xface[Mod_instP]->flexran_agent_notify_ue_state_change(Mod_instP, - rntiP, - PROTOCOL__FLEX_UE_STATE_CHANGE_TYPE__FLUESC_DEACTIVATED); + rntiP, + PROTOCOL__FLEX_UE_STATE_CHANGE_TYPE__FLUESC_DEACTIVATED); } + rrc_mac_remove_ue(Mod_instP,rntiP); } void mac_eNB_rrc_uplane_failure(const module_id_t Mod_instP, - const int CC_idP, - const frame_t frameP, - const sub_frame_t subframeP, - const rnti_t rntiP) -{ - struct rrc_eNB_ue_context_s* ue_context_p = NULL; - ue_context_p = rrc_eNB_get_ue_context( - RC.rrc[Mod_instP], - rntiP); - if (ue_context_p != NULL) { - LOG_I(RRC,"Frame %d, Subframe %d: UE %x U-Plane failure, activating timer\n",frameP,subframeP,rntiP); + const int CC_idP, + const frame_t frameP, + const sub_frame_t subframeP, + const rnti_t rntiP) { + struct rrc_eNB_ue_context_s *ue_context_p = NULL; + ue_context_p = rrc_eNB_get_ue_context( + RC.rrc[Mod_instP], + rntiP); - if(ue_context_p->ue_context.ul_failure_timer == 0) - ue_context_p->ue_context.ul_failure_timer=19999; - } - else { - LOG_W(RRC,"Frame %d, Subframe %d: U-Plane failure: UE %x unknown \n",frameP,subframeP,rntiP); - } + if (ue_context_p != NULL) { + LOG_I(RRC,"Frame %d, Subframe %d: UE %x U-Plane failure, activating timer\n",frameP,subframeP,rntiP); + + if(ue_context_p->ue_context.ul_failure_timer == 0) + ue_context_p->ue_context.ul_failure_timer=19999; + } else { + LOG_W(RRC,"Frame %d, Subframe %d: U-Plane failure: UE %x unknown \n",frameP,subframeP,rntiP); + } } -void mac_eNB_rrc_ul_in_sync(const module_id_t Mod_instP, - const int CC_idP, - const frame_t frameP, - const sub_frame_t subframeP, - const rnti_t rntiP) -{ - struct rrc_eNB_ue_context_s* ue_context_p = NULL; +void mac_eNB_rrc_ul_in_sync(const module_id_t Mod_instP, + const int CC_idP, + const frame_t frameP, + const sub_frame_t subframeP, + const rnti_t rntiP) { + struct rrc_eNB_ue_context_s *ue_context_p = NULL; ue_context_p = rrc_eNB_get_ue_context( RC.rrc[Mod_instP], rntiP); diff --git a/openair2/RRC/LTE/MESSAGES/asn1_msg.c b/openair2/RRC/LTE/MESSAGES/asn1_msg.c index 566661bd20..f0248f34be 100644 --- a/openair2/RRC/LTE/MESSAGES/asn1_msg.c +++ b/openair2/RRC/LTE/MESSAGES/asn1_msg.c @@ -53,8 +53,8 @@ #include "LTE_SRB-ToAddModList.h" #include "LTE_DRB-ToAddModList.h" #if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) -#include "LTE_MCCH-Message.h" -//#define MRB1 1 + #include "LTE_MCCH-Message.h" + //#define MRB1 1 #endif #include "RRC/LTE/rrc_defs.h" @@ -81,14 +81,14 @@ #include "enb_config.h" #if defined(ENABLE_ITTI) -# include "intertask_interface.h" + #include "intertask_interface.h" #endif #include "common/ran_context.h" #include "secu_defs.h" #if !defined (msg) -#define msg printf + #define msg printf #endif @@ -117,8 +117,7 @@ uint16_t two_tier_hexagonal_adjacent_cellIds[7][6] = {{1,2,4,5,7,8}, // CellI * This is a helper function for xer_sprint, which directs all incoming data * into the provided string. */ -static int xer__print2s (const void *buffer, size_t size, void *app_key) -{ +static int xer__print2s (const void *buffer, size_t size, void *app_key) { xer_sprint_string_t *string_buffer = (xer_sprint_string_t *) app_key; size_t string_remaining = string_buffer->string_size - string_buffer->string_index; @@ -134,15 +133,12 @@ static int xer__print2s (const void *buffer, size_t size, void *app_key) return 0; } -int xer_sprint (char *string, size_t string_size, asn_TYPE_descriptor_t *td, void *sptr) -{ +int xer_sprint (char *string, size_t string_size, asn_TYPE_descriptor_t *td, void *sptr) { asn_enc_rval_t er; xer_sprint_string_t string_buffer; - string_buffer.string = string; string_buffer.string_size = string_size; string_buffer.string_index = 0; - er = xer_encode(td, sptr, XER_F_BASIC, xer__print2s, &string_buffer); if (er.encoded < 0) { @@ -158,14 +154,12 @@ int xer_sprint (char *string, size_t string_size, asn_TYPE_descriptor_t *td, voi return er.encoded; } -uint16_t get_adjacent_cell_id(uint8_t Mod_id,uint8_t index) -{ +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 */ -uint8_t get_adjacent_cell_mod_id(uint16_t phyCellId) -{ +uint8_t get_adjacent_cell_mod_id(uint16_t phyCellId) { uint8_t i; for(i=0; i<7; i++) { @@ -178,17 +172,15 @@ uint8_t get_adjacent_cell_mod_id(uint16_t phyCellId) return 0xFF; //error! } -uint8_t do_MIB(rrc_eNB_carrier_data_t *carrier, uint32_t N_RB_DL, uint32_t phich_Resource, uint32_t phich_duration, uint32_t frame) -{ - +uint8_t do_MIB(rrc_eNB_carrier_data_t *carrier, uint32_t N_RB_DL, uint32_t phich_Resource, uint32_t phich_duration, uint32_t frame) { asn_enc_rval_t enc_rval; LTE_BCCH_BCH_Message_t *mib=&carrier->mib ; uint8_t sfn = (uint8_t)((frame>>2)&0xff); uint16_t *spare = calloc(1, sizeof(uint16_t)); + if (spare == NULL) abort(); switch (N_RB_DL) { - case 6: mib->message.dl_Bandwidth = LTE_MasterInformationBlock__dl_Bandwidth_n6; break; @@ -212,6 +204,7 @@ uint8_t do_MIB(rrc_eNB_carrier_data_t *carrier, uint32_t N_RB_DL, uint32_t phich case 100: mib->message.dl_Bandwidth = LTE_MasterInformationBlock__dl_Bandwidth_n100; break; + default: AssertFatal(1==0,"Unknown dl_Bandwidth %d\n",N_RB_DL); } @@ -221,11 +214,10 @@ uint8_t do_MIB(rrc_eNB_carrier_data_t *carrier, uint32_t N_RB_DL, uint32_t phich AssertFatal(phich_duration <= LTE_PHICH_Config__phich_Duration_extended,"Illegal phich_Duration\n"); mib->message.phich_Config.phich_Duration = phich_duration; LOG_I(RRC,"[MIB] systemBandwidth %x, phich_duration %x, phich_resource %x, sfn %x\n", - (uint32_t)mib->message.dl_Bandwidth, - (uint32_t)phich_duration, - (uint32_t)phich_Resource, - (uint32_t)sfn); - + (uint32_t)mib->message.dl_Bandwidth, + (uint32_t)phich_duration, + (uint32_t)phich_Resource, + (uint32_t)sfn); mib->message.systemFrameNumber.buf = &sfn; mib->message.systemFrameNumber.size = 1; mib->message.systemFrameNumber.bits_unused=0; @@ -238,18 +230,17 @@ uint8_t do_MIB(rrc_eNB_carrier_data_t *carrier, uint32_t N_RB_DL, uint32_t phich mib->message.spare.bits_unused = 3; // This makes a spare of 5 bits mib->message.schedulingInfoSIB1_BR_r13 = 0; // turn off eMTC #endif - enc_rval = uper_encode_to_buffer(&asn_DEF_LTE_BCCH_BCH_Message, NULL, - (void*)mib, + (void *)mib, carrier->MIB, 24); AssertFatal (enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %lu)!\n", enc_rval.failed_type->name, enc_rval.encoded); /* -#if defined(ENABLE_ITTI) -# if !defined(DISABLE_XER_SPRINT) + #if defined(ENABLE_ITTI) + # if !defined(DISABLE_XER_SPRINT) { char message_string[20000]; size_t message_string_size; @@ -264,8 +255,8 @@ uint8_t do_MIB(rrc_eNB_carrier_data_t *carrier, uint32_t N_RB_DL, uint32_t phich itti_send_msg_to_task(TASK_UNKNOWN, enb_module_idP, msg_p); } } -# endif -#endif + # endif + #endif */ if (enc_rval.encoded==-1) { return(-1); @@ -276,58 +267,55 @@ uint8_t do_MIB(rrc_eNB_carrier_data_t *carrier, uint32_t N_RB_DL, uint32_t phich //TTN for D2D // 3GPP 36.331 (Section 5.10.7.4) -uint8_t do_MIB_SL(const protocol_ctxt_t* const ctxt_pP, const uint8_t eNB_index, uint32_t frame, uint8_t subframe, uint8_t in_coverage, uint8_t mode) -{ +uint8_t do_MIB_SL(const protocol_ctxt_t *const ctxt_pP, const uint8_t eNB_index, uint32_t frame, uint8_t subframe, uint8_t in_coverage, uint8_t mode) { + asn_enc_rval_t enc_rval; + LTE_SBCCH_SL_BCH_MessageType_t *mib_sl = &UE_rrc_inst[ctxt_pP->module_id].mib_sl[eNB_index]; + uint8_t sfn = (uint8_t)((frame>>2)&0xff); + UE_rrc_inst[ctxt_pP->module_id].MIB = (uint8_t *) malloc16(4); - asn_enc_rval_t enc_rval; - LTE_SBCCH_SL_BCH_MessageType_t *mib_sl = &UE_rrc_inst[ctxt_pP->module_id].mib_sl[eNB_index]; - uint8_t sfn = (uint8_t)((frame>>2)&0xff); - UE_rrc_inst[ctxt_pP->module_id].MIB = (uint8_t*) malloc16(4); + if (in_coverage > 0 ) { + //in coverage + mib_sl->inCoverage_r12 = TRUE; + mib_sl->sl_Bandwidth_r12 = *UE_rrc_inst[ctxt_pP->module_id].sib2[eNB_index]->freqInfo.ul_Bandwidth; - if (in_coverage > 0 ){ - //in coverage - mib_sl->inCoverage_r12 = TRUE; - mib_sl->sl_Bandwidth_r12 = *UE_rrc_inst[ctxt_pP->module_id].sib2[eNB_index]->freqInfo.ul_Bandwidth; - if (UE_rrc_inst[ctxt_pP->module_id].sib1[eNB_index]->tdd_Config) { - mib_sl->tdd_ConfigSL_r12.subframeAssignmentSL_r12 = UE_rrc_inst[ctxt_pP->module_id].sib1[eNB_index]->tdd_Config->subframeAssignment; - } else { - mib_sl->tdd_ConfigSL_r12.subframeAssignmentSL_r12 = LTE_TDD_ConfigSL_r12__subframeAssignmentSL_r12_none; - } - //if triggered by sl communication - if (UE_rrc_inst[ctxt_pP->module_id].sib18[eNB_index]->commConfig_r12->commSyncConfig_r12->list.array[0]->txParameters_r12->syncInfoReserved_r12){ - mib_sl->reserved_r12 = *UE_rrc_inst[ctxt_pP->module_id].sib18[eNB_index]->commConfig_r12->commSyncConfig_r12->list.array[0]->txParameters_r12->syncInfoReserved_r12; - } - //if triggered by sl discovery - if (UE_rrc_inst[ctxt_pP->module_id].sib19[eNB_index]->discConfig_r12->discSyncConfig_r12->list.array[0]->txParameters_r12->syncInfoReserved_r12){ - mib_sl->reserved_r12 = *UE_rrc_inst[ctxt_pP->module_id].sib19[eNB_index]->discConfig_r12->discSyncConfig_r12->list.array[0]->txParameters_r12->syncInfoReserved_r12; - } - //Todo - if triggered by v2x - } else { - //Todo - out of coverage for V2X - // Todo - UE has a selected SyncRef UE - mib_sl->inCoverage_r12 = FALSE; - //set sl-Bandwidth, subframeAssignmentSL and reserved from the pre-configured parameters - } + if (UE_rrc_inst[ctxt_pP->module_id].sib1[eNB_index]->tdd_Config) { + mib_sl->tdd_ConfigSL_r12.subframeAssignmentSL_r12 = UE_rrc_inst[ctxt_pP->module_id].sib1[eNB_index]->tdd_Config->subframeAssignment; + } else { + mib_sl->tdd_ConfigSL_r12.subframeAssignmentSL_r12 = LTE_TDD_ConfigSL_r12__subframeAssignmentSL_r12_none; + } - //set FrameNumber, subFrameNumber - mib_sl->directFrameNumber_r12.buf = &sfn; - mib_sl->directFrameNumber_r12.size = 1; - mib_sl->directFrameNumber_r12.bits_unused=0; - mib_sl->directSubframeNumber_r12 = subframe; + //if triggered by sl communication + if (UE_rrc_inst[ctxt_pP->module_id].sib18[eNB_index]->commConfig_r12->commSyncConfig_r12->list.array[0]->txParameters_r12->syncInfoReserved_r12) { + mib_sl->reserved_r12 = *UE_rrc_inst[ctxt_pP->module_id].sib18[eNB_index]->commConfig_r12->commSyncConfig_r12->list.array[0]->txParameters_r12->syncInfoReserved_r12; + } + //if triggered by sl discovery + if (UE_rrc_inst[ctxt_pP->module_id].sib19[eNB_index]->discConfig_r12->discSyncConfig_r12->list.array[0]->txParameters_r12->syncInfoReserved_r12) { + mib_sl->reserved_r12 = *UE_rrc_inst[ctxt_pP->module_id].sib19[eNB_index]->discConfig_r12->discSyncConfig_r12->list.array[0]->txParameters_r12->syncInfoReserved_r12; + } + //Todo - if triggered by v2x + } else { + //Todo - out of coverage for V2X + // Todo - UE has a selected SyncRef UE + mib_sl->inCoverage_r12 = FALSE; + //set sl-Bandwidth, subframeAssignmentSL and reserved from the pre-configured parameters + } + + //set FrameNumber, subFrameNumber + mib_sl->directFrameNumber_r12.buf = &sfn; + mib_sl->directFrameNumber_r12.size = 1; + mib_sl->directFrameNumber_r12.bits_unused=0; + mib_sl->directSubframeNumber_r12 = subframe; LOG_I(RRC,"[MIB-SL] sfn %x, subframe %x\n", (uint32_t)sfn, (uint8_t)subframe); - - enc_rval = uper_encode_to_buffer(&asn_DEF_LTE_SBCCH_SL_BCH_Message, NULL, - (void*)mib_sl, + (void *)mib_sl, UE_rrc_inst[ctxt_pP->module_id].MIB, 24); AssertFatal (enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %lu)!\n", enc_rval.failed_type->name, enc_rval.encoded); - if (enc_rval.encoded==-1) { return(-1); } @@ -337,13 +325,11 @@ uint8_t do_MIB_SL(const protocol_ctxt_t* const ctxt_pP, const uint8_t eNB_index, uint8_t do_SIB1(rrc_eNB_carrier_data_t *carrier, - int Mod_id,int CC_id + int Mod_id,int CC_id #if defined(ENABLE_ITTI) - , RrcConfigurationReq *configuration + , RrcConfigurationReq *configuration #endif - ) -{ - + ) { // SystemInformation_t systemInformation; #if defined(ENABLE_ITTI) int num_plmn = configuration->num_plmn; @@ -355,20 +341,15 @@ uint8_t do_SIB1(rrc_eNB_carrier_data_t *carrier, asn_enc_rval_t enc_rval; LTE_SchedulingInfo_t schedulingInfo; LTE_SIB_Type_t sib_type; - uint8_t *buffer = carrier->SIB1; LTE_BCCH_DL_SCH_Message_t *bcch_message = &carrier->siblock1; LTE_SystemInformationBlockType1_t **sib1 = &carrier->sib1; int i; - - memset(bcch_message,0,sizeof(LTE_BCCH_DL_SCH_Message_t)); bcch_message->message.present = LTE_BCCH_DL_SCH_MessageType_PR_c1; bcch_message->message.choice.c1.present = LTE_BCCH_DL_SCH_MessageType__c1_PR_systemInformationBlockType1; // memcpy(&bcch_message.message.choice.c1.choice.systemInformationBlockType1,sib1,sizeof(SystemInformationBlockType1_t)); - *sib1 = &bcch_message->message.choice.c1.choice.systemInformationBlockType1; - memset(PLMN_identity_info,0,num_plmn * sizeof(LTE_PLMN_IdentityInfo_t)); memset(&schedulingInfo,0,sizeof(LTE_SchedulingInfo_t)); memset(&sib_type,0,sizeof(LTE_SIB_Type_t)); @@ -377,9 +358,7 @@ uint8_t do_SIB1(rrc_eNB_carrier_data_t *carrier, for (i = 0; i < configuration->num_plmn; ++i) { PLMN_identity_info[i].plmn_Identity.mcc = CALLOC(1,sizeof(*PLMN_identity_info[i].plmn_Identity.mcc)); memset(PLMN_identity_info[i].plmn_Identity.mcc,0,sizeof(*PLMN_identity_info[i].plmn_Identity.mcc)); - asn_set_empty(&PLMN_identity_info[i].plmn_Identity.mcc->list);//.size=0; - #if defined(ENABLE_ITTI) dummy_mcc[i][0] = (configuration->mcc[i] / 100) % 10; dummy_mcc[i][1] = (configuration->mcc[i] / 10) % 10; @@ -392,7 +371,6 @@ uint8_t do_SIB1(rrc_eNB_carrier_data_t *carrier, ASN_SEQUENCE_ADD(&PLMN_identity_info[i].plmn_Identity.mcc->list,&dummy_mcc[i][0]); ASN_SEQUENCE_ADD(&PLMN_identity_info[i].plmn_Identity.mcc->list,&dummy_mcc[i][1]); ASN_SEQUENCE_ADD(&PLMN_identity_info[i].plmn_Identity.mcc->list,&dummy_mcc[i][2]); - PLMN_identity_info[i].plmn_Identity.mnc.list.size=0; PLMN_identity_info[i].plmn_Identity.mnc.list.count=0; #if defined(ENABLE_ITTI) @@ -427,11 +405,9 @@ uint8_t do_SIB1(rrc_eNB_carrier_data_t *carrier, //assign_enum(&PLMN_identity_info.cellReservedForOperatorUse,PLMN_IdentityInfo__cellReservedForOperatorUse_notReserved); PLMN_identity_info[i].cellReservedForOperatorUse=LTE_PLMN_IdentityInfo__cellReservedForOperatorUse_notReserved; - ASN_SEQUENCE_ADD(&(*sib1)->cellAccessRelatedInfo.plmn_IdentityList.list,&PLMN_identity_info[i]); } - // 16 bits (*sib1)->cellAccessRelatedInfo.trackingAreaCode.buf = MALLOC(2); #if defined(ENABLE_ITTI) @@ -443,7 +419,6 @@ uint8_t do_SIB1(rrc_eNB_carrier_data_t *carrier, #endif (*sib1)->cellAccessRelatedInfo.trackingAreaCode.size=2; (*sib1)->cellAccessRelatedInfo.trackingAreaCode.bits_unused=0; - // 28 bits (*sib1)->cellAccessRelatedInfo.cellIdentity.buf = MALLOC(8); #if defined(ENABLE_ITTI) @@ -459,14 +434,11 @@ uint8_t do_SIB1(rrc_eNB_carrier_data_t *carrier, #endif (*sib1)->cellAccessRelatedInfo.cellIdentity.size=4; (*sib1)->cellAccessRelatedInfo.cellIdentity.bits_unused=4; - // assign_enum(&(*sib1)->cellAccessRelatedInfo.cellBarred,SystemInformationBlockType1__cellAccessRelatedInfo__cellBarred_notBarred); (*sib1)->cellAccessRelatedInfo.cellBarred=LTE_SystemInformationBlockType1__cellAccessRelatedInfo__cellBarred_notBarred; - // assign_enum(&(*sib1)->cellAccessRelatedInfo.intraFreqReselection,SystemInformationBlockType1__cellAccessRelatedInfo__intraFreqReselection_allowed); (*sib1)->cellAccessRelatedInfo.intraFreqReselection=LTE_SystemInformationBlockType1__cellAccessRelatedInfo__intraFreqReselection_notAllowed; (*sib1)->cellAccessRelatedInfo.csg_Indication=0; - (*sib1)->cellSelectionInfo.q_RxLevMin=-65; (*sib1)->cellSelectionInfo.q_RxLevMinOffset=NULL; //(*sib1)->p_Max = CALLOC(1, sizeof(P_Max_t)); @@ -477,53 +449,45 @@ uint8_t do_SIB1(rrc_eNB_carrier_data_t *carrier, #else 7; #endif - schedulingInfo.si_Periodicity=LTE_SchedulingInfo__si_Periodicity_rf8; - // This is for SIB2/3 sib_type=LTE_SIB_Type_sibType3; ASN_SEQUENCE_ADD(&schedulingInfo.sib_MappingInfo.list,&sib_type); ASN_SEQUENCE_ADD(&(*sib1)->schedulingInfoList.list,&schedulingInfo); - // ASN_SEQUENCE_ADD(&schedulingInfo.sib_MappingInfo.list,NULL); - #if defined(ENABLE_ITTI) if (configuration->frame_type[CC_id] == TDD) #endif { (*sib1)->tdd_Config = CALLOC(1,sizeof(struct LTE_TDD_Config)); - (*sib1)->tdd_Config->subframeAssignment = #if defined(ENABLE_ITTI) configuration->tdd_config[CC_id]; #else 3; #endif - (*sib1)->tdd_Config->specialSubframePatterns = #if defined(ENABLE_ITTI) configuration->tdd_config_s[CC_id]; #else - 0; + 0; #endif } (*sib1)->si_WindowLength=LTE_SystemInformationBlockType1__si_WindowLength_ms20; (*sib1)->systemInfoValueTag=0; // (*sib1).nonCriticalExtension = calloc(1,sizeof(*(*sib1).nonCriticalExtension)); - #ifdef XER_PRINT - xer_fprint(stdout, &asn_DEF_BCCH_DL_SCH_Message, (void*)bcch_message); + xer_fprint(stdout, &asn_DEF_BCCH_DL_SCH_Message, (void *)bcch_message); #endif enc_rval = uper_encode_to_buffer(&asn_DEF_LTE_BCCH_DL_SCH_Message, NULL, - (void*)bcch_message, + (void *)bcch_message, buffer, 100); AssertFatal (enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %lu)!\n", enc_rval.failed_type->name, enc_rval.encoded); - #if defined(ENABLE_ITTI) # if !defined(DISABLE_XER_SPRINT) { @@ -532,7 +496,6 @@ uint8_t do_SIB1(rrc_eNB_carrier_data_t *carrier, if ((message_string_size = xer_sprint(message_string, sizeof(message_string), &asn_DEF_LTE_BCCH_DL_SCH_Message, (void *)bcch_message)) > 0) { MessageDef *msg_p; - msg_p = itti_alloc_new_message_sized (TASK_RRC_ENB, RRC_DL_BCCH, message_string_size + sizeof (IttiMsgText)); msg_p->ittiMsg.rrc_dl_bcch.size = message_string_size; memcpy(&msg_p->ittiMsg.rrc_dl_bcch.text, message_string, message_string_size); @@ -541,7 +504,6 @@ uint8_t do_SIB1(rrc_eNB_carrier_data_t *carrier, } # endif #endif - LOG_D(RRC,"[eNB] SystemInformationBlockType1 Encoded %zd bits (%zd bytes)\n",enc_rval.encoded,(enc_rval.encoded+7)/8); if (enc_rval.encoded==-1) { @@ -555,13 +517,10 @@ uint8_t do_SIB23(uint8_t Mod_id, int CC_id #if defined(ENABLE_ITTI) - , RrcConfigurationReq *configuration + , RrcConfigurationReq *configuration #endif - ) -{ - + ) { struct LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member *sib2_part,*sib3_part; - #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) //TTN - for D2D struct LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member *sib18_part, *sib19_part, *sib21_part; @@ -573,7 +532,6 @@ uint8_t do_SIB23(uint8_t Mod_id, //struct SL_DiscResourcePool_r12 *SL_DiscResourcePoolPS; //for SIB19 (discRxPoolPS) //struct SL_V2X_ConfigCommon_r14 *SL_V2X_ConfigCommon; #endif - #if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) struct LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member *sib13_part; LTE_MBSFN_SubframeConfigList_t *MBSFNSubframeConfigList; @@ -581,7 +539,6 @@ uint8_t do_SIB23(uint8_t Mod_id, struct LTE_MBSFN_AreaInfo_r9 *MBSFN_Area1, *MBSFN_Area2; #endif asn_enc_rval_t enc_rval; - uint8_t *buffer = RC.rrc[Mod_id]->carrier[CC_id].SIB23; LTE_BCCH_DL_SCH_Message_t *bcch_message = &RC.rrc[Mod_id]->carrier[CC_id].systemInformation; LTE_SystemInformationBlockType2_t **sib2 = &RC.rrc[Mod_id]->carrier[CC_id].sib2; @@ -590,7 +547,6 @@ uint8_t do_SIB23(uint8_t Mod_id, LTE_SystemInformationBlockType13_r9_t **sib13 = &RC.rrc[Mod_id]->carrier[CC_id].sib13; uint8_t MBMS_flag = RC.rrc[Mod_id]->carrier[CC_id].MBMS_flag; #endif - #if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) //TTN - for D2D LTE_SystemInformationBlockType18_r12_t **sib18 = &RC.rrc[Mod_id]->carrier[CC_id].sib18; @@ -624,13 +580,10 @@ uint8_t do_SIB23(uint8_t Mod_id, sib3_part = CALLOC(1,sizeof(struct LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member)); memset(sib2_part,0,sizeof(struct LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member)); memset(sib3_part,0,sizeof(struct LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member)); - sib2_part->present = LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib2; sib3_part->present = LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib3; - *sib2 = &sib2_part->choice.sib2; *sib3 = &sib3_part->choice.sib3; - #if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) if (MBMS_flag > 0) { @@ -641,7 +594,6 @@ uint8_t do_SIB23(uint8_t Mod_id, } #endif - #if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) //TTN - for D2D sib18_part = CALLOC(1,sizeof(struct LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member)); @@ -650,28 +602,20 @@ uint8_t do_SIB23(uint8_t Mod_id, memset(sib18_part,0,sizeof(struct LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member)); memset(sib19_part,0,sizeof(struct LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member)); memset(sib21_part,0,sizeof(struct LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member)); - sib18_part->present = LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib18_v1250; sib19_part->present = LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib19_v1250; sib21_part->present = LTE_SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib21_v1430; - *sib18 = &sib18_part->choice.sib18_v1250; *sib19 = &sib19_part->choice.sib19_v1250; *sib21 = &sib21_part->choice.sib21_v1430; - #endif - - // sib2 - (*sib2)->ac_BarringInfo = NULL; #if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) (*sib2)->ext1 = NULL; (*sib2)->ext2 = NULL; #endif - #if defined(ENABLE_ITTI) - (*sib2)->radioResourceConfigCommon.rach_ConfigCommon.preambleInfo.numberOfRA_Preambles = configuration->rach_numberOfRA_Preambles[CC_id]; (*sib2)->radioResourceConfigCommon.rach_ConfigCommon.preambleInfo.preamblesGroupAConfig = NULL; @@ -694,20 +638,17 @@ uint8_t do_SIB23(uint8_t Mod_id, (*sib2)->radioResourceConfigCommon.rach_ConfigCommon.ra_SupervisionInfo.mac_ContentionResolutionTimer = configuration->rach_macContentionResolutionTimer[CC_id]; (*sib2)->radioResourceConfigCommon.rach_ConfigCommon.maxHARQ_Msg3Tx = configuration->rach_maxHARQ_Msg3Tx[CC_id]; - // BCCH-Config (*sib2)->radioResourceConfigCommon.bcch_Config.modificationPeriodCoeff = configuration->bcch_modificationPeriodCoeff[CC_id]; - // PCCH-Config (*sib2)->radioResourceConfigCommon.pcch_Config.defaultPagingCycle = configuration->pcch_defaultPagingCycle[CC_id]; (*sib2)->radioResourceConfigCommon.pcch_Config.nB = configuration->pcch_nB[CC_id]; LOG_I(RRC,"[SIB2] With ITTI. Basic config of paging cycle DRX: radio frame cycle length %x, paging occasion number %x\n", - (uint32_t)configuration->pcch_defaultPagingCycle[CC_id], - (uint32_t)configuration->pcch_nB[CC_id]); - + (uint32_t)configuration->pcch_defaultPagingCycle[CC_id], + (uint32_t)configuration->pcch_nB[CC_id]); // PRACH-Config (*sib2)->radioResourceConfigCommon.prach_Config.rootSequenceIndex = configuration->prach_root[CC_id]; @@ -719,13 +660,11 @@ uint8_t do_SIB23(uint8_t Mod_id, = configuration->prach_zero_correlation[CC_id]; (*sib2)->radioResourceConfigCommon.prach_Config.prach_ConfigInfo.prach_FreqOffset = configuration->prach_freq_offset[CC_id]; - // PDSCH-Config (*sib2)->radioResourceConfigCommon.pdsch_ConfigCommon.referenceSignalPower = configuration->pdsch_referenceSignalPower[CC_id]; (*sib2)->radioResourceConfigCommon.pdsch_ConfigCommon.p_b = configuration->pdsch_p_b[CC_id]; - // PUSCH-Config (*sib2)->radioResourceConfigCommon.pusch_ConfigCommon.pusch_ConfigBasic.n_SB = configuration->pusch_n_SB[CC_id]; @@ -743,19 +682,17 @@ uint8_t do_SIB23(uint8_t Mod_id, = configuration->pusch_sequenceHoppingEnabled[CC_id]; (*sib2)->radioResourceConfigCommon.pusch_ConfigCommon.ul_ReferenceSignalsPUSCH.cyclicShift = configuration->pusch_nDMRS1[CC_id]; - // PUCCH-Config - (*sib2)->radioResourceConfigCommon.pucch_ConfigCommon.deltaPUCCH_Shift = configuration->pucch_delta_shift[CC_id]; (*sib2)->radioResourceConfigCommon.pucch_ConfigCommon.nRB_CQI = configuration->pucch_nRB_CQI[CC_id]; (*sib2)->radioResourceConfigCommon.pucch_ConfigCommon.nCS_AN = configuration->pucch_nCS_AN[CC_id]; -//#if (LTE_RRC_VERSION < MAKE_VERSION(10, 0, 0)) + //#if (LTE_RRC_VERSION < MAKE_VERSION(10, 0, 0)) (*sib2)->radioResourceConfigCommon.pucch_ConfigCommon.n1PUCCH_AN = configuration->pucch_n1_AN[CC_id]; -//#endif + //#endif // SRS Config if (configuration->srs_enable[CC_id]==1) { @@ -775,6 +712,7 @@ uint8_t do_SIB23(uint8_t Mod_id, } else { (*sib2)->radioResourceConfigCommon.soundingRS_UL_ConfigCommon.choice.setup.srs_MaxUpPts = NULL; } + RC.rrc[Mod_id]->srs_enable[CC_id] = 1; } else { RC.rrc[Mod_id]->srs_enable[CC_id] = 0; @@ -783,7 +721,6 @@ uint8_t do_SIB23(uint8_t Mod_id, } // uplinkPowerControlCommon - (*sib2)->radioResourceConfigCommon.uplinkPowerControlCommon.p0_NominalPUSCH = configuration->pusch_p0_Nominal[CC_id]; (*sib2)->radioResourceConfigCommon.uplinkPowerControlCommon.p0_NominalPUCCH @@ -804,9 +741,7 @@ uint8_t do_SIB23(uint8_t Mod_id, = configuration->msg3_delta_Preamble[CC_id]; (*sib2)->radioResourceConfigCommon.ul_CyclicPrefixLength = configuration->ul_CyclicPrefixLength[CC_id]; - // UE Timers and Constants - (*sib2)->ue_TimersAndConstants.t300 = configuration->ue_TimersAndConstants_t300[CC_id]; (*sib2)->ue_TimersAndConstants.t301 @@ -819,7 +754,6 @@ uint8_t do_SIB23(uint8_t Mod_id, = configuration->ue_TimersAndConstants_t311[CC_id]; (*sib2)->ue_TimersAndConstants.n311 = configuration->ue_TimersAndConstants_n311[CC_id]; - #else (*sib2)->radioResourceConfigCommon.rach_ConfigCommon.preambleInfo.numberOfRA_Preambles=LTE_RACH_ConfigCommon__preambleInfo__numberOfRA_Preambles_n64; (*sib2)->radioResourceConfigCommon.rach_ConfigCommon.preambleInfo.preamblesGroupAConfig = NULL; @@ -831,27 +765,20 @@ uint8_t do_SIB23(uint8_t Mod_id, (*sib2)->radioResourceConfigCommon.rach_ConfigCommon.ra_SupervisionInfo.mac_ContentionResolutionTimer= LTE_RACH_ConfigCommon__ra_SupervisionInfo__mac_ContentionResolutionTimer_sf48; (*sib2)->radioResourceConfigCommon.rach_ConfigCommon.maxHARQ_Msg3Tx = 4; - // BCCH-Config (*sib2)->radioResourceConfigCommon.bcch_Config.modificationPeriodCoeff=BCCH_Config__modificationPeriodCoeff_n2; - // PCCH-Config (*sib2)->radioResourceConfigCommon.pcch_Config.defaultPagingCycle = LTE_PCCH_Config__defaultPagingCycle_rf128; (*sib2)->radioResourceConfigCommon.pcch_Config.nB=LTE_PCCH_Config__nB_oneT; - // PRACH-Config (*sib2)->radioResourceConfigCommon.prach_Config.rootSequenceIndex=Mod_id;//0;//384; (*sib2)->radioResourceConfigCommon.prach_Config.prach_ConfigInfo.prach_ConfigIndex = 0;//3; (*sib2)->radioResourceConfigCommon.prach_Config.prach_ConfigInfo.highSpeedFlag = 0; (*sib2)->radioResourceConfigCommon.prach_Config.prach_ConfigInfo.zeroCorrelationZoneConfig = 1;//12; (*sib2)->radioResourceConfigCommon.prach_Config.prach_ConfigInfo.prach_FreqOffset = 2; - // PDSCH-Config (*sib2)->radioResourceConfigCommon.pdsch_ConfigCommon.referenceSignalPower=0; // corresponds to 24.7 dBm 5 MHz/ 27.7 10 MHz/ 30.7 20 MHz - - (*sib2)->radioResourceConfigCommon.pdsch_ConfigCommon.p_b=0; - // PUSCH-Config (*sib2)->radioResourceConfigCommon.pusch_ConfigCommon.pusch_ConfigBasic.n_SB=1; (*sib2)->radioResourceConfigCommon.pusch_ConfigCommon.pusch_ConfigBasic.hoppingMode=LTE_PUSCH_ConfigCommon__pusch_ConfigBasic__hoppingMode_interSubFrame; @@ -861,55 +788,35 @@ uint8_t do_SIB23(uint8_t Mod_id, (*sib2)->radioResourceConfigCommon.pusch_ConfigCommon.ul_ReferenceSignalsPUSCH.groupAssignmentPUSCH=0; (*sib2)->radioResourceConfigCommon.pusch_ConfigCommon.ul_ReferenceSignalsPUSCH.sequenceHoppingEnabled=0; (*sib2)->radioResourceConfigCommon.pusch_ConfigCommon.ul_ReferenceSignalsPUSCH.cyclicShift=0; - // PUCCH-Config - (*sib2)->radioResourceConfigCommon.pucch_ConfigCommon.deltaPUCCH_Shift=LTE_PUCCH_ConfigCommon__deltaPUCCH_Shift_ds1; (*sib2)->radioResourceConfigCommon.pucch_ConfigCommon.nRB_CQI = 1; (*sib2)->radioResourceConfigCommon.pucch_ConfigCommon.nCS_AN = 0; (*sib2)->radioResourceConfigCommon.pucch_ConfigCommon.n1PUCCH_AN = 32; - - (*sib2)->radioResourceConfigCommon.soundingRS_UL_ConfigCommon.present=LTE_SoundingRS_UL_ConfigCommon_PR_release; (*sib2)->radioResourceConfigCommon.soundingRS_UL_ConfigCommon.choice.release=0; - // uplinkPowerControlCommon - (*sib2)->radioResourceConfigCommon.uplinkPowerControlCommon.p0_NominalPUSCH = -108; (*sib2)->radioResourceConfigCommon.uplinkPowerControlCommon.p0_NominalPUCCH = -108; (*sib2)->radioResourceConfigCommon.uplinkPowerControlCommon.alpha=LTE_UplinkPowerControlCommon__alpha_al1; (*sib2)->radioResourceConfigCommon.uplinkPowerControlCommon.deltaFList_PUCCH.deltaF_PUCCH_Format1=LTE_DeltaFList_PUCCH__deltaF_PUCCH_Format1_deltaF2; (*sib2)->radioResourceConfigCommon.uplinkPowerControlCommon.deltaFList_PUCCH.deltaF_PUCCH_Format1b=LTE_DeltaFList_PUCCH__deltaF_PUCCH_Format1b_deltaF3; - (*sib2)->radioResourceConfigCommon.uplinkPowerControlCommon.deltaFList_PUCCH.deltaF_PUCCH_Format2=LTE_DeltaFList_PUCCH__deltaF_PUCCH_Format2_deltaF0; - (*sib2)->radioResourceConfigCommon.uplinkPowerControlCommon.deltaFList_PUCCH.deltaF_PUCCH_Format2a=LTE_DeltaFList_PUCCH__deltaF_PUCCH_Format2a_deltaF0; - (*sib2)->radioResourceConfigCommon.uplinkPowerControlCommon.deltaFList_PUCCH.deltaF_PUCCH_Format2b=LTE_DeltaFList_PUCCH__deltaF_PUCCH_Format2b_deltaF0; - (*sib2)->radioResourceConfigCommon.uplinkPowerControlCommon.deltaPreambleMsg3 = 6; - (*sib2)->radioResourceConfigCommon.ul_CyclicPrefixLength=UL_CyclicPrefixLength_len1; - (*sib2)->ue_TimersAndConstants.t300=UE_TimersAndConstants__t300_ms1000; - (*sib2)->ue_TimersAndConstants.t301=UE_TimersAndConstants__t301_ms1000; - (*sib2)->ue_TimersAndConstants.t310=UE_TimersAndConstants__t310_ms1000; - (*sib2)->ue_TimersAndConstants.n310=UE_TimersAndConstants__n310_n20; - (*sib2)->ue_TimersAndConstants.t311=UE_TimersAndConstants__t311_ms10000; - (*sib2)->ue_TimersAndConstants.n311=UE_TimersAndConstants__n311_n1; - #endif - (*sib2)->freqInfo.additionalSpectrumEmission = 1; (*sib2)->freqInfo.ul_CarrierFreq = NULL; (*sib2)->freqInfo.ul_Bandwidth = NULL; // (*sib2)->mbsfn_SubframeConfigList = NULL; - #if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) if (MBMS_flag > 0) { @@ -917,37 +824,29 @@ uint8_t do_SIB23(uint8_t Mod_id, LTE_MBSFN_SubframeConfig_t *sib2_mbsfn_SubframeConfig1; (*sib2)->mbsfn_SubframeConfigList = CALLOC(1,sizeof(struct LTE_MBSFN_SubframeConfigList)); MBSFNSubframeConfigList = (*sib2)->mbsfn_SubframeConfigList; - sib2_mbsfn_SubframeConfig1= CALLOC(1,sizeof(*sib2_mbsfn_SubframeConfig1)); - memset((void*)sib2_mbsfn_SubframeConfig1,0,sizeof(*sib2_mbsfn_SubframeConfig1)); - + memset((void *)sib2_mbsfn_SubframeConfig1,0,sizeof(*sib2_mbsfn_SubframeConfig1)); sib2_mbsfn_SubframeConfig1->radioframeAllocationPeriod= LTE_MBSFN_SubframeConfig__radioframeAllocationPeriod_n4; sib2_mbsfn_SubframeConfig1->radioframeAllocationOffset= 1; sib2_mbsfn_SubframeConfig1->subframeAllocation.present= LTE_MBSFN_SubframeConfig__subframeAllocation_PR_oneFrame; sib2_mbsfn_SubframeConfig1->subframeAllocation.choice.oneFrame.buf= MALLOC(1); sib2_mbsfn_SubframeConfig1->subframeAllocation.choice.oneFrame.size= 1; sib2_mbsfn_SubframeConfig1->subframeAllocation.choice.oneFrame.bits_unused= 2; - sib2_mbsfn_SubframeConfig1->subframeAllocation.choice.oneFrame.buf[0]=0x38<<2; - ASN_SEQUENCE_ADD(&MBSFNSubframeConfigList->list,sib2_mbsfn_SubframeConfig1); if (MBMS_flag == 4 ) { LOG_I(RRC,"Adding MBSFN subframe Configuration 2 to SIB2\n"); LTE_MBSFN_SubframeConfig_t *sib2_mbsfn_SubframeConfig2; sib2_mbsfn_SubframeConfig2= CALLOC(1,sizeof(*sib2_mbsfn_SubframeConfig2)); - memset((void*)sib2_mbsfn_SubframeConfig2,0,sizeof(*sib2_mbsfn_SubframeConfig2)); - + memset((void *)sib2_mbsfn_SubframeConfig2,0,sizeof(*sib2_mbsfn_SubframeConfig2)); sib2_mbsfn_SubframeConfig2->radioframeAllocationPeriod= LTE_MBSFN_SubframeConfig__radioframeAllocationPeriod_n4; sib2_mbsfn_SubframeConfig2->radioframeAllocationOffset= 1; sib2_mbsfn_SubframeConfig2->subframeAllocation.present= LTE_MBSFN_SubframeConfig__subframeAllocation_PR_oneFrame; sib2_mbsfn_SubframeConfig2->subframeAllocation.choice.oneFrame.buf= MALLOC(1); sib2_mbsfn_SubframeConfig2->subframeAllocation.choice.oneFrame.size= 1; sib2_mbsfn_SubframeConfig2->subframeAllocation.choice.oneFrame.bits_unused= 2; - sib2_mbsfn_SubframeConfig2->subframeAllocation.choice.oneFrame.buf[0]=0x07<<2; - - ASN_SEQUENCE_ADD(&MBSFNSubframeConfigList->list,sib2_mbsfn_SubframeConfig2); } } @@ -955,29 +854,22 @@ uint8_t do_SIB23(uint8_t Mod_id, #else // no MBMS transmission (*sib2)->mbsfn_SubframeConfigList = NULL; #endif - (*sib2)->timeAlignmentTimerCommon=LTE_TimeAlignmentTimer_infinity;//TimeAlignmentTimer_sf5120; - /// (*SIB3) #if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) (*sib3)->ext1 = NULL; #endif (*sib3)->cellReselectionInfoCommon.q_Hyst=LTE_SystemInformationBlockType3__cellReselectionInfoCommon__q_Hyst_dB4; - (*sib3)->cellReselectionInfoCommon.speedStateReselectionPars=NULL; - (*sib3)->cellReselectionServingFreqInfo.s_NonIntraSearch=NULL; (*sib3)->cellReselectionServingFreqInfo.threshServingLow=31; (*sib3)->cellReselectionServingFreqInfo.cellReselectionPriority=7; - (*sib3)->intraFreqCellReselectionInfo.q_RxLevMin = -70; (*sib3)->intraFreqCellReselectionInfo.p_Max = NULL; (*sib3)->intraFreqCellReselectionInfo.s_IntraSearch = CALLOC(1,sizeof(*(*sib3)->intraFreqCellReselectionInfo.s_IntraSearch)); *(*sib3)->intraFreqCellReselectionInfo.s_IntraSearch = 31; (*sib3)->intraFreqCellReselectionInfo.allowedMeasBandwidth=CALLOC(1,sizeof(*(*sib3)->intraFreqCellReselectionInfo.allowedMeasBandwidth)); - *(*sib3)->intraFreqCellReselectionInfo.allowedMeasBandwidth = LTE_AllowedMeasBandwidth_mbw6; - (*sib3)->intraFreqCellReselectionInfo.presenceAntennaPort1 = 0; (*sib3)->intraFreqCellReselectionInfo.neighCellConfig.buf = CALLOC(8,1); (*sib3)->intraFreqCellReselectionInfo.neighCellConfig.size = 1; @@ -985,7 +877,6 @@ uint8_t do_SIB23(uint8_t Mod_id, (*sib3)->intraFreqCellReselectionInfo.neighCellConfig.bits_unused = 6; (*sib3)->intraFreqCellReselectionInfo.t_ReselectionEUTRA = 1; (*sib3)->intraFreqCellReselectionInfo.t_ReselectionEUTRA_SF = (struct LTE_SpeedStateScaleFactors *)NULL; - // SIB13 // fill in all elements of SIB13 if present #if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) @@ -995,7 +886,6 @@ uint8_t do_SIB23(uint8_t Mod_id, (*sib13)->notificationConfig_r9.notificationRepetitionCoeff_r9= LTE_MBMS_NotificationConfig_r9__notificationRepetitionCoeff_r9_n2; (*sib13)->notificationConfig_r9.notificationOffset_r9= 0; (*sib13)->notificationConfig_r9.notificationSF_Index_r9= 1; - // MBSFN-AreaInfoList MBSFNArea_list= &(*sib13)->mbsfn_AreaInfoList_r9;//CALLOC(1,sizeof(*MBSFNArea_list)); memset(MBSFNArea_list,0,sizeof(*MBSFNArea_list)); @@ -1010,14 +900,9 @@ uint8_t do_SIB23(uint8_t Mod_id, // Subframe Allocation Info MBSFN_Area1->mcch_Config_r9.sf_AllocInfo_r9.buf= MALLOC(1); MBSFN_Area1->mcch_Config_r9.sf_AllocInfo_r9.size= 1; - MBSFN_Area1->mcch_Config_r9.sf_AllocInfo_r9.buf[0]=0x20<<2; // FDD: SF1 - - MBSFN_Area1->mcch_Config_r9.sf_AllocInfo_r9.bits_unused= 2; - MBSFN_Area1->mcch_Config_r9.signallingMCS_r9= LTE_MBSFN_AreaInfo_r9__mcch_Config_r9__signallingMCS_r9_n7; - ASN_SEQUENCE_ADD(&MBSFNArea_list->list,MBSFN_Area1); //MBSFN Area 2: currently only activated for eMBMS relaying @@ -1033,12 +918,8 @@ uint8_t do_SIB23(uint8_t Mod_id, MBSFN_Area2->mcch_Config_r9.sf_AllocInfo_r9.buf= MALLOC(1); MBSFN_Area2->mcch_Config_r9.sf_AllocInfo_r9.size= 1; MBSFN_Area2->mcch_Config_r9.sf_AllocInfo_r9.bits_unused= 2; - MBSFN_Area2->mcch_Config_r9.sf_AllocInfo_r9.buf[0]=0x04<<2; // FDD: SF6 - - MBSFN_Area2->mcch_Config_r9.signallingMCS_r9= LTE_MBSFN_AreaInfo_r9__mcch_Config_r9__signallingMCS_r9_n7; - ASN_SEQUENCE_ADD(&MBSFNArea_list->list,MBSFN_Area2); } @@ -1046,8 +927,6 @@ uint8_t do_SIB23(uint8_t Mod_id, } #endif - - #if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) //TTN - for D2D // SIB18 @@ -1055,10 +934,8 @@ uint8_t do_SIB23(uint8_t Mod_id, (*sib18)->commConfig_r12 = CALLOC (1, sizeof(*(*sib18)->commConfig_r12)); SL_CommRxPoolList= &(*sib18)->commConfig_r12->commRxPool_r12; memset(SL_CommRxPoolList,0,sizeof(*SL_CommRxPoolList)); - SL_CommResourcePool = CALLOC(1, sizeof(*SL_CommResourcePool)); memset(SL_CommResourcePool,0,sizeof(*SL_CommResourcePool)); - SL_CommResourcePool->sc_CP_Len_r12 = configuration->rxPool_sc_CP_Len[CC_id]; SL_CommResourcePool->sc_Period_r12 = configuration->rxPool_sc_Period[CC_id]; SL_CommResourcePool->data_CP_Len_r12 = configuration->rxPool_data_CP_Len[CC_id]; @@ -1069,54 +946,54 @@ uint8_t do_SIB23(uint8_t Mod_id, SL_CommResourcePool->sc_TF_ResourceConfig_r12.offsetIndicator_r12.present = configuration->rxPool_ResourceConfig_offsetIndicator_present[CC_id]; if (SL_CommResourcePool->sc_TF_ResourceConfig_r12.offsetIndicator_r12.present == LTE_SL_OffsetIndicator_r12_PR_small_r12 ) { - SL_CommResourcePool->sc_TF_ResourceConfig_r12.offsetIndicator_r12.choice.small_r12 = configuration->rxPool_ResourceConfig_offsetIndicator_choice[CC_id] ; - } else if (SL_CommResourcePool->sc_TF_ResourceConfig_r12.offsetIndicator_r12.present == LTE_SL_OffsetIndicator_r12_PR_large_r12 ){ - SL_CommResourcePool->sc_TF_ResourceConfig_r12.offsetIndicator_r12.choice.large_r12 = configuration->rxPool_ResourceConfig_offsetIndicator_choice[CC_id] ; + SL_CommResourcePool->sc_TF_ResourceConfig_r12.offsetIndicator_r12.choice.small_r12 = configuration->rxPool_ResourceConfig_offsetIndicator_choice[CC_id] ; + } else if (SL_CommResourcePool->sc_TF_ResourceConfig_r12.offsetIndicator_r12.present == LTE_SL_OffsetIndicator_r12_PR_large_r12 ) { + SL_CommResourcePool->sc_TF_ResourceConfig_r12.offsetIndicator_r12.choice.large_r12 = configuration->rxPool_ResourceConfig_offsetIndicator_choice[CC_id] ; } SL_CommResourcePool->sc_TF_ResourceConfig_r12.subframeBitmap_r12.present = configuration->rxPool_ResourceConfig_subframeBitmap_present[CC_id]; - if (SL_CommResourcePool->sc_TF_ResourceConfig_r12.subframeBitmap_r12.present == LTE_SubframeBitmapSL_r12_PR_bs4_r12){ - //for BS4 - SL_CommResourcePool->sc_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs4_r12.size = configuration->rxPool_ResourceConfig_subframeBitmap_choice_bs_size[CC_id]; - SL_CommResourcePool->sc_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs4_r12.buf = (uint8_t *)configuration->rxPool_ResourceConfig_subframeBitmap_choice_bs_buf[CC_id];; - SL_CommResourcePool->sc_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs4_r12.bits_unused = configuration->rxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused[CC_id]; - } else if (SL_CommResourcePool->sc_TF_ResourceConfig_r12.subframeBitmap_r12.present == LTE_SubframeBitmapSL_r12_PR_bs8_r12){ - //for BS8 - SL_CommResourcePool->sc_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs8_r12.size = configuration->rxPool_ResourceConfig_subframeBitmap_choice_bs_size[CC_id]; - SL_CommResourcePool->sc_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs8_r12.buf = (uint8_t *)configuration->rxPool_ResourceConfig_subframeBitmap_choice_bs_buf[CC_id];; - SL_CommResourcePool->sc_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs8_r12.bits_unused = configuration->rxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused[CC_id]; - } else if (SL_CommResourcePool->sc_TF_ResourceConfig_r12.subframeBitmap_r12.present == LTE_SubframeBitmapSL_r12_PR_bs12_r12){ - //for BS12 - SL_CommResourcePool->sc_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs12_r12.size = configuration->rxPool_ResourceConfig_subframeBitmap_choice_bs_size[CC_id]; - SL_CommResourcePool->sc_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs12_r12.buf = (uint8_t *)configuration->rxPool_ResourceConfig_subframeBitmap_choice_bs_buf[CC_id];; - SL_CommResourcePool->sc_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs12_r12.bits_unused = configuration->rxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused[CC_id]; - }else if (SL_CommResourcePool->sc_TF_ResourceConfig_r12.subframeBitmap_r12.present == LTE_SubframeBitmapSL_r12_PR_bs16_r12){ - //for BS16 - SL_CommResourcePool->sc_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs16_r12.size = configuration->rxPool_ResourceConfig_subframeBitmap_choice_bs_size[CC_id]; - SL_CommResourcePool->sc_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs16_r12.buf = (uint8_t *)configuration->rxPool_ResourceConfig_subframeBitmap_choice_bs_buf[CC_id];; - SL_CommResourcePool->sc_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs16_r12.bits_unused = configuration->rxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused[CC_id]; - }else if (SL_CommResourcePool->sc_TF_ResourceConfig_r12.subframeBitmap_r12.present == LTE_SubframeBitmapSL_r12_PR_bs30_r12){ - //for BS30 - SL_CommResourcePool->sc_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs30_r12.size = configuration->rxPool_ResourceConfig_subframeBitmap_choice_bs_size[CC_id]; - SL_CommResourcePool->sc_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs30_r12.buf = (uint8_t *)configuration->rxPool_ResourceConfig_subframeBitmap_choice_bs_buf[CC_id];; - SL_CommResourcePool->sc_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs30_r12.bits_unused = configuration->rxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused[CC_id]; - }else if (SL_CommResourcePool->sc_TF_ResourceConfig_r12.subframeBitmap_r12.present == LTE_SubframeBitmapSL_r12_PR_bs40_r12){ - //for BS40 - SL_CommResourcePool->sc_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs40_r12.size = configuration->rxPool_ResourceConfig_subframeBitmap_choice_bs_size[CC_id]; - SL_CommResourcePool->sc_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs40_r12.buf = (uint8_t *)configuration->rxPool_ResourceConfig_subframeBitmap_choice_bs_buf[CC_id];; - SL_CommResourcePool->sc_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs40_r12.bits_unused = configuration->rxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused[CC_id]; - }else if (SL_CommResourcePool->sc_TF_ResourceConfig_r12.subframeBitmap_r12.present == LTE_SubframeBitmapSL_r12_PR_bs42_r12){ - //for BS42 - SL_CommResourcePool->sc_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs42_r12.size = configuration->rxPool_ResourceConfig_subframeBitmap_choice_bs_size[CC_id]; - SL_CommResourcePool->sc_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs42_r12.buf = (uint8_t *)configuration->rxPool_ResourceConfig_subframeBitmap_choice_bs_buf[CC_id];; - SL_CommResourcePool->sc_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs42_r12.bits_unused = configuration->rxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused[CC_id]; + + if (SL_CommResourcePool->sc_TF_ResourceConfig_r12.subframeBitmap_r12.present == LTE_SubframeBitmapSL_r12_PR_bs4_r12) { + //for BS4 + SL_CommResourcePool->sc_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs4_r12.size = configuration->rxPool_ResourceConfig_subframeBitmap_choice_bs_size[CC_id]; + SL_CommResourcePool->sc_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs4_r12.buf = (uint8_t *)configuration->rxPool_ResourceConfig_subframeBitmap_choice_bs_buf[CC_id];; + SL_CommResourcePool->sc_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs4_r12.bits_unused = configuration->rxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused[CC_id]; + } else if (SL_CommResourcePool->sc_TF_ResourceConfig_r12.subframeBitmap_r12.present == LTE_SubframeBitmapSL_r12_PR_bs8_r12) { + //for BS8 + SL_CommResourcePool->sc_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs8_r12.size = configuration->rxPool_ResourceConfig_subframeBitmap_choice_bs_size[CC_id]; + SL_CommResourcePool->sc_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs8_r12.buf = (uint8_t *)configuration->rxPool_ResourceConfig_subframeBitmap_choice_bs_buf[CC_id];; + SL_CommResourcePool->sc_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs8_r12.bits_unused = configuration->rxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused[CC_id]; + } else if (SL_CommResourcePool->sc_TF_ResourceConfig_r12.subframeBitmap_r12.present == LTE_SubframeBitmapSL_r12_PR_bs12_r12) { + //for BS12 + SL_CommResourcePool->sc_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs12_r12.size = configuration->rxPool_ResourceConfig_subframeBitmap_choice_bs_size[CC_id]; + SL_CommResourcePool->sc_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs12_r12.buf = (uint8_t *)configuration->rxPool_ResourceConfig_subframeBitmap_choice_bs_buf[CC_id];; + SL_CommResourcePool->sc_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs12_r12.bits_unused = configuration->rxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused[CC_id]; + } else if (SL_CommResourcePool->sc_TF_ResourceConfig_r12.subframeBitmap_r12.present == LTE_SubframeBitmapSL_r12_PR_bs16_r12) { + //for BS16 + SL_CommResourcePool->sc_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs16_r12.size = configuration->rxPool_ResourceConfig_subframeBitmap_choice_bs_size[CC_id]; + SL_CommResourcePool->sc_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs16_r12.buf = (uint8_t *)configuration->rxPool_ResourceConfig_subframeBitmap_choice_bs_buf[CC_id];; + SL_CommResourcePool->sc_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs16_r12.bits_unused = configuration->rxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused[CC_id]; + } else if (SL_CommResourcePool->sc_TF_ResourceConfig_r12.subframeBitmap_r12.present == LTE_SubframeBitmapSL_r12_PR_bs30_r12) { + //for BS30 + SL_CommResourcePool->sc_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs30_r12.size = configuration->rxPool_ResourceConfig_subframeBitmap_choice_bs_size[CC_id]; + SL_CommResourcePool->sc_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs30_r12.buf = (uint8_t *)configuration->rxPool_ResourceConfig_subframeBitmap_choice_bs_buf[CC_id];; + SL_CommResourcePool->sc_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs30_r12.bits_unused = configuration->rxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused[CC_id]; + } else if (SL_CommResourcePool->sc_TF_ResourceConfig_r12.subframeBitmap_r12.present == LTE_SubframeBitmapSL_r12_PR_bs40_r12) { + //for BS40 + SL_CommResourcePool->sc_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs40_r12.size = configuration->rxPool_ResourceConfig_subframeBitmap_choice_bs_size[CC_id]; + SL_CommResourcePool->sc_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs40_r12.buf = (uint8_t *)configuration->rxPool_ResourceConfig_subframeBitmap_choice_bs_buf[CC_id];; + SL_CommResourcePool->sc_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs40_r12.bits_unused = configuration->rxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused[CC_id]; + } else if (SL_CommResourcePool->sc_TF_ResourceConfig_r12.subframeBitmap_r12.present == LTE_SubframeBitmapSL_r12_PR_bs42_r12) { + //for BS42 + SL_CommResourcePool->sc_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs42_r12.size = configuration->rxPool_ResourceConfig_subframeBitmap_choice_bs_size[CC_id]; + SL_CommResourcePool->sc_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs42_r12.buf = (uint8_t *)configuration->rxPool_ResourceConfig_subframeBitmap_choice_bs_buf[CC_id];; + SL_CommResourcePool->sc_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs42_r12.bits_unused = configuration->rxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused[CC_id]; } //dataHoppingConfig_r12 SL_CommResourcePool->dataHoppingConfig_r12.hoppingParameter_r12 = 0; SL_CommResourcePool->dataHoppingConfig_r12.numSubbands_r12 = LTE_SL_HoppingConfigComm_r12__numSubbands_r12_ns1; SL_CommResourcePool->dataHoppingConfig_r12.rb_Offset_r12 = 0; - //ue_SelectedResourceConfig_r12 SL_CommResourcePool->ue_SelectedResourceConfig_r12 = CALLOC (1, sizeof (*SL_CommResourcePool->ue_SelectedResourceConfig_r12)); SL_CommResourcePool->ue_SelectedResourceConfig_r12->data_TF_ResourceConfig_r12.prb_Num_r12 = 20; @@ -1144,13 +1021,11 @@ uint8_t do_SIB23(uint8_t Mod_id, SL_CommResourcePool->txParameters_r12 = CALLOC (1, sizeof (*SL_CommResourcePool->txParameters_r12)); SL_CommResourcePool->txParameters_r12->sc_TxParameters_r12.alpha_r12 = LTE_Alpha_r12_al0; SL_CommResourcePool->txParameters_r12->sc_TxParameters_r12.p0_r12 = 0; - SL_CommResourcePool->ext1 = NULL ; //end SL_CommResourcePool //add SL_CommResourcePool to SL_CommRxPoolList ASN_SEQUENCE_ADD(&SL_CommRxPoolList->list,SL_CommResourcePool); //end commRxPool_r12 - //TODO: commTxPoolNormalCommon_r12, similar to commRxPool_r12 //TODO: commTxPoolExceptional_r12 //TODO: commSyncConfig_r12 @@ -1158,17 +1033,14 @@ uint8_t do_SIB23(uint8_t Mod_id, (*sib18)->ext1 = NULL; (*sib18)->lateNonCriticalExtension = NULL; // end SIB18 - // SIB19 // fill in all elements of SIB19 if present - //discConfig_r12 (*sib19)->discConfig_r12 = CALLOC (1, sizeof(*(*sib19)->discConfig_r12)); SL_DiscRxPoolList = &(*sib19)->discConfig_r12->discRxPool_r12; memset(SL_DiscRxPoolList,0,sizeof(*SL_DiscRxPoolList)); //fill SL_DiscResourcePool SL_DiscResourcePool = CALLOC(1, sizeof(*SL_DiscResourcePool)); - SL_DiscResourcePool->cp_Len_r12 = configuration->discRxPool_cp_Len[CC_id]; SL_DiscResourcePool->discPeriod_r12 = configuration->discRxPool_discPeriod[CC_id]; //sc_TF_ResourceConfig_r12 @@ -1178,137 +1050,134 @@ uint8_t do_SIB23(uint8_t Mod_id, SL_DiscResourcePool->tf_ResourceConfig_r12.prb_Start_r12 = configuration->discRxPool_ResourceConfig_prb_Start[CC_id]; SL_DiscResourcePool->tf_ResourceConfig_r12.prb_End_r12 = configuration->discRxPool_ResourceConfig_prb_End[CC_id]; SL_DiscResourcePool->tf_ResourceConfig_r12.offsetIndicator_r12.present = configuration->discRxPool_ResourceConfig_offsetIndicator_present[CC_id]; + if (SL_DiscResourcePool->tf_ResourceConfig_r12.offsetIndicator_r12.present == LTE_SL_OffsetIndicator_r12_PR_small_r12 ) { - SL_DiscResourcePool->tf_ResourceConfig_r12.offsetIndicator_r12.choice.small_r12 = configuration->discRxPool_ResourceConfig_offsetIndicator_choice[CC_id] ; - } else if (SL_DiscResourcePool->tf_ResourceConfig_r12.offsetIndicator_r12.present == LTE_SL_OffsetIndicator_r12_PR_large_r12 ){ - SL_DiscResourcePool->tf_ResourceConfig_r12.offsetIndicator_r12.choice.large_r12 = configuration->discRxPool_ResourceConfig_offsetIndicator_choice[CC_id] ; + SL_DiscResourcePool->tf_ResourceConfig_r12.offsetIndicator_r12.choice.small_r12 = configuration->discRxPool_ResourceConfig_offsetIndicator_choice[CC_id] ; + } else if (SL_DiscResourcePool->tf_ResourceConfig_r12.offsetIndicator_r12.present == LTE_SL_OffsetIndicator_r12_PR_large_r12 ) { + SL_DiscResourcePool->tf_ResourceConfig_r12.offsetIndicator_r12.choice.large_r12 = configuration->discRxPool_ResourceConfig_offsetIndicator_choice[CC_id] ; } + SL_DiscResourcePool->tf_ResourceConfig_r12.subframeBitmap_r12.present = configuration->discRxPool_ResourceConfig_subframeBitmap_present[CC_id]; - if (SL_DiscResourcePool->tf_ResourceConfig_r12.subframeBitmap_r12.present == LTE_SubframeBitmapSL_r12_PR_bs4_r12){ - //for BS4 - SL_DiscResourcePool->tf_ResourceConfig_r12.subframeBitmap_r12.choice.bs4_r12.size = configuration->discRxPool_ResourceConfig_subframeBitmap_choice_bs_size[CC_id]; - SL_DiscResourcePool->tf_ResourceConfig_r12.subframeBitmap_r12.choice.bs4_r12.buf = (uint8_t *)configuration->discRxPool_ResourceConfig_subframeBitmap_choice_bs_buf[CC_id];; - SL_DiscResourcePool->tf_ResourceConfig_r12.subframeBitmap_r12.choice.bs4_r12.bits_unused = configuration->discRxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused[CC_id]; - } else if (SL_DiscResourcePool->tf_ResourceConfig_r12.subframeBitmap_r12.present == LTE_SubframeBitmapSL_r12_PR_bs8_r12){ - //for BS8 - SL_DiscResourcePool->tf_ResourceConfig_r12.subframeBitmap_r12.choice.bs8_r12.size = configuration->discRxPool_ResourceConfig_subframeBitmap_choice_bs_size[CC_id]; - SL_DiscResourcePool->tf_ResourceConfig_r12.subframeBitmap_r12.choice.bs8_r12.buf = (uint8_t *)configuration->discRxPool_ResourceConfig_subframeBitmap_choice_bs_buf[CC_id];; - SL_DiscResourcePool->tf_ResourceConfig_r12.subframeBitmap_r12.choice.bs8_r12.bits_unused = configuration->discRxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused[CC_id]; - } else if (SL_DiscResourcePool->tf_ResourceConfig_r12.subframeBitmap_r12.present == LTE_SubframeBitmapSL_r12_PR_bs12_r12){ - //for BS12 - SL_DiscResourcePool->tf_ResourceConfig_r12.subframeBitmap_r12.choice.bs12_r12.size = configuration->discRxPool_ResourceConfig_subframeBitmap_choice_bs_size[CC_id]; - SL_DiscResourcePool->tf_ResourceConfig_r12.subframeBitmap_r12.choice.bs12_r12.buf = (uint8_t *)configuration->discRxPool_ResourceConfig_subframeBitmap_choice_bs_buf[CC_id];; - SL_DiscResourcePool->tf_ResourceConfig_r12.subframeBitmap_r12.choice.bs12_r12.bits_unused = configuration->discRxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused[CC_id]; - }else if (SL_DiscResourcePool->tf_ResourceConfig_r12.subframeBitmap_r12.present == LTE_SubframeBitmapSL_r12_PR_bs16_r12){ - //for BS16 - SL_DiscResourcePool->tf_ResourceConfig_r12.subframeBitmap_r12.choice.bs16_r12.size = configuration->discRxPool_ResourceConfig_subframeBitmap_choice_bs_size[CC_id]; - SL_DiscResourcePool->tf_ResourceConfig_r12.subframeBitmap_r12.choice.bs16_r12.buf = (uint8_t *)configuration->discRxPool_ResourceConfig_subframeBitmap_choice_bs_buf[CC_id];; - SL_DiscResourcePool->tf_ResourceConfig_r12.subframeBitmap_r12.choice.bs16_r12.bits_unused = configuration->discRxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused[CC_id]; - }else if (SL_DiscResourcePool->tf_ResourceConfig_r12.subframeBitmap_r12.present == LTE_SubframeBitmapSL_r12_PR_bs30_r12){ - //for BS30 - SL_DiscResourcePool->tf_ResourceConfig_r12.subframeBitmap_r12.choice.bs30_r12.size = configuration->discRxPool_ResourceConfig_subframeBitmap_choice_bs_size[CC_id]; - SL_DiscResourcePool->tf_ResourceConfig_r12.subframeBitmap_r12.choice.bs30_r12.buf = (uint8_t *)configuration->discRxPool_ResourceConfig_subframeBitmap_choice_bs_buf[CC_id];; - SL_DiscResourcePool->tf_ResourceConfig_r12.subframeBitmap_r12.choice.bs30_r12.bits_unused = configuration->discRxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused[CC_id]; - }else if (SL_DiscResourcePool->tf_ResourceConfig_r12.subframeBitmap_r12.present == LTE_SubframeBitmapSL_r12_PR_bs40_r12){ - //for BS40 - SL_DiscResourcePool->tf_ResourceConfig_r12.subframeBitmap_r12.choice.bs40_r12.size = configuration->discRxPool_ResourceConfig_subframeBitmap_choice_bs_size[CC_id]; - SL_DiscResourcePool->tf_ResourceConfig_r12.subframeBitmap_r12.choice.bs40_r12.buf = (uint8_t *)configuration->discRxPool_ResourceConfig_subframeBitmap_choice_bs_buf[CC_id];; - SL_DiscResourcePool->tf_ResourceConfig_r12.subframeBitmap_r12.choice.bs40_r12.bits_unused = configuration->discRxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused[CC_id]; - }else if (SL_DiscResourcePool->tf_ResourceConfig_r12.subframeBitmap_r12.present == LTE_SubframeBitmapSL_r12_PR_bs42_r12){ - //for BS42 - SL_DiscResourcePool->tf_ResourceConfig_r12.subframeBitmap_r12.choice.bs42_r12.size = configuration->discRxPool_ResourceConfig_subframeBitmap_choice_bs_size[CC_id]; - SL_DiscResourcePool->tf_ResourceConfig_r12.subframeBitmap_r12.choice.bs42_r12.buf = (uint8_t *)configuration->discRxPool_ResourceConfig_subframeBitmap_choice_bs_buf[CC_id];; - SL_DiscResourcePool->tf_ResourceConfig_r12.subframeBitmap_r12.choice.bs42_r12.bits_unused = configuration->discRxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused[CC_id]; + + if (SL_DiscResourcePool->tf_ResourceConfig_r12.subframeBitmap_r12.present == LTE_SubframeBitmapSL_r12_PR_bs4_r12) { + //for BS4 + SL_DiscResourcePool->tf_ResourceConfig_r12.subframeBitmap_r12.choice.bs4_r12.size = configuration->discRxPool_ResourceConfig_subframeBitmap_choice_bs_size[CC_id]; + SL_DiscResourcePool->tf_ResourceConfig_r12.subframeBitmap_r12.choice.bs4_r12.buf = (uint8_t *)configuration->discRxPool_ResourceConfig_subframeBitmap_choice_bs_buf[CC_id];; + SL_DiscResourcePool->tf_ResourceConfig_r12.subframeBitmap_r12.choice.bs4_r12.bits_unused = configuration->discRxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused[CC_id]; + } else if (SL_DiscResourcePool->tf_ResourceConfig_r12.subframeBitmap_r12.present == LTE_SubframeBitmapSL_r12_PR_bs8_r12) { + //for BS8 + SL_DiscResourcePool->tf_ResourceConfig_r12.subframeBitmap_r12.choice.bs8_r12.size = configuration->discRxPool_ResourceConfig_subframeBitmap_choice_bs_size[CC_id]; + SL_DiscResourcePool->tf_ResourceConfig_r12.subframeBitmap_r12.choice.bs8_r12.buf = (uint8_t *)configuration->discRxPool_ResourceConfig_subframeBitmap_choice_bs_buf[CC_id];; + SL_DiscResourcePool->tf_ResourceConfig_r12.subframeBitmap_r12.choice.bs8_r12.bits_unused = configuration->discRxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused[CC_id]; + } else if (SL_DiscResourcePool->tf_ResourceConfig_r12.subframeBitmap_r12.present == LTE_SubframeBitmapSL_r12_PR_bs12_r12) { + //for BS12 + SL_DiscResourcePool->tf_ResourceConfig_r12.subframeBitmap_r12.choice.bs12_r12.size = configuration->discRxPool_ResourceConfig_subframeBitmap_choice_bs_size[CC_id]; + SL_DiscResourcePool->tf_ResourceConfig_r12.subframeBitmap_r12.choice.bs12_r12.buf = (uint8_t *)configuration->discRxPool_ResourceConfig_subframeBitmap_choice_bs_buf[CC_id];; + SL_DiscResourcePool->tf_ResourceConfig_r12.subframeBitmap_r12.choice.bs12_r12.bits_unused = configuration->discRxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused[CC_id]; + } else if (SL_DiscResourcePool->tf_ResourceConfig_r12.subframeBitmap_r12.present == LTE_SubframeBitmapSL_r12_PR_bs16_r12) { + //for BS16 + SL_DiscResourcePool->tf_ResourceConfig_r12.subframeBitmap_r12.choice.bs16_r12.size = configuration->discRxPool_ResourceConfig_subframeBitmap_choice_bs_size[CC_id]; + SL_DiscResourcePool->tf_ResourceConfig_r12.subframeBitmap_r12.choice.bs16_r12.buf = (uint8_t *)configuration->discRxPool_ResourceConfig_subframeBitmap_choice_bs_buf[CC_id];; + SL_DiscResourcePool->tf_ResourceConfig_r12.subframeBitmap_r12.choice.bs16_r12.bits_unused = configuration->discRxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused[CC_id]; + } else if (SL_DiscResourcePool->tf_ResourceConfig_r12.subframeBitmap_r12.present == LTE_SubframeBitmapSL_r12_PR_bs30_r12) { + //for BS30 + SL_DiscResourcePool->tf_ResourceConfig_r12.subframeBitmap_r12.choice.bs30_r12.size = configuration->discRxPool_ResourceConfig_subframeBitmap_choice_bs_size[CC_id]; + SL_DiscResourcePool->tf_ResourceConfig_r12.subframeBitmap_r12.choice.bs30_r12.buf = (uint8_t *)configuration->discRxPool_ResourceConfig_subframeBitmap_choice_bs_buf[CC_id];; + SL_DiscResourcePool->tf_ResourceConfig_r12.subframeBitmap_r12.choice.bs30_r12.bits_unused = configuration->discRxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused[CC_id]; + } else if (SL_DiscResourcePool->tf_ResourceConfig_r12.subframeBitmap_r12.present == LTE_SubframeBitmapSL_r12_PR_bs40_r12) { + //for BS40 + SL_DiscResourcePool->tf_ResourceConfig_r12.subframeBitmap_r12.choice.bs40_r12.size = configuration->discRxPool_ResourceConfig_subframeBitmap_choice_bs_size[CC_id]; + SL_DiscResourcePool->tf_ResourceConfig_r12.subframeBitmap_r12.choice.bs40_r12.buf = (uint8_t *)configuration->discRxPool_ResourceConfig_subframeBitmap_choice_bs_buf[CC_id];; + SL_DiscResourcePool->tf_ResourceConfig_r12.subframeBitmap_r12.choice.bs40_r12.bits_unused = configuration->discRxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused[CC_id]; + } else if (SL_DiscResourcePool->tf_ResourceConfig_r12.subframeBitmap_r12.present == LTE_SubframeBitmapSL_r12_PR_bs42_r12) { + //for BS42 + SL_DiscResourcePool->tf_ResourceConfig_r12.subframeBitmap_r12.choice.bs42_r12.size = configuration->discRxPool_ResourceConfig_subframeBitmap_choice_bs_size[CC_id]; + SL_DiscResourcePool->tf_ResourceConfig_r12.subframeBitmap_r12.choice.bs42_r12.buf = (uint8_t *)configuration->discRxPool_ResourceConfig_subframeBitmap_choice_bs_buf[CC_id];; + SL_DiscResourcePool->tf_ResourceConfig_r12.subframeBitmap_r12.choice.bs42_r12.bits_unused = configuration->discRxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused[CC_id]; } //add SL_DiscResourcePool to SL_DiscRxPoolList ASN_SEQUENCE_ADD(&SL_DiscRxPoolList->list,SL_DiscResourcePool); + /* + //for DiscRxPoolPS + (*sib19)->ext1 = CALLOC (1, sizeof(*(*sib19)->ext1)); + (*sib19)->ext1->discConfigPS_13 = CALLOC (1, sizeof(*((*sib19)->ext1->discConfigPS_13))); -/* - //for DiscRxPoolPS - (*sib19)->ext1 = CALLOC (1, sizeof(*(*sib19)->ext1)); - (*sib19)->ext1->discConfigPS_13 = CALLOC (1, sizeof(*((*sib19)->ext1->discConfigPS_13))); + SL_DiscRxPoolPSList = &(*sib19)->ext1->discConfigPS_13->discRxPoolPS_r13; + memset(SL_DiscRxPoolPSList,0,sizeof(*SL_DiscRxPoolPSList)); + //fill SL_DiscResourcePool + SL_DiscResourcePoolPS = CALLOC(1, sizeof(*SL_DiscResourcePoolPS)); - SL_DiscRxPoolPSList = &(*sib19)->ext1->discConfigPS_13->discRxPoolPS_r13; - memset(SL_DiscRxPoolPSList,0,sizeof(*SL_DiscRxPoolPSList)); - //fill SL_DiscResourcePool - SL_DiscResourcePoolPS = CALLOC(1, sizeof(*SL_DiscResourcePoolPS)); + SL_DiscResourcePoolPS->cp_Len_r12 = configuration->discRxPoolPS_cp_Len[CC_id]; + SL_DiscResourcePoolPS->discPeriod_r12 = configuration->discRxPoolPS_discPeriod[CC_id]; + //sc_TF_ResourceConfig_r12 + SL_DiscResourcePoolPS->numRetx_r12 = configuration->discRxPoolPS_numRetx[CC_id]; + SL_DiscResourcePoolPS->numRepetition_r12 = configuration->discRxPoolPS_numRepetition[CC_id]; - SL_DiscResourcePoolPS->cp_Len_r12 = configuration->discRxPoolPS_cp_Len[CC_id]; - SL_DiscResourcePoolPS->discPeriod_r12 = configuration->discRxPoolPS_discPeriod[CC_id]; - //sc_TF_ResourceConfig_r12 - SL_DiscResourcePoolPS->numRetx_r12 = configuration->discRxPoolPS_numRetx[CC_id]; - SL_DiscResourcePoolPS->numRepetition_r12 = configuration->discRxPoolPS_numRepetition[CC_id]; + SL_DiscResourcePoolPS->tf_ResourceConfig_r12.prb_Num_r12 = configuration->discRxPoolPS_ResourceConfig_prb_Num[CC_id]; + SL_DiscResourcePoolPS->tf_ResourceConfig_r12.prb_Start_r12 = configuration->discRxPoolPS_ResourceConfig_prb_Start[CC_id]; + SL_DiscResourcePoolPS->tf_ResourceConfig_r12.prb_End_r12 = configuration->discRxPoolPS_ResourceConfig_prb_End[CC_id]; - SL_DiscResourcePoolPS->tf_ResourceConfig_r12.prb_Num_r12 = configuration->discRxPoolPS_ResourceConfig_prb_Num[CC_id]; - SL_DiscResourcePoolPS->tf_ResourceConfig_r12.prb_Start_r12 = configuration->discRxPoolPS_ResourceConfig_prb_Start[CC_id]; - SL_DiscResourcePoolPS->tf_ResourceConfig_r12.prb_End_r12 = configuration->discRxPoolPS_ResourceConfig_prb_End[CC_id]; + SL_DiscResourcePoolPS->tf_ResourceConfig_r12.offsetIndicator_r12.present = configuration->discRxPoolPS_ResourceConfig_offsetIndicator_present[CC_id]; + if (SL_DiscResourcePoolPS->tf_ResourceConfig_r12.offsetIndicator_r12.present == SL_OffsetIndicator_r12_PR_small_r12 ) { + SL_DiscResourcePoolPS->tf_ResourceConfig_r12.offsetIndicator_r12.choice.small_r12 = configuration->discRxPoolPS_ResourceConfig_offsetIndicator_choice[CC_id] ; + } else if (SL_DiscResourcePoolPS->tf_ResourceConfig_r12.offsetIndicator_r12.present == SL_OffsetIndicator_r12_PR_large_r12 ){ + SL_DiscResourcePoolPS->tf_ResourceConfig_r12.offsetIndicator_r12.choice.large_r12 = configuration->discRxPoolPS_ResourceConfig_offsetIndicator_choice[CC_id] ; + } - SL_DiscResourcePoolPS->tf_ResourceConfig_r12.offsetIndicator_r12.present = configuration->discRxPoolPS_ResourceConfig_offsetIndicator_present[CC_id]; - if (SL_DiscResourcePoolPS->tf_ResourceConfig_r12.offsetIndicator_r12.present == SL_OffsetIndicator_r12_PR_small_r12 ) { - SL_DiscResourcePoolPS->tf_ResourceConfig_r12.offsetIndicator_r12.choice.small_r12 = configuration->discRxPoolPS_ResourceConfig_offsetIndicator_choice[CC_id] ; - } else if (SL_DiscResourcePoolPS->tf_ResourceConfig_r12.offsetIndicator_r12.present == SL_OffsetIndicator_r12_PR_large_r12 ){ - SL_DiscResourcePoolPS->tf_ResourceConfig_r12.offsetIndicator_r12.choice.large_r12 = configuration->discRxPoolPS_ResourceConfig_offsetIndicator_choice[CC_id] ; - } - - SL_DiscResourcePoolPS->tf_ResourceConfig_r12.subframeBitmap_r12.present = configuration->discRxPoolPS_ResourceConfig_subframeBitmap_present[CC_id]; - if (SL_DiscResourcePoolPS->tf_ResourceConfig_r12.subframeBitmap_r12.present == SubframeBitmapSL_r12_PR_bs4_r12){ - //for BS4 - SL_DiscResourcePoolPS->tf_ResourceConfig_r12.subframeBitmap_r12.choice.bs4_r12.size = configuration->discRxPoolPS_ResourceConfig_subframeBitmap_choice_bs_size[CC_id]; - SL_DiscResourcePoolPS->tf_ResourceConfig_r12.subframeBitmap_r12.choice.bs4_r12.buf = configuration->discRxPoolPS_ResourceConfig_subframeBitmap_choice_bs_buf[CC_id];; - SL_DiscResourcePoolPS->tf_ResourceConfig_r12.subframeBitmap_r12.choice.bs4_r12.bits_unused = configuration->discRxPoolPS_ResourceConfig_subframeBitmap_choice_bs_bits_unused[CC_id]; - } else if (SL_DiscResourcePoolPS->tf_ResourceConfig_r12.subframeBitmap_r12.present == SubframeBitmapSL_r12_PR_bs8_r12){ - //for BS8 - SL_DiscResourcePoolPS->tf_ResourceConfig_r12.subframeBitmap_r12.choice.bs8_r12.size = configuration->discRxPoolPS_ResourceConfig_subframeBitmap_choice_bs_size[CC_id]; - SL_DiscResourcePoolPS->tf_ResourceConfig_r12.subframeBitmap_r12.choice.bs8_r12.buf = configuration->discRxPoolPS_ResourceConfig_subframeBitmap_choice_bs_buf[CC_id];; - SL_DiscResourcePoolPS->tf_ResourceConfig_r12.subframeBitmap_r12.choice.bs8_r12.bits_unused = configuration->discRxPoolPS_ResourceConfig_subframeBitmap_choice_bs_bits_unused[CC_id]; - } else if (SL_DiscResourcePoolPS->tf_ResourceConfig_r12.subframeBitmap_r12.present == SubframeBitmapSL_r12_PR_bs12_r12){ - //for BS12 - SL_DiscResourcePoolPS->tf_ResourceConfig_r12.subframeBitmap_r12.choice.bs12_r12.size = configuration->discRxPoolPS_ResourceConfig_subframeBitmap_choice_bs_size[CC_id]; - SL_DiscResourcePoolPS->tf_ResourceConfig_r12.subframeBitmap_r12.choice.bs12_r12.buf = configuration->discRxPoolPS_ResourceConfig_subframeBitmap_choice_bs_buf[CC_id];; - SL_DiscResourcePoolPS->tf_ResourceConfig_r12.subframeBitmap_r12.choice.bs12_r12.bits_unused = configuration->discRxPoolPS_ResourceConfig_subframeBitmap_choice_bs_bits_unused[CC_id]; - }else if (SL_DiscResourcePoolPS->tf_ResourceConfig_r12.subframeBitmap_r12.present == SubframeBitmapSL_r12_PR_bs16_r12){ - //for BS16 - SL_DiscResourcePoolPS->tf_ResourceConfig_r12.subframeBitmap_r12.choice.bs16_r12.size = configuration->discRxPoolPS_ResourceConfig_subframeBitmap_choice_bs_size[CC_id]; - SL_DiscResourcePoolPS->tf_ResourceConfig_r12.subframeBitmap_r12.choice.bs16_r12.buf = configuration->discRxPoolPS_ResourceConfig_subframeBitmap_choice_bs_buf[CC_id];; - SL_DiscResourcePoolPS->tf_ResourceConfig_r12.subframeBitmap_r12.choice.bs16_r12.bits_unused = configuration->discRxPoolPS_ResourceConfig_subframeBitmap_choice_bs_bits_unused[CC_id]; - }else if (SL_DiscResourcePoolPS->tf_ResourceConfig_r12.subframeBitmap_r12.present == SubframeBitmapSL_r12_PR_bs30_r12){ - //for BS30 - SL_DiscResourcePoolPS->tf_ResourceConfig_r12.subframeBitmap_r12.choice.bs30_r12.size = configuration->discRxPoolPS_ResourceConfig_subframeBitmap_choice_bs_size[CC_id]; - SL_DiscResourcePoolPS->tf_ResourceConfig_r12.subframeBitmap_r12.choice.bs30_r12.buf = configuration->discRxPoolPS_ResourceConfig_subframeBitmap_choice_bs_buf[CC_id];; - SL_DiscResourcePoolPS->tf_ResourceConfig_r12.subframeBitmap_r12.choice.bs30_r12.bits_unused = configuration->discRxPoolPS_ResourceConfig_subframeBitmap_choice_bs_bits_unused[CC_id]; - }else if (SL_DiscResourcePoolPS->tf_ResourceConfig_r12.subframeBitmap_r12.present == SubframeBitmapSL_r12_PR_bs40_r12){ - //for BS40 - SL_DiscResourcePoolPS->tf_ResourceConfig_r12.subframeBitmap_r12.choice.bs40_r12.size = configuration->discRxPoolPS_ResourceConfig_subframeBitmap_choice_bs_size[CC_id]; - SL_DiscResourcePoolPS->tf_ResourceConfig_r12.subframeBitmap_r12.choice.bs40_r12.buf = configuration->discRxPoolPS_ResourceConfig_subframeBitmap_choice_bs_buf[CC_id];; - SL_DiscResourcePoolPS->tf_ResourceConfig_r12.subframeBitmap_r12.choice.bs40_r12.bits_unused = configuration->discRxPoolPS_ResourceConfig_subframeBitmap_choice_bs_bits_unused[CC_id]; - }else if (SL_DiscResourcePoolPS->tf_ResourceConfig_r12.subframeBitmap_r12.present == SubframeBitmapSL_r12_PR_bs42_r12){ - //for BS42 - SL_DiscResourcePoolPS->tf_ResourceConfig_r12.subframeBitmap_r12.choice.bs42_r12.size = configuration->discRxPoolPS_ResourceConfig_subframeBitmap_choice_bs_size[CC_id]; - SL_DiscResourcePoolPS->tf_ResourceConfig_r12.subframeBitmap_r12.choice.bs42_r12.buf = configuration->discRxPoolPS_ResourceConfig_subframeBitmap_choice_bs_buf[CC_id];; - SL_DiscResourcePoolPS->tf_ResourceConfig_r12.subframeBitmap_r12.choice.bs42_r12.bits_unused = configuration->discRxPoolPS_ResourceConfig_subframeBitmap_choice_bs_bits_unused[CC_id]; - } - - //add SL_DiscResourcePool to SL_DiscRxPoolList - ASN_SEQUENCE_ADD(&SL_DiscRxPoolPSList->list,SL_DiscResourcePoolPS); -*/ + SL_DiscResourcePoolPS->tf_ResourceConfig_r12.subframeBitmap_r12.present = configuration->discRxPoolPS_ResourceConfig_subframeBitmap_present[CC_id]; + if (SL_DiscResourcePoolPS->tf_ResourceConfig_r12.subframeBitmap_r12.present == SubframeBitmapSL_r12_PR_bs4_r12){ + //for BS4 + SL_DiscResourcePoolPS->tf_ResourceConfig_r12.subframeBitmap_r12.choice.bs4_r12.size = configuration->discRxPoolPS_ResourceConfig_subframeBitmap_choice_bs_size[CC_id]; + SL_DiscResourcePoolPS->tf_ResourceConfig_r12.subframeBitmap_r12.choice.bs4_r12.buf = configuration->discRxPoolPS_ResourceConfig_subframeBitmap_choice_bs_buf[CC_id];; + SL_DiscResourcePoolPS->tf_ResourceConfig_r12.subframeBitmap_r12.choice.bs4_r12.bits_unused = configuration->discRxPoolPS_ResourceConfig_subframeBitmap_choice_bs_bits_unused[CC_id]; + } else if (SL_DiscResourcePoolPS->tf_ResourceConfig_r12.subframeBitmap_r12.present == SubframeBitmapSL_r12_PR_bs8_r12){ + //for BS8 + SL_DiscResourcePoolPS->tf_ResourceConfig_r12.subframeBitmap_r12.choice.bs8_r12.size = configuration->discRxPoolPS_ResourceConfig_subframeBitmap_choice_bs_size[CC_id]; + SL_DiscResourcePoolPS->tf_ResourceConfig_r12.subframeBitmap_r12.choice.bs8_r12.buf = configuration->discRxPoolPS_ResourceConfig_subframeBitmap_choice_bs_buf[CC_id];; + SL_DiscResourcePoolPS->tf_ResourceConfig_r12.subframeBitmap_r12.choice.bs8_r12.bits_unused = configuration->discRxPoolPS_ResourceConfig_subframeBitmap_choice_bs_bits_unused[CC_id]; + } else if (SL_DiscResourcePoolPS->tf_ResourceConfig_r12.subframeBitmap_r12.present == SubframeBitmapSL_r12_PR_bs12_r12){ + //for BS12 + SL_DiscResourcePoolPS->tf_ResourceConfig_r12.subframeBitmap_r12.choice.bs12_r12.size = configuration->discRxPoolPS_ResourceConfig_subframeBitmap_choice_bs_size[CC_id]; + SL_DiscResourcePoolPS->tf_ResourceConfig_r12.subframeBitmap_r12.choice.bs12_r12.buf = configuration->discRxPoolPS_ResourceConfig_subframeBitmap_choice_bs_buf[CC_id];; + SL_DiscResourcePoolPS->tf_ResourceConfig_r12.subframeBitmap_r12.choice.bs12_r12.bits_unused = configuration->discRxPoolPS_ResourceConfig_subframeBitmap_choice_bs_bits_unused[CC_id]; + }else if (SL_DiscResourcePoolPS->tf_ResourceConfig_r12.subframeBitmap_r12.present == SubframeBitmapSL_r12_PR_bs16_r12){ + //for BS16 + SL_DiscResourcePoolPS->tf_ResourceConfig_r12.subframeBitmap_r12.choice.bs16_r12.size = configuration->discRxPoolPS_ResourceConfig_subframeBitmap_choice_bs_size[CC_id]; + SL_DiscResourcePoolPS->tf_ResourceConfig_r12.subframeBitmap_r12.choice.bs16_r12.buf = configuration->discRxPoolPS_ResourceConfig_subframeBitmap_choice_bs_buf[CC_id];; + SL_DiscResourcePoolPS->tf_ResourceConfig_r12.subframeBitmap_r12.choice.bs16_r12.bits_unused = configuration->discRxPoolPS_ResourceConfig_subframeBitmap_choice_bs_bits_unused[CC_id]; + }else if (SL_DiscResourcePoolPS->tf_ResourceConfig_r12.subframeBitmap_r12.present == SubframeBitmapSL_r12_PR_bs30_r12){ + //for BS30 + SL_DiscResourcePoolPS->tf_ResourceConfig_r12.subframeBitmap_r12.choice.bs30_r12.size = configuration->discRxPoolPS_ResourceConfig_subframeBitmap_choice_bs_size[CC_id]; + SL_DiscResourcePoolPS->tf_ResourceConfig_r12.subframeBitmap_r12.choice.bs30_r12.buf = configuration->discRxPoolPS_ResourceConfig_subframeBitmap_choice_bs_buf[CC_id];; + SL_DiscResourcePoolPS->tf_ResourceConfig_r12.subframeBitmap_r12.choice.bs30_r12.bits_unused = configuration->discRxPoolPS_ResourceConfig_subframeBitmap_choice_bs_bits_unused[CC_id]; + }else if (SL_DiscResourcePoolPS->tf_ResourceConfig_r12.subframeBitmap_r12.present == SubframeBitmapSL_r12_PR_bs40_r12){ + //for BS40 + SL_DiscResourcePoolPS->tf_ResourceConfig_r12.subframeBitmap_r12.choice.bs40_r12.size = configuration->discRxPoolPS_ResourceConfig_subframeBitmap_choice_bs_size[CC_id]; + SL_DiscResourcePoolPS->tf_ResourceConfig_r12.subframeBitmap_r12.choice.bs40_r12.buf = configuration->discRxPoolPS_ResourceConfig_subframeBitmap_choice_bs_buf[CC_id];; + SL_DiscResourcePoolPS->tf_ResourceConfig_r12.subframeBitmap_r12.choice.bs40_r12.bits_unused = configuration->discRxPoolPS_ResourceConfig_subframeBitmap_choice_bs_bits_unused[CC_id]; + }else if (SL_DiscResourcePoolPS->tf_ResourceConfig_r12.subframeBitmap_r12.present == SubframeBitmapSL_r12_PR_bs42_r12){ + //for BS42 + SL_DiscResourcePoolPS->tf_ResourceConfig_r12.subframeBitmap_r12.choice.bs42_r12.size = configuration->discRxPoolPS_ResourceConfig_subframeBitmap_choice_bs_size[CC_id]; + SL_DiscResourcePoolPS->tf_ResourceConfig_r12.subframeBitmap_r12.choice.bs42_r12.buf = configuration->discRxPoolPS_ResourceConfig_subframeBitmap_choice_bs_buf[CC_id];; + SL_DiscResourcePoolPS->tf_ResourceConfig_r12.subframeBitmap_r12.choice.bs42_r12.bits_unused = configuration->discRxPoolPS_ResourceConfig_subframeBitmap_choice_bs_bits_unused[CC_id]; + } + //add SL_DiscResourcePool to SL_DiscRxPoolList + ASN_SEQUENCE_ADD(&SL_DiscRxPoolPSList->list,SL_DiscResourcePoolPS); + */ (*sib19)->lateNonCriticalExtension = NULL; //end SIB19 - //SIB21 (*sib21)->sl_V2X_ConfigCommon_r14 = CALLOC (1, sizeof(*(*sib21)->sl_V2X_ConfigCommon_r14)); //SL_V2X_ConfigCommon= (*sib21)->sl_V2X_ConfigCommon_r14; memset((*sib21)->sl_V2X_ConfigCommon_r14,0,sizeof(*(*sib21)->sl_V2X_ConfigCommon_r14)); - struct LTE_SL_CommRxPoolListV2X_r14 *SL_CommRxPoolListV2X; struct LTE_SL_CommResourcePoolV2X_r14 *SL_CommResourcePoolV2X; (*sib21)->sl_V2X_ConfigCommon_r14->v2x_CommRxPool_r14 = CALLOC(1, sizeof(*(*sib21)->sl_V2X_ConfigCommon_r14->v2x_CommRxPool_r14)); SL_CommRxPoolListV2X = (*sib21)->sl_V2X_ConfigCommon_r14->v2x_CommRxPool_r14; - SL_CommResourcePoolV2X = CALLOC(1, sizeof(*SL_CommResourcePoolV2X)); memset(SL_CommResourcePoolV2X,0,sizeof(*SL_CommResourcePoolV2X)); - SL_CommResourcePoolV2X->sl_OffsetIndicator_r14 = CALLOC(1, sizeof(*SL_CommResourcePoolV2X->sl_OffsetIndicator_r14)); SL_CommResourcePoolV2X->sl_OffsetIndicator_r14->present = LTE_SL_OffsetIndicator_r12_PR_small_r12; SL_CommResourcePoolV2X->sl_OffsetIndicator_r14->choice.small_r12 = 0; @@ -1321,34 +1190,26 @@ uint8_t do_SIB23(uint8_t Mod_id, SL_CommResourcePoolV2X->sl_Subframe_r14.choice.bs40_r14.buf[2] = 0xFF; SL_CommResourcePoolV2X->sl_Subframe_r14.choice.bs40_r14.buf[3] = 0xFF; SL_CommResourcePoolV2X->sl_Subframe_r14.choice.bs40_r14.buf[4] = 0xFF; - SL_CommResourcePoolV2X->adjacencyPSCCH_PSSCH_r14 = 1; SL_CommResourcePoolV2X->sizeSubchannel_r14 = 10; SL_CommResourcePoolV2X->numSubchannel_r14 = 5; SL_CommResourcePoolV2X->startRB_Subchannel_r14 = 10; - //rxParametersNCell_r12 SL_CommResourcePoolV2X->rxParametersNCell_r14 = CALLOC (1, sizeof (*SL_CommResourcePoolV2X->rxParametersNCell_r14)); SL_CommResourcePoolV2X->rxParametersNCell_r14->tdd_Config_r14 = CALLOC (1, sizeof (*SL_CommResourcePoolV2X->rxParametersNCell_r14->tdd_Config_r14)); SL_CommResourcePoolV2X->rxParametersNCell_r14->tdd_Config_r14->subframeAssignment = 0 ; SL_CommResourcePoolV2X->rxParametersNCell_r14->tdd_Config_r14->specialSubframePatterns = 0; SL_CommResourcePoolV2X->rxParametersNCell_r14->syncConfigIndex_r14 = 0; - ASN_SEQUENCE_ADD(&SL_CommRxPoolListV2X->list,SL_CommResourcePoolV2X); //end SIB21 #endif - - bcch_message->message.present = LTE_BCCH_DL_SCH_MessageType_PR_c1; bcch_message->message.choice.c1.present = LTE_BCCH_DL_SCH_MessageType__c1_PR_systemInformation; - /* memcpy((void*)&bcch_message.message.choice.c1.choice.systemInformation, (void*)systemInformation, sizeof(SystemInformation_t));*/ - bcch_message->message.choice.c1.choice.systemInformation.criticalExtensions.present = LTE_SystemInformation__criticalExtensions_PR_systemInformation_r8; bcch_message->message.choice.c1.choice.systemInformation.criticalExtensions.choice.systemInformation_r8.sib_TypeAndInfo.list.count=0; - // asn_set_empty(&systemInformation->criticalExtensions.choice.systemInformation_r8.sib_TypeAndInfo.list);//.size=0; // systemInformation->criticalExtensions.choice.systemInformation_r8.sib_TypeAndInfo.list.count=0; ASN_SEQUENCE_ADD(&bcch_message->message.choice.c1.choice.systemInformation.criticalExtensions.choice.systemInformation_r8.sib_TypeAndInfo.list, @@ -1360,20 +1221,20 @@ uint8_t do_SIB23(uint8_t Mod_id, if (MBMS_flag > 0) { ASN_SEQUENCE_ADD(&bcch_message->message.choice.c1.choice.systemInformation.criticalExtensions.choice.systemInformation_r8.sib_TypeAndInfo.list,sib13_part); } + #endif if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) { - xer_fprint(stdout, &asn_DEF_LTE_BCCH_DL_SCH_Message, (void*)bcch_message); + xer_fprint(stdout, &asn_DEF_LTE_BCCH_DL_SCH_Message, (void *)bcch_message); } + enc_rval = uper_encode_to_buffer(&asn_DEF_LTE_BCCH_DL_SCH_Message, NULL, - (void*)bcch_message, + (void *)bcch_message, buffer, 900); AssertFatal (enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %lu)!\n", enc_rval.failed_type->name, enc_rval.encoded); - - #if defined(ENABLE_ITTI) # if !defined(DISABLE_XER_SPRINT) { @@ -1382,17 +1243,14 @@ uint8_t do_SIB23(uint8_t Mod_id, if ((message_string_size = xer_sprint(message_string, sizeof(message_string), &asn_DEF_LTE_BCCH_DL_SCH_Message, (void *)bcch_message)) > 0) { MessageDef *msg_p; - msg_p = itti_alloc_new_message_sized (TASK_RRC_ENB, RRC_DL_BCCH, message_string_size + sizeof (IttiMsgText)); msg_p->ittiMsg.rrc_dl_bcch.size = message_string_size; memcpy(&msg_p->ittiMsg.rrc_dl_bcch.text, message_string, message_string_size); - itti_send_msg_to_task(TASK_UNKNOWN, Mod_id, msg_p); } } # endif #endif - LOG_D(RRC,"[eNB] SystemInformation Encoded %zd bits (%zd bytes)\n",enc_rval.encoded,(enc_rval.encoded+7)/8); if (enc_rval.encoded==-1) { @@ -1403,22 +1261,15 @@ uint8_t do_SIB23(uint8_t Mod_id, return((enc_rval.encoded+7)/8); } -uint8_t do_RRCConnectionRequest(uint8_t Mod_id, uint8_t *buffer,uint8_t *rv) -{ - +uint8_t do_RRCConnectionRequest(uint8_t Mod_id, uint8_t *buffer,uint8_t *rv) { asn_enc_rval_t enc_rval; uint8_t buf[5],buf2=0; - LTE_UL_CCCH_Message_t ul_ccch_msg; - LTE_RRCConnectionRequest_t *rrcConnectionRequest; - memset((void *)&ul_ccch_msg,0,sizeof(LTE_UL_CCCH_Message_t)); - ul_ccch_msg.message.present = LTE_UL_CCCH_MessageType_PR_c1; ul_ccch_msg.message.choice.c1.present = LTE_UL_CCCH_MessageType__c1_PR_rrcConnectionRequest; rrcConnectionRequest = &ul_ccch_msg.message.choice.c1.choice.rrcConnectionRequest; - rrcConnectionRequest->criticalExtensions.present = LTE_RRCConnectionRequest__criticalExtensions_PR_rrcConnectionRequest_r8; if (1) { @@ -1447,20 +1298,16 @@ uint8_t do_RRCConnectionRequest(uint8_t Mod_id, uint8_t *buffer,uint8_t *rv) } rrcConnectionRequest->criticalExtensions.choice.rrcConnectionRequest_r8.establishmentCause = LTE_EstablishmentCause_mo_Signalling; //EstablishmentCause_mo_Data; - rrcConnectionRequest->criticalExtensions.choice.rrcConnectionRequest_r8.spare.buf = &buf2; rrcConnectionRequest->criticalExtensions.choice.rrcConnectionRequest_r8.spare.size=1; rrcConnectionRequest->criticalExtensions.choice.rrcConnectionRequest_r8.spare.bits_unused = 7; - - enc_rval = uper_encode_to_buffer(&asn_DEF_LTE_UL_CCCH_Message, NULL, - (void*)&ul_ccch_msg, + (void *)&ul_ccch_msg, buffer, 100); AssertFatal (enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %lu)!\n", enc_rval.failed_type->name, enc_rval.encoded); - #if defined(ENABLE_ITTI) # if !defined(DISABLE_XER_SPRINT) { @@ -1469,219 +1316,196 @@ uint8_t do_RRCConnectionRequest(uint8_t Mod_id, uint8_t *buffer,uint8_t *rv) if ((message_string_size = xer_sprint(message_string, sizeof(message_string), &asn_DEF_LTE_UL_CCCH_Message, (void *) &ul_ccch_msg)) > 0) { MessageDef *msg_p; - msg_p = itti_alloc_new_message_sized (TASK_RRC_UE, RRC_UL_CCCH, message_string_size + sizeof (IttiMsgText)); msg_p->ittiMsg.rrc_ul_ccch.size = message_string_size; memcpy(&msg_p->ittiMsg.rrc_ul_ccch.text, message_string, message_string_size); - itti_send_msg_to_task(TASK_UNKNOWN, NB_eNB_INST + Mod_id, msg_p); } } # endif #endif - LOG_D(RRC,"[UE] RRCConnectionRequest Encoded %zd bits (%zd bytes) \n",enc_rval.encoded,(enc_rval.encoded+7)/8); - return((enc_rval.encoded+7)/8); - } //TTN for D2D - 3GPP TS 36.331 (Section 5.10.2.3) -uint8_t do_SidelinkUEInformation(uint8_t Mod_id, uint8_t *buffer, LTE_SL_DestinationInfoList_r12_t *destinationInfoList, long *discTxResourceReq, SL_TRIGGER_t mode) -{ +uint8_t do_SidelinkUEInformation(uint8_t Mod_id, uint8_t *buffer, LTE_SL_DestinationInfoList_r12_t *destinationInfoList, long *discTxResourceReq, SL_TRIGGER_t mode) { + asn_enc_rval_t enc_rval; + LTE_UL_DCCH_Message_t ul_dcch_msg; + LTE_SidelinkUEInformation_r12_t *sidelinkUEInformation; + LTE_ARFCN_ValueEUTRA_r9_t carrierFreq = 25655;//sidelink communication frequency (hardcoded - should come from SIB2) + memset((void *)&ul_dcch_msg,0,sizeof(LTE_UL_DCCH_Message_t)); + ul_dcch_msg.message.present = LTE_UL_DCCH_MessageType_PR_messageClassExtension; + ul_dcch_msg.message.choice.messageClassExtension.present = LTE_UL_DCCH_MessageType__messageClassExtension_PR_c2; + ul_dcch_msg.message.choice.messageClassExtension.choice.c2.present = LTE_UL_DCCH_MessageType__messageClassExtension__c2_PR_sidelinkUEInformation_r12; + sidelinkUEInformation = &ul_dcch_msg.message.choice.messageClassExtension.choice.c2.choice.sidelinkUEInformation_r12; + //3GPP TS 36.331 (Section 5.10.2.3) + sidelinkUEInformation->criticalExtensions.present = LTE_SidelinkUEInformation_r12__criticalExtensions_PR_c1; + sidelinkUEInformation->criticalExtensions.choice.c1.present = LTE_SidelinkUEInformation_r12__criticalExtensions__c1_PR_sidelinkUEInformation_r12; - asn_enc_rval_t enc_rval; - LTE_UL_DCCH_Message_t ul_dcch_msg; - LTE_SidelinkUEInformation_r12_t *sidelinkUEInformation; - LTE_ARFCN_ValueEUTRA_r9_t carrierFreq = 25655;//sidelink communication frequency (hardcoded - should come from SIB2) - - memset((void *)&ul_dcch_msg,0,sizeof(LTE_UL_DCCH_Message_t)); - ul_dcch_msg.message.present = LTE_UL_DCCH_MessageType_PR_messageClassExtension; - ul_dcch_msg.message.choice.messageClassExtension.present = LTE_UL_DCCH_MessageType__messageClassExtension_PR_c2; - ul_dcch_msg.message.choice.messageClassExtension.choice.c2.present = LTE_UL_DCCH_MessageType__messageClassExtension__c2_PR_sidelinkUEInformation_r12; - sidelinkUEInformation = &ul_dcch_msg.message.choice.messageClassExtension.choice.c2.choice.sidelinkUEInformation_r12; - - //3GPP TS 36.331 (Section 5.10.2.3) - sidelinkUEInformation->criticalExtensions.present = LTE_SidelinkUEInformation_r12__criticalExtensions_PR_c1; - sidelinkUEInformation->criticalExtensions.choice.c1.present = LTE_SidelinkUEInformation_r12__criticalExtensions__c1_PR_sidelinkUEInformation_r12; - switch(mode) { - //if SIB18 is available - case SL_RECEIVE_COMMUNICATION: // to receive sidelink communication + switch(mode) { + //if SIB18 is available + case SL_RECEIVE_COMMUNICATION: // to receive sidelink communication sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.commRxInterestedFreq_r12 = CALLOC(1, - sizeof(*sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.commRxInterestedFreq_r12)); - memcpy((void*)sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.commRxInterestedFreq_r12, (void*)&carrierFreq, - sizeof(LTE_ARFCN_ValueEUTRA_r9_t)); + sizeof(*sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.commRxInterestedFreq_r12)); + memcpy((void *)sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.commRxInterestedFreq_r12, (void *)&carrierFreq, + sizeof(LTE_ARFCN_ValueEUTRA_r9_t)); break; - case SL_TRANSMIT_NON_RELAY_ONE_TO_MANY: //to transmit non-relay related one-to-many sidelink communication + case SL_TRANSMIT_NON_RELAY_ONE_TO_MANY: //to transmit non-relay related one-to-many sidelink communication //commTxResourceReq sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.commTxResourceReq_r12 = CALLOC(1, - sizeof(*sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.commTxResourceReq_r12)); + sizeof(*sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.commTxResourceReq_r12)); sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.commTxResourceReq_r12->carrierFreq_r12 = CALLOC(1, - sizeof(*sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.commTxResourceReq_r12->carrierFreq_r12)); - memcpy((void*)sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.commTxResourceReq_r12->carrierFreq_r12, (void*)&carrierFreq, - sizeof(LTE_ARFCN_ValueEUTRA_r9_t)); + sizeof(*sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.commTxResourceReq_r12->carrierFreq_r12)); + memcpy((void *)sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.commTxResourceReq_r12->carrierFreq_r12, (void *)&carrierFreq, + sizeof(LTE_ARFCN_ValueEUTRA_r9_t)); memcpy(&sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.commTxResourceReq_r12->destinationInfoList_r12, - destinationInfoList, - sizeof(LTE_SL_DestinationInfoList_r12_t)); + destinationInfoList, + sizeof(LTE_SL_DestinationInfoList_r12_t)); break; - case SL_TRANSMIT_NON_RELAY_ONE_TO_ONE://transmit non-relay related one-to-one sidelink communication + case SL_TRANSMIT_NON_RELAY_ONE_TO_ONE://transmit non-relay related one-to-one sidelink communication //if commTxResourceUC-ReqAllowed is included in SIB18 sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.nonCriticalExtension = CALLOC(1, - sizeof(*sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.nonCriticalExtension)); - + sizeof(*sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.nonCriticalExtension)); sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.nonCriticalExtension->commTxResourceReqUC_r13 = CALLOC(1, - sizeof(*sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.nonCriticalExtension->commTxResourceReqUC_r13)); + sizeof(*sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.nonCriticalExtension->commTxResourceReqUC_r13)); sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.nonCriticalExtension->commTxResourceReqUC_r13->carrierFreq_r12 = CALLOC(1, - sizeof(*sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.nonCriticalExtension->commTxResourceReqUC_r13->carrierFreq_r12)); - memcpy((void*)sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.nonCriticalExtension->commTxResourceReqUC_r13->carrierFreq_r12, (void*)&carrierFreq, - sizeof (LTE_ARFCN_ValueEUTRA_r9_t)); + sizeof(*sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.nonCriticalExtension->commTxResourceReqUC_r13->carrierFreq_r12)); + memcpy((void *)sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.nonCriticalExtension->commTxResourceReqUC_r13->carrierFreq_r12, (void *)&carrierFreq, + sizeof (LTE_ARFCN_ValueEUTRA_r9_t)); memcpy(&sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.nonCriticalExtension->commTxResourceReqUC_r13->destinationInfoList_r12, - destinationInfoList, - sizeof(LTE_SL_DestinationInfoList_r12_t)); + destinationInfoList, + sizeof(LTE_SL_DestinationInfoList_r12_t)); break; - case SL_TRANSMIT_RELAY_ONE_TO_ONE: //transmit relay related one-to-one sidelink communication + case SL_TRANSMIT_RELAY_ONE_TO_ONE: //transmit relay related one-to-one sidelink communication //if SIB19 includes discConfigRelay and UE acts a relay or UE has a selected relay sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.nonCriticalExtension = CALLOC(1, - sizeof(*sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.nonCriticalExtension)); + sizeof(*sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.nonCriticalExtension)); sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.nonCriticalExtension->commTxResourceInfoReqRelay_r13= CALLOC(1, - sizeof(*sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.nonCriticalExtension->commTxResourceInfoReqRelay_r13)); + sizeof(*sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.nonCriticalExtension->commTxResourceInfoReqRelay_r13)); sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.nonCriticalExtension->commTxResourceInfoReqRelay_r13->commTxResourceReqRelayUC_r13 = CALLOC(1, - sizeof(*sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.nonCriticalExtension->commTxResourceInfoReqRelay_r13->commTxResourceReqRelayUC_r13)); + sizeof(*sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.nonCriticalExtension->commTxResourceInfoReqRelay_r13->commTxResourceReqRelayUC_r13)); memcpy(&sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.nonCriticalExtension->commTxResourceInfoReqRelay_r13->commTxResourceReqRelayUC_r13->destinationInfoList_r12, - destinationInfoList, - sizeof(*destinationInfoList)); + destinationInfoList, + sizeof(*destinationInfoList)); //set ue-type to relayUE or remoteUE - sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.nonCriticalExtension->commTxResourceInfoReqRelay_r13->ue_Type_r13 =LTE_SidelinkUEInformation_v1310_IEs__commTxResourceInfoReqRelay_r13__ue_Type_r13_relayUE; + sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.nonCriticalExtension->commTxResourceInfoReqRelay_r13->ue_Type_r13 + =LTE_SidelinkUEInformation_v1310_IEs__commTxResourceInfoReqRelay_r13__ue_Type_r13_relayUE; //sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12->nonCriticalExtension->commTxResourceInfoReqRelay_r13->ue_Type_r13 =SidelinkUEInformation_v1310_IEs__commTxResourceInfoReqRelay_r13__ue_Type_r13_remoteUE; break; - case SL_TRANSMIT_RELAY_ONE_TO_MANY: //transmit relay related one-to-many sidelink communication + case SL_TRANSMIT_RELAY_ONE_TO_MANY: //transmit relay related one-to-many sidelink communication //if SIB19 includes discConfigRelay and UE acts a relay //set ue-type to relayUE sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.nonCriticalExtension = CALLOC(1, - sizeof(*sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.nonCriticalExtension)); + sizeof(*sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.nonCriticalExtension)); sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.nonCriticalExtension->commTxResourceInfoReqRelay_r13= CALLOC(1, - sizeof(*sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.nonCriticalExtension->commTxResourceInfoReqRelay_r13)); + sizeof(*sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.nonCriticalExtension->commTxResourceInfoReqRelay_r13)); sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.nonCriticalExtension->commTxResourceInfoReqRelay_r13->commTxResourceReqRelay_r13 = CALLOC(1, - sizeof(*sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.nonCriticalExtension->commTxResourceInfoReqRelay_r13->commTxResourceReqRelay_r13)); - sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.nonCriticalExtension->commTxResourceInfoReqRelay_r13->ue_Type_r13 = LTE_SidelinkUEInformation_v1310_IEs__commTxResourceInfoReqRelay_r13__ue_Type_r13_relayUE; + sizeof(*sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.nonCriticalExtension->commTxResourceInfoReqRelay_r13->commTxResourceReqRelay_r13)); + sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.nonCriticalExtension->commTxResourceInfoReqRelay_r13->ue_Type_r13 = + LTE_SidelinkUEInformation_v1310_IEs__commTxResourceInfoReqRelay_r13__ue_Type_r13_relayUE; memcpy(&sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.nonCriticalExtension->commTxResourceInfoReqRelay_r13->commTxResourceReqRelay_r13->destinationInfoList_r12, - destinationInfoList, - sizeof(*destinationInfoList)); + destinationInfoList, + sizeof(*destinationInfoList)); break; - //if SIB19 is available - //we consider only one frequency - a serving frequency - case SL_RECEIVE_DISCOVERY: //receive sidelink discovery announcements - + //if SIB19 is available + //we consider only one frequency - a serving frequency + case SL_RECEIVE_DISCOVERY: //receive sidelink discovery announcements sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.discRxInterest_r12 = CALLOC(1, - sizeof(*sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.discRxInterest_r12)); + sizeof(*sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.discRxInterest_r12)); *sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.discRxInterest_r12 = LTE_SidelinkUEInformation_r12_IEs__discRxInterest_r12_true; break; - case SL_TRANSMIT_NON_PS_DISCOVERY://to transmit non-PS related sidelink discovery announcements + + case SL_TRANSMIT_NON_PS_DISCOVERY://to transmit non-PS related sidelink discovery announcements //for the first frequency sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.discTxResourceReq_r12 = CALLOC(1, - sizeof(*sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.discTxResourceReq_r12)); - - memcpy((void*)sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.discTxResourceReq_r12, - (void*)discTxResourceReq, - sizeof(long)); + sizeof(*sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.discTxResourceReq_r12)); + memcpy((void *)sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.discTxResourceReq_r12, + (void *)discTxResourceReq, + sizeof(long)); //for additional frequency break; - case SL_TRANSMIT_PS_DISCOVERY://to transmit PS related sidelink discovery announcements + case SL_TRANSMIT_PS_DISCOVERY://to transmit PS related sidelink discovery announcements //if to transmit non-relay PS related discovery announcements and SIB19 includes discConfigPS //if UE is acting as relay UE and SIB includes discConfigRelay (relay threshold condition) //if relay UE/has a selected relay UE and if SIB19 includes discConfigRelay sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.nonCriticalExtension = CALLOC(1, - sizeof(*sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.nonCriticalExtension)); + sizeof(*sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.nonCriticalExtension)); sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.nonCriticalExtension->discTxResourceReqPS_r13 = CALLOC(1, - sizeof(*sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.nonCriticalExtension->discTxResourceReqPS_r13)); + sizeof(*sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.nonCriticalExtension->discTxResourceReqPS_r13)); sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.nonCriticalExtension->discTxResourceReqPS_r13->discTxResourceReq_r13 = *discTxResourceReq; break; - //SIB21 - case SL_RECEIVE_V2X: + + //SIB21 + case SL_RECEIVE_V2X: //TODO break; - case SL_TRANSMIT_V2X: + + case SL_TRANSMIT_V2X: //TODO break; - //TODO: request sidelink discovery transmission/reception gaps - //TODO: report the system information parameters related to sidelink discovery of carriers other than the primary - default: + + //TODO: request sidelink discovery transmission/reception gaps + //TODO: report the system information parameters related to sidelink discovery of carriers other than the primary + default: break; - } + } - if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) { - xer_fprint(stdout, &asn_DEF_LTE_UL_DCCH_Message, (void*)&ul_dcch_msg); - } - - - enc_rval = uper_encode_to_buffer(&asn_DEF_LTE_UL_DCCH_Message, - NULL, - (void*)&ul_dcch_msg, - buffer, - 100); - AssertFatal (enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %lu)!\n", - enc_rval.failed_type->name, enc_rval.encoded); + if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) { + xer_fprint(stdout, &asn_DEF_LTE_UL_DCCH_Message, (void *)&ul_dcch_msg); + } + enc_rval = uper_encode_to_buffer(&asn_DEF_LTE_UL_DCCH_Message, + NULL, + (void *)&ul_dcch_msg, + buffer, + 100); + AssertFatal (enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %lu)!\n", + enc_rval.failed_type->name, enc_rval.encoded); #if defined(ENABLE_ITTI) # if !defined(DISABLE_XER_SPRINT) - { - char message_string[20000]; - size_t message_string_size; + { + char message_string[20000]; + size_t message_string_size; - if ((message_string_size = xer_sprint(message_string, sizeof(message_string), &asn_DEF_LTE_UL_DCCH_Message, (void *) &ul_dcch_msg)) > 0) { - MessageDef *msg_p; - - msg_p = itti_alloc_new_message_sized (TASK_RRC_UE, RRC_UL_DCCH, message_string_size + sizeof (IttiMsgText)); - msg_p->ittiMsg.rrc_ul_dcch.size = message_string_size; - memcpy(&msg_p->ittiMsg.rrc_ul_dcch.text, message_string, message_string_size); - - itti_send_msg_to_task(TASK_UNKNOWN, NB_eNB_INST + Mod_id, msg_p); - } - } + if ((message_string_size = xer_sprint(message_string, sizeof(message_string), &asn_DEF_LTE_UL_DCCH_Message, (void *) &ul_dcch_msg)) > 0) { + MessageDef *msg_p; + msg_p = itti_alloc_new_message_sized (TASK_RRC_UE, RRC_UL_DCCH, message_string_size + sizeof (IttiMsgText)); + msg_p->ittiMsg.rrc_ul_dcch.size = message_string_size; + memcpy(&msg_p->ittiMsg.rrc_ul_dcch.text, message_string, message_string_size); + itti_send_msg_to_task(TASK_UNKNOWN, NB_eNB_INST + Mod_id, msg_p); + } + } # endif #endif - #ifdef USER_MODE - LOG_D(RRC,"SidelinkUEInformation Encoded %d bits (%d bytes)\n",enc_rval.encoded,(enc_rval.encoded+7)/8); + LOG_D(RRC,"SidelinkUEInformation Encoded %d bits (%d bytes)\n",enc_rval.encoded,(enc_rval.encoded+7)/8); #endif - - return((enc_rval.encoded+7)/8); - + return((enc_rval.encoded+7)/8); } -uint8_t do_RRCConnectionSetupComplete(uint8_t Mod_id, uint8_t *buffer, const uint8_t Transaction_id, const int dedicatedInfoNASLength, const char *dedicatedInfoNAS) -{ - - +uint8_t do_RRCConnectionSetupComplete(uint8_t Mod_id, uint8_t *buffer, const uint8_t Transaction_id, const int dedicatedInfoNASLength, const char *dedicatedInfoNAS) { asn_enc_rval_t enc_rval; - LTE_UL_DCCH_Message_t ul_dcch_msg; - LTE_RRCConnectionSetupComplete_t *rrcConnectionSetupComplete; - memset((void *)&ul_dcch_msg,0,sizeof(LTE_UL_DCCH_Message_t)); - ul_dcch_msg.message.present = LTE_UL_DCCH_MessageType_PR_c1; ul_dcch_msg.message.choice.c1.present = LTE_UL_DCCH_MessageType__c1_PR_rrcConnectionSetupComplete; rrcConnectionSetupComplete = &ul_dcch_msg.message.choice.c1.choice.rrcConnectionSetupComplete; - rrcConnectionSetupComplete->rrc_TransactionIdentifier = Transaction_id; rrcConnectionSetupComplete->criticalExtensions.present = LTE_RRCConnectionSetupComplete__criticalExtensions_PR_c1; rrcConnectionSetupComplete->criticalExtensions.choice.c1.present = LTE_RRCConnectionSetupComplete__criticalExtensions__c1_PR_rrcConnectionSetupComplete_r8; - rrcConnectionSetupComplete->criticalExtensions.choice.c1.choice.rrcConnectionSetupComplete_r8.nonCriticalExtension=CALLOC(1, sizeof(*rrcConnectionSetupComplete->criticalExtensions.choice.c1.choice.rrcConnectionSetupComplete_r8.nonCriticalExtension)); - rrcConnectionSetupComplete->criticalExtensions.choice.c1.choice.rrcConnectionSetupComplete_r8.selectedPLMN_Identity= 1; - rrcConnectionSetupComplete->criticalExtensions.choice.c1.choice.rrcConnectionSetupComplete_r8.registeredMME = NULL;//calloc(1,sizeof(*rrcConnectionSetupComplete->criticalExtensions.choice.c1.choice.rrcConnectionSetupComplete_r8.registeredMME)); /* @@ -1695,22 +1519,19 @@ uint8_t do_RRCConnectionSetupComplete(uint8_t Mod_id, uint8_t *buffer, const uin memset(&rrcConnectionSetupComplete->criticalExtensions.choice.c1.choice.rrcConnectionSetupComplete_r8.dedicatedInfoNAS,0,sizeof(OCTET_STRING_t)); OCTET_STRING_fromBuf(&rrcConnectionSetupComplete->criticalExtensions.choice.c1.choice.rrcConnectionSetupComplete_r8.dedicatedInfoNAS, dedicatedInfoNAS, dedicatedInfoNASLength); - /* rrcConnectionSetupComplete->criticalExtensions.choice.c1.choice.rrcConnectionSetupComplete_r8.registeredMME->mmec.buf = calloc(1,1); rrcConnectionSetupComplete->criticalExtensions.choice.c1.choice.rrcConnectionSetupComplete_r8.registeredMME->mmec.buf[0] = 0x98; rrcConnectionSetupComplete->criticalExtensions.choice.c1.choice.rrcConnectionSetupComplete_r8.registeredMME->mmec.size=1; rrcConnectionSetupComplete->criticalExtensions.choice.c1.choice.rrcConnectionSetupComplete_r8.registeredMME->mmec.bits_unused=0; */ - enc_rval = uper_encode_to_buffer(&asn_DEF_LTE_UL_DCCH_Message, NULL, - (void*)&ul_dcch_msg, + (void *)&ul_dcch_msg, buffer, 100); AssertFatal (enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %lu)!\n", enc_rval.failed_type->name, enc_rval.encoded); - #if defined(ENABLE_ITTI) # if !defined(DISABLE_XER_SPRINT) { @@ -1719,59 +1540,45 @@ uint8_t do_RRCConnectionSetupComplete(uint8_t Mod_id, uint8_t *buffer, const uin if ((message_string_size = xer_sprint(message_string, sizeof(message_string), &asn_DEF_LTE_UL_DCCH_Message, (void *) &ul_dcch_msg)) > 0) { MessageDef *msg_p; - msg_p = itti_alloc_new_message_sized (TASK_RRC_UE, RRC_UL_DCCH, message_string_size + sizeof (IttiMsgText)); msg_p->ittiMsg.rrc_ul_dcch.size = message_string_size; memcpy(&msg_p->ittiMsg.rrc_ul_dcch.text, message_string, message_string_size); - itti_send_msg_to_task(TASK_UNKNOWN, NB_eNB_INST + Mod_id, msg_p); } } # endif #endif - LOG_D(RRC,"RRCConnectionSetupComplete Encoded %zd bits (%zd bytes)\n",enc_rval.encoded,(enc_rval.encoded+7)/8); - return((enc_rval.encoded+7)/8); - } //------------------------------------------------------------------------------ uint8_t do_RRCConnectionReconfigurationComplete( - const protocol_ctxt_t* const ctxt_pP, - uint8_t* buffer, + const protocol_ctxt_t *const ctxt_pP, + uint8_t *buffer, const uint8_t Transaction_id ) //------------------------------------------------------------------------------ { - - asn_enc_rval_t enc_rval; - LTE_UL_DCCH_Message_t ul_dcch_msg; - LTE_RRCConnectionReconfigurationComplete_t *rrcConnectionReconfigurationComplete; - memset((void *)&ul_dcch_msg,0,sizeof(LTE_UL_DCCH_Message_t)); - ul_dcch_msg.message.present = LTE_UL_DCCH_MessageType_PR_c1; ul_dcch_msg.message.choice.c1.present = LTE_UL_DCCH_MessageType__c1_PR_rrcConnectionReconfigurationComplete; rrcConnectionReconfigurationComplete = &ul_dcch_msg.message.choice.c1.choice.rrcConnectionReconfigurationComplete; - rrcConnectionReconfigurationComplete->rrc_TransactionIdentifier = Transaction_id; rrcConnectionReconfigurationComplete->criticalExtensions.present = LTE_RRCConnectionReconfigurationComplete__criticalExtensions_PR_rrcConnectionReconfigurationComplete_r8; rrcConnectionReconfigurationComplete->criticalExtensions.choice.rrcConnectionReconfigurationComplete_r8.nonCriticalExtension=NULL; - enc_rval = uper_encode_to_buffer(&asn_DEF_LTE_UL_DCCH_Message, NULL, - (void*)&ul_dcch_msg, + (void *)&ul_dcch_msg, buffer, 100); AssertFatal (enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %lu)!\n", enc_rval.failed_type->name, enc_rval.encoded); - #if defined(ENABLE_ITTI) # if !defined(DISABLE_XER_SPRINT) { @@ -1780,19 +1587,15 @@ do_RRCConnectionReconfigurationComplete( if ((message_string_size = xer_sprint(message_string, sizeof(message_string), &asn_DEF_LTE_UL_DCCH_Message, (void *) &ul_dcch_msg)) > 0) { MessageDef *msg_p; - msg_p = itti_alloc_new_message_sized (TASK_RRC_UE, RRC_UL_DCCH, message_string_size + sizeof (IttiMsgText)); msg_p->ittiMsg.rrc_ul_dcch.size = message_string_size; memcpy(&msg_p->ittiMsg.rrc_ul_dcch.text, message_string, message_string_size); - itti_send_msg_to_task(TASK_UNKNOWN, ctxt_pP->instance, msg_p); } } # endif #endif - LOG_D(RRC,"RRCConnectionReconfigurationComplete Encoded %zd bits (%zd bytes)\n",enc_rval.encoded,(enc_rval.encoded+7)/8); - return((enc_rval.encoded+7)/8); } @@ -1800,39 +1603,31 @@ do_RRCConnectionReconfigurationComplete( //------------------------------------------------------------------------------ uint8_t do_RRCConnectionSetup( - const protocol_ctxt_t* const ctxt_pP, - rrc_eNB_ue_context_t* const ue_context_pP, + const protocol_ctxt_t *const ctxt_pP, + rrc_eNB_ue_context_t *const ue_context_pP, int CC_id, - uint8_t* const buffer, + uint8_t *const buffer, const uint8_t transmission_mode, const uint8_t Transaction_id, LTE_SRB_ToAddModList_t **SRB_configList, - struct LTE_PhysicalConfigDedicated **physicalConfigDedicated) -{ - + struct LTE_PhysicalConfigDedicated **physicalConfigDedicated) { asn_enc_rval_t enc_rval; eNB_RRC_INST *rrc = RC.rrc[ctxt_pP->module_id]; rrc_eNB_carrier_data_t *carrier = &rrc->carrier[CC_id]; - - long* logicalchannelgroup = NULL; - struct LTE_SRB_ToAddMod* SRB1_config = NULL; - struct LTE_SRB_ToAddMod__rlc_Config* SRB1_rlc_config = NULL; - struct LTE_SRB_ToAddMod__logicalChannelConfig* SRB1_lchan_config = NULL; - struct LTE_LogicalChannelConfig__ul_SpecificParameters* SRB1_ul_SpecificParameters = NULL; - + long *logicalchannelgroup = NULL; + struct LTE_SRB_ToAddMod *SRB1_config = NULL; + struct LTE_SRB_ToAddMod__rlc_Config *SRB1_rlc_config = NULL; + struct LTE_SRB_ToAddMod__logicalChannelConfig *SRB1_lchan_config = NULL; + struct LTE_LogicalChannelConfig__ul_SpecificParameters *SRB1_ul_SpecificParameters = NULL; #ifdef CBA - struct LTE_PUSCH_CBAConfigDedicated_vlola* pusch_CBAConfigDedicated_vlola = NULL; - long* betaOffset_CBA_Index = NULL; - long* cShift_CBA = NULL; + struct LTE_PUSCH_CBAConfigDedicated_vlola *pusch_CBAConfigDedicated_vlola = NULL; + long *betaOffset_CBA_Index = NULL; + long *cShift_CBA = NULL; #endif - LTE_PhysicalConfigDedicated_t* physicalConfigDedicated2 = NULL; - + LTE_PhysicalConfigDedicated_t *physicalConfigDedicated2 = NULL; LTE_DL_CCCH_Message_t dl_ccch_msg; - - LTE_RRCConnectionSetup_t* rrcConnectionSetup = NULL; - + LTE_RRCConnectionSetup_t *rrcConnectionSetup = NULL; LTE_DL_FRAME_PARMS *frame_parms = &RC.eNB[ctxt_pP->module_id][CC_id]->frame_parms; - memset((void *)&dl_ccch_msg,0,sizeof(LTE_DL_CCCH_Message_t)); dl_ccch_msg.message.present = LTE_DL_CCCH_MessageType_PR_c1; dl_ccch_msg.message.choice.c1.present = LTE_DL_CCCH_MessageType__c1_PR_rrcConnectionSetup; @@ -1847,14 +1642,11 @@ do_RRCConnectionSetup( } *SRB_configList = CALLOC(1,sizeof(LTE_SRB_ToAddModList_t)); - /// SRB1 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 = LTE_SRB_ToAddMod__rlc_Config_PR_explicitValue; SRB1_rlc_config->choice.explicitValue.present=LTE_RLC_Config_PR_am; #if defined(ENABLE_ITTI) @@ -1864,44 +1656,31 @@ do_RRCConnectionSetup( SRB1_rlc_config->choice.explicitValue.choice.am.ul_AM_RLC.maxRetxThreshold = rrc->srb1_max_retx_threshold; SRB1_rlc_config->choice.explicitValue.choice.am.dl_AM_RLC.t_Reordering = rrc->srb1_timer_reordering; SRB1_rlc_config->choice.explicitValue.choice.am.dl_AM_RLC.t_StatusProhibit = rrc->srb1_timer_status_prohibit; -#else +#else SRB1_rlc_config->choice.explicitValue.choice.am.ul_AM_RLC.t_PollRetransmit = LTE_T_PollRetransmit_ms20;; SRB1_rlc_config->choice.explicitValue.choice.am.ul_AM_RLC.pollPDU = LTE_PollPDU_p4;; SRB1_rlc_config->choice.explicitValue.choice.am.ul_AM_RLC.pollByte = LTE_PollByte_kBinfinity; SRB1_rlc_config->choice.explicitValue.choice.am.ul_AM_RLC.maxRetxThreshold = LTE_UL_AM_RLC__maxRetxThreshold_t8; SRB1_rlc_config->choice.explicitValue.choice.am.dl_AM_RLC.t_Reordering = LTE_T_Reordering_ms35; SRB1_rlc_config->choice.explicitValue.choice.am.dl_AM_RLC.t_StatusProhibit = LTE_T_StatusProhibit_ms0; -#endif - +#endif SRB1_lchan_config = CALLOC(1,sizeof(*SRB1_lchan_config)); SRB1_config->logicalChannelConfig = SRB1_lchan_config; - SRB1_lchan_config->present = LTE_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=LTE_LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_infinity; - //assign_enum(&SRB1_ul_SpecificParameters->bucketSizeDuration,LogicalChannelConfig__ul_SpecificParameters__bucketSizeDuration_ms50); SRB1_ul_SpecificParameters->bucketSizeDuration=LTE_LogicalChannelConfig__ul_SpecificParameters__bucketSizeDuration_ms50; - logicalchannelgroup = CALLOC(1,sizeof(long)); *logicalchannelgroup=0; SRB1_ul_SpecificParameters->logicalChannelGroup = logicalchannelgroup; - - ASN_SEQUENCE_ADD(&(*SRB_configList)->list,SRB1_config); - // PhysicalConfigDedicated - 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)); @@ -1909,10 +1688,12 @@ do_RRCConnectionSetup( 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 = CALLOC(1,sizeof(*physicalConfigDedicated2->cqi_ReportConfig)); + if (rrc->srs_enable[CC_id]==1) physicalConfigDedicated2->soundingRS_UL_ConfigDedicated = CALLOC(1,sizeof(*physicalConfigDedicated2->soundingRS_UL_ConfigDedicated)); else physicalConfigDedicated2->soundingRS_UL_ConfigDedicated = NULL; + physicalConfigDedicated2->antennaInfo = CALLOC(1,sizeof(*physicalConfigDedicated2->antennaInfo)); physicalConfigDedicated2->schedulingRequestConfig = CALLOC(1,sizeof(*physicalConfigDedicated2->schedulingRequestConfig)); @@ -1940,7 +1721,6 @@ do_RRCConnectionSetup( 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, @@ -1953,9 +1733,7 @@ do_RRCConnectionSetup( sizeof(*physicalConfigDedicated2->uplinkPowerControlDedicated->filterCoefficient)); // assign_enum(physicalConfigDedicated2->uplinkPowerControlDedicated->filterCoefficient,FilterCoefficient_fc4); // fc4 dB *physicalConfigDedicated2->uplinkPowerControlDedicated->filterCoefficient=LTE_FilterCoefficient_fc4; // fc4 dB - // TPC-PDCCH-Config - physicalConfigDedicated2->tpc_PDCCH_ConfigPUCCH->present=LTE_TPC_PDCCH_Config_PR_setup; physicalConfigDedicated2->tpc_PDCCH_ConfigPUCCH->choice.setup.tpc_Index.present = LTE_TPC_Index_PR_indexOfFormat3; physicalConfigDedicated2->tpc_PDCCH_ConfigPUCCH->choice.setup.tpc_Index.choice.indexOfFormat3 = 1; @@ -1964,7 +1742,6 @@ do_RRCConnectionSetup( physicalConfigDedicated2->tpc_PDCCH_ConfigPUCCH->choice.setup.tpc_RNTI.buf[0]=0x12; physicalConfigDedicated2->tpc_PDCCH_ConfigPUCCH->choice.setup.tpc_RNTI.buf[1]=0x34+ue_context_pP->local_uid; physicalConfigDedicated2->tpc_PDCCH_ConfigPUCCH->choice.setup.tpc_RNTI.bits_unused=0; - physicalConfigDedicated2->tpc_PDCCH_ConfigPUSCH->present=LTE_TPC_PDCCH_Config_PR_setup; physicalConfigDedicated2->tpc_PDCCH_ConfigPUSCH->choice.setup.tpc_Index.present = LTE_TPC_Index_PR_indexOfFormat3; physicalConfigDedicated2->tpc_PDCCH_ConfigPUSCH->choice.setup.tpc_Index.choice.indexOfFormat3 = 1; @@ -1973,9 +1750,7 @@ do_RRCConnectionSetup( physicalConfigDedicated2->tpc_PDCCH_ConfigPUSCH->choice.setup.tpc_RNTI.buf[0]=0x22; physicalConfigDedicated2->tpc_PDCCH_ConfigPUSCH->choice.setup.tpc_RNTI.buf[1]=0x34+ue_context_pP->local_uid; 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)); #if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) *physicalConfigDedicated2->cqi_ReportConfig->cqi_ReportModeAperiodic= LTE_CQI_ReportModeAperiodic_rm30; @@ -1984,65 +1759,67 @@ do_RRCConnectionSetup( #endif physicalConfigDedicated2->cqi_ReportConfig->nomPDSCH_RS_EPRE_Offset = 0; // 0 dB //physicalConfigDedicated2->cqi_ReportConfig->cqi_ReportPeriodic=NULL; - physicalConfigDedicated2->cqi_ReportConfig->cqi_ReportPeriodic=CALLOC(1,sizeof(*physicalConfigDedicated2->cqi_ReportConfig->cqi_ReportPeriodic)); physicalConfigDedicated2->cqi_ReportConfig->cqi_ReportPeriodic->present = LTE_CQI_ReportPeriodic_PR_release; - /* - 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->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; - */ + physicalConfigDedicated2->cqi_ReportConfig->cqi_ReportPeriodic->choice.setup.ri_ConfigIndex=NULL; + physicalConfigDedicated2->cqi_ReportConfig->cqi_ReportPeriodic->choice.setup.simultaneousAckNackAndCQI=0; + */ //soundingRS-UL-ConfigDedicated if (rrc->srs_enable[CC_id]==1) { physicalConfigDedicated2->soundingRS_UL_ConfigDedicated->present = LTE_SoundingRS_UL_ConfigDedicated_PR_setup; physicalConfigDedicated2->soundingRS_UL_ConfigDedicated->choice.setup.srs_Bandwidth = - LTE_SoundingRS_UL_ConfigDedicated__setup__srs_Bandwidth_bw0; + LTE_SoundingRS_UL_ConfigDedicated__setup__srs_Bandwidth_bw0; physicalConfigDedicated2->soundingRS_UL_ConfigDedicated->choice.setup.srs_HoppingBandwidth = - LTE_SoundingRS_UL_ConfigDedicated__setup__srs_HoppingBandwidth_hbw0; + LTE_SoundingRS_UL_ConfigDedicated__setup__srs_HoppingBandwidth_hbw0; physicalConfigDedicated2->soundingRS_UL_ConfigDedicated->choice.setup.freqDomainPosition=0; physicalConfigDedicated2->soundingRS_UL_ConfigDedicated->choice.setup.duration=1; + if (carrier->sib1->tdd_Config==NULL) { // FDD if (carrier->sib2->radioResourceConfigCommon.soundingRS_UL_ConfigCommon.present - == LTE_SoundingRS_UL_ConfigCommon_PR_setup) - if (carrier->sib2->radioResourceConfigCommon.soundingRS_UL_ConfigCommon.choice.setup.srs_SubframeConfig!=0) - LOG_W(RRC,"This code has been optimized for SRS Subframe Config 0, but current config is %zd. Expect undefined behaviour!\n", - carrier->sib2->radioResourceConfigCommon.soundingRS_UL_ConfigCommon.choice.setup.srs_SubframeConfig); - if (ue_context_pP->local_uid >=20) - LOG_W(RRC,"This code has been optimized for up to 10 UEs, but current UE_id is %d. Expect undefined behaviour!\n", - ue_context_pP->local_uid); + == LTE_SoundingRS_UL_ConfigCommon_PR_setup) + if (carrier->sib2->radioResourceConfigCommon.soundingRS_UL_ConfigCommon.choice.setup.srs_SubframeConfig!=0) + LOG_W(RRC,"This code has been optimized for SRS Subframe Config 0, but current config is %zd. Expect undefined behaviour!\n", + carrier->sib2->radioResourceConfigCommon.soundingRS_UL_ConfigCommon.choice.setup.srs_SubframeConfig); + + if (ue_context_pP->local_uid >=20) + LOG_W(RRC,"This code has been optimized for up to 10 UEs, but current UE_id is %d. Expect undefined behaviour!\n", + ue_context_pP->local_uid); + //the current code will allow for 20 UEs - to be revised for more physicalConfigDedicated2->soundingRS_UL_ConfigDedicated->choice.setup.srs_ConfigIndex=7+ue_context_pP->local_uid/2; physicalConfigDedicated2->soundingRS_UL_ConfigDedicated->choice.setup.transmissionComb= ue_context_pP->local_uid%2; - } - else { + } else { if (carrier->sib2->radioResourceConfigCommon.soundingRS_UL_ConfigCommon.present - == LTE_SoundingRS_UL_ConfigCommon_PR_setup) - if (carrier->sib2->radioResourceConfigCommon.soundingRS_UL_ConfigCommon.choice.setup.srs_SubframeConfig!=7) { - LOG_W(RRC,"This code has been optimized for SRS Subframe Config 7 and TDD config 3, but current configs are %zd and %zd. Expect undefined behaviour!\n", - carrier->sib2->radioResourceConfigCommon.soundingRS_UL_ConfigCommon.choice.setup.srs_SubframeConfig, - carrier->sib1->tdd_Config->subframeAssignment); - } - if (ue_context_pP->local_uid >=6) - LOG_W(RRC,"This code has been optimized for up to 6 UEs, but current UE_id is %d. Expect undefined behaviour!\n", - ue_context_pP->local_uid); + == LTE_SoundingRS_UL_ConfigCommon_PR_setup) + if (carrier->sib2->radioResourceConfigCommon.soundingRS_UL_ConfigCommon.choice.setup.srs_SubframeConfig!=7) { + LOG_W(RRC,"This code has been optimized for SRS Subframe Config 7 and TDD config 3, but current configs are %zd and %zd. Expect undefined behaviour!\n", + carrier->sib2->radioResourceConfigCommon.soundingRS_UL_ConfigCommon.choice.setup.srs_SubframeConfig, + carrier->sib1->tdd_Config->subframeAssignment); + } + + if (ue_context_pP->local_uid >=6) + LOG_W(RRC,"This code has been optimized for up to 6 UEs, but current UE_id is %d. Expect undefined behaviour!\n", + ue_context_pP->local_uid); + physicalConfigDedicated2->soundingRS_UL_ConfigDedicated->choice.setup.srs_ConfigIndex=17+ue_context_pP->local_uid/2; physicalConfigDedicated2->soundingRS_UL_ConfigDedicated->choice.setup.transmissionComb= ue_context_pP->local_uid%2; } + LOG_W(RRC,"local UID %d, srs ConfigIndex %zd, TransmissionComb %zd\n",ue_context_pP->local_uid, - physicalConfigDedicated2->soundingRS_UL_ConfigDedicated->choice.setup.srs_ConfigIndex, - physicalConfigDedicated2->soundingRS_UL_ConfigDedicated->choice.setup.transmissionComb); - + physicalConfigDedicated2->soundingRS_UL_ConfigDedicated->choice.setup.srs_ConfigIndex, + physicalConfigDedicated2->soundingRS_UL_ConfigDedicated->choice.setup.transmissionComb); physicalConfigDedicated2->soundingRS_UL_ConfigDedicated->choice.setup.cyclicShift= - LTE_SoundingRS_UL_ConfigDedicated__setup__cyclicShift_cs0; + LTE_SoundingRS_UL_ConfigDedicated__setup__cyclicShift_cs0; } - //AntennaInfoDedicated physicalConfigDedicated2->antennaInfo = CALLOC(1,sizeof(*physicalConfigDedicated2->antennaInfo)); physicalConfigDedicated2->antennaInfo->present = LTE_PhysicalConfigDedicated__antennaInfo_PR_explicitValue; @@ -2050,99 +1827,102 @@ do_RRCConnectionSetup( // AntennaInfoDedicated__transmissionMode_tm2); switch (transmission_mode) { - default: - LOG_W(RRC,"At RRCConnectionSetup Transmission mode can only take values 1 or 2! Defaulting to 1!\n"); - case 1: - physicalConfigDedicated2->antennaInfo->choice.explicitValue.transmissionMode= LTE_AntennaInfoDedicated__transmissionMode_tm1; - break; + default: + LOG_W(RRC,"At RRCConnectionSetup Transmission mode can only take values 1 or 2! Defaulting to 1!\n"); - case 2: - physicalConfigDedicated2->antennaInfo->choice.explicitValue.transmissionMode= LTE_AntennaInfoDedicated__transmissionMode_tm2; - break; - /* - case 3: - physicalConfigDedicated2->antennaInfo->choice.explicitValue.transmissionMode= AntennaInfoDedicated__transmissionMode_tm3; - physicalConfigDedicated2->antennaInfo->choice.explicitValue.codebookSubsetRestriction= CALLOC(1, - sizeof(*physicalConfigDedicated2->antennaInfo->choice.explicitValue.codebookSubsetRestriction)); - physicalConfigDedicated2->antennaInfo->choice.explicitValue.codebookSubsetRestriction->present = - AntennaInfoDedicated__codebookSubsetRestriction_PR_n2TxAntenna_tm3; - physicalConfigDedicated2->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm3.buf= MALLOC(1); - physicalConfigDedicated2->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm3.buf[0] = 0xc0; - physicalConfigDedicated2->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm3.size=1; - physicalConfigDedicated2->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm3.bits_unused=6; + case 1: + physicalConfigDedicated2->antennaInfo->choice.explicitValue.transmissionMode= LTE_AntennaInfoDedicated__transmissionMode_tm1; + break; - break; + case 2: + physicalConfigDedicated2->antennaInfo->choice.explicitValue.transmissionMode= LTE_AntennaInfoDedicated__transmissionMode_tm2; + break; + /* + case 3: + physicalConfigDedicated2->antennaInfo->choice.explicitValue.transmissionMode= AntennaInfoDedicated__transmissionMode_tm3; + physicalConfigDedicated2->antennaInfo->choice.explicitValue.codebookSubsetRestriction= CALLOC(1, + sizeof(*physicalConfigDedicated2->antennaInfo->choice.explicitValue.codebookSubsetRestriction)); + physicalConfigDedicated2->antennaInfo->choice.explicitValue.codebookSubsetRestriction->present = + AntennaInfoDedicated__codebookSubsetRestriction_PR_n2TxAntenna_tm3; + physicalConfigDedicated2->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm3.buf= MALLOC(1); + physicalConfigDedicated2->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm3.buf[0] = 0xc0; + physicalConfigDedicated2->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm3.size=1; + physicalConfigDedicated2->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm3.bits_unused=6; - case 4: - physicalConfigDedicated2->antennaInfo->choice.explicitValue.transmissionMode= AntennaInfoDedicated__transmissionMode_tm4; - break; + break; - case 5: - physicalConfigDedicated2->antennaInfo->choice.explicitValue.transmissionMode= AntennaInfoDedicated__transmissionMode_tm5; - break; + case 4: + physicalConfigDedicated2->antennaInfo->choice.explicitValue.transmissionMode= AntennaInfoDedicated__transmissionMode_tm4; + break; - case 6: - physicalConfigDedicated2->antennaInfo->choice.explicitValue.transmissionMode= AntennaInfoDedicated__transmissionMode_tm6; - break; + case 5: + physicalConfigDedicated2->antennaInfo->choice.explicitValue.transmissionMode= AntennaInfoDedicated__transmissionMode_tm5; + break; - case 7: - physicalConfigDedicated2->antennaInfo->choice.explicitValue.transmissionMode= AntennaInfoDedicated__transmissionMode_tm7; - break; - */ + case 6: + physicalConfigDedicated2->antennaInfo->choice.explicitValue.transmissionMode= AntennaInfoDedicated__transmissionMode_tm6; + break; + + case 7: + physicalConfigDedicated2->antennaInfo->choice.explicitValue.transmissionMode= AntennaInfoDedicated__transmissionMode_tm7; + break; + */ } - physicalConfigDedicated2->antennaInfo->choice.explicitValue.ue_TransmitAntennaSelection.present = LTE_AntennaInfoDedicated__ue_TransmitAntennaSelection_PR_release; physicalConfigDedicated2->antennaInfo->choice.explicitValue.ue_TransmitAntennaSelection.choice.release = 0; - // SchedulingRequestConfig - physicalConfigDedicated2->schedulingRequestConfig->present = LTE_SchedulingRequestConfig_PR_setup; + if (carrier->sib1->tdd_Config == NULL) { physicalConfigDedicated2->schedulingRequestConfig->choice.setup.sr_PUCCH_ResourceIndex = 71 - ue_context_pP->local_uid/10;//ue_context_pP->local_uid; } else { - switch (carrier->sib1->tdd_Config->subframeAssignment) { + switch (carrier->sib1->tdd_Config->subframeAssignment) { case 1: - switch(frame_parms->N_RB_UL){ + switch(frame_parms->N_RB_UL) { case 25: - physicalConfigDedicated2->schedulingRequestConfig->choice.setup.sr_PUCCH_ResourceIndex = 15 - ue_context_pP->local_uid/4; - break; + physicalConfigDedicated2->schedulingRequestConfig->choice.setup.sr_PUCCH_ResourceIndex = 15 - ue_context_pP->local_uid/4; + break; + case 50: - physicalConfigDedicated2->schedulingRequestConfig->choice.setup.sr_PUCCH_ResourceIndex = 31 - ue_context_pP->local_uid/4; - break; + physicalConfigDedicated2->schedulingRequestConfig->choice.setup.sr_PUCCH_ResourceIndex = 31 - ue_context_pP->local_uid/4; + break; + case 100: - physicalConfigDedicated2->schedulingRequestConfig->choice.setup.sr_PUCCH_ResourceIndex = 63 - ue_context_pP->local_uid/4; - break; - } - break; + physicalConfigDedicated2->schedulingRequestConfig->choice.setup.sr_PUCCH_ResourceIndex = 63 - ue_context_pP->local_uid/4; + break; + } + + break; + default: - physicalConfigDedicated2->schedulingRequestConfig->choice.setup.sr_PUCCH_ResourceIndex = 71 - ue_context_pP->local_uid/10;//ue_context_pP->local_uid; - break; - } + physicalConfigDedicated2->schedulingRequestConfig->choice.setup.sr_PUCCH_ResourceIndex = 71 - ue_context_pP->local_uid/10;//ue_context_pP->local_uid; + break; + } } if (carrier->sib1->tdd_Config == NULL) { // FDD physicalConfigDedicated2->schedulingRequestConfig->choice.setup.sr_ConfigIndex = 5+(ue_context_pP->local_uid%10); // Isr = 5 (every 10 subframes, offset=2+UE_id mod3) } else { switch (carrier->sib1->tdd_Config->subframeAssignment) { - case 1: - physicalConfigDedicated2->schedulingRequestConfig->choice.setup.sr_ConfigIndex = 7+(ue_context_pP->local_uid&1)+(( - ue_context_pP->local_uid&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 1: + physicalConfigDedicated2->schedulingRequestConfig->choice.setup.sr_ConfigIndex = 7+(ue_context_pP->local_uid&1)+(( + ue_context_pP->local_uid&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_context_pP->local_uid%3); // Isr = 5 (every 10 subframes, offset=2 for UE0, 3 for UE1, 3 for UE2, 2 for UE3 , etc..) - break; + case 3: + physicalConfigDedicated2->schedulingRequestConfig->choice.setup.sr_ConfigIndex = 7+ + (ue_context_pP->local_uid%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_context_pP->local_uid&1); // 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_context_pP->local_uid&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; + default: + physicalConfigDedicated2->schedulingRequestConfig->choice.setup.sr_ConfigIndex = 7; // Isr = 5 (every 10 subframes, offset=2 for all UE0 etc..) + break; } } @@ -2150,7 +1930,6 @@ do_RRCConnectionSetup( //SchedulingRequestConfig__setup__dsr_TransMax_n4); // assign_enum(&physicalConfigDedicated2->schedulingRequestConfig->choice.setup.dsr_TransMax = SchedulingRequestConfig__setup__dsr_TransMax_n4; physicalConfigDedicated2->schedulingRequestConfig->choice.setup.dsr_TransMax = LTE_SchedulingRequestConfig__setup__dsr_TransMax_n4; - rrcConnectionSetup->rrc_TransactionIdentifier = Transaction_id; rrcConnectionSetup->criticalExtensions.present = LTE_RRCConnectionSetup__criticalExtensions_PR_c1; rrcConnectionSetup->criticalExtensions.choice.c1.present = LTE_RRCConnectionSetup__criticalExtensions__c1_PR_rrcConnectionSetup_r8 ; @@ -2170,21 +1949,22 @@ do_RRCConnectionSetup( rrcConnectionSetup->criticalExtensions.choice.c1.choice.rrcConnectionSetup_r8.radioResourceConfigDedicated.sps_CBA_ConfigList_vlola = NULL; #endif - if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) { - xer_fprint(stdout, &asn_DEF_LTE_DL_CCCH_Message, (void*)&dl_ccch_msg); + xer_fprint(stdout, &asn_DEF_LTE_DL_CCCH_Message, (void *)&dl_ccch_msg); } + enc_rval = uper_encode_to_buffer(&asn_DEF_LTE_DL_CCCH_Message, NULL, - (void*)&dl_ccch_msg, + (void *)&dl_ccch_msg, buffer, 100); - if(enc_rval.encoded == -1) - { - LOG_I(RRC, "[eNB AssertFatal]ASN1 message encoding failed (%s, %lu)!\n", - enc_rval.failed_type->name, enc_rval.encoded); - return -1; + + if(enc_rval.encoded == -1) { + LOG_I(RRC, "[eNB AssertFatal]ASN1 message encoding failed (%s, %lu)!\n", + enc_rval.failed_type->name, enc_rval.encoded); + return -1; } + #if defined(ENABLE_ITTI) # if !defined(DISABLE_XER_SPRINT) { @@ -2193,34 +1973,29 @@ do_RRCConnectionSetup( if ((message_string_size = xer_sprint(message_string, sizeof(message_string), &asn_DEF_LTE_DL_CCCH_Message, (void *) &dl_ccch_msg)) > 0) { MessageDef *msg_p; - msg_p = itti_alloc_new_message_sized (TASK_RRC_ENB, RRC_DL_CCCH, message_string_size + sizeof (IttiMsgText)); msg_p->ittiMsg.rrc_dl_ccch.size = message_string_size; memcpy(&msg_p->ittiMsg.rrc_dl_ccch.text, message_string, message_string_size); - itti_send_msg_to_task(TASK_UNKNOWN, ctxt_pP->instance, msg_p); } } # endif #endif - LOG_D(RRC,"RRCConnectionSetup Encoded %zd bits (%zd bytes) \n", enc_rval.encoded,(enc_rval.encoded+7)/8); - // FREEMEM(SRB_list); // free(SRB1_config); // free(SRB1_rlc_config); // free(SRB1_lchan_config); // free(SRB1_ul_SpecificParameters); - return((enc_rval.encoded+7)/8); } //------------------------------------------------------------------------------ uint8_t do_SecurityModeCommand( - const protocol_ctxt_t* const ctxt_pP, - uint8_t* const buffer, + const protocol_ctxt_t *const ctxt_pP, + uint8_t *const buffer, const uint8_t Transaction_id, const uint8_t cipheringAlgorithm, const uint8_t integrityProtAlgorithm @@ -2229,15 +2004,11 @@ do_SecurityModeCommand( { LTE_DL_DCCH_Message_t dl_dcch_msg; asn_enc_rval_t enc_rval; - memset(&dl_dcch_msg,0,sizeof(LTE_DL_DCCH_Message_t)); - dl_dcch_msg.message.present = LTE_DL_DCCH_MessageType_PR_c1; dl_dcch_msg.message.choice.c1.present = LTE_DL_DCCH_MessageType__c1_PR_securityModeCommand; - dl_dcch_msg.message.choice.c1.choice.securityModeCommand.rrc_TransactionIdentifier = Transaction_id; dl_dcch_msg.message.choice.c1.choice.securityModeCommand.criticalExtensions.present = LTE_SecurityModeCommand__criticalExtensions_PR_c1; - dl_dcch_msg.message.choice.c1.choice.securityModeCommand.criticalExtensions.choice.c1.present = LTE_SecurityModeCommand__criticalExtensions__c1_PR_securityModeCommand_r8; // the two following information could be based on the mod_id @@ -2247,19 +2018,21 @@ do_SecurityModeCommand( = (e_LTE_SecurityAlgorithmConfig__integrityProtAlgorithm)integrityProtAlgorithm; if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) { - xer_fprint(stdout, &asn_DEF_LTE_DL_DCCH_Message, (void*)&dl_dcch_msg); + xer_fprint(stdout, &asn_DEF_LTE_DL_DCCH_Message, (void *)&dl_dcch_msg); } + enc_rval = uper_encode_to_buffer(&asn_DEF_LTE_DL_DCCH_Message, NULL, - (void*)&dl_dcch_msg, + (void *)&dl_dcch_msg, buffer, 100); - if(enc_rval.encoded == -1) - { - LOG_I(RRC, "[eNB AssertFatal]ASN1 message encoding failed (%s, %lu)!\n", - enc_rval.failed_type->name, enc_rval.encoded); - return -1; + + if(enc_rval.encoded == -1) { + LOG_I(RRC, "[eNB AssertFatal]ASN1 message encoding failed (%s, %lu)!\n", + enc_rval.failed_type->name, enc_rval.encoded); + return -1; } + #if defined(ENABLE_ITTI) # if !defined(DISABLE_XER_SPRINT) { @@ -2268,17 +2041,14 @@ do_SecurityModeCommand( if ((message_string_size = xer_sprint(message_string, sizeof(message_string), &asn_DEF_LTE_DL_DCCH_Message, (void *) &dl_dcch_msg)) > 0) { MessageDef *msg_p; - msg_p = itti_alloc_new_message_sized (TASK_RRC_ENB, RRC_DL_DCCH, message_string_size + sizeof (IttiMsgText)); msg_p->ittiMsg.rrc_dl_dcch.size = message_string_size; memcpy(&msg_p->ittiMsg.rrc_dl_dcch.text, message_string, message_string_size); - itti_send_msg_to_task(TASK_UNKNOWN, ctxt_pP->instance, msg_p); } } # endif #endif - LOG_D(RRC,"[eNB %d] securityModeCommand for UE %x Encoded %zd bits (%zd bytes)\n", ctxt_pP->module_id, ctxt_pP->rnti, @@ -2300,25 +2070,19 @@ do_SecurityModeCommand( //------------------------------------------------------------------------------ uint8_t do_UECapabilityEnquiry( - const protocol_ctxt_t* const ctxt_pP, - uint8_t* const buffer, + const protocol_ctxt_t *const ctxt_pP, + uint8_t *const buffer, const uint8_t Transaction_id ) //------------------------------------------------------------------------------ { - LTE_DL_DCCH_Message_t dl_dcch_msg; - LTE_RAT_Type_t rat=LTE_RAT_Type_eutra; asn_enc_rval_t enc_rval; - memset(&dl_dcch_msg,0,sizeof(LTE_DL_DCCH_Message_t)); - dl_dcch_msg.message.present = LTE_DL_DCCH_MessageType_PR_c1; dl_dcch_msg.message.choice.c1.present = LTE_DL_DCCH_MessageType__c1_PR_ueCapabilityEnquiry; - dl_dcch_msg.message.choice.c1.choice.ueCapabilityEnquiry.rrc_TransactionIdentifier = Transaction_id; - dl_dcch_msg.message.choice.c1.choice.ueCapabilityEnquiry.criticalExtensions.present = LTE_UECapabilityEnquiry__criticalExtensions_PR_c1; dl_dcch_msg.message.choice.c1.choice.ueCapabilityEnquiry.criticalExtensions.choice.c1.present = LTE_UECapabilityEnquiry__criticalExtensions__c1_PR_ueCapabilityEnquiry_r8; @@ -2327,19 +2091,21 @@ do_UECapabilityEnquiry( &rat); if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) { - xer_fprint(stdout, &asn_DEF_LTE_DL_DCCH_Message, (void*)&dl_dcch_msg); + xer_fprint(stdout, &asn_DEF_LTE_DL_DCCH_Message, (void *)&dl_dcch_msg); } + enc_rval = uper_encode_to_buffer(&asn_DEF_LTE_DL_DCCH_Message, NULL, - (void*)&dl_dcch_msg, + (void *)&dl_dcch_msg, buffer, 100); - if(enc_rval.encoded == -1) - { - LOG_I(RRC, "[eNB AssertFatal]ASN1 message encoding failed (%s, %lu)!\n", - enc_rval.failed_type->name, enc_rval.encoded); - return -1; + + if(enc_rval.encoded == -1) { + LOG_I(RRC, "[eNB AssertFatal]ASN1 message encoding failed (%s, %lu)!\n", + enc_rval.failed_type->name, enc_rval.encoded); + return -1; } + #if defined(ENABLE_ITTI) # if !defined(DISABLE_XER_SPRINT) { @@ -2348,17 +2114,14 @@ do_UECapabilityEnquiry( if ((message_string_size = xer_sprint(message_string, sizeof(message_string), &asn_DEF_LTE_DL_DCCH_Message, (void *) &dl_dcch_msg)) > 0) { MessageDef *msg_p; - msg_p = itti_alloc_new_message_sized (TASK_RRC_ENB, RRC_DL_CCCH, message_string_size + sizeof (IttiMsgText)); msg_p->ittiMsg.rrc_dl_ccch.size = message_string_size; memcpy(&msg_p->ittiMsg.rrc_dl_ccch.text, message_string, message_string_size); - itti_send_msg_to_task(TASK_UNKNOWN, ctxt_pP->instance, msg_p); } } # endif #endif - LOG_D(RRC,"[eNB %d] UECapabilityRequest for UE %x Encoded %zd bits (%zd bytes)\n", ctxt_pP->module_id, ctxt_pP->rnti, @@ -2378,7 +2141,7 @@ do_UECapabilityEnquiry( //------------------------------------------------------------------------------ uint16_t do_RRCConnectionReconfiguration( - const protocol_ctxt_t* const ctxt_pP, + const protocol_ctxt_t *const ctxt_pP, uint8_t *buffer, uint8_t Transaction_id, LTE_SRB_ToAddModList_t *SRB_list, @@ -2407,24 +2170,17 @@ do_RRCConnectionReconfiguration( ) //------------------------------------------------------------------------------ { - asn_enc_rval_t enc_rval; - LTE_DL_DCCH_Message_t dl_dcch_msg; LTE_RRCConnectionReconfiguration_t *rrcConnectionReconfiguration; - - memset(&dl_dcch_msg,0,sizeof(LTE_DL_DCCH_Message_t)); - dl_dcch_msg.message.present = LTE_DL_DCCH_MessageType_PR_c1; dl_dcch_msg.message.choice.c1.present = LTE_DL_DCCH_MessageType__c1_PR_rrcConnectionReconfiguration; rrcConnectionReconfiguration = &dl_dcch_msg.message.choice.c1.choice.rrcConnectionReconfiguration; - // RRCConnectionReconfiguration rrcConnectionReconfiguration->rrc_TransactionIdentifier = Transaction_id; rrcConnectionReconfiguration->criticalExtensions.present = LTE_RRCConnectionReconfiguration__criticalExtensions_PR_c1; rrcConnectionReconfiguration->criticalExtensions.choice.c1.present = LTE_RRCConnectionReconfiguration__criticalExtensions__c1_PR_rrcConnectionReconfiguration_r8 ; - rrcConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.radioResourceConfigDedicated = CALLOC(1, sizeof(*rrcConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.radioResourceConfigDedicated)); rrcConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.radioResourceConfigDedicated->srb_ToAddModList = SRB_list; @@ -2451,9 +2207,8 @@ do_RRCConnectionReconfiguration( if (MeasId_list != NULL) { rrcConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.measConfig = CALLOC(1, sizeof(*rrcConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.measConfig)); - memset((void*)rrcConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.measConfig, + memset((void *)rrcConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.measConfig, 0, sizeof(*rrcConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.measConfig)); - 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; @@ -2485,9 +2240,8 @@ do_RRCConnectionReconfiguration( 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, + memcpy((void *)rrcConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.mobilityControlInfo, (void *)mobilityInfo, sizeof(LTE_MobilityControlInfo_t)); - } else { rrcConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.mobilityControlInfo = NULL; } @@ -2498,55 +2252,64 @@ do_RRCConnectionReconfiguration( //TTN for D2D //allocate dedicated resource pools for SL communication (sl_CommConfig_r12) if (sl_CommConfig != NULL) { - LOG_I(RRC,"[RRCConnectionReconfiguration] allocating a dedicated resource pool for SL communication \n"); - rrcConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.nonCriticalExtension = CALLOC(1, - sizeof(*rrcConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.nonCriticalExtension)); - rrcConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.nonCriticalExtension->nonCriticalExtension = CALLOC(1, - sizeof(*rrcConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.nonCriticalExtension->nonCriticalExtension)); - rrcConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.nonCriticalExtension->nonCriticalExtension->nonCriticalExtension = CALLOC(1, - sizeof(*rrcConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.nonCriticalExtension->nonCriticalExtension->nonCriticalExtension)); - rrcConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension = CALLOC(1, - sizeof(*rrcConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension)); - rrcConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension = CALLOC(1, - sizeof(*rrcConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension)); - rrcConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->sl_CommConfig_r12 = CALLOC(1, - sizeof(*rrcConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->sl_CommConfig_r12)); - memcpy((void*)rrcConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->sl_CommConfig_r12, (void*)sl_CommConfig, - sizeof(LTE_SL_CommConfig_r12_t)); + LOG_I(RRC,"[RRCConnectionReconfiguration] allocating a dedicated resource pool for SL communication \n"); + rrcConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.nonCriticalExtension = CALLOC(1, + sizeof(*rrcConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.nonCriticalExtension)); + rrcConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.nonCriticalExtension->nonCriticalExtension = CALLOC(1, + sizeof(*rrcConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.nonCriticalExtension->nonCriticalExtension)); + rrcConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.nonCriticalExtension->nonCriticalExtension->nonCriticalExtension = CALLOC(1, + sizeof(*rrcConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.nonCriticalExtension->nonCriticalExtension->nonCriticalExtension)); + rrcConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension = CALLOC(1, + sizeof(*rrcConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension)); + rrcConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension + = CALLOC(1, + sizeof(*rrcConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension)); + rrcConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->sl_CommConfig_r12 + = CALLOC(1, + sizeof(*rrcConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->sl_CommConfig_r12)); + memcpy((void *) + rrcConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->sl_CommConfig_r12, + (void *)sl_CommConfig, + sizeof(LTE_SL_CommConfig_r12_t)); } //allocate dedicated resource pools for SL discovery (sl_DiscConfig) - if (sl_DiscConfig != NULL){ - LOG_I(RRC,"[RRCConnectionReconfiguration] allocating a dedicated resource pool for SL discovery \n"); - rrcConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.nonCriticalExtension = CALLOC(1, - sizeof(*rrcConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.nonCriticalExtension)); - rrcConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.nonCriticalExtension->nonCriticalExtension = CALLOC(1, - sizeof(*rrcConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.nonCriticalExtension->nonCriticalExtension)); - rrcConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.nonCriticalExtension->nonCriticalExtension->nonCriticalExtension = CALLOC(1, - sizeof(*rrcConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.nonCriticalExtension->nonCriticalExtension->nonCriticalExtension)); - rrcConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension = CALLOC(1, - sizeof(*rrcConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension)); - rrcConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension = CALLOC(1, - sizeof(*rrcConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension)); - rrcConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->sl_DiscConfig_r12 = CALLOC(1, - sizeof(*rrcConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->sl_DiscConfig_r12)); - memcpy((void*)rrcConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->sl_DiscConfig_r12, (void*)sl_DiscConfig, - sizeof(LTE_SL_DiscConfig_r12_t)); + if (sl_DiscConfig != NULL) { + LOG_I(RRC,"[RRCConnectionReconfiguration] allocating a dedicated resource pool for SL discovery \n"); + rrcConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.nonCriticalExtension = CALLOC(1, + sizeof(*rrcConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.nonCriticalExtension)); + rrcConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.nonCriticalExtension->nonCriticalExtension = CALLOC(1, + sizeof(*rrcConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.nonCriticalExtension->nonCriticalExtension)); + rrcConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.nonCriticalExtension->nonCriticalExtension->nonCriticalExtension = CALLOC(1, + sizeof(*rrcConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.nonCriticalExtension->nonCriticalExtension->nonCriticalExtension)); + rrcConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension = CALLOC(1, + sizeof(*rrcConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension)); + rrcConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension + = CALLOC(1, + sizeof(*rrcConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension)); + rrcConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->sl_DiscConfig_r12 + = CALLOC(1, + sizeof(*rrcConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->sl_DiscConfig_r12)); + memcpy((void *) + rrcConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->sl_DiscConfig_r12, + (void *)sl_DiscConfig, + sizeof(LTE_SL_DiscConfig_r12_t)); } enc_rval = uper_encode_to_buffer(&asn_DEF_LTE_DL_DCCH_Message, NULL, - (void*)&dl_dcch_msg, + (void *)&dl_dcch_msg, buffer, RRC_BUF_SIZE); - if(enc_rval.encoded == -1) - { - LOG_I(RRC, "[eNB AssertFatal]ASN1 message encoding failed (%s, %lu)!\n", - enc_rval.failed_type->name, enc_rval.encoded); - return -1; + + if(enc_rval.encoded == -1) { + LOG_I(RRC, "[eNB AssertFatal]ASN1 message encoding failed (%s, %lu)!\n", + enc_rval.failed_type->name, enc_rval.encoded); + return -1; } + if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) { - xer_fprint(stdout,&asn_DEF_LTE_DL_DCCH_Message,(void*)&dl_dcch_msg); + xer_fprint(stdout,&asn_DEF_LTE_DL_DCCH_Message,(void *)&dl_dcch_msg); } #if defined(ENABLE_ITTI) @@ -2557,67 +2320,57 @@ do_RRCConnectionReconfiguration( if ((message_string_size = xer_sprint(message_string, sizeof(message_string), &asn_DEF_LTE_DL_DCCH_Message, (void *) &dl_dcch_msg)) > 0) { MessageDef *msg_p; - msg_p = itti_alloc_new_message_sized (TASK_RRC_ENB, RRC_DL_DCCH, message_string_size + sizeof (IttiMsgText)); msg_p->ittiMsg.rrc_dl_dcch.size = message_string_size; memcpy(&msg_p->ittiMsg.rrc_dl_dcch.text, message_string, message_string_size); - itti_send_msg_to_task(TASK_UNKNOWN, ctxt_pP->instance, msg_p); } } # endif #endif - LOG_I(RRC,"RRCConnectionReconfiguration Encoded %zd bits (%zd bytes)\n",enc_rval.encoded,(enc_rval.encoded+7)/8); // for (i=0;i<30;i++) // msg("%x.",buffer[i]); // msg("\n"); - - return((enc_rval.encoded+7)/8); } //------------------------------------------------------------------------------ uint8_t do_RRCConnectionReestablishment( - const protocol_ctxt_t* const ctxt_pP, - rrc_eNB_ue_context_t* const ue_context_pP, + const protocol_ctxt_t *const ctxt_pP, + rrc_eNB_ue_context_t *const ue_context_pP, int CC_id, - uint8_t* const buffer, + uint8_t *const buffer, const uint8_t transmission_mode, const uint8_t Transaction_id, LTE_SRB_ToAddModList_t **SRB_configList, - struct LTE_PhysicalConfigDedicated **physicalConfigDedicated) -{ + struct LTE_PhysicalConfigDedicated **physicalConfigDedicated) { asn_enc_rval_t enc_rval; - - long* logicalchannelgroup = NULL; - struct LTE_SRB_ToAddMod* SRB1_config = NULL; - struct LTE_SRB_ToAddMod* SRB2_config = NULL; - struct LTE_SRB_ToAddMod__rlc_Config* SRB1_rlc_config = NULL; - struct LTE_SRB_ToAddMod__logicalChannelConfig* SRB1_lchan_config = NULL; - struct LTE_LogicalChannelConfig__ul_SpecificParameters* SRB1_ul_SpecificParameters = NULL; + long *logicalchannelgroup = NULL; + struct LTE_SRB_ToAddMod *SRB1_config = NULL; + struct LTE_SRB_ToAddMod *SRB2_config = NULL; + struct LTE_SRB_ToAddMod__rlc_Config *SRB1_rlc_config = NULL; + struct LTE_SRB_ToAddMod__logicalChannelConfig *SRB1_lchan_config = NULL; + struct LTE_LogicalChannelConfig__ul_SpecificParameters *SRB1_ul_SpecificParameters = NULL; eNB_RRC_INST *rrc = RC.rrc[ctxt_pP->module_id]; - #ifdef CBA - struct LTE_PUSCH_CBAConfigDedicated_vlola* pusch_CBAConfigDedicated_vlola = NULL; - long* betaOffset_CBA_Index = NULL; - long* cShift_CBA = NULL; + struct LTE_PUSCH_CBAConfigDedicated_vlola *pusch_CBAConfigDedicated_vlola = NULL; + long *betaOffset_CBA_Index = NULL; + long *cShift_CBA = NULL; #endif - LTE_PhysicalConfigDedicated_t* physicalConfigDedicated2 = NULL; - + LTE_PhysicalConfigDedicated_t *physicalConfigDedicated2 = NULL; LTE_DL_CCCH_Message_t dl_ccch_msg; - - LTE_RRCConnectionReestablishment_t* rrcConnectionReestablishment = NULL; - + LTE_RRCConnectionReestablishment_t *rrcConnectionReestablishment = NULL; int i = 0; LTE_SRB_ToAddModList_t **SRB_configList2 = NULL; SRB_configList2 = &ue_context_pP->ue_context.SRB_configList2[Transaction_id]; + if (*SRB_configList2) { free(*SRB_configList2); } - *SRB_configList2 = CALLOC(1, sizeof(LTE_SRB_ToAddModList_t)); + *SRB_configList2 = CALLOC(1, sizeof(LTE_SRB_ToAddModList_t)); memset((void *)&dl_ccch_msg, 0, sizeof(LTE_DL_CCCH_Message_t)); dl_ccch_msg.message.present = LTE_DL_CCCH_MessageType_PR_c1; dl_ccch_msg.message.choice.c1.present = LTE_DL_CCCH_MessageType__c1_PR_rrcConnectionReestablishment; @@ -2626,15 +2379,15 @@ do_RRCConnectionReestablishment( // RRCConnectionReestablishment // Configure SRB1 - // get old configuration of SRB2 if (*SRB_configList != NULL) { for (i = 0; (i < (*SRB_configList)->list.count) && (i < 3); i++) { LOG_D(RRC, "(*SRB_configList)->list.array[%d]->srb_Identity=%ld\n", - i, (*SRB_configList)->list.array[i]->srb_Identity); - if ((*SRB_configList)->list.array[i]->srb_Identity == 2 ){ + i, (*SRB_configList)->list.array[i]->srb_Identity); + + if ((*SRB_configList)->list.array[i]->srb_Identity == 2 ) { SRB2_config = (*SRB_configList)->list.array[i]; - } else if ((*SRB_configList)->list.array[i]->srb_Identity == 1 ){ + } else if ((*SRB_configList)->list.array[i]->srb_Identity == 1 ) { SRB1_config = (*SRB_configList)->list.array[i]; } } @@ -2645,44 +2398,36 @@ do_RRCConnectionReestablishment( LOG_W(RRC,"SRB1 configuration does not exist in SRB configuration list, use default\n"); /// SRB1 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 = LTE_SRB_ToAddMod__rlc_Config_PR_explicitValue; SRB1_rlc_config->choice.explicitValue.present=LTE_RLC_Config_PR_am; - #if defined(ENABLE_ITTI) +#if defined(ENABLE_ITTI) SRB1_rlc_config->choice.explicitValue.choice.am.ul_AM_RLC.t_PollRetransmit = rrc->srb1_timer_poll_retransmit; SRB1_rlc_config->choice.explicitValue.choice.am.ul_AM_RLC.pollPDU = rrc->srb1_poll_pdu; SRB1_rlc_config->choice.explicitValue.choice.am.ul_AM_RLC.pollByte = rrc->srb1_poll_byte; SRB1_rlc_config->choice.explicitValue.choice.am.ul_AM_RLC.maxRetxThreshold = rrc->srb1_max_retx_threshold; SRB1_rlc_config->choice.explicitValue.choice.am.dl_AM_RLC.t_Reordering = rrc->srb1_timer_reordering; SRB1_rlc_config->choice.explicitValue.choice.am.dl_AM_RLC.t_StatusProhibit = rrc->srb1_timer_status_prohibit; - #else +#else SRB1_rlc_config->choice.explicitValue.choice.am.ul_AM_RLC.t_PollRetransmit = LTE_T_PollRetransmit_ms20;; SRB1_rlc_config->choice.explicitValue.choice.am.ul_AM_RLC.pollPDU = LTE_PollPDU_p4;; SRB1_rlc_config->choice.explicitValue.choice.am.ul_AM_RLC.pollByte = LTE_PollByte_kBinfinity; SRB1_rlc_config->choice.explicitValue.choice.am.ul_AM_RLC.maxRetxThreshold = LTE_UL_AM_RLC__maxRetxThreshold_t8; SRB1_rlc_config->choice.explicitValue.choice.am.dl_AM_RLC.t_Reordering = LTE_T_Reordering_ms35; SRB1_rlc_config->choice.explicitValue.choice.am.dl_AM_RLC.t_StatusProhibit = LTE_T_StatusProhibit_ms0; - #endif - +#endif SRB1_lchan_config = CALLOC(1, sizeof(*SRB1_lchan_config)); SRB1_config->logicalChannelConfig = SRB1_lchan_config; - SRB1_lchan_config->present = LTE_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=LTE_LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_infinity; - //assign_enum(&SRB1_ul_SpecificParameters->bucketSizeDuration,LogicalChannelConfig__ul_SpecificParameters__bucketSizeDuration_ms50); SRB1_ul_SpecificParameters->bucketSizeDuration=LTE_LogicalChannelConfig__ul_SpecificParameters__bucketSizeDuration_ms50; - logicalchannelgroup = CALLOC(1, sizeof(long)); *logicalchannelgroup = 0; SRB1_ul_SpecificParameters->logicalChannelGroup = logicalchannelgroup; @@ -2699,11 +2444,8 @@ do_RRCConnectionReestablishment( } *SRB_configList = CALLOC(1, sizeof(LTE_SRB_ToAddModList_t)); - ASN_SEQUENCE_ADD(&(*SRB_configList)->list,SRB1_config); - physicalConfigDedicated2 = *physicalConfigDedicated; - rrcConnectionReestablishment->rrc_TransactionIdentifier = Transaction_id; rrcConnectionReestablishment->criticalExtensions.present = LTE_RRCConnectionReestablishment__criticalExtensions_PR_c1; rrcConnectionReestablishment->criticalExtensions.choice.c1.present = LTE_RRCConnectionReestablishment__criticalExtensions__c1_PR_rrcConnectionReestablishment_r8; @@ -2713,27 +2455,28 @@ do_RRCConnectionReestablishment( rrcConnectionReestablishment->criticalExtensions.choice.c1.choice.rrcConnectionReestablishment_r8.radioResourceConfigDedicated.sps_Config = NULL; rrcConnectionReestablishment->criticalExtensions.choice.c1.choice.rrcConnectionReestablishment_r8.radioResourceConfigDedicated.physicalConfigDedicated = physicalConfigDedicated2; rrcConnectionReestablishment->criticalExtensions.choice.c1.choice.rrcConnectionReestablishment_r8.radioResourceConfigDedicated.mac_MainConfig = NULL; - uint8_t KeNB_star[32] = { 0 }; uint16_t pci = rrc->carrier[CC_id].physCellId; uint32_t earfcn_dl = (uint32_t)freq_to_arfcn10(RC.mac[ctxt_pP->module_id]->common_channels[CC_id].eutra_band, - rrc->carrier[CC_id].dl_CarrierFreq); + rrc->carrier[CC_id].dl_CarrierFreq); bool is_rel8_only = true; + if (earfcn_dl > 65535) { is_rel8_only = false; } LOG_D(RRC, "pci=%d, eutra_band=%d, downlink_frequency=%d, earfcn_dl=%u, is_rel8_only=%s\n", - pci, - RC.mac[ctxt_pP->module_id]->common_channels[CC_id].eutra_band, - rrc->carrier[CC_id].dl_CarrierFreq, - earfcn_dl, - is_rel8_only == true ? "true": "false"); + pci, + RC.mac[ctxt_pP->module_id]->common_channels[CC_id].eutra_band, + rrc->carrier[CC_id].dl_CarrierFreq, + earfcn_dl, + is_rel8_only == true ? "true": "false"); #if defined(ENABLE_SECURITY) + if (ue_context_pP->ue_context.nh_ncc >= 0) { derive_keNB_star(ue_context_pP->ue_context.nh, pci, earfcn_dl, is_rel8_only, KeNB_star); rrcConnectionReestablishment->criticalExtensions.choice.c1.choice.rrcConnectionReestablishment_r8.nextHopChainingCount = ue_context_pP->ue_context.nh_ncc; - } else { // first HO + } else { // first HO derive_keNB_star (ue_context_pP->ue_context.kenb, pci, earfcn_dl, is_rel8_only, KeNB_star); // LG: really 1 rrcConnectionReestablishment->criticalExtensions.choice.c1.choice.rrcConnectionReestablishment_r8.nextHopChainingCount = 0; @@ -2745,23 +2488,24 @@ do_RRCConnectionReestablishment( #else rrcConnectionReestablishment->criticalExtensions.choice.c1.choice.rrcConnectionReestablishment_r8.nextHopChainingCount = 0; #endif - rrcConnectionReestablishment->criticalExtensions.choice.c1.choice.rrcConnectionReestablishment_r8.nonCriticalExtension = NULL; if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) { - xer_fprint(stdout, &asn_DEF_LTE_DL_CCCH_Message, (void*)&dl_ccch_msg); + xer_fprint(stdout, &asn_DEF_LTE_DL_CCCH_Message, (void *)&dl_ccch_msg); } + enc_rval = uper_encode_to_buffer(&asn_DEF_LTE_DL_CCCH_Message, NULL, - (void*)&dl_ccch_msg, + (void *)&dl_ccch_msg, buffer, 100); - if(enc_rval.encoded == -1) - { - LOG_I(RRC, "[eNB AssertFatal]ASN1 message encoding failed (%s, %lu)!\n", - enc_rval.failed_type->name, enc_rval.encoded); - return -1; + + if(enc_rval.encoded == -1) { + LOG_I(RRC, "[eNB AssertFatal]ASN1 message encoding failed (%s, %lu)!\n", + enc_rval.failed_type->name, enc_rval.encoded); + return -1; } + #if defined(ENABLE_ITTI) # if !defined(DISABLE_XER_SPRINT) { @@ -2770,22 +2514,18 @@ do_RRCConnectionReestablishment( if ((message_string_size = xer_sprint(message_string, sizeof(message_string), &asn_DEF_LTE_DL_CCCH_Message, (void *) &dl_ccch_msg)) > 0) { MessageDef *msg_p; - msg_p = itti_alloc_new_message_sized (TASK_RRC_ENB, RRC_DL_CCCH, message_string_size + sizeof (IttiMsgText)); msg_p->ittiMsg.rrc_dl_ccch.size = message_string_size; memcpy(&msg_p->ittiMsg.rrc_dl_ccch.text, message_string, message_string_size); - itti_send_msg_to_task(TASK_UNKNOWN, ctxt_pP->instance, msg_p); } } # endif #endif - #ifdef USER_MODE LOG_D(RRC,"RRCConnectionReestablishment Encoded %zd bits (%zd bytes)\n", enc_rval.encoded,(enc_rval.encoded+7)/8); #endif - return((enc_rval.encoded+7)/8); } @@ -2793,37 +2533,35 @@ do_RRCConnectionReestablishment( uint8_t do_RRCConnectionReestablishmentReject( uint8_t Mod_id, - uint8_t* const buffer) + uint8_t *const buffer) //------------------------------------------------------------------------------ { - asn_enc_rval_t enc_rval; - LTE_DL_CCCH_Message_t dl_ccch_msg; LTE_RRCConnectionReestablishmentReject_t *rrcConnectionReestablishmentReject; - memset((void *)&dl_ccch_msg,0,sizeof(LTE_DL_CCCH_Message_t)); dl_ccch_msg.message.present = LTE_DL_CCCH_MessageType_PR_c1; dl_ccch_msg.message.choice.c1.present = LTE_DL_CCCH_MessageType__c1_PR_rrcConnectionReestablishmentReject; rrcConnectionReestablishmentReject = &dl_ccch_msg.message.choice.c1.choice.rrcConnectionReestablishmentReject; - // RRCConnectionReestablishmentReject rrcConnectionReestablishmentReject->criticalExtensions.present = LTE_RRCConnectionReestablishmentReject__criticalExtensions_PR_rrcConnectionReestablishmentReject_r8; if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) { - xer_fprint(stdout, &asn_DEF_LTE_DL_CCCH_Message, (void*)&dl_ccch_msg); + xer_fprint(stdout, &asn_DEF_LTE_DL_CCCH_Message, (void *)&dl_ccch_msg); } + enc_rval = uper_encode_to_buffer(&asn_DEF_LTE_DL_CCCH_Message, NULL, - (void*)&dl_ccch_msg, + (void *)&dl_ccch_msg, buffer, 100); - if(enc_rval.encoded == -1) - { - LOG_I(RRC, "[eNB AssertFatal]ASN1 message encoding failed (%s, %lu)!\n", - enc_rval.failed_type->name, enc_rval.encoded); - return -1; + + if(enc_rval.encoded == -1) { + LOG_I(RRC, "[eNB AssertFatal]ASN1 message encoding failed (%s, %lu)!\n", + enc_rval.failed_type->name, enc_rval.encoded); + return -1; } + #if defined(ENABLE_ITTI) # if !defined(DISABLE_XER_SPRINT) { @@ -2832,20 +2570,16 @@ do_RRCConnectionReestablishmentReject( if ((message_string_size = xer_sprint(message_string, sizeof(message_string), &asn_DEF_LTE_DL_CCCH_Message, (void *) &dl_ccch_msg)) > 0) { MessageDef *msg_p; - msg_p = itti_alloc_new_message_sized (TASK_RRC_ENB, RRC_DL_CCCH, message_string_size + sizeof (IttiMsgText)); msg_p->ittiMsg.rrc_dl_ccch.size = message_string_size; memcpy(&msg_p->ittiMsg.rrc_dl_ccch.text, message_string, message_string_size); - itti_send_msg_to_task(TASK_UNKNOWN, Mod_id, msg_p); } } # endif #endif - LOG_D(RRC,"RRCConnectionReestablishmentReject Encoded %zd bits (%zd bytes)\n", enc_rval.encoded,(enc_rval.encoded+7)/8); - return((enc_rval.encoded+7)/8); } @@ -2853,20 +2587,16 @@ do_RRCConnectionReestablishmentReject( uint8_t do_RRCConnectionReject( uint8_t Mod_id, - uint8_t* const buffer) + uint8_t *const buffer) //------------------------------------------------------------------------------ { - asn_enc_rval_t enc_rval; - LTE_DL_CCCH_Message_t dl_ccch_msg; LTE_RRCConnectionReject_t *rrcConnectionReject; - memset((void *)&dl_ccch_msg,0,sizeof(LTE_DL_CCCH_Message_t)); dl_ccch_msg.message.present = LTE_DL_CCCH_MessageType_PR_c1; dl_ccch_msg.message.choice.c1.present = LTE_DL_CCCH_MessageType__c1_PR_rrcConnectionReject; rrcConnectionReject = &dl_ccch_msg.message.choice.c1.choice.rrcConnectionReject; - // RRCConnectionReject rrcConnectionReject->criticalExtensions.present = LTE_RRCConnectionReject__criticalExtensions_PR_c1; rrcConnectionReject->criticalExtensions.choice.c1.present = LTE_RRCConnectionReject__criticalExtensions__c1_PR_rrcConnectionReject_r8; @@ -2874,19 +2604,21 @@ do_RRCConnectionReject( rrcConnectionReject->criticalExtensions.choice.c1.choice.rrcConnectionReject_r8.waitTime = 1; if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) { - xer_fprint(stdout, &asn_DEF_LTE_DL_CCCH_Message, (void*)&dl_ccch_msg); + xer_fprint(stdout, &asn_DEF_LTE_DL_CCCH_Message, (void *)&dl_ccch_msg); } + enc_rval = uper_encode_to_buffer(&asn_DEF_LTE_DL_CCCH_Message, NULL, - (void*)&dl_ccch_msg, + (void *)&dl_ccch_msg, buffer, 100); - if(enc_rval.encoded == -1) - { - LOG_I(RRC, "[eNB AssertFatal]ASN1 message encoding failed (%s, %lu)!\n", - enc_rval.failed_type->name, enc_rval.encoded); - return -1; + + if(enc_rval.encoded == -1) { + LOG_I(RRC, "[eNB AssertFatal]ASN1 message encoding failed (%s, %lu)!\n", + enc_rval.failed_type->name, enc_rval.encoded); + return -1; } + #if defined(ENABLE_ITTI) # if !defined(DISABLE_XER_SPRINT) { @@ -2895,59 +2627,44 @@ do_RRCConnectionReject( if ((message_string_size = xer_sprint(message_string, sizeof(message_string), &asn_DEF_LTE_DL_CCCH_Message, (void *) &dl_ccch_msg)) > 0) { MessageDef *msg_p; - msg_p = itti_alloc_new_message_sized (TASK_RRC_ENB, RRC_DL_CCCH, message_string_size + sizeof (IttiMsgText)); msg_p->ittiMsg.rrc_dl_ccch.size = message_string_size; memcpy(&msg_p->ittiMsg.rrc_dl_ccch.text, message_string, message_string_size); - itti_send_msg_to_task(TASK_UNKNOWN, Mod_id, msg_p); } } # endif #endif - LOG_D(RRC,"RRCConnectionReject Encoded %zd bits (%zd bytes)\n", enc_rval.encoded,(enc_rval.encoded+7)/8); - return((enc_rval.encoded+7)/8); } uint8_t do_RRCConnectionRelease( uint8_t Mod_id, uint8_t *buffer, - uint8_t Transaction_id) -{ - + uint8_t Transaction_id) { asn_enc_rval_t enc_rval; - LTE_DL_DCCH_Message_t dl_dcch_msg; LTE_RRCConnectionRelease_t *rrcConnectionRelease; - - memset(&dl_dcch_msg,0,sizeof(LTE_DL_DCCH_Message_t)); - dl_dcch_msg.message.present = LTE_DL_DCCH_MessageType_PR_c1; dl_dcch_msg.message.choice.c1.present = LTE_DL_DCCH_MessageType__c1_PR_rrcConnectionRelease; rrcConnectionRelease = &dl_dcch_msg.message.choice.c1.choice.rrcConnectionRelease; - // RRCConnectionRelease rrcConnectionRelease->rrc_TransactionIdentifier = Transaction_id; rrcConnectionRelease->criticalExtensions.present = LTE_RRCConnectionRelease__criticalExtensions_PR_c1; rrcConnectionRelease->criticalExtensions.choice.c1.present =LTE_RRCConnectionRelease__criticalExtensions__c1_PR_rrcConnectionRelease_r8 ; - rrcConnectionRelease->criticalExtensions.choice.c1.choice.rrcConnectionRelease_r8.releaseCause = LTE_ReleaseCause_other; rrcConnectionRelease->criticalExtensions.choice.c1.choice.rrcConnectionRelease_r8.redirectedCarrierInfo = NULL; rrcConnectionRelease->criticalExtensions.choice.c1.choice.rrcConnectionRelease_r8.idleModeMobilityControlInfo = NULL; - rrcConnectionRelease->criticalExtensions.choice.c1.choice.rrcConnectionRelease_r8.nonCriticalExtension=CALLOC(1, sizeof(*rrcConnectionRelease->criticalExtensions.choice.c1.choice.rrcConnectionRelease_r8.nonCriticalExtension)); - enc_rval = uper_encode_to_buffer(&asn_DEF_LTE_DL_DCCH_Message, NULL, - (void*)&dl_dcch_msg, + (void *)&dl_dcch_msg, buffer, RRC_BUF_SIZE); - return((enc_rval.encoded+7)/8); } @@ -2959,9 +2676,7 @@ uint8_t do_MBSFNAreaConfig(uint8_t Mod_id, uint8_t sync_area, uint8_t *buffer, LTE_MCCH_Message_t *mcch_message, - LTE_MBSFNAreaConfiguration_r9_t **mbsfnAreaConfiguration) -{ - + LTE_MBSFNAreaConfiguration_r9_t **mbsfnAreaConfiguration) { asn_enc_rval_t enc_rval; LTE_MBSFN_SubframeConfig_t *mbsfn_SubframeConfig1; LTE_PMCH_Info_r9_t *pmch_Info_1; @@ -2969,17 +2684,13 @@ uint8_t do_MBSFNAreaConfig(uint8_t Mod_id, // MBMS_SessionInfo_r9_t *mbms_Session_2; eNB_RRC_INST *rrc = RC.rrc[Mod_id]; rrc_eNB_carrier_data_t *carrier = &rrc->carrier[0]; - - memset(mcch_message,0,sizeof(LTE_MCCH_Message_t)); mcch_message->message.present = LTE_MCCH_MessageType_PR_c1; mcch_message->message.choice.c1.present = LTE_MCCH_MessageType__c1_PR_mbsfnAreaConfiguration_r9; *mbsfnAreaConfiguration = &mcch_message->message.choice.c1.choice.mbsfnAreaConfiguration_r9; - // Common Subframe Allocation (CommonSF-Alloc-r9) - mbsfn_SubframeConfig1= CALLOC(1,sizeof(*mbsfn_SubframeConfig1)); - memset((void*)mbsfn_SubframeConfig1,0,sizeof(*mbsfn_SubframeConfig1)); + memset((void *)mbsfn_SubframeConfig1,0,sizeof(*mbsfn_SubframeConfig1)); // mbsfn_SubframeConfig1->radioframeAllocationPeriod= LTE_MBSFN_SubframeConfig__radioframeAllocationPeriod_n4; mbsfn_SubframeConfig1->radioframeAllocationOffset= 1; @@ -2990,36 +2701,33 @@ uint8_t do_MBSFNAreaConfig(uint8_t Mod_id, // CURRENTLY WE ARE SUPPORITNG ONLY ONE sf ALLOCATION switch (sync_area) { - case 0: - if (carrier->sib1->tdd_Config != NULL) {// pattern 001110 for TDD - mbsfn_SubframeConfig1->subframeAllocation.choice.oneFrame.buf[0]=0x08<<2;// shift 2bits cuz 2last bits are unused. - } else { //111000 - mbsfn_SubframeConfig1->subframeAllocation.choice.oneFrame.buf[0]=0x38<<2; - } + case 0: + if (carrier->sib1->tdd_Config != NULL) {// pattern 001110 for TDD + mbsfn_SubframeConfig1->subframeAllocation.choice.oneFrame.buf[0]=0x08<<2;// shift 2bits cuz 2last bits are unused. + } else { //111000 + mbsfn_SubframeConfig1->subframeAllocation.choice.oneFrame.buf[0]=0x38<<2; + } - break; + break; - case 1: - if (carrier->sib1->tdd_Config != NULL) { - mbsfn_SubframeConfig1->subframeAllocation.choice.oneFrame.buf[0]=0x08<<2;// shift 2bits cuz 2last bits are unused. - } else { // 000111 - mbsfn_SubframeConfig1->subframeAllocation.choice.oneFrame.buf[0]=0x07<<2; - } + case 1: + if (carrier->sib1->tdd_Config != NULL) { + mbsfn_SubframeConfig1->subframeAllocation.choice.oneFrame.buf[0]=0x08<<2;// shift 2bits cuz 2last bits are unused. + } else { // 000111 + mbsfn_SubframeConfig1->subframeAllocation.choice.oneFrame.buf[0]=0x07<<2; + } - default : - break; + default : + break; } ASN_SEQUENCE_ADD(&(*mbsfnAreaConfiguration)->commonSF_Alloc_r9.list,mbsfn_SubframeConfig1); - // commonSF-AllocPeriod-r9 (*mbsfnAreaConfiguration)->commonSF_AllocPeriod_r9= LTE_MBSFNAreaConfiguration_r9__commonSF_AllocPeriod_r9_rf16; - // PMCHs Information List (PMCH-InfoList-r9) // PMCH_1 Config pmch_Info_1 = CALLOC(1,sizeof(LTE_PMCH_Info_r9_t)); - memset((void*)pmch_Info_1,0,sizeof(LTE_PMCH_Info_r9_t)); - + memset((void *)pmch_Info_1,0,sizeof(LTE_PMCH_Info_r9_t)); /* * take the value of last mbsfn subframe in this CSA period because there is only one PMCH in this mbsfn area * Note: this has to be set based on the subframeAllocation and CSA @@ -3027,7 +2735,6 @@ uint8_t do_MBSFNAreaConfig(uint8_t Mod_id, pmch_Info_1->pmch_Config_r9.sf_AllocEnd_r9= 3; pmch_Info_1->pmch_Config_r9.dataMCS_r9= 7; pmch_Info_1->pmch_Config_r9.mch_SchedulingPeriod_r9= LTE_PMCH_Config_r9__mch_SchedulingPeriod_r9_rf16; - // MBMSs-SessionInfoList-r9 // pmch_Info_1->mbms_SessionInfoList_r9 = CALLOC(1,sizeof(struct MBMS_SessionInfoList_r9)); // Session 1 @@ -3038,7 +2745,7 @@ uint8_t do_MBSFNAreaConfig(uint8_t Mod_id, mbms_Session_1->tmgi_r9.plmn_Id_r9.choice.plmn_Index_r9= 1; // Service ID memset(&mbms_Session_1->tmgi_r9.serviceId_r9,0,sizeof(OCTET_STRING_t));// need to check - OCTET_STRING_fromBuf(&mbms_Session_1->tmgi_r9.serviceId_r9,(const char*)&TMGI[2],3); + OCTET_STRING_fromBuf(&mbms_Session_1->tmgi_r9.serviceId_r9,(const char *)&TMGI[2],3); // Session ID is still missing here, it can be used as an rab id or mrb id mbms_Session_1->sessionId_r9 = CALLOC(1,sizeof(OCTET_STRING_t)); mbms_Session_1->sessionId_r9->buf= MALLOC(1); @@ -3047,7 +2754,6 @@ uint8_t do_MBSFNAreaConfig(uint8_t Mod_id, // Logical Channel ID mbms_Session_1->logicalChannelIdentity_r9= MTCH; ASN_SEQUENCE_ADD(&pmch_Info_1->mbms_SessionInfoList_r9.list,mbms_Session_1); - /* // Session 2 //mbms_Session_2 = CALLOC(1,sizeof(MBMS_SessionInfo_r9_t)); memset(mbms_Session_2,0,sizeof(MBMS_SessionInfo_r9_t)); @@ -3068,19 +2774,21 @@ uint8_t do_MBSFNAreaConfig(uint8_t Mod_id, ASN_SEQUENCE_ADD(&(*mbsfnAreaConfiguration)->pmch_InfoList_r9.list,pmch_Info_1); if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) { - xer_fprint(stdout,&asn_DEF_LTE_MCCH_Message,(void*)mcch_message); + xer_fprint(stdout,&asn_DEF_LTE_MCCH_Message,(void *)mcch_message); } + enc_rval = uper_encode_to_buffer(&asn_DEF_LTE_MCCH_Message, NULL, - (void*)mcch_message, + (void *)mcch_message, buffer, 100); - if(enc_rval.encoded == -1) - { - LOG_I(RRC, "[eNB AssertFatal]ASN1 message encoding failed (%s, %lu)!\n", - enc_rval.failed_type->name, enc_rval.encoded); - return -1; + + if(enc_rval.encoded == -1) { + LOG_I(RRC, "[eNB AssertFatal]ASN1 message encoding failed (%s, %lu)!\n", + enc_rval.failed_type->name, enc_rval.encoded); + return -1; } + #if defined(ENABLE_ITTI) # if !defined(DISABLE_XER_SPRINT) { @@ -3089,17 +2797,14 @@ uint8_t do_MBSFNAreaConfig(uint8_t Mod_id, if ((message_string_size = xer_sprint(message_string, sizeof(message_string), &asn_DEF_LTE_MCCH_Message, (void *) &mcch_message)) > 0) { MessageDef *msg_p; - msg_p = itti_alloc_new_message_sized (TASK_RRC_ENB, RRC_DL_MCCH, message_string_size); msg_p->ittiMsg.rrc_dl_mcch.size = message_string_size; memcpy(&msg_p->ittiMsg.rrc_dl_mcch.text, message_string, message_string_size); - itti_send_msg_to_task(TASK_UNKNOWN, Mod_id, msg_p); } } # endif #endif - LOG_D(RRC,"[eNB] MCCH Message Encoded %zd bits (%zd bytes)\n",enc_rval.encoded,(enc_rval.encoded+7)/8); if (enc_rval.encoded==-1) { @@ -3111,24 +2816,17 @@ uint8_t do_MBSFNAreaConfig(uint8_t Mod_id, } #endif -uint8_t do_MeasurementReport(uint8_t Mod_id, uint8_t *buffer,int measid,int phy_id,long rsrp_s,long rsrq_s,long rsrp_t,long rsrq_t) -{ - +uint8_t do_MeasurementReport(uint8_t Mod_id, uint8_t *buffer,int measid,int phy_id,long rsrp_s,long rsrq_s,long rsrp_t,long rsrq_t) { asn_enc_rval_t enc_rval; - LTE_UL_DCCH_Message_t ul_dcch_msg; - LTE_MeasurementReport_t *measurementReport; - ul_dcch_msg.message.present = LTE_UL_DCCH_MessageType_PR_c1; ul_dcch_msg.message.choice.c1.present = LTE_UL_DCCH_MessageType__c1_PR_measurementReport; measurementReport = &ul_dcch_msg.message.choice.c1.choice.measurementReport; - measurementReport->criticalExtensions.present=LTE_MeasurementReport__criticalExtensions_PR_c1; measurementReport->criticalExtensions.choice.c1.present=LTE_MeasurementReport__criticalExtensions__c1_PR_measurementReport_r8; measurementReport->criticalExtensions.choice.c1.choice.measurementReport_r8.nonCriticalExtension=CALLOC(1, sizeof(*measurementReport->criticalExtensions.choice.c1.choice.measurementReport_r8.nonCriticalExtension)); - measurementReport->criticalExtensions.choice.c1.choice.measurementReport_r8.measResults.measId=measid; #if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) measurementReport->criticalExtensions.choice.c1.choice.measurementReport_r8.measResults.measResultPCell.rsrpResult=rsrp_s; @@ -3140,24 +2838,17 @@ uint8_t do_MeasurementReport(uint8_t Mod_id, uint8_t *buffer,int measid,int phy_ measurementReport->criticalExtensions.choice.c1.choice.measurementReport_r8.measResults.measResultNeighCells=CALLOC(1, sizeof(*measurementReport->criticalExtensions.choice.c1.choice.measurementReport_r8.measResults.measResultNeighCells)); measurementReport->criticalExtensions.choice.c1.choice.measurementReport_r8.measResults.measResultNeighCells->present=LTE_MeasResults__measResultNeighCells_PR_measResultListEUTRA; - LTE_MeasResultListEUTRA_t *measResultListEUTRA2; measResultListEUTRA2 = CALLOC(1,sizeof(*measResultListEUTRA2)); - struct LTE_MeasResultEUTRA *measresulteutra2; measresulteutra2 = CALLOC(1,sizeof(*measresulteutra2)); measresulteutra2->physCellId=phy_id;//1; - struct LTE_MeasResultEUTRA__cgi_Info *measresult_cgi2; measresult_cgi2 = CALLOC(1,sizeof(*measresult_cgi2)); - memset(&measresult_cgi2->cellGlobalId.plmn_Identity,0,sizeof(measresult_cgi2->cellGlobalId.plmn_Identity)); - // measresult_cgi2->cellGlobalId.plmn_Identity.mcc=CALLOC(1,sizeof(measresult_cgi2->cellGlobalId.plmn_Identity.mcc)); measresult_cgi2->cellGlobalId.plmn_Identity.mcc = CALLOC(1, sizeof(*measresult_cgi2->cellGlobalId.plmn_Identity.mcc)); - asn_set_empty(&measresult_cgi2->cellGlobalId.plmn_Identity.mcc->list);//.size=0; - LTE_MCC_MNC_Digit_t dummy; dummy=2; ASN_SEQUENCE_ADD(&measresult_cgi2->cellGlobalId.plmn_Identity.mcc->list,&dummy); @@ -3165,14 +2856,12 @@ uint8_t do_MeasurementReport(uint8_t Mod_id, uint8_t *buffer,int measid,int phy_ 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; @@ -3180,40 +2869,32 @@ uint8_t do_MeasurementReport(uint8_t Mod_id, uint8_t *buffer,int measid,int phy_ 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 LTE_MeasResultEUTRA__measResult meas2; // int rsrp_va=10; - meas2.rsrpResult=&(rsrp_t); //&rsrp_va; meas2.rsrqResult=&(rsrq_t); - measresulteutra2->measResult=meas2; - 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_LTE_UL_DCCH_Message, NULL, - (void*)&ul_dcch_msg, + (void *)&ul_dcch_msg, buffer, 100); - if(enc_rval.encoded == -1) - { - LOG_I(RRC, "[eNB AssertFatal]ASN1 message encoding failed (%s, %lu)!\n", - enc_rval.failed_type->name, enc_rval.encoded); - return -1; + + if(enc_rval.encoded == -1) { + LOG_I(RRC, "[eNB AssertFatal]ASN1 message encoding failed (%s, %lu)!\n", + enc_rval.failed_type->name, enc_rval.encoded); + return -1; } + #if defined(ENABLE_ITTI) # if !defined(DISABLE_XER_SPRINT) { @@ -3222,30 +2903,22 @@ uint8_t do_MeasurementReport(uint8_t Mod_id, uint8_t *buffer,int measid,int phy_ if ((message_string_size = xer_sprint(message_string, sizeof(message_string), &asn_DEF_LTE_UL_DCCH_Message, (void *) &ul_dcch_msg)) > 0) { MessageDef *msg_p; - msg_p = itti_alloc_new_message_sized (TASK_RRC_UE, RRC_DL_DCCH, message_string_size + sizeof (IttiMsgText)); msg_p->ittiMsg.rrc_dl_dcch.size = message_string_size; memcpy(&msg_p->ittiMsg.rrc_dl_dcch.text, message_string, message_string_size); - itti_send_msg_to_task(TASK_UNKNOWN, NB_eNB_INST + Mod_id, msg_p); } } # endif #endif - printf("Measurement Report Encoded %zu bits (%zu bytes)\n",enc_rval.encoded,(enc_rval.encoded+7)/8); - return((enc_rval.encoded+7)/8); } -uint8_t do_DLInformationTransfer(uint8_t Mod_id, uint8_t **buffer, uint8_t transaction_id, uint32_t pdu_length, uint8_t *pdu_buffer) -{ +uint8_t do_DLInformationTransfer(uint8_t Mod_id, uint8_t **buffer, uint8_t transaction_id, uint32_t pdu_length, uint8_t *pdu_buffer) { ssize_t encoded; - LTE_DL_DCCH_Message_t dl_dcch_msg; - memset(&dl_dcch_msg, 0, sizeof(LTE_DL_DCCH_Message_t)); - dl_dcch_msg.message.present = LTE_DL_DCCH_MessageType_PR_c1; dl_dcch_msg.message.choice.c1.present = LTE_DL_DCCH_MessageType__c1_PR_dlInformationTransfer; dl_dcch_msg.message.choice.c1.choice.dlInformationTransfer.rrc_TransactionIdentifier = transaction_id; @@ -3255,12 +2928,10 @@ uint8_t do_DLInformationTransfer(uint8_t Mod_id, uint8_t **buffer, uint8_t trans LTE_DLInformationTransfer_r8_IEs__dedicatedInfoType_PR_dedicatedInfoNAS; dl_dcch_msg.message.choice.c1.choice.dlInformationTransfer.criticalExtensions.choice.c1.choice.dlInformationTransfer_r8.dedicatedInfoType.choice.dedicatedInfoNAS.size = pdu_length; dl_dcch_msg.message.choice.c1.choice.dlInformationTransfer.criticalExtensions.choice.c1.choice.dlInformationTransfer_r8.dedicatedInfoType.choice.dedicatedInfoNAS.buf = pdu_buffer; - - encoded = uper_encode_to_new_buffer (&asn_DEF_LTE_DL_DCCH_Message, NULL, (void*) &dl_dcch_msg, (void **) buffer); - + encoded = uper_encode_to_new_buffer (&asn_DEF_LTE_DL_DCCH_Message, NULL, (void *) &dl_dcch_msg, (void **) buffer); /* -#if defined(ENABLE_ITTI) -# if !defined(DISABLE_XER_SPRINT) + #if defined(ENABLE_ITTI) + # if !defined(DISABLE_XER_SPRINT) { char message_string[10000]; size_t message_string_size; @@ -3275,31 +2946,24 @@ uint8_t do_DLInformationTransfer(uint8_t Mod_id, uint8_t **buffer, uint8_t trans itti_send_msg_to_task(TASK_UNKNOWN, Mod_id, msg_p); } } -# endif -#endif + # endif + #endif */ - return encoded; } -uint8_t do_Paging(uint8_t Mod_id, uint8_t *buffer, ue_paging_identity_t ue_paging_identity, cn_domain_t cn_domain) -{ +uint8_t do_Paging(uint8_t Mod_id, uint8_t *buffer, ue_paging_identity_t ue_paging_identity, cn_domain_t cn_domain) { LOG_D(RRC, "[eNB %d] do_Paging start\n", Mod_id); asn_enc_rval_t enc_rval; - LTE_PCCH_Message_t pcch_msg; LTE_PagingRecord_t *paging_record_p; int j; - pcch_msg.message.present = LTE_PCCH_MessageType_PR_c1; pcch_msg.message.choice.c1.present = LTE_PCCH_MessageType__c1_PR_paging; - pcch_msg.message.choice.c1.choice.paging.pagingRecordList = CALLOC(1,sizeof(*pcch_msg.message.choice.c1.choice.paging.pagingRecordList)); - pcch_msg.message.choice.c1.choice.paging.systemInfoModification = NULL; pcch_msg.message.choice.c1.choice.paging.etws_Indication = NULL; pcch_msg.message.choice.c1.choice.paging.nonCriticalExtension = NULL; - asn_set_empty(&pcch_msg.message.choice.c1.choice.paging.pagingRecordList->list); pcch_msg.message.choice.c1.choice.paging.pagingRecordList->list.count = 0; @@ -3317,11 +2981,12 @@ uint8_t do_Paging(uint8_t Mod_id, uint8_t *buffer, ue_paging_identity_t ue_pagin &paging_record_p->ue_Identity.choice.s_TMSI.mmec); paging_record_p->ue_Identity.choice.s_TMSI.mmec.bits_unused = 0; M_TMSI_TO_OCTET_STRING(ue_paging_identity.choice.s_tmsi.m_tmsi, - &paging_record_p->ue_Identity.choice.s_TMSI.m_TMSI); + &paging_record_p->ue_Identity.choice.s_TMSI.m_TMSI); paging_record_p->ue_Identity.choice.s_TMSI.m_TMSI.bits_unused = 0; } else if (ue_paging_identity.presenceMask == UE_PAGING_IDENTITY_imsi) { paging_record_p->ue_Identity.present = LTE_PagingUE_Identity_PR_imsi; LTE_IMSI_Digit_t imsi_digit[21]; + for (j = 0; j< ue_paging_identity.choice.imsi.length; j++) { /* IMSI size */ imsi_digit[j] = (LTE_IMSI_Digit_t)ue_paging_identity.choice.imsi.buffer[j]; ASN_SEQUENCE_ADD(&paging_record_p->ue_Identity.choice.imsi.list, &imsi_digit[j]); @@ -3334,33 +2999,30 @@ uint8_t do_Paging(uint8_t Mod_id, uint8_t *buffer, ue_paging_identity_t ue_pagin } else { paging_record_p->cn_Domain = LTE_PagingRecord__cn_Domain_cs; } + /* add to list */ ASN_SEQUENCE_ADD(&pcch_msg.message.choice.c1.choice.paging.pagingRecordList->list, paging_record_p); LOG_D(RRC, "[eNB %d] do_Paging paging_record: cn_Domain %ld, ue_paging_identity.presenceMask %d, PagingRecordList.count %d\n", - Mod_id, paging_record_p->cn_Domain, ue_paging_identity.presenceMask, pcch_msg.message.choice.c1.choice.paging.pagingRecordList->list.count); + Mod_id, paging_record_p->cn_Domain, ue_paging_identity.presenceMask, pcch_msg.message.choice.c1.choice.paging.pagingRecordList->list.count); + enc_rval = uper_encode_to_buffer(&asn_DEF_LTE_PCCH_Message, NULL, (void *)&pcch_msg, buffer, RRC_BUF_SIZE); - enc_rval = uper_encode_to_buffer(&asn_DEF_LTE_PCCH_Message, NULL, (void*)&pcch_msg, buffer, RRC_BUF_SIZE); - if(enc_rval.encoded == -1) - { - LOG_I(RRC, "[eNB AssertFatal]ASN1 message encoding failed (%s, %lu)!\n", - enc_rval.failed_type->name, enc_rval.encoded); - return -1; + if(enc_rval.encoded == -1) { + LOG_I(RRC, "[eNB AssertFatal]ASN1 message encoding failed (%s, %lu)!\n", + enc_rval.failed_type->name, enc_rval.encoded); + return -1; } + if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) { - xer_fprint(stdout, &asn_DEF_LTE_PCCH_Message, (void*)&pcch_msg); + xer_fprint(stdout, &asn_DEF_LTE_PCCH_Message, (void *)&pcch_msg); } return((enc_rval.encoded+7)/8); } -uint8_t do_ULInformationTransfer(uint8_t **buffer, uint32_t pdu_length, uint8_t *pdu_buffer) -{ +uint8_t do_ULInformationTransfer(uint8_t **buffer, uint32_t pdu_length, uint8_t *pdu_buffer) { ssize_t encoded; - LTE_UL_DCCH_Message_t ul_dcch_msg; - memset(&ul_dcch_msg, 0, sizeof(LTE_UL_DCCH_Message_t)); - ul_dcch_msg.message.present = LTE_UL_DCCH_MessageType_PR_c1; ul_dcch_msg.message.choice.c1.present = LTE_UL_DCCH_MessageType__c1_PR_ulInformationTransfer; ul_dcch_msg.message.choice.c1.choice.ulInformationTransfer.criticalExtensions.present = LTE_ULInformationTransfer__criticalExtensions_PR_c1; @@ -3369,33 +3031,24 @@ uint8_t do_ULInformationTransfer(uint8_t **buffer, uint32_t pdu_length, uint8_t LTE_ULInformationTransfer_r8_IEs__dedicatedInfoType_PR_dedicatedInfoNAS; ul_dcch_msg.message.choice.c1.choice.ulInformationTransfer.criticalExtensions.choice.c1.choice.ulInformationTransfer_r8.dedicatedInfoType.choice.dedicatedInfoNAS.size = pdu_length; ul_dcch_msg.message.choice.c1.choice.ulInformationTransfer.criticalExtensions.choice.c1.choice.ulInformationTransfer_r8.dedicatedInfoType.choice.dedicatedInfoNAS.buf = pdu_buffer; - - encoded = uper_encode_to_new_buffer (&asn_DEF_LTE_UL_DCCH_Message, NULL, (void*) &ul_dcch_msg, (void **) buffer); - + encoded = uper_encode_to_new_buffer (&asn_DEF_LTE_UL_DCCH_Message, NULL, (void *) &ul_dcch_msg, (void **) buffer); return encoded; } -OAI_UECapability_t *fill_ue_capability(char *UE_EUTRA_Capability_xer_fname) -{ +OAI_UECapability_t *fill_ue_capability(char *UE_EUTRA_Capability_xer_fname) { static OAI_UECapability_t UECapability; /* TODO declared static to allow returning this has an address should be allocated in a cleaner way. */ static LTE_SupportedBandEUTRA_t Bandlist[4]; // the macro ASN_SEQUENCE_ADD() does not copy the source, but only stores a reference to it static LTE_InterFreqBandInfo_t InterFreqBandInfo[4][4]; // the macro ASN_SEQUENCE_ADD() does not copy the source, but only stores a reference to it static LTE_BandInfoEUTRA_t BandInfoEUTRA[4]; // the macro ASN_SEQUENCE_ADD() does not copy the source, but only stores a reference to it - asn_enc_rval_t enc_rval; asn_dec_rval_t dec_rval; - long maxNumberROHC_ContextSessions = LTE_PDCP_Parameters__maxNumberROHC_ContextSessions_cs16; int i; - LTE_UE_EUTRA_Capability_t *UE_EUTRA_Capability; char UE_EUTRA_Capability_xer[8192]; size_t size; - LOG_I(RRC,"Allocating %zu bytes for UE_EUTRA_Capability\n",sizeof(*UE_EUTRA_Capability)); - UE_EUTRA_Capability = CALLOC(1, sizeof(*UE_EUTRA_Capability)); - assert(UE_EUTRA_Capability); if (!UE_EUTRA_Capability_xer_fname) { @@ -3407,10 +3060,8 @@ OAI_UECapability_t *fill_ue_capability(char *UE_EUTRA_Capability_xer_fname) Bandlist[2].halfDuplex = 0; Bandlist[3].bandEUTRA = 38; // UL/DL 2570-2620, TDD Bandlist[3].halfDuplex = 0; - - memset((void*)InterFreqBandInfo, 0, sizeof(InterFreqBandInfo)); - memset((void*)BandInfoEUTRA, 0, sizeof(BandInfoEUTRA)); - + memset((void *)InterFreqBandInfo, 0, sizeof(InterFreqBandInfo)); + memset((void *)BandInfoEUTRA, 0, sizeof(BandInfoEUTRA)); InterFreqBandInfo[0][0].interFreqNeedForGaps = 0; InterFreqBandInfo[0][1].interFreqNeedForGaps = 1; InterFreqBandInfo[0][2].interFreqNeedForGaps = 1; @@ -3427,8 +3078,6 @@ OAI_UECapability_t *fill_ue_capability(char *UE_EUTRA_Capability_xer_fname) InterFreqBandInfo[3][1].interFreqNeedForGaps = 1; InterFreqBandInfo[3][2].interFreqNeedForGaps = 1; InterFreqBandInfo[3][3].interFreqNeedForGaps = 0; - - UE_EUTRA_Capability->accessStratumRelease = 0;//AccessStratumRelease_rel8; UE_EUTRA_Capability->ue_Category = 4; UE_EUTRA_Capability->pdcp_Parameters.supportedROHC_Profiles.profile0x0001=0; @@ -3440,47 +3089,39 @@ OAI_UECapability_t *fill_ue_capability(char *UE_EUTRA_Capability_xer_fname) UE_EUTRA_Capability->pdcp_Parameters.supportedROHC_Profiles.profile0x0102=0; UE_EUTRA_Capability->pdcp_Parameters.supportedROHC_Profiles.profile0x0103=0; UE_EUTRA_Capability->pdcp_Parameters.supportedROHC_Profiles.profile0x0104=0; - UE_EUTRA_Capability->pdcp_Parameters.maxNumberROHC_ContextSessions = &maxNumberROHC_ContextSessions; - UE_EUTRA_Capability->phyLayerParameters.ue_TxAntennaSelectionSupported = 0; UE_EUTRA_Capability->phyLayerParameters.ue_SpecificRefSigsSupported = 0; UE_EUTRA_Capability->rf_Parameters.supportedBandListEUTRA.list.count = 0; - ASN_SEQUENCE_ADD(&UE_EUTRA_Capability->rf_Parameters.supportedBandListEUTRA.list,(void*)&Bandlist[0]); - ASN_SEQUENCE_ADD(&UE_EUTRA_Capability->rf_Parameters.supportedBandListEUTRA.list,(void*)&Bandlist[1]); - ASN_SEQUENCE_ADD(&UE_EUTRA_Capability->rf_Parameters.supportedBandListEUTRA.list,(void*)&Bandlist[2]); - ASN_SEQUENCE_ADD(&UE_EUTRA_Capability->rf_Parameters.supportedBandListEUTRA.list,(void*)&Bandlist[3]); - - ASN_SEQUENCE_ADD(&UE_EUTRA_Capability->measParameters.bandListEUTRA.list,(void*)&BandInfoEUTRA[0]); - ASN_SEQUENCE_ADD(&UE_EUTRA_Capability->measParameters.bandListEUTRA.list,(void*)&BandInfoEUTRA[1]); - ASN_SEQUENCE_ADD(&UE_EUTRA_Capability->measParameters.bandListEUTRA.list,(void*)&BandInfoEUTRA[2]); - ASN_SEQUENCE_ADD(&UE_EUTRA_Capability->measParameters.bandListEUTRA.list,(void*)&BandInfoEUTRA[3]); - - ASN_SEQUENCE_ADD(&UE_EUTRA_Capability->measParameters.bandListEUTRA.list.array[0]->interFreqBandList.list,(void*)&InterFreqBandInfo[0][0]); - ASN_SEQUENCE_ADD(&UE_EUTRA_Capability->measParameters.bandListEUTRA.list.array[0]->interFreqBandList.list,(void*)&InterFreqBandInfo[0][1]); - ASN_SEQUENCE_ADD(&UE_EUTRA_Capability->measParameters.bandListEUTRA.list.array[0]->interFreqBandList.list,(void*)&InterFreqBandInfo[0][2]); - ASN_SEQUENCE_ADD(&UE_EUTRA_Capability->measParameters.bandListEUTRA.list.array[0]->interFreqBandList.list,(void*)&InterFreqBandInfo[0][3]); - - ASN_SEQUENCE_ADD(&UE_EUTRA_Capability->measParameters.bandListEUTRA.list.array[1]->interFreqBandList.list,(void*)&InterFreqBandInfo[1][0]); - ASN_SEQUENCE_ADD(&UE_EUTRA_Capability->measParameters.bandListEUTRA.list.array[1]->interFreqBandList.list,(void*)&InterFreqBandInfo[1][1]); - ASN_SEQUENCE_ADD(&UE_EUTRA_Capability->measParameters.bandListEUTRA.list.array[1]->interFreqBandList.list,(void*)&InterFreqBandInfo[1][2]); - ASN_SEQUENCE_ADD(&UE_EUTRA_Capability->measParameters.bandListEUTRA.list.array[1]->interFreqBandList.list,(void*)&InterFreqBandInfo[1][3]); - - ASN_SEQUENCE_ADD(&UE_EUTRA_Capability->measParameters.bandListEUTRA.list.array[2]->interFreqBandList.list,(void*)&InterFreqBandInfo[2][0]); - ASN_SEQUENCE_ADD(&UE_EUTRA_Capability->measParameters.bandListEUTRA.list.array[2]->interFreqBandList.list,(void*)&InterFreqBandInfo[2][1]); - ASN_SEQUENCE_ADD(&UE_EUTRA_Capability->measParameters.bandListEUTRA.list.array[2]->interFreqBandList.list,(void*)&InterFreqBandInfo[2][2]); - ASN_SEQUENCE_ADD(&UE_EUTRA_Capability->measParameters.bandListEUTRA.list.array[2]->interFreqBandList.list,(void*)&InterFreqBandInfo[2][3]); - - ASN_SEQUENCE_ADD(&UE_EUTRA_Capability->measParameters.bandListEUTRA.list.array[3]->interFreqBandList.list,(void*)&InterFreqBandInfo[3][0]); - ASN_SEQUENCE_ADD(&UE_EUTRA_Capability->measParameters.bandListEUTRA.list.array[3]->interFreqBandList.list,(void*)&InterFreqBandInfo[3][1]); - ASN_SEQUENCE_ADD(&UE_EUTRA_Capability->measParameters.bandListEUTRA.list.array[3]->interFreqBandList.list,(void*)&InterFreqBandInfo[3][2]); - ASN_SEQUENCE_ADD(&UE_EUTRA_Capability->measParameters.bandListEUTRA.list.array[3]->interFreqBandList.list,(void*)&InterFreqBandInfo[3][3]); + ASN_SEQUENCE_ADD(&UE_EUTRA_Capability->rf_Parameters.supportedBandListEUTRA.list,(void *)&Bandlist[0]); + ASN_SEQUENCE_ADD(&UE_EUTRA_Capability->rf_Parameters.supportedBandListEUTRA.list,(void *)&Bandlist[1]); + ASN_SEQUENCE_ADD(&UE_EUTRA_Capability->rf_Parameters.supportedBandListEUTRA.list,(void *)&Bandlist[2]); + ASN_SEQUENCE_ADD(&UE_EUTRA_Capability->rf_Parameters.supportedBandListEUTRA.list,(void *)&Bandlist[3]); + ASN_SEQUENCE_ADD(&UE_EUTRA_Capability->measParameters.bandListEUTRA.list,(void *)&BandInfoEUTRA[0]); + ASN_SEQUENCE_ADD(&UE_EUTRA_Capability->measParameters.bandListEUTRA.list,(void *)&BandInfoEUTRA[1]); + ASN_SEQUENCE_ADD(&UE_EUTRA_Capability->measParameters.bandListEUTRA.list,(void *)&BandInfoEUTRA[2]); + ASN_SEQUENCE_ADD(&UE_EUTRA_Capability->measParameters.bandListEUTRA.list,(void *)&BandInfoEUTRA[3]); + ASN_SEQUENCE_ADD(&UE_EUTRA_Capability->measParameters.bandListEUTRA.list.array[0]->interFreqBandList.list,(void *)&InterFreqBandInfo[0][0]); + ASN_SEQUENCE_ADD(&UE_EUTRA_Capability->measParameters.bandListEUTRA.list.array[0]->interFreqBandList.list,(void *)&InterFreqBandInfo[0][1]); + ASN_SEQUENCE_ADD(&UE_EUTRA_Capability->measParameters.bandListEUTRA.list.array[0]->interFreqBandList.list,(void *)&InterFreqBandInfo[0][2]); + ASN_SEQUENCE_ADD(&UE_EUTRA_Capability->measParameters.bandListEUTRA.list.array[0]->interFreqBandList.list,(void *)&InterFreqBandInfo[0][3]); + ASN_SEQUENCE_ADD(&UE_EUTRA_Capability->measParameters.bandListEUTRA.list.array[1]->interFreqBandList.list,(void *)&InterFreqBandInfo[1][0]); + ASN_SEQUENCE_ADD(&UE_EUTRA_Capability->measParameters.bandListEUTRA.list.array[1]->interFreqBandList.list,(void *)&InterFreqBandInfo[1][1]); + ASN_SEQUENCE_ADD(&UE_EUTRA_Capability->measParameters.bandListEUTRA.list.array[1]->interFreqBandList.list,(void *)&InterFreqBandInfo[1][2]); + ASN_SEQUENCE_ADD(&UE_EUTRA_Capability->measParameters.bandListEUTRA.list.array[1]->interFreqBandList.list,(void *)&InterFreqBandInfo[1][3]); + ASN_SEQUENCE_ADD(&UE_EUTRA_Capability->measParameters.bandListEUTRA.list.array[2]->interFreqBandList.list,(void *)&InterFreqBandInfo[2][0]); + ASN_SEQUENCE_ADD(&UE_EUTRA_Capability->measParameters.bandListEUTRA.list.array[2]->interFreqBandList.list,(void *)&InterFreqBandInfo[2][1]); + ASN_SEQUENCE_ADD(&UE_EUTRA_Capability->measParameters.bandListEUTRA.list.array[2]->interFreqBandList.list,(void *)&InterFreqBandInfo[2][2]); + ASN_SEQUENCE_ADD(&UE_EUTRA_Capability->measParameters.bandListEUTRA.list.array[2]->interFreqBandList.list,(void *)&InterFreqBandInfo[2][3]); + ASN_SEQUENCE_ADD(&UE_EUTRA_Capability->measParameters.bandListEUTRA.list.array[3]->interFreqBandList.list,(void *)&InterFreqBandInfo[3][0]); + ASN_SEQUENCE_ADD(&UE_EUTRA_Capability->measParameters.bandListEUTRA.list.array[3]->interFreqBandList.list,(void *)&InterFreqBandInfo[3][1]); + ASN_SEQUENCE_ADD(&UE_EUTRA_Capability->measParameters.bandListEUTRA.list.array[3]->interFreqBandList.list,(void *)&InterFreqBandInfo[3][2]); + ASN_SEQUENCE_ADD(&UE_EUTRA_Capability->measParameters.bandListEUTRA.list.array[3]->interFreqBandList.list,(void *)&InterFreqBandInfo[3][3]); // UE_EUTRA_Capability->measParameters.bandListEUTRA.list.count = 0; // no measurements on other bands // UE_EUTRA_Capability->featureGroupIndicators // null - if(usim_test == 1) - { + if(usim_test == 1) { // featureGroup is mandatory for CMW tests // featureGroup is filled only for usim-test mode BIT_STRING_t *bit_string = CALLOC(1, sizeof(*bit_string)); @@ -3494,8 +3135,7 @@ OAI_UECapability_t *fill_ue_capability(char *UE_EUTRA_Capability_xer_fname) // UE_EUTRA_Capability->interRAT_Parameters // null } else { - - FILE* f = fopen(UE_EUTRA_Capability_xer_fname, "r"); + FILE *f = fopen(UE_EUTRA_Capability_xer_fname, "r"); assert(f); size = fread(UE_EUTRA_Capability_xer, 1, sizeof UE_EUTRA_Capability_xer, f); fclose(f); @@ -3506,30 +3146,29 @@ OAI_UECapability_t *fill_ue_capability(char *UE_EUTRA_Capability_xer_fname) return(NULL); } - dec_rval = xer_decode(0, &asn_DEF_LTE_UE_EUTRA_Capability, (void*)UE_EUTRA_Capability, UE_EUTRA_Capability_xer, size); + dec_rval = xer_decode(0, &asn_DEF_LTE_UE_EUTRA_Capability, (void *)UE_EUTRA_Capability, UE_EUTRA_Capability_xer, size); assert(dec_rval.code == RC_OK); } UECapability.UE_EUTRA_Capability = UE_EUTRA_Capability; + if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) { - xer_fprint(stdout,&asn_DEF_LTE_UE_EUTRA_Capability,(void *)UE_EUTRA_Capability); + xer_fprint(stdout,&asn_DEF_LTE_UE_EUTRA_Capability,(void *)UE_EUTRA_Capability); } + enc_rval = uper_encode_to_buffer(&asn_DEF_LTE_UE_EUTRA_Capability, NULL, - (void*)UE_EUTRA_Capability, + (void *)UE_EUTRA_Capability, &UECapability.sdu[0], MAX_UE_CAPABILITY_SIZE); AssertFatal (enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %lu)!\n", enc_rval.failed_type->name, enc_rval.encoded); - #if defined(ENABLE_ITTI) # if defined(DISABLE_XER_SPRINT) { MessageDef *msg_p; - msg_p = itti_alloc_new_message (TASK_RRC_UE, RRC_UE_EUTRA_CAPABILITY); memcpy (&msg_p->ittiMsg, (void *) UE_EUTRA_Capability, sizeof(RrcUeEutraCapability)); - itti_send_msg_to_task (TASK_UNKNOWN, NB_eNB_INST, msg_p); } # else @@ -3539,17 +3178,14 @@ OAI_UECapability_t *fill_ue_capability(char *UE_EUTRA_Capability_xer_fname) if ((message_string_size = xer_sprint(message_string, sizeof(message_string), &asn_DEF_LTE_UE_EUTRA_Capability, (void *)UE_EUTRA_Capability)) > 0) { MessageDef *msg_p; - msg_p = itti_alloc_new_message_sized (TASK_RRC_UE, RRC_UE_EUTRA_CAPABILITY, message_string_size + sizeof (IttiMsgText)); msg_p->ittiMsg.rrc_ue_eutra_capability.size = message_string_size; memcpy(&msg_p->ittiMsg.rrc_ue_eutra_capability.text, message_string, message_string_size); - itti_send_msg_to_task(TASK_UNKNOWN, INSTANCE_DEFAULT, msg_p); } } # endif #endif - UECapability.sdu_size = (enc_rval.encoded + 7) / 8; LOG_I(PHY, "[RRC]UE Capability encoded, %d bytes (%zd bits)\n", UECapability.sdu_size, enc_rval.encoded + 7); @@ -3564,7 +3200,6 @@ OAI_UECapability_t *fill_ue_capability(char *UE_EUTRA_Capability_xer_fname) LOG_D(PHY, "[RRC]UE Capability encoded, %s\n", sdu); free(sdu); } - return(&UECapability); } diff --git a/openair2/RRC/LTE/MESSAGES/asn1_msg.h b/openair2/RRC/LTE/MESSAGES/asn1_msg.h index 562f7c33ba..2d0c6ba7b6 100644 --- a/openair2/RRC/LTE/MESSAGES/asn1_msg.h +++ b/openair2/RRC/LTE/MESSAGES/asn1_msg.h @@ -71,7 +71,7 @@ uint8_t do_MIB(rrc_eNB_carrier_data_t *carrier, uint32_t N_RB_DL, uint32_t phich @param carrier pointer to Carrier information @param Mod_id Instance of eNB @param Component carrier Component carrier to configure -@param configuration Pointer Configuration Request structure +@param configuration Pointer Configuration Request structure @return size of encoded bit stream in bytes*/ uint8_t do_SIB1(rrc_eNB_carrier_data_t *carrier,int Mod_id,int CC_id, RrcConfigurationReq *configuration @@ -91,7 +91,7 @@ uint8_t do_SIB1(rrc_eNB_carrier_data_t *carrier,int Mod_id,int CC_id, RrcConfigu uint8_t do_SIB23(uint8_t Mod_id, int CC_id #if defined(ENABLE_ITTI) - , RrcConfigurationReq *configuration + , RrcConfigurationReq *configuration #endif ); @@ -115,16 +115,16 @@ uint8_t do_SidelinkUEInformation(uint8_t Mod_id, uint8_t *buffer, LTE_SL_Destina /** \brief Generate an RRCConnectionSetupComplete UL-DCCH-Message (UE) @param buffer Pointer to PER-encoded ASN.1 description of UL-DCCH-Message PDU @returns Size of encoded bit stream in bytes*/ -uint8_t do_RRCConnectionSetupComplete(uint8_t Mod_id, uint8_t* buffer, const uint8_t Transaction_id, const int dedicatedInfoNASLength, - const char* dedicatedInfoNAS); +uint8_t do_RRCConnectionSetupComplete(uint8_t Mod_id, uint8_t *buffer, const uint8_t Transaction_id, const int dedicatedInfoNASLength, + const char *dedicatedInfoNAS); /** \brief Generate an RRCConnectionReconfigurationComplete UL-DCCH-Message (UE) @param buffer Pointer to PER-encoded ASN.1 description of UL-DCCH-Message PDU @returns Size of encoded bit stream in bytes*/ uint8_t do_RRCConnectionReconfigurationComplete( - const protocol_ctxt_t* const ctxt_pP, - uint8_t* buffer, + const protocol_ctxt_t *const ctxt_pP, + uint8_t *buffer, const uint8_t Transaction_id ); @@ -143,14 +143,14 @@ PhysicalConfigDedicated IEs. The latter does not enable periodic CQI reporting @returns Size of encoded bit stream in bytes*/ uint8_t do_RRCConnectionSetup( - const protocol_ctxt_t* const ctxt_pP, - rrc_eNB_ue_context_t* const ue_context_pP, + const protocol_ctxt_t *const ctxt_pP, + rrc_eNB_ue_context_t *const ue_context_pP, int CC_id, - uint8_t* const buffer, + uint8_t *const buffer, const uint8_t transmission_mode, const uint8_t Transaction_id, - LTE_SRB_ToAddModList_t** SRB_configList, - struct LTE_PhysicalConfigDedicated** physicalConfigDedicated + LTE_SRB_ToAddModList_t **SRB_configList, + struct LTE_PhysicalConfigDedicated **physicalConfigDedicated ); /** @@ -177,31 +177,31 @@ do_RRCConnectionSetup( uint16_t do_RRCConnectionReconfiguration( - const protocol_ctxt_t* const ctxt_pP, - uint8_t *buffer, - uint8_t Transaction_id, - LTE_SRB_ToAddModList_t *SRB_list, - LTE_DRB_ToAddModList_t *DRB_list, - LTE_DRB_ToReleaseList_t *DRB_list2, - struct LTE_SPS_Config *sps_Config, - struct LTE_PhysicalConfigDedicated *physicalConfigDedicated, - LTE_MeasObjectToAddModList_t *MeasObj_list, - LTE_ReportConfigToAddModList_t *ReportConfig_list, - LTE_QuantityConfig_t *quantityConfig, - LTE_MeasIdToAddModList_t *MeasId_list, - LTE_MAC_MainConfig_t *mac_MainConfig, - LTE_MeasGapConfig_t *measGapConfig, - LTE_MobilityControlInfo_t *mobilityInfo, - struct LTE_MeasConfig__speedStatePars *speedStatePars, - LTE_RSRP_Range_t *rsrp, - LTE_C_RNTI_t *cba_rnti, - struct LTE_RRCConnectionReconfiguration_r8_IEs__dedicatedInfoNASList* dedicatedInfoNASList, + const protocol_ctxt_t *const ctxt_pP, + uint8_t *buffer, + uint8_t Transaction_id, + LTE_SRB_ToAddModList_t *SRB_list, + LTE_DRB_ToAddModList_t *DRB_list, + LTE_DRB_ToReleaseList_t *DRB_list2, + struct LTE_SPS_Config *sps_Config, + struct LTE_PhysicalConfigDedicated *physicalConfigDedicated, + LTE_MeasObjectToAddModList_t *MeasObj_list, + LTE_ReportConfigToAddModList_t *ReportConfig_list, + LTE_QuantityConfig_t *quantityConfig, + LTE_MeasIdToAddModList_t *MeasId_list, + LTE_MAC_MainConfig_t *mac_MainConfig, + LTE_MeasGapConfig_t *measGapConfig, + LTE_MobilityControlInfo_t *mobilityInfo, + struct LTE_MeasConfig__speedStatePars *speedStatePars, + LTE_RSRP_Range_t *rsrp, + LTE_C_RNTI_t *cba_rnti, + struct LTE_RRCConnectionReconfiguration_r8_IEs__dedicatedInfoNASList *dedicatedInfoNASList, LTE_SL_CommConfig_r12_t *sl_CommConfig, LTE_SL_DiscConfig_r12_t *sl_DiscConfig #if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) - , LTE_SCellToAddMod_r10_t *SCell_config + , LTE_SCellToAddMod_r10_t *SCell_config #endif - ); +); /** \brief Generate an RRCConnectionReestablishment DL-CCCH-Message (eNB). This routine configures SRB_ToAddMod (SRB1/SRB2) and PhysicalConfigDedicated IEs. The latter does not enable periodic CQI reporting (PUCCH format 2/2a/2b) or SRS. @@ -216,10 +216,10 @@ PhysicalConfigDedicated IEs. The latter does not enable periodic CQI reporting @returns Size of encoded bit stream in bytes*/ uint8_t do_RRCConnectionReestablishment( - const protocol_ctxt_t* const ctxt_pP, - rrc_eNB_ue_context_t* const ue_context_pP, + const protocol_ctxt_t *const ctxt_pP, + rrc_eNB_ue_context_t *const ue_context_pP, int CC_id, - uint8_t* const buffer, + uint8_t *const buffer, const uint8_t transmission_mode, const uint8_t Transaction_id, LTE_SRB_ToAddModList_t **SRB_configList, @@ -232,8 +232,8 @@ do_RRCConnectionReestablishment( @returns Size of encoded bit stream in bytes*/ uint8_t do_RRCConnectionReestablishmentReject( - uint8_t Mod_id, - uint8_t* const buffer); + uint8_t Mod_id, + uint8_t *const buffer); /** \brief Generate an RRCConnectionReject DL-CCCH-Message (eNB). @@ -242,8 +242,8 @@ do_RRCConnectionReestablishmentReject( @returns Size of encoded bit stream in bytes*/ uint8_t do_RRCConnectionReject( - uint8_t Mod_id, - uint8_t* const buffer); + uint8_t Mod_id, + uint8_t *const buffer); /** \brief Generate an RRCConnectionRequest UL-CCCH-Message (UE) based on random string or S-TMSI. This @@ -286,14 +286,14 @@ OAI_UECapability_t *fill_ue_capability(char *LTE_UE_EUTRA_Capability_xer); uint8_t do_UECapabilityEnquiry( - const protocol_ctxt_t* const ctxt_pP, - uint8_t* const buffer, + const protocol_ctxt_t *const ctxt_pP, + uint8_t *const buffer, const uint8_t Transaction_id ); uint8_t do_SecurityModeCommand( - const protocol_ctxt_t* const ctxt_pP, - uint8_t* const buffer, + const protocol_ctxt_t *const ctxt_pP, + uint8_t *const buffer, const uint8_t Transaction_id, const uint8_t cipheringAlgorithm, const uint8_t integrityProtAlgorithm); diff --git a/openair2/RRC/LTE/rrc_defs.h b/openair2/RRC/LTE/rrc_defs.h index fd54ab5892..1d9e447984 100644 --- a/openair2/RRC/LTE/rrc_defs.h +++ b/openair2/RRC/LTE/rrc_defs.h @@ -64,10 +64,10 @@ #define IPV4_ADDR "%u.%u.%u.%u" #define IPV4_ADDR_FORMAT(aDDRESS) \ - (uint8_t)((aDDRESS) & 0x000000ff), \ - (uint8_t)(((aDDRESS) & 0x0000ff00) >> 8 ), \ - (uint8_t)(((aDDRESS) & 0x00ff0000) >> 16), \ - (uint8_t)(((aDDRESS) & 0xff000000) >> 24) + (uint8_t)((aDDRESS) & 0x000000ff), \ + (uint8_t)(((aDDRESS) & 0x0000ff00) >> 8 ), \ + (uint8_t)(((aDDRESS) & 0x00ff0000) >> 16), \ + (uint8_t)(((aDDRESS) & 0xff000000) >> 24) //----------------------------------------------------- @@ -84,74 +84,74 @@ #define GROUP_COMMUNICATION_RELEASE_RSP 8 #define PC5S_ESTABLISH_REQ 9 #define PC5S_ESTABLISH_RSP 10 -#define PC5_DISCOVERY_MESSAGE 11 +#define PC5_DISCOVERY_MESSAGE 11 -#define PC5_DISCOVERY_PAYLOAD_SIZE 29 +#define PC5_DISCOVERY_PAYLOAD_SIZE 29 typedef enum { - UE_STATE_OFF_NETWORK, - UE_STATE_ON_NETWORK + UE_STATE_OFF_NETWORK, + UE_STATE_ON_NETWORK } SL_UE_STATE_t; typedef enum { - GROUP_COMMUNICATION_RELEASE_OK = 0, - GROUP_COMMUNICATION_RELEASE_FAILURE + GROUP_COMMUNICATION_RELEASE_OK = 0, + GROUP_COMMUNICATION_RELEASE_FAILURE } Group_Communication_Status_t; struct GroupCommunicationEstablishReq { - uint32_t sourceL2Id; - uint32_t groupL2Id; - uint32_t groupIpAddress; - uint8_t pppp; + uint32_t sourceL2Id; + uint32_t groupL2Id; + uint32_t groupIpAddress; + uint8_t pppp; }; struct GroupCommunicationReleaseReq { - uint32_t sourceL2Id; - uint32_t groupL2Id; - int slrb_id; + uint32_t sourceL2Id; + uint32_t groupL2Id; + int slrb_id; }; struct DirectCommunicationEstablishReq { - uint32_t sourceL2Id; - uint32_t destinationL2Id; - uint32_t pppp; + uint32_t sourceL2Id; + uint32_t destinationL2Id; + uint32_t pppp; }; -struct PC5SEstablishReq{ - uint8_t type; - uint32_t sourceL2Id; - uint32_t destinationL2Id; +struct PC5SEstablishReq { + uint8_t type; + uint32_t sourceL2Id; + uint32_t destinationL2Id; }; -struct PC5SEstablishRsp{ - uint32_t slrbid_lcid28; - uint32_t slrbid_lcid29; - uint32_t slrbid_lcid30; +struct PC5SEstablishRsp { + uint32_t slrbid_lcid28; + uint32_t slrbid_lcid29; + uint32_t slrbid_lcid30; }; //PC5_DISCOVERY MESSAGE typedef struct { - unsigned char payload[PC5_DISCOVERY_PAYLOAD_SIZE]; - uint32_t measuredPower; + unsigned char payload[PC5_DISCOVERY_PAYLOAD_SIZE]; + uint32_t measuredPower; } __attribute__((__packed__)) PC5DiscoveryMessage ; struct sidelink_ctrl_element { - unsigned short type; - union { - struct GroupCommunicationEstablishReq group_comm_establish_req; - struct DirectCommunicationEstablishReq direct_comm_establish_req; - Group_Communication_Status_t group_comm_release_rsp; - //struct DirectCommunicationReleaseReq direct_comm_release_req; - SL_UE_STATE_t ue_state; - int slrb_id; - struct PC5SEstablishReq pc5s_establish_req; - struct PC5SEstablishRsp pc5s_establish_rsp; - PC5DiscoveryMessage pc5_discovery_message; - } sidelinkPrimitive; + unsigned short type; + union { + struct GroupCommunicationEstablishReq group_comm_establish_req; + struct DirectCommunicationEstablishReq direct_comm_establish_req; + Group_Communication_Status_t group_comm_release_rsp; + //struct DirectCommunicationReleaseReq direct_comm_release_req; + SL_UE_STATE_t ue_state; + int slrb_id; + struct PC5SEstablishReq pc5s_establish_req; + struct PC5SEstablishRsp pc5s_establish_rsp; + PC5DiscoveryMessage pc5_discovery_message; + } sidelinkPrimitive; }; @@ -167,7 +167,7 @@ void *send_UE_status_notification(void *); //#include "COMMON/openair_defs.h" #ifndef USER_MODE -//#include + //#include #endif #include "LTE_SystemInformationBlockType1.h" @@ -182,18 +182,18 @@ void *send_UE_status_notification(void *); #include "LTE_SBCCH-SL-BCH-MessageType.h" #include "LTE_BCCH-BCH-Message.h" #if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) -#include "LTE_MCCH-Message.h" -#include "LTE_MBSFNAreaConfiguration-r9.h" + #include "LTE_MCCH-Message.h" + #include "LTE_MBSFNAreaConfiguration-r9.h" #endif #if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) -#include "LTE_SCellToAddMod-r10.h" + #include "LTE_SCellToAddMod-r10.h" #endif #include "LTE_AS-Config.h" #include "LTE_AS-Context.h" #include "LTE_UE-EUTRA-Capability.h" #include "LTE_MeasResults.h" #if (LTE_RRC_VERSION >= MAKE_VERSION(12, 0, 0)) -#include "LTE_SidelinkUEInformation-r12.h" + #include "LTE_SidelinkUEInformation-r12.h" #endif /* for ImsiMobileIdentity_t */ @@ -203,66 +203,66 @@ void *send_UE_status_notification(void *); * the code is in favor of Rel14, those defines do the translation */ #if (LTE_RRC_VERSION < MAKE_VERSION(14, 0, 0)) -# define CipheringAlgorithm_r12_t e_SecurityAlgorithmConfig__cipheringAlgorithm -# define CipheringAlgorithm_r12_eea0 SecurityAlgorithmConfig__cipheringAlgorithm_eea0 -# define CipheringAlgorithm_r12_eea1 SecurityAlgorithmConfig__cipheringAlgorithm_eea1 -# define CipheringAlgorithm_r12_eea2 SecurityAlgorithmConfig__cipheringAlgorithm_eea2 -# define CipheringAlgorithm_r12_spare1 SecurityAlgorithmConfig__cipheringAlgorithm_spare1 -# define Alpha_r12_al0 UplinkPowerControlCommon__alpha_al0 -# define Alpha_r12_al04 UplinkPowerControlCommon__alpha_al04 -# define Alpha_r12_al05 UplinkPowerControlCommon__alpha_al05 -# define Alpha_r12_al06 UplinkPowerControlCommon__alpha_al06 -# define Alpha_r12_al07 UplinkPowerControlCommon__alpha_al07 -# define Alpha_r12_al08 UplinkPowerControlCommon__alpha_al08 -# define Alpha_r12_al09 UplinkPowerControlCommon__alpha_al09 -# define Alpha_r12_al1 UplinkPowerControlCommon__alpha_al1 -# define PreambleTransMax_n3 RACH_ConfigCommon__ra_SupervisionInfo__preambleTransMax_n3 -# define PreambleTransMax_n4 RACH_ConfigCommon__ra_SupervisionInfo__preambleTransMax_n4 -# define PreambleTransMax_n5 RACH_ConfigCommon__ra_SupervisionInfo__preambleTransMax_n5 -# define PreambleTransMax_n6 RACH_ConfigCommon__ra_SupervisionInfo__preambleTransMax_n6 -# define PreambleTransMax_n7 RACH_ConfigCommon__ra_SupervisionInfo__preambleTransMax_n7 -# define PreambleTransMax_n8 RACH_ConfigCommon__ra_SupervisionInfo__preambleTransMax_n8 -# define PreambleTransMax_n10 RACH_ConfigCommon__ra_SupervisionInfo__preambleTransMax_n10 -# define PreambleTransMax_n20 RACH_ConfigCommon__ra_SupervisionInfo__preambleTransMax_n20 -# define PreambleTransMax_n50 RACH_ConfigCommon__ra_SupervisionInfo__preambleTransMax_n50 -# define PreambleTransMax_n100 RACH_ConfigCommon__ra_SupervisionInfo__preambleTransMax_n100 -# define PreambleTransMax_n200 RACH_ConfigCommon__ra_SupervisionInfo__preambleTransMax_n200 -# define PeriodicBSR_Timer_r12_sf5 MAC_MainConfig__ul_SCH_Config__periodicBSR_Timer_sf5 -# define PeriodicBSR_Timer_r12_sf10 MAC_MainConfig__ul_SCH_Config__periodicBSR_Timer_sf10 -# define PeriodicBSR_Timer_r12_sf16 MAC_MainConfig__ul_SCH_Config__periodicBSR_Timer_sf16 -# define PeriodicBSR_Timer_r12_sf20 MAC_MainConfig__ul_SCH_Config__periodicBSR_Timer_sf20 -# define PeriodicBSR_Timer_r12_sf32 MAC_MainConfig__ul_SCH_Config__periodicBSR_Timer_sf32 -# define PeriodicBSR_Timer_r12_sf40 MAC_MainConfig__ul_SCH_Config__periodicBSR_Timer_sf40 -# define PeriodicBSR_Timer_r12_sf64 MAC_MainConfig__ul_SCH_Config__periodicBSR_Timer_sf64 -# define PeriodicBSR_Timer_r12_sf80 MAC_MainConfig__ul_SCH_Config__periodicBSR_Timer_sf80 -# define PeriodicBSR_Timer_r12_sf128 MAC_MainConfig__ul_SCH_Config__periodicBSR_Timer_sf128 -# define PeriodicBSR_Timer_r12_sf160 MAC_MainConfig__ul_SCH_Config__periodicBSR_Timer_sf160 -# define PeriodicBSR_Timer_r12_sf320 MAC_MainConfig__ul_SCH_Config__periodicBSR_Timer_sf320 -# define PeriodicBSR_Timer_r12_sf640 MAC_MainConfig__ul_SCH_Config__periodicBSR_Timer_sf640 -# define PeriodicBSR_Timer_r12_sf1280 MAC_MainConfig__ul_SCH_Config__periodicBSR_Timer_sf1280 -# define PeriodicBSR_Timer_r12_sf2560 MAC_MainConfig__ul_SCH_Config__periodicBSR_Timer_sf2560 -# define PeriodicBSR_Timer_r12_infinity MAC_MainConfig__ul_SCH_Config__periodicBSR_Timer_infinity -# define RetxBSR_Timer_r12_sf320 MAC_MainConfig__ul_SCH_Config__retxBSR_Timer_sf320 -# define RetxBSR_Timer_r12_sf640 MAC_MainConfig__ul_SCH_Config__retxBSR_Timer_sf640 -# define RetxBSR_Timer_r12_sf1280 MAC_MainConfig__ul_SCH_Config__retxBSR_Timer_sf1280 -# define RetxBSR_Timer_r12_sf2560 MAC_MainConfig__ul_SCH_Config__retxBSR_Timer_sf2560 -# define RetxBSR_Timer_r12_sf5120 MAC_MainConfig__ul_SCH_Config__retxBSR_Timer_sf5120 -# define RetxBSR_Timer_r12_sf10240 MAC_MainConfig__ul_SCH_Config__retxBSR_Timer_sf10240 + #define CipheringAlgorithm_r12_t e_SecurityAlgorithmConfig__cipheringAlgorithm + #define CipheringAlgorithm_r12_eea0 SecurityAlgorithmConfig__cipheringAlgorithm_eea0 + #define CipheringAlgorithm_r12_eea1 SecurityAlgorithmConfig__cipheringAlgorithm_eea1 + #define CipheringAlgorithm_r12_eea2 SecurityAlgorithmConfig__cipheringAlgorithm_eea2 + #define CipheringAlgorithm_r12_spare1 SecurityAlgorithmConfig__cipheringAlgorithm_spare1 + #define Alpha_r12_al0 UplinkPowerControlCommon__alpha_al0 + #define Alpha_r12_al04 UplinkPowerControlCommon__alpha_al04 + #define Alpha_r12_al05 UplinkPowerControlCommon__alpha_al05 + #define Alpha_r12_al06 UplinkPowerControlCommon__alpha_al06 + #define Alpha_r12_al07 UplinkPowerControlCommon__alpha_al07 + #define Alpha_r12_al08 UplinkPowerControlCommon__alpha_al08 + #define Alpha_r12_al09 UplinkPowerControlCommon__alpha_al09 + #define Alpha_r12_al1 UplinkPowerControlCommon__alpha_al1 + #define PreambleTransMax_n3 RACH_ConfigCommon__ra_SupervisionInfo__preambleTransMax_n3 + #define PreambleTransMax_n4 RACH_ConfigCommon__ra_SupervisionInfo__preambleTransMax_n4 + #define PreambleTransMax_n5 RACH_ConfigCommon__ra_SupervisionInfo__preambleTransMax_n5 + #define PreambleTransMax_n6 RACH_ConfigCommon__ra_SupervisionInfo__preambleTransMax_n6 + #define PreambleTransMax_n7 RACH_ConfigCommon__ra_SupervisionInfo__preambleTransMax_n7 + #define PreambleTransMax_n8 RACH_ConfigCommon__ra_SupervisionInfo__preambleTransMax_n8 + #define PreambleTransMax_n10 RACH_ConfigCommon__ra_SupervisionInfo__preambleTransMax_n10 + #define PreambleTransMax_n20 RACH_ConfigCommon__ra_SupervisionInfo__preambleTransMax_n20 + #define PreambleTransMax_n50 RACH_ConfigCommon__ra_SupervisionInfo__preambleTransMax_n50 + #define PreambleTransMax_n100 RACH_ConfigCommon__ra_SupervisionInfo__preambleTransMax_n100 + #define PreambleTransMax_n200 RACH_ConfigCommon__ra_SupervisionInfo__preambleTransMax_n200 + #define PeriodicBSR_Timer_r12_sf5 MAC_MainConfig__ul_SCH_Config__periodicBSR_Timer_sf5 + #define PeriodicBSR_Timer_r12_sf10 MAC_MainConfig__ul_SCH_Config__periodicBSR_Timer_sf10 + #define PeriodicBSR_Timer_r12_sf16 MAC_MainConfig__ul_SCH_Config__periodicBSR_Timer_sf16 + #define PeriodicBSR_Timer_r12_sf20 MAC_MainConfig__ul_SCH_Config__periodicBSR_Timer_sf20 + #define PeriodicBSR_Timer_r12_sf32 MAC_MainConfig__ul_SCH_Config__periodicBSR_Timer_sf32 + #define PeriodicBSR_Timer_r12_sf40 MAC_MainConfig__ul_SCH_Config__periodicBSR_Timer_sf40 + #define PeriodicBSR_Timer_r12_sf64 MAC_MainConfig__ul_SCH_Config__periodicBSR_Timer_sf64 + #define PeriodicBSR_Timer_r12_sf80 MAC_MainConfig__ul_SCH_Config__periodicBSR_Timer_sf80 + #define PeriodicBSR_Timer_r12_sf128 MAC_MainConfig__ul_SCH_Config__periodicBSR_Timer_sf128 + #define PeriodicBSR_Timer_r12_sf160 MAC_MainConfig__ul_SCH_Config__periodicBSR_Timer_sf160 + #define PeriodicBSR_Timer_r12_sf320 MAC_MainConfig__ul_SCH_Config__periodicBSR_Timer_sf320 + #define PeriodicBSR_Timer_r12_sf640 MAC_MainConfig__ul_SCH_Config__periodicBSR_Timer_sf640 + #define PeriodicBSR_Timer_r12_sf1280 MAC_MainConfig__ul_SCH_Config__periodicBSR_Timer_sf1280 + #define PeriodicBSR_Timer_r12_sf2560 MAC_MainConfig__ul_SCH_Config__periodicBSR_Timer_sf2560 + #define PeriodicBSR_Timer_r12_infinity MAC_MainConfig__ul_SCH_Config__periodicBSR_Timer_infinity + #define RetxBSR_Timer_r12_sf320 MAC_MainConfig__ul_SCH_Config__retxBSR_Timer_sf320 + #define RetxBSR_Timer_r12_sf640 MAC_MainConfig__ul_SCH_Config__retxBSR_Timer_sf640 + #define RetxBSR_Timer_r12_sf1280 MAC_MainConfig__ul_SCH_Config__retxBSR_Timer_sf1280 + #define RetxBSR_Timer_r12_sf2560 MAC_MainConfig__ul_SCH_Config__retxBSR_Timer_sf2560 + #define RetxBSR_Timer_r12_sf5120 MAC_MainConfig__ul_SCH_Config__retxBSR_Timer_sf5120 + #define RetxBSR_Timer_r12_sf10240 MAC_MainConfig__ul_SCH_Config__retxBSR_Timer_sf10240 #endif // This corrects something generated by asn1c which is different between Rel8 and Rel10 #if (LTE_RRC_VERSION <= MAKE_VERSION(10, 0, 0)) -#define SystemInformation_r8_IEs__sib_TypeAndInfo__Member SystemInformation_r8_IEs_sib_TypeAndInfo_Member -#define SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib2 SystemInformation_r8_IEs_sib_TypeAndInfo_Member_PR_sib2 -#define SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib3 SystemInformation_r8_IEs_sib_TypeAndInfo_Member_PR_sib3 -#define SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib4 SystemInformation_r8_IEs_sib_TypeAndInfo_Member_PR_sib4 -#define SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib5 SystemInformation_r8_IEs_sib_TypeAndInfo_Member_PR_sib5 -#define SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib6 SystemInformation_r8_IEs_sib_TypeAndInfo_Member_PR_sib6 -#define SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib7 SystemInformation_r8_IEs_sib_TypeAndInfo_Member_PR_sib7 -#define SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib8 SystemInformation_r8_IEs_sib_TypeAndInfo_Member_PR_sib8 -#define SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib9 SystemInformation_r8_IEs_sib_TypeAndInfo_Member_PR_sib9 -#define SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib10 SystemInformation_r8_IEs_sib_TypeAndInfo_Member_PR_sib10 -#define SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib11 SystemInformation_r8_IEs_sib_TypeAndInfo_Member_PR_sib11 + #define SystemInformation_r8_IEs__sib_TypeAndInfo__Member SystemInformation_r8_IEs_sib_TypeAndInfo_Member + #define SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib2 SystemInformation_r8_IEs_sib_TypeAndInfo_Member_PR_sib2 + #define SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib3 SystemInformation_r8_IEs_sib_TypeAndInfo_Member_PR_sib3 + #define SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib4 SystemInformation_r8_IEs_sib_TypeAndInfo_Member_PR_sib4 + #define SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib5 SystemInformation_r8_IEs_sib_TypeAndInfo_Member_PR_sib5 + #define SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib6 SystemInformation_r8_IEs_sib_TypeAndInfo_Member_PR_sib6 + #define SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib7 SystemInformation_r8_IEs_sib_TypeAndInfo_Member_PR_sib7 + #define SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib8 SystemInformation_r8_IEs_sib_TypeAndInfo_Member_PR_sib8 + #define SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib9 SystemInformation_r8_IEs_sib_TypeAndInfo_Member_PR_sib9 + #define SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib10 SystemInformation_r8_IEs_sib_TypeAndInfo_Member_PR_sib10 + #define SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib11 SystemInformation_r8_IEs_sib_TypeAndInfo_Member_PR_sib11 #endif @@ -279,13 +279,13 @@ void *send_UE_status_notification(void *); */ //#include "L3_rrc_defs.h" #ifndef NO_RRM -#include "L3_rrc_interface.h" -#include "rrc_rrm_msg.h" -#include "rrc_rrm_interface.h" + #include "L3_rrc_interface.h" + #include "rrc_rrm_msg.h" + #include "rrc_rrm_interface.h" #endif #if defined(ENABLE_ITTI) -# include "intertask_interface.h" + #include "intertask_interface.h" #endif /* TODO: be sure this include is correct. @@ -293,11 +293,11 @@ void *send_UE_status_notification(void *); * issue #186. */ #if !defined(ENABLE_ITTI) -# include "as_message.h" + #include "as_message.h" #endif #if defined(ENABLE_USE_MME) -# include "commonDef.h" + #include "commonDef.h" #endif //-------- @@ -516,29 +516,29 @@ typedef struct eNB_RRC_UE_s { #if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) LTE_SCellToAddMod_r10_t sCell_config[2]; #endif - LTE_SRB_ToAddModList_t* SRB_configList; - LTE_SRB_ToAddModList_t* SRB_configList2[RRC_TRANSACTION_IDENTIFIER_NUMBER]; - LTE_DRB_ToAddModList_t* DRB_configList; - LTE_DRB_ToAddModList_t* DRB_configList2[RRC_TRANSACTION_IDENTIFIER_NUMBER]; - LTE_DRB_ToReleaseList_t* DRB_Release_configList2[RRC_TRANSACTION_IDENTIFIER_NUMBER]; + LTE_SRB_ToAddModList_t *SRB_configList; + LTE_SRB_ToAddModList_t *SRB_configList2[RRC_TRANSACTION_IDENTIFIER_NUMBER]; + LTE_DRB_ToAddModList_t *DRB_configList; + LTE_DRB_ToAddModList_t *DRB_configList2[RRC_TRANSACTION_IDENTIFIER_NUMBER]; + LTE_DRB_ToReleaseList_t *DRB_Release_configList2[RRC_TRANSACTION_IDENTIFIER_NUMBER]; uint8_t DRB_active[8]; - struct LTE_PhysicalConfigDedicated* physicalConfigDedicated; - struct LTE_SPS_Config* sps_Config; - LTE_MeasObjectToAddMod_t* MeasObj[MAX_MEAS_OBJ]; - struct LTE_ReportConfigToAddMod* ReportConfig[MAX_MEAS_CONFIG]; - struct LTE_QuantityConfig* QuantityConfig; - struct LTE_MeasIdToAddMod* MeasId[MAX_MEAS_ID]; - LTE_MAC_MainConfig_t* mac_MainConfig; - LTE_MeasGapConfig_t* measGapConfig; + struct LTE_PhysicalConfigDedicated *physicalConfigDedicated; + struct LTE_SPS_Config *sps_Config; + LTE_MeasObjectToAddMod_t *MeasObj[MAX_MEAS_OBJ]; + struct LTE_ReportConfigToAddMod *ReportConfig[MAX_MEAS_CONFIG]; + struct LTE_QuantityConfig *QuantityConfig; + struct LTE_MeasIdToAddMod *MeasId[MAX_MEAS_ID]; + LTE_MAC_MainConfig_t *mac_MainConfig; + LTE_MeasGapConfig_t *measGapConfig; SRB_INFO SI; SRB_INFO Srb0; SRB_INFO_TABLE_ENTRY Srb1; SRB_INFO_TABLE_ENTRY Srb2; - LTE_MeasConfig_t* measConfig; - HANDOVER_INFO* handover_info; - LTE_MeasResults_t* measResults; + LTE_MeasConfig_t *measConfig; + HANDOVER_INFO *handover_info; + LTE_MeasResults_t *measResults; - LTE_UE_EUTRA_Capability_t* UE_Capability; + LTE_UE_EUTRA_Capability_t *UE_Capability; ImsiMobileIdentity_t imsi; #if defined(ENABLE_SECURITY) @@ -601,7 +601,7 @@ typedef struct eNB_RRC_UE_s { uint32_t ue_reestablishment_timer_thres; /* RRC inactivity timer: on timeout, should release RRC connection for inactivity on all E-RABs */ uint32_t ue_rrc_inactivity_timer; - uint32_t ue_rrc_inactivity_timer_thres; + uint32_t ue_rrc_inactivity_timer_thres; uint8_t e_rab_release_command_flag; int8_t reestablishment_xid; } eNB_RRC_UE_t; @@ -771,7 +771,7 @@ typedef struct UE_RRC_INST_s { //current destination uint32_t destinationL2Id; //List of destinations - uint32_t destinationList[MAX_NUM_DEST]; + uint32_t destinationList[MAX_NUM_DEST]; //sl_discovery.. SRB_INFO SL_Discovery[NB_CNX_UE]; #endif diff --git a/openair2/RRC/LTE/rrc_eNB.c b/openair2/RRC/LTE/rrc_eNB.c index 412128b017..3f3248aaca 100644 --- a/openair2/RRC/LTE/rrc_eNB.c +++ b/openair2/RRC/LTE/rrc_eNB.c @@ -75,29 +75,29 @@ #include "OCG_extern.h" #if defined(ENABLE_SECURITY) -# include "UTIL/OSA/osa_defs.h" + #include "UTIL/OSA/osa_defs.h" #endif #if defined(ENABLE_USE_MME) -# include "rrc_eNB_S1AP.h" -# include "rrc_eNB_GTPV1U.h" -# if defined(ENABLE_ITTI) -# else -# include "../../S1AP/s1ap_eNB.h" -# endif + #include "rrc_eNB_S1AP.h" + #include "rrc_eNB_GTPV1U.h" + #if defined(ENABLE_ITTI) + #else + #include "../../S1AP/s1ap_eNB.h" + #endif #else -# define EPC_MODE_ENABLED 0 + #define EPC_MODE_ENABLED 0 #endif #include "pdcp.h" #include "gtpv1u_eNB_task.h" #if defined(ENABLE_ITTI) -# include "intertask_interface.h" + #include "intertask_interface.h" #endif #if ENABLE_RAL -# include "rrc_eNB_ral.h" + #include "rrc_eNB_ral.h" #endif #include "SIMULATION/TOOLS/sim.h" // for taus @@ -106,12 +106,12 @@ extern RAN_CONTEXT_t RC; #ifdef PHY_EMUL -extern EMULATION_VARS *Emul_vars; + extern EMULATION_VARS *Emul_vars; #endif extern eNB_MAC_INST *eNB_mac_inst; extern UE_MAC_INST *UE_mac_inst; #ifdef BIGPHYSAREA -extern void* bigphys_malloc(int); + extern void *bigphys_malloc(int); #endif extern uint16_t two_tier_hexagonal_cellIds[7]; @@ -120,30 +120,30 @@ mui_t rrc_eNB_mui = 0; void openair_rrc_on( - const protocol_ctxt_t* const ctxt_pP + const protocol_ctxt_t *const ctxt_pP ) //----------------------------------------------------------------------------- { int CC_id; + LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" ENB:OPENAIR RRC IN....\n", + PROTOCOL_RRC_CTXT_ARGS(ctxt_pP)); - LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" ENB:OPENAIR RRC IN....\n", - PROTOCOL_RRC_CTXT_ARGS(ctxt_pP)); - for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { - rrc_config_buffer (&RC.rrc[ctxt_pP->module_id]->carrier[CC_id].SI, BCCH, 1); - RC.rrc[ctxt_pP->module_id]->carrier[CC_id].SI.Active = 1; - rrc_config_buffer (&RC.rrc[ctxt_pP->module_id]->carrier[CC_id].Srb0, CCCH, 1); - RC.rrc[ctxt_pP->module_id]->carrier[CC_id].Srb0.Active = 1; - } + for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { + rrc_config_buffer (&RC.rrc[ctxt_pP->module_id]->carrier[CC_id].SI, BCCH, 1); + RC.rrc[ctxt_pP->module_id]->carrier[CC_id].SI.Active = 1; + rrc_config_buffer (&RC.rrc[ctxt_pP->module_id]->carrier[CC_id].Srb0, CCCH, 1); + RC.rrc[ctxt_pP->module_id]->carrier[CC_id].Srb0.Active = 1; + } } //----------------------------------------------------------------------------- static void init_SI( - const protocol_ctxt_t* const ctxt_pP, + const protocol_ctxt_t *const ctxt_pP, const int CC_id #if defined(ENABLE_ITTI) , - RrcConfigurationReq * configuration + RrcConfigurationReq *configuration #endif ) //----------------------------------------------------------------------------- @@ -151,14 +151,11 @@ init_SI( #if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) int i; #endif - #if (LTE_RRC_VERSION >= MAKE_VERSION(13, 1, 0)) LTE_SystemInformationBlockType1_v1310_IEs_t *sib1_v13ext=(LTE_SystemInformationBlockType1_v1310_IEs_t *)NULL; #endif - LOG_D(RRC,"%s()\n\n\n\n",__FUNCTION__); - - RC.rrc[ctxt_pP->module_id]->carrier[CC_id].MIB = (uint8_t*) malloc16(4); + RC.rrc[ctxt_pP->module_id]->carrier[CC_id].MIB = (uint8_t *) malloc16(4); // copy basic parameters RC.rrc[ctxt_pP->module_id]->carrier[CC_id].physCellId = configuration->Nid_cell[CC_id]; RC.rrc[ctxt_pP->module_id]->carrier[CC_id].p_eNB = configuration->nb_antenna_ports[CC_id]; @@ -168,84 +165,74 @@ init_SI( #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) RC.rrc[ctxt_pP->module_id]->carrier[CC_id].pbch_repetition = configuration->pbch_repetition[CC_id]; #endif - LOG_I(RRC, "Configuring MIB (N_RB_DL %d,phich_Resource %d,phich_Duration %d)\n", - (int)configuration->N_RB_DL[CC_id], - (int)configuration->phich_resource[CC_id], - (int)configuration->phich_duration[CC_id]); + LOG_I(RRC, "Configuring MIB (N_RB_DL %d,phich_Resource %d,phich_Duration %d)\n", + (int)configuration->N_RB_DL[CC_id], + (int)configuration->phich_resource[CC_id], + (int)configuration->phich_duration[CC_id]); do_MIB(&RC.rrc[ctxt_pP->module_id]->carrier[CC_id], #ifdef ENABLE_ITTI - configuration->N_RB_DL[CC_id], - configuration->phich_resource[CC_id], - configuration->phich_duration[CC_id] + configuration->N_RB_DL[CC_id], + configuration->phich_resource[CC_id], + configuration->phich_duration[CC_id] #else - 50,0,0 + 50,0,0 #endif - ,0); - - + ,0); RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sizeof_SIB1 = 0; RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sizeof_SIB23 = 0; - RC.rrc[ctxt_pP->module_id]->carrier[CC_id].SIB1 = (uint8_t*) malloc16(32); - + RC.rrc[ctxt_pP->module_id]->carrier[CC_id].SIB1 = (uint8_t *) malloc16(32); AssertFatal(RC.rrc[ctxt_pP->module_id]->carrier[CC_id].SIB1!=NULL,PROTOCOL_RRC_CTXT_FMT" init_SI: FATAL, no memory for SIB1 allocated\n", - PROTOCOL_RRC_CTXT_ARGS(ctxt_pP)); + PROTOCOL_RRC_CTXT_ARGS(ctxt_pP)); RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sizeof_SIB1 = do_SIB1(&RC.rrc[ctxt_pP->module_id]->carrier[CC_id],ctxt_pP->module_id,CC_id #if defined(ENABLE_ITTI) - , configuration + , configuration #endif - ); - + ); AssertFatal(RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sizeof_SIB1 != 255,"FATAL, RC.rrc[enb_mod_idP].carrier[CC_id].sizeof_SIB1 == 255"); - - RC.rrc[ctxt_pP->module_id]->carrier[CC_id].SIB23 = (uint8_t*) malloc16(64); + RC.rrc[ctxt_pP->module_id]->carrier[CC_id].SIB23 = (uint8_t *) malloc16(64); AssertFatal(RC.rrc[ctxt_pP->module_id]->carrier[CC_id].SIB23!=NULL,"cannot allocate memory for SIB"); RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sizeof_SIB23 = do_SIB23( - ctxt_pP->module_id, - - CC_id + ctxt_pP->module_id, + CC_id #if defined(ENABLE_ITTI) - , configuration + , configuration #endif - ); - + ); AssertFatal(RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sizeof_SIB23 != 255,"FATAL, RC.rrc[mod].carrier[CC_id].sizeof_SIB23 == 255"); - - LOG_T(RRC, PROTOCOL_RRC_CTXT_FMT" SIB2/3 Contents (partial)\n", - PROTOCOL_RRC_CTXT_ARGS(ctxt_pP)); + PROTOCOL_RRC_CTXT_ARGS(ctxt_pP)); LOG_T(RRC, PROTOCOL_RRC_CTXT_FMT" pusch_config_common.n_SB = %ld\n", - PROTOCOL_RRC_CTXT_ARGS(ctxt_pP), - RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib2->radioResourceConfigCommon.pusch_ConfigCommon. - pusch_ConfigBasic.n_SB); + PROTOCOL_RRC_CTXT_ARGS(ctxt_pP), + RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib2->radioResourceConfigCommon.pusch_ConfigCommon. + pusch_ConfigBasic.n_SB); LOG_T(RRC, PROTOCOL_RRC_CTXT_FMT" pusch_config_common.hoppingMode = %ld\n", - PROTOCOL_RRC_CTXT_ARGS(ctxt_pP), - RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib2->radioResourceConfigCommon.pusch_ConfigCommon. - pusch_ConfigBasic.hoppingMode); + PROTOCOL_RRC_CTXT_ARGS(ctxt_pP), + RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib2->radioResourceConfigCommon.pusch_ConfigCommon. + pusch_ConfigBasic.hoppingMode); LOG_T(RRC, PROTOCOL_RRC_CTXT_FMT" pusch_config_common.pusch_HoppingOffset = %ld\n", - PROTOCOL_RRC_CTXT_ARGS(ctxt_pP), - RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib2->radioResourceConfigCommon.pusch_ConfigCommon. - pusch_ConfigBasic.pusch_HoppingOffset); + PROTOCOL_RRC_CTXT_ARGS(ctxt_pP), + RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib2->radioResourceConfigCommon.pusch_ConfigCommon. + pusch_ConfigBasic.pusch_HoppingOffset); LOG_T(RRC, PROTOCOL_RRC_CTXT_FMT" pusch_config_common.enable64QAM = %d\n", - PROTOCOL_RRC_CTXT_ARGS(ctxt_pP), - (int)RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib2->radioResourceConfigCommon.pusch_ConfigCommon. - pusch_ConfigBasic.enable64QAM); + PROTOCOL_RRC_CTXT_ARGS(ctxt_pP), + (int)RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib2->radioResourceConfigCommon.pusch_ConfigCommon. + pusch_ConfigBasic.enable64QAM); LOG_T(RRC, PROTOCOL_RRC_CTXT_FMT" pusch_config_common.groupHoppingEnabled = %d\n", - PROTOCOL_RRC_CTXT_ARGS(ctxt_pP), - (int)RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib2->radioResourceConfigCommon.pusch_ConfigCommon. - ul_ReferenceSignalsPUSCH.groupHoppingEnabled); + PROTOCOL_RRC_CTXT_ARGS(ctxt_pP), + (int)RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib2->radioResourceConfigCommon.pusch_ConfigCommon. + ul_ReferenceSignalsPUSCH.groupHoppingEnabled); LOG_T(RRC, PROTOCOL_RRC_CTXT_FMT" pusch_config_common.groupAssignmentPUSCH = %ld\n", - PROTOCOL_RRC_CTXT_ARGS(ctxt_pP), - RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib2->radioResourceConfigCommon.pusch_ConfigCommon. - ul_ReferenceSignalsPUSCH.groupAssignmentPUSCH); + PROTOCOL_RRC_CTXT_ARGS(ctxt_pP), + RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib2->radioResourceConfigCommon.pusch_ConfigCommon. + ul_ReferenceSignalsPUSCH.groupAssignmentPUSCH); LOG_T(RRC, PROTOCOL_RRC_CTXT_FMT" pusch_config_common.sequenceHoppingEnabled = %d\n", - PROTOCOL_RRC_CTXT_ARGS(ctxt_pP), - (int)RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib2->radioResourceConfigCommon.pusch_ConfigCommon. - ul_ReferenceSignalsPUSCH.sequenceHoppingEnabled); + PROTOCOL_RRC_CTXT_ARGS(ctxt_pP), + (int)RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib2->radioResourceConfigCommon.pusch_ConfigCommon. + ul_ReferenceSignalsPUSCH.sequenceHoppingEnabled); LOG_T(RRC, PROTOCOL_RRC_CTXT_FMT" pusch_config_common.cyclicShift = %ld\n", - PROTOCOL_RRC_CTXT_ARGS(ctxt_pP), - RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib2->radioResourceConfigCommon.pusch_ConfigCommon. - ul_ReferenceSignalsPUSCH.cyclicShift); - + PROTOCOL_RRC_CTXT_ARGS(ctxt_pP), + RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib2->radioResourceConfigCommon.pusch_ConfigCommon. + ul_ReferenceSignalsPUSCH.cyclicShift); #if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) if (RC.rrc[ctxt_pP->module_id]->carrier[CC_id].MBMS_flag > 0) { @@ -253,177 +240,174 @@ init_SI( // SIB 2 // LOG_D(RRC, "[eNB %d] mbsfn_SubframeConfigList.list.count = %ld\n", enb_mod_idP, RC.rrc[enb_mod_idP].sib2->mbsfn_SubframeConfigList->list.count); LOG_D(RRC, PROTOCOL_RRC_CTXT_FMT" SIB13 contents for MBSFN subframe allocation %d/%d(partial)\n", - PROTOCOL_RRC_CTXT_ARGS(ctxt_pP), - i, - RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib2->mbsfn_SubframeConfigList->list.count); + PROTOCOL_RRC_CTXT_ARGS(ctxt_pP), + i, + RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib2->mbsfn_SubframeConfigList->list.count); LOG_D(RRC, PROTOCOL_RRC_CTXT_FMT" mbsfn_Subframe_pattern is = %x\n", - PROTOCOL_RRC_CTXT_ARGS(ctxt_pP), - RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib2->mbsfn_SubframeConfigList->list.array[i]->subframeAllocation.choice.oneFrame.buf[0] >> 0); + PROTOCOL_RRC_CTXT_ARGS(ctxt_pP), + RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib2->mbsfn_SubframeConfigList->list.array[i]->subframeAllocation.choice.oneFrame.buf[0] >> 0); LOG_D(RRC, PROTOCOL_RRC_CTXT_FMT" radioframe_allocation_period = %ld (just index number, not the real value)\n", - PROTOCOL_RRC_CTXT_ARGS(ctxt_pP), - RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib2->mbsfn_SubframeConfigList->list.array[i]->radioframeAllocationPeriod); // need to display the real value, using array of char (like in dumping SIB2) + PROTOCOL_RRC_CTXT_ARGS(ctxt_pP), + RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib2->mbsfn_SubframeConfigList->list.array[i]->radioframeAllocationPeriod); // need to display the real value, using array of char (like in dumping SIB2) LOG_D(RRC, PROTOCOL_RRC_CTXT_FMT" radioframe_allocation_offset = %ld\n", - PROTOCOL_RRC_CTXT_ARGS(ctxt_pP), - RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib2->mbsfn_SubframeConfigList->list.array[i]->radioframeAllocationOffset); + PROTOCOL_RRC_CTXT_ARGS(ctxt_pP), + RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib2->mbsfn_SubframeConfigList->list.array[i]->radioframeAllocationOffset); } #if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) + // SIB13 for (i = 0; i < RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib13->mbsfn_AreaInfoList_r9.list.count; i++) { LOG_D(RRC, PROTOCOL_RRC_CTXT_FMT" SIB13 contents for MBSFN sync area %d/%d (partial)\n", - PROTOCOL_RRC_CTXT_ARGS(ctxt_pP), - i, - RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib13->mbsfn_AreaInfoList_r9.list.count); + PROTOCOL_RRC_CTXT_ARGS(ctxt_pP), + i, + RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib13->mbsfn_AreaInfoList_r9.list.count); LOG_D(RRC, PROTOCOL_RRC_CTXT_FMT" MCCH Repetition Period: %ld (just index number, not real value)\n", - PROTOCOL_RRC_CTXT_ARGS(ctxt_pP), - RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib13->mbsfn_AreaInfoList_r9.list.array[i]->mcch_Config_r9.mcch_RepetitionPeriod_r9); + PROTOCOL_RRC_CTXT_ARGS(ctxt_pP), + RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib13->mbsfn_AreaInfoList_r9.list.array[i]->mcch_Config_r9.mcch_RepetitionPeriod_r9); LOG_D(RRC, PROTOCOL_RRC_CTXT_FMT" MCCH Offset: %ld\n", - PROTOCOL_RRC_CTXT_ARGS(ctxt_pP), - RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib13->mbsfn_AreaInfoList_r9.list.array[i]->mcch_Config_r9.mcch_Offset_r9); + PROTOCOL_RRC_CTXT_ARGS(ctxt_pP), + RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib13->mbsfn_AreaInfoList_r9.list.array[i]->mcch_Config_r9.mcch_Offset_r9); } + #endif - } - else memset((void*)&RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib13,0,sizeof(RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib13)); + } else memset((void *)&RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib13,0,sizeof(RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib13)); //TTN - SIB 18 for (int j = 0; j < RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib18->commConfig_r12->commRxPool_r12.list.count; j++) { - LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" Contents of SIB18 %d/%d \n", - PROTOCOL_RRC_CTXT_ARGS(ctxt_pP), - j+1, - RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib18->commConfig_r12->commRxPool_r12.list.count); - LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" SIB18 rxPool_sc_CP_Len: %ld \n", - PROTOCOL_RRC_CTXT_ARGS(ctxt_pP), - RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib18->commConfig_r12->commRxPool_r12.list.array[j]->sc_CP_Len_r12); - LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" SIB18 sc_Period_r12: %ld \n", - PROTOCOL_RRC_CTXT_ARGS(ctxt_pP), - RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib18->commConfig_r12->commRxPool_r12.list.array[j]->sc_Period_r12); - LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" SIB18 data_CP_Len_r12: %ld \n", - PROTOCOL_RRC_CTXT_ARGS(ctxt_pP), - RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib18->commConfig_r12->commRxPool_r12.list.array[j]->data_CP_Len_r12); - LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" SIB18 prb_Num_r12: %ld \n", - PROTOCOL_RRC_CTXT_ARGS(ctxt_pP), - RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib18->commConfig_r12->commRxPool_r12.list.array[j]->sc_TF_ResourceConfig_r12.prb_Num_r12); - LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" SIB18 prb_Start_r12: %ld \n", - PROTOCOL_RRC_CTXT_ARGS(ctxt_pP), - RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib18->commConfig_r12->commRxPool_r12.list.array[j]->sc_TF_ResourceConfig_r12.prb_Start_r12); - LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" SIB18 prb_End_r12: %ld \n", - PROTOCOL_RRC_CTXT_ARGS(ctxt_pP), - RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib18->commConfig_r12->commRxPool_r12.list.array[j]->sc_TF_ResourceConfig_r12.prb_End_r12); - LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" SIB18 offsetIndicator: %ld \n", - PROTOCOL_RRC_CTXT_ARGS(ctxt_pP), - RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib18->commConfig_r12->commRxPool_r12.list.array[j]->sc_TF_ResourceConfig_r12.offsetIndicator_r12.choice.small_r12); - LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" SIB18 subframeBitmap_choice_bs_buf: %s \n", - PROTOCOL_RRC_CTXT_ARGS(ctxt_pP), - RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib18->commConfig_r12->commRxPool_r12.list.array[j]->sc_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs16_r12.buf); - + LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" Contents of SIB18 %d/%d \n", + PROTOCOL_RRC_CTXT_ARGS(ctxt_pP), + j+1, + RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib18->commConfig_r12->commRxPool_r12.list.count); + LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" SIB18 rxPool_sc_CP_Len: %ld \n", + PROTOCOL_RRC_CTXT_ARGS(ctxt_pP), + RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib18->commConfig_r12->commRxPool_r12.list.array[j]->sc_CP_Len_r12); + LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" SIB18 sc_Period_r12: %ld \n", + PROTOCOL_RRC_CTXT_ARGS(ctxt_pP), + RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib18->commConfig_r12->commRxPool_r12.list.array[j]->sc_Period_r12); + LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" SIB18 data_CP_Len_r12: %ld \n", + PROTOCOL_RRC_CTXT_ARGS(ctxt_pP), + RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib18->commConfig_r12->commRxPool_r12.list.array[j]->data_CP_Len_r12); + LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" SIB18 prb_Num_r12: %ld \n", + PROTOCOL_RRC_CTXT_ARGS(ctxt_pP), + RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib18->commConfig_r12->commRxPool_r12.list.array[j]->sc_TF_ResourceConfig_r12.prb_Num_r12); + LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" SIB18 prb_Start_r12: %ld \n", + PROTOCOL_RRC_CTXT_ARGS(ctxt_pP), + RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib18->commConfig_r12->commRxPool_r12.list.array[j]->sc_TF_ResourceConfig_r12.prb_Start_r12); + LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" SIB18 prb_End_r12: %ld \n", + PROTOCOL_RRC_CTXT_ARGS(ctxt_pP), + RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib18->commConfig_r12->commRxPool_r12.list.array[j]->sc_TF_ResourceConfig_r12.prb_End_r12); + LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" SIB18 offsetIndicator: %ld \n", + PROTOCOL_RRC_CTXT_ARGS(ctxt_pP), + RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib18->commConfig_r12->commRxPool_r12.list.array[j]->sc_TF_ResourceConfig_r12.offsetIndicator_r12.choice.small_r12); + LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" SIB18 subframeBitmap_choice_bs_buf: %s \n", + PROTOCOL_RRC_CTXT_ARGS(ctxt_pP), + RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib18->commConfig_r12->commRxPool_r12.list.array[j]->sc_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs16_r12.buf); } //TTN - SIB 19 for (int j = 0; j < RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib19->discConfig_r12->discRxPool_r12.list.count; j++) { - LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" Contents of SIB19 %d/%d \n", - PROTOCOL_RRC_CTXT_ARGS(ctxt_pP), - j+1, - RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib19->discConfig_r12->discRxPool_r12.list.count); - LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" SIB19 cp_Len_r12: %ld \n", - PROTOCOL_RRC_CTXT_ARGS(ctxt_pP), - RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib19->discConfig_r12->discRxPool_r12.list.array[j]->cp_Len_r12); - LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" SIB19 discPeriod_r12: %ld \n", - PROTOCOL_RRC_CTXT_ARGS(ctxt_pP), - RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib19->discConfig_r12->discRxPool_r12.list.array[j]->discPeriod_r12); - LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" SIB19 numRetx_r12: %ld \n", - PROTOCOL_RRC_CTXT_ARGS(ctxt_pP), - RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib19->discConfig_r12->discRxPool_r12.list.array[j]->numRetx_r12); - LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" SIB19 numRepetition_r12: %ld \n", - PROTOCOL_RRC_CTXT_ARGS(ctxt_pP), - RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib19->discConfig_r12->discRxPool_r12.list.array[j]->numRepetition_r12); - LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" SIB19 tf_ResourceConfig_r12 prb_Num_r12: %ld \n", - PROTOCOL_RRC_CTXT_ARGS(ctxt_pP), - RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib19->discConfig_r12->discRxPool_r12.list.array[j]->tf_ResourceConfig_r12.prb_Num_r12); - LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" SIB19 tf_ResourceConfig_r12 prb_Start_r12: %ld \n", - PROTOCOL_RRC_CTXT_ARGS(ctxt_pP), - RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib19->discConfig_r12->discRxPool_r12.list.array[j]->tf_ResourceConfig_r12.prb_Start_r12); - LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" SIB19 tf_ResourceConfig_r12 prb_End_r12: %ld \n", - PROTOCOL_RRC_CTXT_ARGS(ctxt_pP), - RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib19->discConfig_r12->discRxPool_r12.list.array[j]->tf_ResourceConfig_r12.prb_End_r12); - LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" SIB19 tf_ResourceConfig_r12 offsetIndicator: %ld \n", - PROTOCOL_RRC_CTXT_ARGS(ctxt_pP), - RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib19->discConfig_r12->discRxPool_r12.list.array[j]->tf_ResourceConfig_r12.offsetIndicator_r12.choice.small_r12); - LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" SIB19 tf_ResourceConfig_r12 subframeBitmap_choice_bs_buf: %s \n", - PROTOCOL_RRC_CTXT_ARGS(ctxt_pP), - RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib19->discConfig_r12->discRxPool_r12.list.array[j]->tf_ResourceConfig_r12.subframeBitmap_r12.choice.bs16_r12.buf); - + LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" Contents of SIB19 %d/%d \n", + PROTOCOL_RRC_CTXT_ARGS(ctxt_pP), + j+1, + RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib19->discConfig_r12->discRxPool_r12.list.count); + LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" SIB19 cp_Len_r12: %ld \n", + PROTOCOL_RRC_CTXT_ARGS(ctxt_pP), + RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib19->discConfig_r12->discRxPool_r12.list.array[j]->cp_Len_r12); + LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" SIB19 discPeriod_r12: %ld \n", + PROTOCOL_RRC_CTXT_ARGS(ctxt_pP), + RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib19->discConfig_r12->discRxPool_r12.list.array[j]->discPeriod_r12); + LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" SIB19 numRetx_r12: %ld \n", + PROTOCOL_RRC_CTXT_ARGS(ctxt_pP), + RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib19->discConfig_r12->discRxPool_r12.list.array[j]->numRetx_r12); + LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" SIB19 numRepetition_r12: %ld \n", + PROTOCOL_RRC_CTXT_ARGS(ctxt_pP), + RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib19->discConfig_r12->discRxPool_r12.list.array[j]->numRepetition_r12); + LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" SIB19 tf_ResourceConfig_r12 prb_Num_r12: %ld \n", + PROTOCOL_RRC_CTXT_ARGS(ctxt_pP), + RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib19->discConfig_r12->discRxPool_r12.list.array[j]->tf_ResourceConfig_r12.prb_Num_r12); + LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" SIB19 tf_ResourceConfig_r12 prb_Start_r12: %ld \n", + PROTOCOL_RRC_CTXT_ARGS(ctxt_pP), + RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib19->discConfig_r12->discRxPool_r12.list.array[j]->tf_ResourceConfig_r12.prb_Start_r12); + LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" SIB19 tf_ResourceConfig_r12 prb_End_r12: %ld \n", + PROTOCOL_RRC_CTXT_ARGS(ctxt_pP), + RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib19->discConfig_r12->discRxPool_r12.list.array[j]->tf_ResourceConfig_r12.prb_End_r12); + LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" SIB19 tf_ResourceConfig_r12 offsetIndicator: %ld \n", + PROTOCOL_RRC_CTXT_ARGS(ctxt_pP), + RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib19->discConfig_r12->discRxPool_r12.list.array[j]->tf_ResourceConfig_r12.offsetIndicator_r12.choice.small_r12); + LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" SIB19 tf_ResourceConfig_r12 subframeBitmap_choice_bs_buf: %s \n", + PROTOCOL_RRC_CTXT_ARGS(ctxt_pP), + RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib19->discConfig_r12->discRxPool_r12.list.array[j]->tf_ResourceConfig_r12.subframeBitmap_r12.choice.bs16_r12.buf); } #endif - LOG_D(RRC, - PROTOCOL_RRC_CTXT_FMT" RRC_UE --- MAC_CONFIG_REQ (SIB1.tdd & SIB2 params) ---> MAC_UE\n", - PROTOCOL_RRC_CTXT_ARGS(ctxt_pP)); - + PROTOCOL_RRC_CTXT_FMT" RRC_UE --- MAC_CONFIG_REQ (SIB1.tdd & SIB2 params) ---> MAC_UE\n", + PROTOCOL_RRC_CTXT_ARGS(ctxt_pP)); #if (LTE_RRC_VERSION >= MAKE_VERSION(13, 0, 0)) - if ((RC.rrc[ctxt_pP->module_id]->carrier[CC_id].mib.message.schedulingInfoSIB1_BR_r13>0) && + + if ((RC.rrc[ctxt_pP->module_id]->carrier[CC_id].mib.message.schedulingInfoSIB1_BR_r13>0) && (RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib1_BR!=NULL)) { - AssertFatal(RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib1_BR->nonCriticalExtension!=NULL, - "sib2_br->nonCriticalExtension is null (v8.9)\n"); - AssertFatal(RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib1_BR->nonCriticalExtension->nonCriticalExtension!=NULL, - "sib2_br->nonCriticalExtension is null (v9.2)\n"); - AssertFatal(RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib1_BR->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension!=NULL, - "sib2_br->nonCriticalExtension is null (v11.3)\n"); - AssertFatal(RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib1_BR->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension!=NULL, - "sib2_br->nonCriticalExtension is null (v12.5)\n"); - AssertFatal(RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib1_BR->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension!=NULL, - "sib2_br->nonCriticalExtension is null (v13.10)\n"); - sib1_v13ext = RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib1_BR->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension; + AssertFatal(RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib1_BR->nonCriticalExtension!=NULL, + "sib2_br->nonCriticalExtension is null (v8.9)\n"); + AssertFatal(RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib1_BR->nonCriticalExtension->nonCriticalExtension!=NULL, + "sib2_br->nonCriticalExtension is null (v9.2)\n"); + AssertFatal(RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib1_BR->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension!=NULL, + "sib2_br->nonCriticalExtension is null (v11.3)\n"); + AssertFatal(RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib1_BR->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension!=NULL, + "sib2_br->nonCriticalExtension is null (v12.5)\n"); + AssertFatal(RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib1_BR->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension!=NULL, + "sib2_br->nonCriticalExtension is null (v13.10)\n"); + sib1_v13ext = RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib1_BR->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension->nonCriticalExtension; } -#endif +#endif LOG_D(RRC, "About to call rrc_mac_config_req_eNB\n"); - rrc_mac_config_req_eNB(ctxt_pP->module_id, CC_id, - RC.rrc[ctxt_pP->module_id]->carrier[CC_id].physCellId, - RC.rrc[ctxt_pP->module_id]->carrier[CC_id].p_eNB, - RC.rrc[ctxt_pP->module_id]->carrier[CC_id].Ncp, - RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib1->freqBandIndicator, - RC.rrc[ctxt_pP->module_id]->carrier[CC_id].dl_CarrierFreq, + RC.rrc[ctxt_pP->module_id]->carrier[CC_id].physCellId, + RC.rrc[ctxt_pP->module_id]->carrier[CC_id].p_eNB, + RC.rrc[ctxt_pP->module_id]->carrier[CC_id].Ncp, + RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib1->freqBandIndicator, + RC.rrc[ctxt_pP->module_id]->carrier[CC_id].dl_CarrierFreq, #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - RC.rrc[ctxt_pP->module_id]->carrier[CC_id].pbch_repetition, + RC.rrc[ctxt_pP->module_id]->carrier[CC_id].pbch_repetition, #endif - 0, // rnti - (LTE_BCCH_BCH_Message_t *) - &RC.rrc[ctxt_pP->module_id]->carrier[CC_id].mib, - (LTE_RadioResourceConfigCommonSIB_t *) & - RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib2->radioResourceConfigCommon, + 0, // rnti + (LTE_BCCH_BCH_Message_t *) + &RC.rrc[ctxt_pP->module_id]->carrier[CC_id].mib, + (LTE_RadioResourceConfigCommonSIB_t *) & + RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib2->radioResourceConfigCommon, #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - (LTE_RadioResourceConfigCommonSIB_t *) & - RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib2_BR->radioResourceConfigCommon, + (LTE_RadioResourceConfigCommonSIB_t *) & + RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib2_BR->radioResourceConfigCommon, #endif - (struct LTE_PhysicalConfigDedicated *)NULL, + (struct LTE_PhysicalConfigDedicated *)NULL, #if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) - (LTE_SCellToAddMod_r10_t *)NULL, - //(struct LTE_PhysicalConfigDedicatedSCell_r10 *)NULL, + (LTE_SCellToAddMod_r10_t *)NULL, + //(struct LTE_PhysicalConfigDedicatedSCell_r10 *)NULL, #endif - (LTE_MeasObjectToAddMod_t **) NULL, - (LTE_MAC_MainConfig_t *) NULL, 0, - (struct LTE_LogicalChannelConfig *)NULL, - (LTE_MeasGapConfig_t *) NULL, - RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib1->tdd_Config, - NULL, - &RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib1->schedulingInfoList, - RC.rrc[ctxt_pP->module_id]->carrier[CC_id].ul_CarrierFreq, - RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib2->freqInfo.ul_Bandwidth, - &RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib2->freqInfo.additionalSpectrumEmission, - (LTE_MBSFN_SubframeConfigList_t*) RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib2->mbsfn_SubframeConfigList + (LTE_MeasObjectToAddMod_t **) NULL, + (LTE_MAC_MainConfig_t *) NULL, 0, + (struct LTE_LogicalChannelConfig *)NULL, + (LTE_MeasGapConfig_t *) NULL, + RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib1->tdd_Config, + NULL, + &RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib1->schedulingInfoList, + RC.rrc[ctxt_pP->module_id]->carrier[CC_id].ul_CarrierFreq, + RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib2->freqInfo.ul_Bandwidth, + &RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib2->freqInfo.additionalSpectrumEmission, + (LTE_MBSFN_SubframeConfigList_t *) RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib2->mbsfn_SubframeConfigList #if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) - , - RC.rrc[ctxt_pP->module_id]->carrier[CC_id].MBMS_flag, - (LTE_MBSFN_AreaInfoList_r9_t*) & RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib13->mbsfn_AreaInfoList_r9, - (LTE_PMCH_InfoList_r9_t *) NULL + , + RC.rrc[ctxt_pP->module_id]->carrier[CC_id].MBMS_flag, + (LTE_MBSFN_AreaInfoList_r9_t *) & RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sib13->mbsfn_AreaInfoList_r9, + (LTE_PMCH_InfoList_r9_t *) NULL #endif #if (LTE_RRC_VERSION >= MAKE_VERSION(13, 0, 0)) - , - sib1_v13ext + , + sib1_v13ext #endif - ); + ); } #if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) @@ -435,92 +419,81 @@ init_MCCH( ) //----------------------------------------------------------------------------- { - int sync_area = 0; // initialize RRC_eNB_INST MCCH entry RC.rrc[enb_mod_idP]->carrier[CC_id].MCCH_MESSAGE = - malloc(RC.rrc[enb_mod_idP]->carrier[CC_id].num_mbsfn_sync_area * sizeof(uint8_t*)); + malloc(RC.rrc[enb_mod_idP]->carrier[CC_id].num_mbsfn_sync_area * sizeof(uint8_t *)); for (sync_area = 0; sync_area < RC.rrc[enb_mod_idP]->carrier[CC_id].num_mbsfn_sync_area; sync_area++) { - RC.rrc[enb_mod_idP]->carrier[CC_id].sizeof_MCCH_MESSAGE[sync_area] = 0; RC.rrc[enb_mod_idP]->carrier[CC_id].MCCH_MESSAGE[sync_area] = (uint8_t *) malloc16(32); - AssertFatal(RC.rrc[enb_mod_idP]->carrier[CC_id].MCCH_MESSAGE[sync_area] != NULL, - "[eNB %d]init_MCCH: FATAL, no memory for MCCH MESSAGE allocated \n", enb_mod_idP); + "[eNB %d]init_MCCH: FATAL, no memory for MCCH MESSAGE allocated \n", enb_mod_idP); RC.rrc[enb_mod_idP]->carrier[CC_id].sizeof_MCCH_MESSAGE[sync_area] = do_MBSFNAreaConfig(enb_mod_idP, - sync_area, - (uint8_t *)RC.rrc[enb_mod_idP]->carrier[CC_id].MCCH_MESSAGE[sync_area], - &RC.rrc[enb_mod_idP]->carrier[CC_id].mcch, - &RC.rrc[enb_mod_idP]->carrier[CC_id].mcch_message); - + sync_area, + (uint8_t *)RC.rrc[enb_mod_idP]->carrier[CC_id].MCCH_MESSAGE[sync_area], + &RC.rrc[enb_mod_idP]->carrier[CC_id].mcch, + &RC.rrc[enb_mod_idP]->carrier[CC_id].mcch_message); LOG_I(RRC, "mcch message pointer %p for sync area %d \n", - RC.rrc[enb_mod_idP]->carrier[CC_id].MCCH_MESSAGE[sync_area], - sync_area); + RC.rrc[enb_mod_idP]->carrier[CC_id].MCCH_MESSAGE[sync_area], + sync_area); LOG_D(RRC, "[eNB %d] MCCH_MESSAGE contents for Sync Area %d (partial)\n", enb_mod_idP, sync_area); LOG_D(RRC, "[eNB %d] CommonSF_AllocPeriod_r9 %ld\n", enb_mod_idP, - RC.rrc[enb_mod_idP]->carrier[CC_id].mcch_message->commonSF_AllocPeriod_r9); + RC.rrc[enb_mod_idP]->carrier[CC_id].mcch_message->commonSF_AllocPeriod_r9); LOG_D(RRC, - "[eNB %d] CommonSF_Alloc_r9.list.count (number of MBSFN Subframe Pattern) %d\n", - enb_mod_idP, RC.rrc[enb_mod_idP]->carrier[CC_id].mcch_message->commonSF_Alloc_r9.list.count); + "[eNB %d] CommonSF_Alloc_r9.list.count (number of MBSFN Subframe Pattern) %d\n", + enb_mod_idP, RC.rrc[enb_mod_idP]->carrier[CC_id].mcch_message->commonSF_Alloc_r9.list.count); LOG_D(RRC, "[eNB %d] MBSFN Subframe Pattern: %02x (in hex)\n", - enb_mod_idP, - RC.rrc[enb_mod_idP]->carrier[CC_id].mcch_message->commonSF_Alloc_r9.list.array[0]->subframeAllocation. - choice.oneFrame.buf[0]); - + enb_mod_idP, + RC.rrc[enb_mod_idP]->carrier[CC_id].mcch_message->commonSF_Alloc_r9.list.array[0]->subframeAllocation. + choice.oneFrame.buf[0]); AssertFatal(RC.rrc[enb_mod_idP]->carrier[CC_id].sizeof_MCCH_MESSAGE[sync_area] != 255, - "RC.rrc[enb_mod_idP]->carrier[CC_id].sizeof_MCCH_MESSAGE[sync_area] == 255"); + "RC.rrc[enb_mod_idP]->carrier[CC_id].sizeof_MCCH_MESSAGE[sync_area] == 255"); RC.rrc[enb_mod_idP]->carrier[CC_id].MCCH_MESS[sync_area].Active = 1; } - //Set the RC.rrc[enb_mod_idP]->MCCH_MESS.Active to 1 (allow to transfer MCCH message RRC->MAC in function mac_rrc_data_req) - // ??Configure MCCH logical channel // call mac_config_req with appropriate structure from ASN.1 description - - // LOG_I(RRC, "DUY: serviceID is %d\n",RC.rrc[enb_mod_idP]->mcch_message->pmch_InfoList_r9.list.array[0]->mbms_SessionInfoList_r9.list.array[0]->tmgi_r9.serviceId_r9.buf[2]); // LOG_I(RRC, "DUY: session ID is %d\n",RC.rrc[enb_mod_idP]->mcch_message->pmch_InfoList_r9.list.array[0]->mbms_SessionInfoList_r9.list.array[0]->sessionId_r9->buf[0]); rrc_mac_config_req_eNB(enb_mod_idP, CC_id, - 0,0,0,0,0, + 0,0,0,0,0, #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - 0, + 0, #endif - 0,//rnti - (LTE_BCCH_BCH_Message_t *)NULL, - (LTE_RadioResourceConfigCommonSIB_t *) NULL, + 0,//rnti + (LTE_BCCH_BCH_Message_t *)NULL, + (LTE_RadioResourceConfigCommonSIB_t *) NULL, #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - (LTE_RadioResourceConfigCommonSIB_t *) NULL, + (LTE_RadioResourceConfigCommonSIB_t *) NULL, #endif - (struct LTE_PhysicalConfigDedicated *)NULL, + (struct LTE_PhysicalConfigDedicated *)NULL, #if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) - (LTE_SCellToAddMod_r10_t *)NULL, - //(struct LTE_PhysicalConfigDedicatedSCell_r10 *)NULL, + (LTE_SCellToAddMod_r10_t *)NULL, + //(struct LTE_PhysicalConfigDedicatedSCell_r10 *)NULL, #endif - (LTE_MeasObjectToAddMod_t **) NULL, - (LTE_MAC_MainConfig_t *) NULL, - 0, - (struct LTE_LogicalChannelConfig *)NULL, - (LTE_MeasGapConfig_t *) NULL, - (LTE_TDD_Config_t *) NULL, - (LTE_MobilityControlInfo_t *)NULL, - (LTE_SchedulingInfoList_t *) NULL, - 0, NULL, NULL, (LTE_MBSFN_SubframeConfigList_t *) NULL + (LTE_MeasObjectToAddMod_t **) NULL, + (LTE_MAC_MainConfig_t *) NULL, + 0, + (struct LTE_LogicalChannelConfig *)NULL, + (LTE_MeasGapConfig_t *) NULL, + (LTE_TDD_Config_t *) NULL, + (LTE_MobilityControlInfo_t *)NULL, + (LTE_SchedulingInfoList_t *) NULL, + 0, NULL, NULL, (LTE_MBSFN_SubframeConfigList_t *) NULL #if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) - , - 0, - (LTE_MBSFN_AreaInfoList_r9_t *) NULL, - (LTE_PMCH_InfoList_r9_t *) & (RC.rrc[enb_mod_idP]->carrier[CC_id].mcch_message->pmch_InfoList_r9) + , + 0, + (LTE_MBSFN_AreaInfoList_r9_t *) NULL, + (LTE_PMCH_InfoList_r9_t *) & (RC.rrc[enb_mod_idP]->carrier[CC_id].mcch_message->pmch_InfoList_r9) #endif #if (LTE_RRC_VERSION >= MAKE_VERSION(13, 0, 0)) - , - (LTE_SystemInformationBlockType1_v1310_IEs_t *)NULL + , + (LTE_SystemInformationBlockType1_v1310_IEs_t *)NULL #endif - ); - + ); //LOG_I(RRC,"DUY: lcid after rrc_mac_config_req is %02d\n",RC.rrc[enb_mod_idP]->mcch_message->pmch_InfoList_r9.list.array[0]->mbms_SessionInfoList_r9.list.array[0]->logicalChannelIdentity_r9); - } //----------------------------------------------------------------------------- @@ -536,13 +509,11 @@ static void init_MBMS( if (RC.rrc[enb_mod_idP]->carrier[CC_id].MBMS_flag > 0) { PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, enb_mod_idP, ENB_FLAG_YES, NOT_A_RNTI, frameP, 0,enb_mod_idP); - LOG_D(RRC, "[eNB %d] Frame %d : Radio Bearer config request for MBMS\n", enb_mod_idP, frameP); //check the lcid // Configuring PDCP and RLC for MBMS Radio Bearer - rrc_pdcp_config_asn1_req(&ctxt, - (LTE_SRB_ToAddModList_t *)NULL, // LTE_SRB_ToAddModList - (LTE_DRB_ToAddModList_t *)NULL, // LTE_DRB_ToAddModList + (LTE_SRB_ToAddModList_t *)NULL, // LTE_SRB_ToAddModList + (LTE_DRB_ToAddModList_t *)NULL, // LTE_DRB_ToAddModList (LTE_DRB_ToReleaseList_t *)NULL, 0, // security mode NULL, // key rrc encryption @@ -552,18 +523,15 @@ static void init_MBMS( , &(RC.rrc[enb_mod_idP]->carrier[CC_id].mcch_message->pmch_InfoList_r9) #endif ,NULL); - rrc_rlc_config_asn1_req(&ctxt, NULL, // LTE_SRB_ToAddModList NULL, // LTE_DRB_ToAddModList NULL, // DRB_ToReleaseList &(RC.rrc[enb_mod_idP]->carrier[CC_id].mcch_message->pmch_InfoList_r9) - #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) ,0, 0 #endif - ); - + ); //rrc_mac_config_req(); } } @@ -616,14 +584,14 @@ rrc_eNB_get_next_transaction_identifier( //----------------------------------------------------------------------------- // return the ue context if there is already an UE with ue_identityP, NULL otherwise -static struct rrc_eNB_ue_context_s* +static struct rrc_eNB_ue_context_s * rrc_eNB_ue_context_random_exist( - const protocol_ctxt_t* const ctxt_pP, + const protocol_ctxt_t *const ctxt_pP, const uint64_t ue_identityP ) //----------------------------------------------------------------------------- { - struct rrc_eNB_ue_context_s* ue_context_p = NULL; + struct rrc_eNB_ue_context_s *ue_context_p = NULL; RB_FOREACH(ue_context_p, rrc_ue_tree_s, &(RC.rrc[ctxt_pP->module_id]->rrc_ue_head)) { if (ue_context_p->ue_context.random_ue_identity == ue_identityP) return ue_context_p; @@ -632,47 +600,47 @@ rrc_eNB_ue_context_random_exist( } //----------------------------------------------------------------------------- // return the ue context if there is already an UE with the same S-TMSI(MMEC+M-TMSI), NULL otherwise -static struct rrc_eNB_ue_context_s* +static struct rrc_eNB_ue_context_s * rrc_eNB_ue_context_stmsi_exist( - const protocol_ctxt_t* const ctxt_pP, + const protocol_ctxt_t *const ctxt_pP, const mme_code_t mme_codeP, const m_tmsi_t m_tmsiP ) //----------------------------------------------------------------------------- { - struct rrc_eNB_ue_context_s* ue_context_p = NULL; + struct rrc_eNB_ue_context_s *ue_context_p = NULL; RB_FOREACH(ue_context_p, rrc_ue_tree_s, &(RC.rrc[ctxt_pP->module_id]->rrc_ue_head)) { LOG_I(RRC,"checking for UE S-TMSI %x, mme %x (%p): rnti %x", - m_tmsiP, mme_codeP, ue_context_p, - ue_context_p->ue_context.rnti); + m_tmsiP, mme_codeP, ue_context_p, + ue_context_p->ue_context.rnti); + if (ue_context_p->ue_context.Initialue_identity_s_TMSI.presence == TRUE) { printf("=> S-TMSI %x, MME %x\n", - ue_context_p->ue_context.Initialue_identity_s_TMSI.m_tmsi, - ue_context_p->ue_context.Initialue_identity_s_TMSI.mme_code); + ue_context_p->ue_context.Initialue_identity_s_TMSI.m_tmsi, + ue_context_p->ue_context.Initialue_identity_s_TMSI.mme_code); + if (ue_context_p->ue_context.Initialue_identity_s_TMSI.m_tmsi == m_tmsiP) if (ue_context_p->ue_context.Initialue_identity_s_TMSI.mme_code == mme_codeP) return ue_context_p; - } - else + } else printf("\n"); - } return NULL; } //----------------------------------------------------------------------------- // return a new ue context structure if ue_identityP, ctxt_pP->rnti not found in collection -static struct rrc_eNB_ue_context_s* +static struct rrc_eNB_ue_context_s * rrc_eNB_get_next_free_ue_context( - const protocol_ctxt_t* const ctxt_pP, + const protocol_ctxt_t *const ctxt_pP, const uint64_t ue_identityP ) //----------------------------------------------------------------------------- { - struct rrc_eNB_ue_context_s* ue_context_p = NULL; + struct rrc_eNB_ue_context_s *ue_context_p = NULL; ue_context_p = rrc_eNB_get_ue_context( - RC.rrc[ctxt_pP->module_id], - ctxt_pP->rnti); + RC.rrc[ctxt_pP->module_id], + ctxt_pP->rnti); if (ue_context_p == NULL) { ue_context_p = rrc_eNB_allocate_new_UE_context(RC.rrc[ctxt_pP->module_id]); @@ -693,7 +661,6 @@ rrc_eNB_get_next_free_ue_context( PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP), ue_context_p->local_uid); return ue_context_p; - } else { LOG_E(RRC, PROTOCOL_RRC_CTXT_UE_FMT" Cannot create new UE context, already exist\n", @@ -705,8 +672,8 @@ rrc_eNB_get_next_free_ue_context( //----------------------------------------------------------------------------- void rrc_eNB_free_mem_UE_context( - const protocol_ctxt_t* const ctxt_pP, - struct rrc_eNB_ue_context_s* const ue_context_pP + const protocol_ctxt_t *const ctxt_pP, + struct rrc_eNB_ue_context_s *const ue_context_pP ) //----------------------------------------------------------------------------- { @@ -725,11 +692,11 @@ rrc_eNB_free_mem_UE_context( ue_context_pP->ue_context.SRB_configList = NULL; } - for(i = 0;i < RRC_TRANSACTION_IDENTIFIER_NUMBER;i++){ - if (ue_context_pP->ue_context.SRB_configList2[i]) { - free(ue_context_pP->ue_context.SRB_configList2[i]); - ue_context_pP->ue_context.SRB_configList2[i] = NULL; - } + for(i = 0; i < RRC_TRANSACTION_IDENTIFIER_NUMBER; i++) { + if (ue_context_pP->ue_context.SRB_configList2[i]) { + free(ue_context_pP->ue_context.SRB_configList2[i]); + ue_context_pP->ue_context.SRB_configList2[i] = NULL; + } } if (ue_context_pP->ue_context.DRB_configList) { @@ -737,15 +704,16 @@ rrc_eNB_free_mem_UE_context( ue_context_pP->ue_context.DRB_configList = NULL; } - for(i = 0;i < RRC_TRANSACTION_IDENTIFIER_NUMBER;i++){ - if (ue_context_pP->ue_context.DRB_configList2[i]) { - free(ue_context_pP->ue_context.DRB_configList2[i]); - ue_context_pP->ue_context.DRB_configList2[i] = NULL; - } - if (ue_context_pP->ue_context.DRB_Release_configList2[i]) { - free(ue_context_pP->ue_context.DRB_Release_configList2[i]); - ue_context_pP->ue_context.DRB_Release_configList2[i] = NULL; - } + for(i = 0; i < RRC_TRANSACTION_IDENTIFIER_NUMBER; i++) { + if (ue_context_pP->ue_context.DRB_configList2[i]) { + free(ue_context_pP->ue_context.DRB_configList2[i]); + ue_context_pP->ue_context.DRB_configList2[i] = NULL; + } + + if (ue_context_pP->ue_context.DRB_Release_configList2[i]) { + free(ue_context_pP->ue_context.DRB_Release_configList2[i]); + ue_context_pP->ue_context.DRB_Release_configList2[i] = NULL; + } } memset(ue_context_pP->ue_context.DRB_active, 0, sizeof(ue_context_pP->ue_context.DRB_active)); @@ -784,14 +752,14 @@ rrc_eNB_free_mem_UE_context( ue_context_pP->ue_context.mac_MainConfig = NULL; } -/* if (ue_context_pP->ue_context.measGapConfig) { - ASN_STRUCT_FREE(asn_DEF_LTE_MeasGapConfig, ue_context_pP->ue_context.measGapConfig); - ue_context_pP->ue_context.measGapConfig = NULL; - }*/ - if (ue_context_pP->ue_context.handover_info) { - ASN_STRUCT_FREE(asn_DEF_LTE_Handover, ue_context_pP->ue_context.handover_info); - ue_context_pP->ue_context.handover_info = NULL; - } + /* if (ue_context_pP->ue_context.measGapConfig) { + ASN_STRUCT_FREE(asn_DEF_LTE_MeasGapConfig, ue_context_pP->ue_context.measGapConfig); + ue_context_pP->ue_context.measGapConfig = NULL; + }*/ + if (ue_context_pP->ue_context.handover_info) { + ASN_STRUCT_FREE(asn_DEF_LTE_Handover, ue_context_pP->ue_context.handover_info); + ue_context_pP->ue_context.handover_info = NULL; + } //SRB_INFO SI; //SRB_INFO Srb0; @@ -833,9 +801,9 @@ rrc_eNB_free_mem_UE_context( //----------------------------------------------------------------------------- /* -* Should be called when UE context in eNB should be released +* Should be called when UE context in eNB should be released * or when S1 command UE_CONTEXT_RELEASE_REQ should be sent -*/ +*/ void rrc_eNB_free_UE( const module_id_t enb_mod_idP, @@ -846,175 +814,180 @@ rrc_eNB_free_UE( if (enb_mod_idP >= NB_eNB_INST) { LOG_E(RRC, "eNB instance invalid (%d/%d) for UE %x!\n", - enb_mod_idP, - NB_eNB_INST, - rnti); - + enb_mod_idP, + NB_eNB_INST, + rnti); return; } if (EPC_MODE_ENABLED) { if ((ue_context_pP->ue_context.ul_failure_timer >= 20000) && (mac_eNB_get_rrc_status(enb_mod_idP, rnti) >= RRC_CONNECTED)) { - LOG_I(RRC, "[eNB %d] S1AP_UE_CONTEXT_RELEASE_REQ sent for RNTI %x, cause 21, radio connection with ue lost\n", - enb_mod_idP, - rnti); - - rrc_eNB_send_S1AP_UE_CONTEXT_RELEASE_REQ(enb_mod_idP, ue_context_pP, S1AP_CAUSE_RADIO_NETWORK, 21); + LOG_I(RRC, "[eNB %d] S1AP_UE_CONTEXT_RELEASE_REQ sent for RNTI %x, cause 21, radio connection with ue lost\n", + enb_mod_idP, + rnti); + rrc_eNB_send_S1AP_UE_CONTEXT_RELEASE_REQ(enb_mod_idP, ue_context_pP, S1AP_CAUSE_RADIO_NETWORK, 21); // send cause 21: radio connection with ue lost /* From 3GPP 36300v10 p129 : 19.2.2.2.2 S1 UE Context Release Request (eNB triggered) * If the E-UTRAN internal reason is a radio link failure detected in the eNB, the eNB shall wait a sufficient time before * triggering the S1 UE Context Release Request procedure in order to allow the UE to perform the NAS recovery * procedure, see TS 23.401 [17]. */ - return; } - - if((ue_context_pP->ue_context.ue_rrc_inactivity_timer >= ue_context_pP->ue_context.ue_rrc_inactivity_timer_thres) && - (mac_eNB_get_rrc_status(enb_mod_idP, rnti) >= RRC_CONNECTED)) { - LOG_I(RRC, "[eNB %d] S1AP_UE_CONTEXT_RELEASE_REQ sent for RNTI %x, cause 20, user inactivity\n", - enb_mod_idP, - rnti); - - rrc_eNB_send_S1AP_UE_CONTEXT_RELEASE_REQ(enb_mod_idP, ue_context_pP, S1AP_CAUSE_RADIO_NETWORK, 20); - // send cause 20: user inactivity + if((ue_context_pP->ue_context.ue_rrc_inactivity_timer >= ue_context_pP->ue_context.ue_rrc_inactivity_timer_thres) && + (mac_eNB_get_rrc_status(enb_mod_idP, rnti) >= RRC_CONNECTED)) { + LOG_I(RRC, "[eNB %d] S1AP_UE_CONTEXT_RELEASE_REQ sent for RNTI %x, cause 20, user inactivity\n", + enb_mod_idP, + rnti); + rrc_eNB_send_S1AP_UE_CONTEXT_RELEASE_REQ(enb_mod_idP, ue_context_pP, S1AP_CAUSE_RADIO_NETWORK, 20); + // send cause 20: user inactivity return; } } - LOG_W(RRC, "[eNB %d] Removing UE RNTI %x\n", - enb_mod_idP, - rnti); - + LOG_W(RRC, "[eNB %d] Removing UE RNTI %x\n", + enb_mod_idP, + rnti); // add UE info to freeList LOG_I(RRC, "Put UE %x into freeList\n", - rnti); - + rnti); put_UE_in_freelist(enb_mod_idP, rnti, 1); } -void remove_UE_from_freelist(module_id_t mod_id, rnti_t rnti) -{ - - eNB_MAC_INST *eNB_MAC = RC.mac[mod_id]; - pthread_mutex_lock(&lock_ue_freelist); - UE_free_list_t *free_list = &eNB_MAC->UE_free_list; - free_list->UE_free_ctrl[free_list->head_freelist].rnti = 0; - free_list->head_freelist = (free_list->head_freelist + 1) % (NUMBER_OF_UE_MAX+1); - free_list->num_UEs--; - pthread_mutex_unlock(&lock_ue_freelist); +void remove_UE_from_freelist(module_id_t mod_id, rnti_t rnti) { + eNB_MAC_INST *eNB_MAC = RC.mac[mod_id]; + pthread_mutex_lock(&lock_ue_freelist); + UE_free_list_t *free_list = &eNB_MAC->UE_free_list; + free_list->UE_free_ctrl[free_list->head_freelist].rnti = 0; + free_list->head_freelist = (free_list->head_freelist + 1) % (NUMBER_OF_UE_MAX+1); + free_list->num_UEs--; + pthread_mutex_unlock(&lock_ue_freelist); } -void put_UE_in_freelist(module_id_t mod_id, rnti_t rnti, boolean_t removeFlag) -{ - UE_free_list_t *free_list = NULL; - eNB_MAC_INST *eNB_MAC = RC.mac[mod_id]; - pthread_mutex_lock(&lock_ue_freelist); - free_list = &eNB_MAC->UE_free_list; - free_list->UE_free_ctrl[free_list->tail_freelist].rnti = rnti; - free_list->UE_free_ctrl[free_list->tail_freelist].removeContextFlg = removeFlag; - free_list->num_UEs++; - free_list->tail_freelist = (free_list->tail_freelist + 1) % (NUMBER_OF_UE_MAX+1); - pthread_mutex_unlock(&lock_ue_freelist); +void put_UE_in_freelist(module_id_t mod_id, rnti_t rnti, boolean_t removeFlag) { + UE_free_list_t *free_list = NULL; + eNB_MAC_INST *eNB_MAC = RC.mac[mod_id]; + pthread_mutex_lock(&lock_ue_freelist); + free_list = &eNB_MAC->UE_free_list; + free_list->UE_free_ctrl[free_list->tail_freelist].rnti = rnti; + free_list->UE_free_ctrl[free_list->tail_freelist].removeContextFlg = removeFlag; + free_list->num_UEs++; + free_list->tail_freelist = (free_list->tail_freelist + 1) % (NUMBER_OF_UE_MAX+1); + pthread_mutex_unlock(&lock_ue_freelist); } -void release_UE_in_freeList(module_id_t mod_id) -{ - int i, j , CC_id, pdu_number; - protocol_ctxt_t ctxt; - LTE_eNB_ULSCH_t *ulsch = NULL; - LTE_eNB_DLSCH_t *dlsch = NULL; - nfapi_ul_config_request_body_t *ul_req_tmp = NULL; - PHY_VARS_eNB *eNB_PHY = NULL; - struct rrc_eNB_ue_context_s *ue_context_pP = NULL; - eNB_MAC_INST *eNB_MAC = RC.mac[mod_id]; - boolean_t remove_UEContext; - rnti_t rnti; - int head, tail, ue_num; +void release_UE_in_freeList(module_id_t mod_id) { + int i, j, CC_id, pdu_number; + protocol_ctxt_t ctxt; + LTE_eNB_ULSCH_t *ulsch = NULL; + LTE_eNB_DLSCH_t *dlsch = NULL; + nfapi_ul_config_request_body_t *ul_req_tmp = NULL; + PHY_VARS_eNB *eNB_PHY = NULL; + struct rrc_eNB_ue_context_s *ue_context_pP = NULL; + eNB_MAC_INST *eNB_MAC = RC.mac[mod_id]; + boolean_t remove_UEContext; + rnti_t rnti; + int head, tail, ue_num; + pthread_mutex_lock(&lock_ue_freelist); + head = eNB_MAC->UE_free_list.head_freelist; + tail = eNB_MAC->UE_free_list.tail_freelist; - pthread_mutex_lock(&lock_ue_freelist); - head = eNB_MAC->UE_free_list.head_freelist; - tail = eNB_MAC->UE_free_list.tail_freelist; - if(head == tail){ - pthread_mutex_unlock(&lock_ue_freelist); - return; - } - if(tail < head){ - tail = head + eNB_MAC->UE_free_list.num_UEs; - } + if(head == tail) { pthread_mutex_unlock(&lock_ue_freelist); + return; + } - for(ue_num = head; ue_num < tail; ue_num++){ - ue_num = ue_num % (NUMBER_OF_UE_MAX+1); - rnti = eNB_MAC->UE_free_list.UE_free_ctrl[ue_num].rnti; - if(rnti != 0){ - remove_UEContext = eNB_MAC->UE_free_list.UE_free_ctrl[ue_num].removeContextFlg; - PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, mod_id, ENB_FLAG_YES, rnti, 0, 0,mod_id); - for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { - eNB_PHY = RC.eNB[mod_id][CC_id]; - for (i=0; iulsch[i]; - if((ulsch != NULL) && (ulsch->rnti == rnti)){ - void clean_eNb_ulsch(LTE_eNB_ULSCH_t *ulsch); - LOG_I(RRC, "clean_eNb_ulsch ulsch[%d] UE %x\n", i, rnti); - clean_eNb_ulsch(ulsch); - } - if(eNB_PHY->uci_vars[i].rnti == rnti){ - LOG_I(MAC, "clean eNb uci_vars[%d] UE %x \n",i, rnti); - memset(&eNB_PHY->uci_vars[i],0,sizeof(LTE_eNB_UCI)); - } - } - for (i=0; idlsch[i][0]; - if((dlsch != NULL) && (dlsch->rnti == rnti)){ - void clean_eNb_dlsch(LTE_eNB_DLSCH_t *dlsch); - LOG_I(RRC, "clean_eNb_dlsch dlsch[%d] UE %x \n", i, rnti); - clean_eNb_dlsch(dlsch); - } - } + if(tail < head) { + tail = head + eNB_MAC->UE_free_list.num_UEs; + } - if (rrc_agent_registered[mod_id]) { - agent_rrc_xface[mod_id]->flexran_agent_notify_ue_state_change(mod_id, - rnti, PROTOCOL__FLEX_UE_STATE_CHANGE_TYPE__FLUESC_DEACTIVATED); - } + pthread_mutex_unlock(&lock_ue_freelist); - for(j = 0; j < 10; j++){ - ul_req_tmp = &eNB_MAC->UL_req_tmp[CC_id][j].ul_config_request_body; - if(ul_req_tmp){ - pdu_number = ul_req_tmp->number_of_pdus; - for(int pdu_index = pdu_number-1; pdu_index >= 0; pdu_index--){ - if((ul_req_tmp->ul_config_pdu_list[pdu_index].ulsch_pdu.ulsch_pdu_rel8.rnti == rnti) || - (ul_req_tmp->ul_config_pdu_list[pdu_index].uci_harq_pdu.ue_information.ue_information_rel8.rnti == rnti) || - (ul_req_tmp->ul_config_pdu_list[pdu_index].uci_cqi_pdu.ue_information.ue_information_rel8.rnti == rnti) || - (ul_req_tmp->ul_config_pdu_list[pdu_index].uci_sr_pdu.ue_information.ue_information_rel8.rnti == rnti) || - (ul_req_tmp->ul_config_pdu_list[pdu_index].srs_pdu.srs_pdu_rel8.rnti == rnti)){ - LOG_I(RRC, "remove UE %x from ul_config_pdu_list %d/%d\n", rnti, pdu_index, pdu_number); - if(pdu_index < pdu_number -1){ - memcpy(&ul_req_tmp->ul_config_pdu_list[pdu_index], &ul_req_tmp->ul_config_pdu_list[pdu_index+1], (pdu_number-1-pdu_index) * sizeof(nfapi_ul_config_request_pdu_t)); - } - ul_req_tmp->number_of_pdus--; - } - } - } - } - } - rrc_mac_remove_ue(mod_id,rnti); - rrc_rlc_remove_ue(&ctxt); - pdcp_remove_UE(&ctxt); + for(ue_num = head; ue_num < tail; ue_num++) { + ue_num = ue_num % (NUMBER_OF_UE_MAX+1); + rnti = eNB_MAC->UE_free_list.UE_free_ctrl[ue_num].rnti; - if(remove_UEContext){ - ue_context_pP = rrc_eNB_get_ue_context( - RC.rrc[mod_id],rnti); - if(ue_context_pP){ - rrc_eNB_remove_ue_context(&ctxt,RC.rrc[mod_id], - (struct rrc_eNB_ue_context_s*) ue_context_pP); - } - } - LOG_I(RRC, "[release_UE_in_freeList] remove UE %x from freeList\n", rnti); - remove_UE_from_freelist(mod_id, rnti); + if(rnti != 0) { + remove_UEContext = eNB_MAC->UE_free_list.UE_free_ctrl[ue_num].removeContextFlg; + PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, mod_id, ENB_FLAG_YES, rnti, 0, 0,mod_id); + + for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { + eNB_PHY = RC.eNB[mod_id][CC_id]; + + for (i=0; iulsch[i]; + + if((ulsch != NULL) && (ulsch->rnti == rnti)) { + void clean_eNb_ulsch(LTE_eNB_ULSCH_t *ulsch); + LOG_I(RRC, "clean_eNb_ulsch ulsch[%d] UE %x\n", i, rnti); + clean_eNb_ulsch(ulsch); + } + + if(eNB_PHY->uci_vars[i].rnti == rnti) { + LOG_I(MAC, "clean eNb uci_vars[%d] UE %x \n",i, rnti); + memset(&eNB_PHY->uci_vars[i],0,sizeof(LTE_eNB_UCI)); + } } + + for (i=0; idlsch[i][0]; + + if((dlsch != NULL) && (dlsch->rnti == rnti)) { + void clean_eNb_dlsch(LTE_eNB_DLSCH_t *dlsch); + LOG_I(RRC, "clean_eNb_dlsch dlsch[%d] UE %x \n", i, rnti); + clean_eNb_dlsch(dlsch); + } + } + + if (rrc_agent_registered[mod_id]) { + agent_rrc_xface[mod_id]->flexran_agent_notify_ue_state_change(mod_id, + rnti, PROTOCOL__FLEX_UE_STATE_CHANGE_TYPE__FLUESC_DEACTIVATED); + } + + for(j = 0; j < 10; j++) { + ul_req_tmp = &eNB_MAC->UL_req_tmp[CC_id][j].ul_config_request_body; + + if(ul_req_tmp) { + pdu_number = ul_req_tmp->number_of_pdus; + + for(int pdu_index = pdu_number-1; pdu_index >= 0; pdu_index--) { + if((ul_req_tmp->ul_config_pdu_list[pdu_index].ulsch_pdu.ulsch_pdu_rel8.rnti == rnti) || + (ul_req_tmp->ul_config_pdu_list[pdu_index].uci_harq_pdu.ue_information.ue_information_rel8.rnti == rnti) || + (ul_req_tmp->ul_config_pdu_list[pdu_index].uci_cqi_pdu.ue_information.ue_information_rel8.rnti == rnti) || + (ul_req_tmp->ul_config_pdu_list[pdu_index].uci_sr_pdu.ue_information.ue_information_rel8.rnti == rnti) || + (ul_req_tmp->ul_config_pdu_list[pdu_index].srs_pdu.srs_pdu_rel8.rnti == rnti)) { + LOG_I(RRC, "remove UE %x from ul_config_pdu_list %d/%d\n", rnti, pdu_index, pdu_number); + + if(pdu_index < pdu_number -1) { + memcpy(&ul_req_tmp->ul_config_pdu_list[pdu_index], &ul_req_tmp->ul_config_pdu_list[pdu_index+1], (pdu_number-1-pdu_index) * sizeof(nfapi_ul_config_request_pdu_t)); + } + + ul_req_tmp->number_of_pdus--; + } + } + } + } + } + + rrc_mac_remove_ue(mod_id,rnti); + rrc_rlc_remove_ue(&ctxt); + pdcp_remove_UE(&ctxt); + + if(remove_UEContext) { + ue_context_pP = rrc_eNB_get_ue_context( + RC.rrc[mod_id],rnti); + + if(ue_context_pP) { + rrc_eNB_remove_ue_context(&ctxt,RC.rrc[mod_id], + (struct rrc_eNB_ue_context_s *) ue_context_pP); + } + } + + LOG_I(RRC, "[release_UE_in_freeList] remove UE %x from freeList\n", rnti); + remove_UE_from_freelist(mod_id, rnti); } + } } //----------------------------------------------------------------------------- @@ -1032,12 +1005,10 @@ rrc_eNB_process_RRCConnectionSetupComplete( LOG_I(RRC, PROTOCOL_RRC_CTXT_UE_FMT" [RAPROC] Logical Channel UL-DCCH, " "processing LTE_RRCConnectionSetupComplete from UE (SRB1 Active)\n", PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP)); - ue_context_pP->ue_context.Srb1.Active = 1; ue_context_pP->ue_context.Status = RRC_CONNECTED; ue_context_pP->ue_context.ue_rrc_inactivity_timer = 1; // set rrc inactivity when UE goes into RRC_CONNECTED ue_context_pP->ue_context.ue_rrc_inactivity_timer_thres = 10000; // The value should come from config file - T(T_ENB_RRC_CONNECTION_SETUP_COMPLETE, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame), T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti)); @@ -1053,39 +1024,32 @@ rrc_eNB_process_RRCConnectionSetupComplete( //----------------------------------------------------------------------------- void rrc_eNB_generate_SecurityModeCommand( - const protocol_ctxt_t* const ctxt_pP, - rrc_eNB_ue_context_t* const ue_context_pP + const protocol_ctxt_t *const ctxt_pP, + rrc_eNB_ue_context_t *const ue_context_pP ) //----------------------------------------------------------------------------- { uint8_t buffer[100]; uint8_t size; - T(T_ENB_RRC_SECURITY_MODE_COMMAND, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame), T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti)); - size = do_SecurityModeCommand( ctxt_pP, buffer, rrc_eNB_get_next_transaction_identifier(ctxt_pP->module_id), ue_context_pP->ue_context.ciphering_algorithm, ue_context_pP->ue_context.integrity_algorithm); - - LOG_DUMPMSG(RRC,DEBUG_RRC,(char *)buffer,size,"[MSG] RRC Security Mode Command\n"); - LOG_I(RRC, PROTOCOL_RRC_CTXT_UE_FMT" Logical Channel DL-DCCH, Generate SecurityModeCommand (bytes %d)\n", PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP), size); - LOG_D(RRC, PROTOCOL_RRC_CTXT_UE_FMT" --- PDCP_DATA_REQ/%d Bytes (securityModeCommand to UE MUI %d) --->[PDCP][RB %02d]\n", PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP), size, rrc_eNB_mui, DCCH); - MSC_LOG_TX_MESSAGE( MSC_RRC_ENB, MSC_RRC_UE, @@ -1096,50 +1060,42 @@ rrc_eNB_generate_SecurityModeCommand( ue_context_pP->ue_context.rnti, rrc_eNB_mui, size); - rrc_data_req( - ctxt_pP, - DCCH, - rrc_eNB_mui++, - SDU_CONFIRM_NO, - size, - buffer, - PDCP_TRANSMISSION_MODE_CONTROL); - + ctxt_pP, + DCCH, + rrc_eNB_mui++, + SDU_CONFIRM_NO, + size, + buffer, + PDCP_TRANSMISSION_MODE_CONTROL); } //----------------------------------------------------------------------------- void rrc_eNB_generate_UECapabilityEnquiry( - const protocol_ctxt_t* const ctxt_pP, - rrc_eNB_ue_context_t* const ue_context_pP + const protocol_ctxt_t *const ctxt_pP, + rrc_eNB_ue_context_t *const ue_context_pP ) //----------------------------------------------------------------------------- { - uint8_t buffer[100]; uint8_t size; - T(T_ENB_RRC_UE_CAPABILITY_ENQUIRY, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame), T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti)); - size = do_UECapabilityEnquiry( ctxt_pP, buffer, rrc_eNB_get_next_transaction_identifier(ctxt_pP->module_id)); - LOG_I(RRC, PROTOCOL_RRC_CTXT_UE_FMT" Logical Channel DL-DCCH, Generate UECapabilityEnquiry (bytes %d)\n", PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP), size); - LOG_D(RRC, PROTOCOL_RRC_CTXT_UE_FMT" --- PDCP_DATA_REQ/%d Bytes (UECapabilityEnquiry MUI %d) --->[PDCP][RB %02d]\n", PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP), size, rrc_eNB_mui, DCCH); - MSC_LOG_TX_MESSAGE( MSC_RRC_ENB, MSC_RRC_UE, @@ -1150,40 +1106,34 @@ rrc_eNB_generate_UECapabilityEnquiry( ue_context_pP->ue_context.rnti, rrc_eNB_mui, size); - rrc_data_req( - ctxt_pP, - DCCH, - rrc_eNB_mui++, - SDU_CONFIRM_NO, - size, - buffer, - PDCP_TRANSMISSION_MODE_CONTROL); - + ctxt_pP, + DCCH, + rrc_eNB_mui++, + SDU_CONFIRM_NO, + size, + buffer, + PDCP_TRANSMISSION_MODE_CONTROL); } //----------------------------------------------------------------------------- void rrc_eNB_generate_RRCConnectionReject( - const protocol_ctxt_t* const ctxt_pP, - rrc_eNB_ue_context_t* const ue_context_pP, + const protocol_ctxt_t *const ctxt_pP, + rrc_eNB_ue_context_t *const ue_context_pP, const int CC_id ) //----------------------------------------------------------------------------- { - T(T_ENB_RRC_CONNECTION_REJECT, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame), T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti)); - RC.rrc[ctxt_pP->module_id]->carrier[CC_id].Srb0.Tx_buffer.payload_size = do_RRCConnectionReject(ctxt_pP->module_id, - (uint8_t*) RC.rrc[ctxt_pP->module_id]->carrier[CC_id].Srb0.Tx_buffer.Payload); - + (uint8_t *) RC.rrc[ctxt_pP->module_id]->carrier[CC_id].Srb0.Tx_buffer.Payload); LOG_DUMPMSG(RRC,DEBUG_RRC, (char *)(RC.rrc[ctxt_pP->module_id]->carrier[CC_id].Srb0.Tx_buffer.Payload), RC.rrc[ctxt_pP->module_id]->carrier[CC_id].Srb0.Tx_buffer.payload_size, "[MSG] RRCConnectionReject\n"); - MSC_LOG_TX_MESSAGE( MSC_RRC_ENB, MSC_RRC_UE, @@ -1193,7 +1143,6 @@ rrc_eNB_generate_RRCConnectionReject( MSC_AS_TIME_ARGS(ctxt_pP), ue_context_pP == NULL ? -1 : ue_context_pP->ue_context.rnti, RC.rrc[ctxt_pP->module_id]->carrier[CC_id].Srb0.Tx_buffer.payload_size); - LOG_I(RRC, PROTOCOL_RRC_CTXT_UE_FMT" [RAPROC] Logical Channel DL-CCCH, Generating LTE_RRCConnectionReject (bytes %d)\n", PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP), @@ -1203,8 +1152,8 @@ rrc_eNB_generate_RRCConnectionReject( //----------------------------------------------------------------------------- void rrc_eNB_generate_RRCConnectionReestablishment( - const protocol_ctxt_t* const ctxt_pP, - rrc_eNB_ue_context_t* const ue_context_pP, + const protocol_ctxt_t *const ctxt_pP, + rrc_eNB_ue_context_t *const ue_context_pP, const int CC_id ) //----------------------------------------------------------------------------- @@ -1213,16 +1162,14 @@ rrc_eNB_generate_RRCConnectionReestablishment( LTE_SRB_ToAddModList_t **SRB_configList; LTE_SRB_ToAddMod_t *SRB1_config; int cnt; - T(T_ENB_RRC_CONNECTION_REESTABLISHMENT, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame), T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti)); - SRB_configList = &ue_context_pP->ue_context.SRB_configList; RC.rrc[ctxt_pP->module_id]->carrier[CC_id].Srb0.Tx_buffer.payload_size = do_RRCConnectionReestablishment(ctxt_pP, ue_context_pP, CC_id, - (uint8_t*) RC.rrc[ctxt_pP->module_id]->carrier[CC_id].Srb0.Tx_buffer.Payload, + (uint8_t *) RC.rrc[ctxt_pP->module_id]->carrier[CC_id].Srb0.Tx_buffer.Payload, (uint8_t) RC.rrc[ctxt_pP->module_id]->carrier[CC_id].p_eNB, //at this point we do not have the UE capability information, so it can only be TM1 or TM2 rrc_eNB_get_next_transaction_identifier(ctxt_pP->module_id), SRB_configList, @@ -1231,7 +1178,7 @@ rrc_eNB_generate_RRCConnectionReestablishment( (char *)(RC.rrc[ctxt_pP->module_id]->carrier[CC_id].Srb0.Tx_buffer.Payload), RC.rrc[ctxt_pP->module_id]->carrier[CC_id].Srb0.Tx_buffer.payload_size, "[MSG] RRCConnectionReestablishment\n" - ); + ); // configure SRB1 for UE if (*SRB_configList != NULL) { @@ -1254,38 +1201,38 @@ rrc_eNB_generate_RRCConnectionReestablishment( PROTOCOL_RRC_CTXT_UE_FMT" RRC_eNB --- MAC_CONFIG_REQ (SRB1) ---> MAC_eNB\n", PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP)); rrc_mac_config_req_eNB(ctxt_pP->module_id, - ue_context_pP->ue_context.primaryCC_id, - 0,0,0,0,0, + ue_context_pP->ue_context.primaryCC_id, + 0,0,0,0,0, #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - 0, + 0, #endif - ctxt_pP->rnti, - (LTE_BCCH_BCH_Message_t *) NULL, - (LTE_RadioResourceConfigCommonSIB_t *) NULL, + ctxt_pP->rnti, + (LTE_BCCH_BCH_Message_t *) NULL, + (LTE_RadioResourceConfigCommonSIB_t *) NULL, #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - (LTE_RadioResourceConfigCommonSIB_t *) NULL, + (LTE_RadioResourceConfigCommonSIB_t *) NULL, #endif - (struct LTE_PhysicalConfigDedicated* ) ue_context_pP->ue_context.physicalConfigDedicated, + (struct LTE_PhysicalConfigDedicated * ) ue_context_pP->ue_context.physicalConfigDedicated, #if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) - (LTE_SCellToAddMod_r10_t *)NULL, - //(struct LTE_PhysicalConfigDedicatedSCell_r10 *)NULL, + (LTE_SCellToAddMod_r10_t *)NULL, + //(struct LTE_PhysicalConfigDedicatedSCell_r10 *)NULL, #endif - (LTE_MeasObjectToAddMod_t **) NULL, - ue_context_pP->ue_context.mac_MainConfig, - 1, - SRB1_logicalChannelConfig, - ue_context_pP->ue_context.measGapConfig, - (LTE_TDD_Config_t *) NULL, - NULL, - (LTE_SchedulingInfoList_t *) NULL, - 0, NULL, NULL, (LTE_MBSFN_SubframeConfigList_t *) NULL + (LTE_MeasObjectToAddMod_t **) NULL, + ue_context_pP->ue_context.mac_MainConfig, + 1, + SRB1_logicalChannelConfig, + ue_context_pP->ue_context.measGapConfig, + (LTE_TDD_Config_t *) NULL, + NULL, + (LTE_SchedulingInfoList_t *) NULL, + 0, NULL, NULL, (LTE_MBSFN_SubframeConfigList_t *) NULL #if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) - , 0, (LTE_MBSFN_AreaInfoList_r9_t *) NULL, (LTE_PMCH_InfoList_r9_t *) NULL + , 0, (LTE_MBSFN_AreaInfoList_r9_t *) NULL, (LTE_PMCH_InfoList_r9_t *) NULL #endif #if (LTE_RRC_VERSION >= MAKE_VERSION(13, 0, 0)) - ,(LTE_SystemInformationBlockType1_v1310_IEs_t *)NULL + ,(LTE_SystemInformationBlockType1_v1310_IEs_t *)NULL #endif - ); + ); break; } } @@ -1299,23 +1246,23 @@ rrc_eNB_generate_RRCConnectionReestablishment( MSC_AS_TIME_ARGS(ctxt_pP), ue_context_pP->ue_context.rnti, RC.rrc[ctxt_pP->module_id]->carrier[CC_id].Srb0.Tx_buffer.payload_size); - LOG_I(RRC, PROTOCOL_RRC_CTXT_UE_FMT" [RAPROC] Logical Channel DL-CCCH, Generating LTE_RRCConnectionReestablishment (bytes %d)\n", PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP), RC.rrc[ctxt_pP->module_id]->carrier[CC_id].Srb0.Tx_buffer.payload_size); - int UE_id = find_UE_id(ctxt_pP->module_id, ctxt_pP->rnti); - if(UE_id != -1){ + + if(UE_id != -1) { // activate release timer, if RRCComplete not received after 100 frames, remove UE RC.mac[ctxt_pP->module_id]->UE_list.UE_sched_ctrl[UE_id].ue_reestablishment_reject_timer = 1; // remove UE after 100 frames after LTE_RRCConnectionReestablishmentRelease is triggered RC.mac[ctxt_pP->module_id]->UE_list.UE_sched_ctrl[UE_id].ue_reestablishment_reject_timer_thres = 1000; - }else{ + } else { LOG_E(RRC, - PROTOCOL_RRC_CTXT_UE_FMT" Generating LTE_RRCConnectionReestablishment without UE_id(MAC) rnti %x\n", - PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP),ctxt_pP->rnti); + PROTOCOL_RRC_CTXT_UE_FMT" Generating LTE_RRCConnectionReestablishment without UE_id(MAC) rnti %x\n", + PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP),ctxt_pP->rnti); } + // activate release timer, if RRCComplete not received after 100 frames, remove UE ue_context_pP->ue_context.ue_reestablishment_timer = 1; // remove UE after 100 frames after LTE_RRCConnectionReestablishmentRelease is triggered @@ -1325,25 +1272,23 @@ rrc_eNB_generate_RRCConnectionReestablishment( //----------------------------------------------------------------------------- void rrc_eNB_process_RRCConnectionReestablishmentComplete( - const protocol_ctxt_t* const ctxt_pP, + const protocol_ctxt_t *const ctxt_pP, const rnti_t reestablish_rnti, - rrc_eNB_ue_context_t* ue_context_pP, + rrc_eNB_ue_context_t *ue_context_pP, const uint8_t xid, - LTE_RRCConnectionReestablishmentComplete_r8_IEs_t * LTE_RRCConnectionReestablishmentComplete + LTE_RRCConnectionReestablishmentComplete_r8_IEs_t *LTE_RRCConnectionReestablishmentComplete ) //----------------------------------------------------------------------------- { LOG_I(RRC, PROTOCOL_RRC_CTXT_UE_FMT" [RAPROC] Logical Channel UL-DCCH, processing LTE_RRCConnectionReestablishmentComplete from UE (SRB1 Active)\n", PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP)); - T(T_ENB_RRC_CONNECTION_REESTABLISHMENT_COMPLETE, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame), T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti)); - - LTE_DRB_ToAddModList_t* DRB_configList = ue_context_pP->ue_context.DRB_configList; - LTE_SRB_ToAddModList_t* SRB_configList = ue_context_pP->ue_context.SRB_configList; - LTE_SRB_ToAddModList_t** SRB_configList2 = NULL; - LTE_DRB_ToAddModList_t** DRB_configList2 = NULL; + LTE_DRB_ToAddModList_t *DRB_configList = ue_context_pP->ue_context.DRB_configList; + LTE_SRB_ToAddModList_t *SRB_configList = ue_context_pP->ue_context.SRB_configList; + LTE_SRB_ToAddModList_t **SRB_configList2 = NULL; + LTE_DRB_ToAddModList_t **DRB_configList2 = NULL; struct LTE_SRB_ToAddMod *SRB2_config = NULL; struct LTE_DRB_ToAddMod *DRB_config = NULL; int i = 0; @@ -1367,185 +1312,175 @@ rrc_eNB_process_RRCConnectionReestablishmentComplete( (void)dedicatedInfoNas; LTE_C_RNTI_t *cba_RNTI = NULL; uint8_t next_xid = rrc_eNB_get_next_transaction_identifier(ctxt_pP->module_id); - ue_context_pP->ue_context.Status = RRC_CONNECTED; ue_context_pP->ue_context.ue_rrc_inactivity_timer = 1; // set rrc inactivity when UE goes into RRC_CONNECTED ue_context_pP->ue_context.ue_rrc_inactivity_timer_thres = 10000; // The value should come from config file ue_context_pP->ue_context.reestablishment_xid = next_xid; - SRB_configList2 = &ue_context_pP->ue_context.SRB_configList2[xid]; + // get old configuration of SRB2 if (*SRB_configList2 != NULL) { - if((*SRB_configList2)->list.count!=0){ + if((*SRB_configList2)->list.count!=0) { LOG_D(RRC, "SRB_configList2(%p) count is %d\n SRB_configList2->list.array[0] addr is %p", - SRB_configList2, (*SRB_configList2)->list.count, (*SRB_configList2)->list.array[0]); + SRB_configList2, (*SRB_configList2)->list.count, (*SRB_configList2)->list.array[0]); } + for (i = 0; (i < (*SRB_configList2)->list.count) && (i < 3); i++) { - if ((*SRB_configList2)->list.array[i]->srb_Identity == 2 ){ + if ((*SRB_configList2)->list.array[i]->srb_Identity == 2 ) { LOG_D(RRC, "get SRB2_config from (ue_context_pP->ue_context.SRB_configList2[%d])\n", xid); SRB2_config = (*SRB_configList2)->list.array[i]; break; } } } + SRB_configList2 = &ue_context_pP->ue_context.SRB_configList2[next_xid]; DRB_configList2 = &ue_context_pP->ue_context.DRB_configList2[next_xid]; - if(SRB_configList2!=NULL){ + if(SRB_configList2!=NULL) { if (*SRB_configList2) { free(*SRB_configList2); LOG_D(RRC, "free(ue_context_pP->ue_context.SRB_configList2[%d])\n", next_xid); } - }else{ - LOG_E(RRC, "SRB_configList2 is null\n"); + } else { + LOG_E(RRC, "SRB_configList2 is null\n"); } + *SRB_configList2 = CALLOC(1, sizeof(**SRB_configList2)); + if (SRB2_config != NULL) { // Add SRB2 to SRB configuration list - ASN_SEQUENCE_ADD(&SRB_configList->list, SRB2_config); ASN_SEQUENCE_ADD(&(*SRB_configList2)->list, SRB2_config); - LOG_D(RRC, "Add SRB2_config (srb_Identity:%ld) to ue_context_pP->ue_context.SRB_configList\n", - SRB2_config->srb_Identity); + SRB2_config->srb_Identity); LOG_D(RRC, "Add SRB2_config (srb_Identity:%ld) to ue_context_pP->ue_context.SRB_configList2[%d]\n", - SRB2_config->srb_Identity, next_xid); + SRB2_config->srb_Identity, next_xid); } else { // SRB configuration list only contains SRB1. LOG_W(RRC,"SRB2 configuration does not exist in SRB configuration list\n"); } - - - if(DRB_configList2!=NULL){ + if(DRB_configList2!=NULL) { if (*DRB_configList2) { free(*DRB_configList2); LOG_D(RRC, "free(ue_context_pP->ue_context.DRB_configList2[%d])\n", next_xid); } - }else{ - LOG_E(RRC, "DRB_configList2 is null\n"); + } else { + LOG_E(RRC, "DRB_configList2 is null\n"); } + *DRB_configList2 = CALLOC(1, sizeof(**DRB_configList2)); if (DRB_configList != NULL) { LOG_D(RRC, "get DRB_config from (ue_context_pP->ue_context.DRB_configList)\n"); + for (i = 0; (i < DRB_configList->list.count) && (i < 3); i++) { DRB_config = DRB_configList->list.array[i]; - // Add DRB to DRB configuration list, for LTE_RRCConnectionReconfigurationComplete ASN_SEQUENCE_ADD(&(*DRB_configList2)->list, DRB_config); } } + ue_context_pP->ue_context.Srb1.Active = 1; //ue_context_pP->ue_context.Srb2.Srb_info.Srb_id = 2; +#if defined(ENABLE_USE_MME) + hashtable_rc_t h_rc; + int j; + rrc_ue_s1ap_ids_t *rrc_ue_s1ap_ids_p = NULL; + uint16_t ue_initial_id = ue_context_pP->ue_context.ue_initial_id; + uint32_t eNB_ue_s1ap_id = ue_context_pP->ue_context.eNB_ue_s1ap_id; + eNB_RRC_INST *rrc_instance_p = RC.rrc[ENB_INSTANCE_TO_MODULE_ID(ctxt_pP->instance)]; -#if defined(ENABLE_USE_MME) - hashtable_rc_t h_rc; - int j; - rrc_ue_s1ap_ids_t* rrc_ue_s1ap_ids_p = NULL; - uint16_t ue_initial_id = ue_context_pP->ue_context.ue_initial_id; - uint32_t eNB_ue_s1ap_id = ue_context_pP->ue_context.eNB_ue_s1ap_id; - eNB_RRC_INST *rrc_instance_p = RC.rrc[ENB_INSTANCE_TO_MODULE_ID(ctxt_pP->instance)]; - if (eNB_ue_s1ap_id > 0) { - h_rc = hashtable_get(rrc_instance_p->s1ap_id2_s1ap_ids, (hash_key_t)eNB_ue_s1ap_id, (void**)&rrc_ue_s1ap_ids_p); - if (h_rc == HASH_TABLE_OK) { - rrc_ue_s1ap_ids_p->ue_rnti = ctxt_pP->rnti; - } + if (eNB_ue_s1ap_id > 0) { + h_rc = hashtable_get(rrc_instance_p->s1ap_id2_s1ap_ids, (hash_key_t)eNB_ue_s1ap_id, (void **)&rrc_ue_s1ap_ids_p); + + if (h_rc == HASH_TABLE_OK) { + rrc_ue_s1ap_ids_p->ue_rnti = ctxt_pP->rnti; } - if (ue_initial_id != 0) { - h_rc = hashtable_get(rrc_instance_p->initial_id2_s1ap_ids, (hash_key_t)ue_initial_id, (void**)&rrc_ue_s1ap_ids_p); - if (h_rc == HASH_TABLE_OK) { - rrc_ue_s1ap_ids_p->ue_rnti = ctxt_pP->rnti; - } + } + + if (ue_initial_id != 0) { + h_rc = hashtable_get(rrc_instance_p->initial_id2_s1ap_ids, (hash_key_t)ue_initial_id, (void **)&rrc_ue_s1ap_ids_p); + + if (h_rc == HASH_TABLE_OK) { + rrc_ue_s1ap_ids_p->ue_rnti = ctxt_pP->rnti; } + } - gtpv1u_enb_create_tunnel_req_t create_tunnel_req; + gtpv1u_enb_create_tunnel_req_t create_tunnel_req; + /* Save e RAB information for later */ + memset(&create_tunnel_req, 0, sizeof(create_tunnel_req)); - /* Save e RAB information for later */ - memset(&create_tunnel_req, 0 , sizeof(create_tunnel_req)); - - for ( j = 0, i = 0; i < NB_RB_MAX; i++) { - if (ue_context_pP->ue_context.e_rab[i].status == E_RAB_STATUS_ESTABLISHED || ue_context_pP->ue_context.e_rab[i].status == E_RAB_STATUS_DONE) { - create_tunnel_req.eps_bearer_id[j] = ue_context_pP->ue_context.e_rab[i].param.e_rab_id; - create_tunnel_req.sgw_S1u_teid[j] = ue_context_pP->ue_context.e_rab[i].param.gtp_teid; - - memcpy(&create_tunnel_req.sgw_addr[j], - &ue_context_pP->ue_context.e_rab[i].param.sgw_addr, - sizeof(transport_layer_addr_t)); - j++; - } + for ( j = 0, i = 0; i < NB_RB_MAX; i++) { + if (ue_context_pP->ue_context.e_rab[i].status == E_RAB_STATUS_ESTABLISHED || ue_context_pP->ue_context.e_rab[i].status == E_RAB_STATUS_DONE) { + create_tunnel_req.eps_bearer_id[j] = ue_context_pP->ue_context.e_rab[i].param.e_rab_id; + create_tunnel_req.sgw_S1u_teid[j] = ue_context_pP->ue_context.e_rab[i].param.gtp_teid; + memcpy(&create_tunnel_req.sgw_addr[j], + &ue_context_pP->ue_context.e_rab[i].param.sgw_addr, + sizeof(transport_layer_addr_t)); + j++; } + } - create_tunnel_req.rnti = ctxt_pP->rnti; // warning put zero above - create_tunnel_req.num_tunnels = j; - - gtpv1u_update_s1u_tunnel( - ctxt_pP->instance, - &create_tunnel_req, - reestablish_rnti); + create_tunnel_req.rnti = ctxt_pP->rnti; // warning put zero above + create_tunnel_req.num_tunnels = j; + gtpv1u_update_s1u_tunnel( + ctxt_pP->instance, + &create_tunnel_req, + reestablish_rnti); #endif /* Update RNTI in ue_context */ ue_context_pP->ue_id_rnti = ctxt_pP->rnti; // here ue_id_rnti is just a key, may be something else ue_context_pP->ue_context.rnti = ctxt_pP->rnti; #if defined(ENABLE_USE_MME) - uint8_t send_security_mode_command = FALSE; - rrc_pdcp_config_security( - ctxt_pP, - ue_context_pP, - send_security_mode_command); - LOG_D(RRC, "set security successfully \n"); + uint8_t send_security_mode_command = FALSE; + rrc_pdcp_config_security( + ctxt_pP, + ue_context_pP, + send_security_mode_command); + LOG_D(RRC, "set security successfully \n"); #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); - // LTE_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 = LTE_MeasObjectToAddMod__measObject_PR_measObjectEUTRA; MeasObj->measObject.choice.measObjectEUTRA.carrierFreq = 3350; //band 7, 2.68GHz @@ -1557,10 +1492,8 @@ rrc_eNB_process_RRCConnectionReestablishmentComplete( 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 = (LTE_CellsToAddModList_t *) CALLOC(1, sizeof(*CellsToAddModList)); - CellsToAddModList = MeasObj->measObject.choice.measObjectEUTRA.cellsToAddModList; // Add adjacent cell lists (6 per eNB) @@ -1569,28 +1502,19 @@ rrc_eNB_process_RRCConnectionReestablishmentComplete( CellToAdd->cellIndex = i + 1; CellToAdd->physCellId = get_adjacent_cell_id(ctxt_pP->module_id, i); CellToAdd->cellIndividualOffset = LTE_Q_OffsetRange_dB0; - ASN_SEQUENCE_ADD(&CellsToAddModList->list, CellToAdd); } ASN_SEQUENCE_ADD(&MeasObj_list->list, MeasObj); // LTE_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)); - ReportConfig_per = CALLOC(1, sizeof(*ReportConfig_per)); - ReportConfig_A1 = CALLOC(1, sizeof(*ReportConfig_A1)); - ReportConfig_A2 = CALLOC(1, sizeof(*ReportConfig_A2)); - ReportConfig_A3 = CALLOC(1, sizeof(*ReportConfig_A3)); - ReportConfig_A4 = CALLOC(1, sizeof(*ReportConfig_A4)); - ReportConfig_A5 = CALLOC(1, sizeof(*ReportConfig_A5)); - ReportConfig_per->reportConfigId = 1; ReportConfig_per->reportConfig.present = LTE_ReportConfigToAddMod__reportConfig_PR_reportConfigEUTRA; ReportConfig_per->reportConfig.choice.reportConfigEUTRA.triggerType.present = @@ -1602,9 +1526,7 @@ rrc_eNB_process_RRCConnectionReestablishmentComplete( ReportConfig_per->reportConfig.choice.reportConfigEUTRA.maxReportCells = 2; ReportConfig_per->reportConfig.choice.reportConfigEUTRA.reportInterval = LTE_ReportInterval_ms120; ReportConfig_per->reportConfig.choice.reportConfigEUTRA.reportAmount = LTE_ReportConfigEUTRA__reportAmount_infinity; - ASN_SEQUENCE_ADD(&ReportConfig_list->list, ReportConfig_per); - ReportConfig_A1->reportConfigId = 2; ReportConfig_A1->reportConfig.present = LTE_ReportConfigToAddMod__reportConfig_PR_reportConfigEUTRA; ReportConfig_A1->reportConfig.choice.reportConfigEUTRA.triggerType.present = @@ -1615,13 +1537,11 @@ rrc_eNB_process_RRCConnectionReestablishmentComplete( a1_Threshold.present = LTE_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 = LTE_ReportConfigEUTRA__triggerQuantity_rsrp; ReportConfig_A1->reportConfig.choice.reportConfigEUTRA.reportQuantity = LTE_ReportConfigEUTRA__reportQuantity_both; ReportConfig_A1->reportConfig.choice.reportConfigEUTRA.maxReportCells = 2; ReportConfig_A1->reportConfig.choice.reportConfigEUTRA.reportInterval = LTE_ReportInterval_ms120; ReportConfig_A1->reportConfig.choice.reportConfigEUTRA.reportAmount = LTE_ReportConfigEUTRA__reportAmount_infinity; - ASN_SEQUENCE_ADD(&ReportConfig_list->list, ReportConfig_A1); if (RC.rrc[ctxt_pP->module_id]->HO_flag == 1 /*HO_MEASURMENT */ ) { @@ -1637,39 +1557,32 @@ rrc_eNB_process_RRCConnectionReestablishmentComplete( eventA2.a2_Threshold.present = LTE_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 = LTE_ReportConfigEUTRA__triggerQuantity_rsrp; ReportConfig_A2->reportConfig.choice.reportConfigEUTRA.reportQuantity = LTE_ReportConfigEUTRA__reportQuantity_both; ReportConfig_A2->reportConfig.choice.reportConfigEUTRA.maxReportCells = 2; ReportConfig_A2->reportConfig.choice.reportConfigEUTRA.reportInterval = LTE_ReportInterval_ms120; ReportConfig_A2->reportConfig.choice.reportConfigEUTRA.reportAmount = LTE_ReportConfigEUTRA__reportAmount_infinity; - ASN_SEQUENCE_ADD(&ReportConfig_list->list, ReportConfig_A2); - ReportConfig_A3->reportConfigId = 4; ReportConfig_A3->reportConfig.present = LTE_ReportConfigToAddMod__reportConfig_PR_reportConfigEUTRA; ReportConfig_A3->reportConfig.choice.reportConfigEUTRA.triggerType.present = LTE_ReportConfigEUTRA__triggerType_PR_event; ReportConfig_A3->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.present = LTE_ReportConfigEUTRA__triggerType__event__eventId_PR_eventA3; - 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 = LTE_ReportConfigEUTRA__triggerQuantity_rsrp; ReportConfig_A3->reportConfig.choice.reportConfigEUTRA.reportQuantity = LTE_ReportConfigEUTRA__reportQuantity_both; ReportConfig_A3->reportConfig.choice.reportConfigEUTRA.maxReportCells = 2; ReportConfig_A3->reportConfig.choice.reportConfigEUTRA.reportInterval = LTE_ReportInterval_ms120; ReportConfig_A3->reportConfig.choice.reportConfigEUTRA.reportAmount = LTE_ReportConfigEUTRA__reportAmount_infinity; - ReportConfig_A3->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.hysteresis = 0.5; // FIXME ...hysteresis is of type long! ReportConfig_A3->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.timeToTrigger = LTE_TimeToTrigger_ms40; ASN_SEQUENCE_ADD(&ReportConfig_list->list, ReportConfig_A3); - ReportConfig_A4->reportConfigId = 5; ReportConfig_A4->reportConfig.present = LTE_ReportConfigToAddMod__reportConfig_PR_reportConfigEUTRA; ReportConfig_A4->reportConfig.choice.reportConfigEUTRA.triggerType.present = @@ -1680,16 +1593,13 @@ rrc_eNB_process_RRCConnectionReestablishmentComplete( eventA4.a4_Threshold.present = LTE_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 = LTE_ReportConfigEUTRA__triggerQuantity_rsrp; ReportConfig_A4->reportConfig.choice.reportConfigEUTRA.reportQuantity = LTE_ReportConfigEUTRA__reportQuantity_both; ReportConfig_A4->reportConfig.choice.reportConfigEUTRA.maxReportCells = 2; ReportConfig_A4->reportConfig.choice.reportConfigEUTRA.reportInterval = LTE_ReportInterval_ms120; ReportConfig_A4->reportConfig.choice.reportConfigEUTRA.reportAmount = LTE_ReportConfigEUTRA__reportAmount_infinity; - ASN_SEQUENCE_ADD(&ReportConfig_list->list, ReportConfig_A4); - ReportConfig_A5->reportConfigId = 6; ReportConfig_A5->reportConfig.present = LTE_ReportConfigToAddMod__reportConfig_PR_reportConfigEUTRA; ReportConfig_A5->reportConfig.choice.reportConfigEUTRA.triggerType.present = @@ -1704,20 +1614,16 @@ rrc_eNB_process_RRCConnectionReestablishmentComplete( 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 = LTE_ReportConfigEUTRA__triggerQuantity_rsrp; ReportConfig_A5->reportConfig.choice.reportConfigEUTRA.reportQuantity = LTE_ReportConfigEUTRA__reportQuantity_both; ReportConfig_A5->reportConfig.choice.reportConfigEUTRA.maxReportCells = 2; ReportConfig_A5->reportConfig.choice.reportConfigEUTRA.reportInterval = LTE_ReportInterval_ms120; ReportConfig_A5->reportConfig.choice.reportConfigEUTRA.reportAmount = LTE_ReportConfigEUTRA__reportAmount_infinity; - ASN_SEQUENCE_ADD(&ReportConfig_list->list, ReportConfig_A5); // LTE_RRCConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.measConfig->reportConfigToAddModList = ReportConfig_list; - rsrp = CALLOC(1, sizeof(LTE_RSRP_Range_t)); *rsrp = 20; - Sparams = CALLOC(1, sizeof(*Sparams)); Sparams->present = LTE_MeasConfig__speedStatePars_PR_setup; Sparams->choice.setup.timeToTrigger_SF.sf_High = LTE_SpeedStateScaleFactors__sf_Medium_oDot75; @@ -1726,7 +1632,6 @@ rrc_eNB_process_RRCConnectionReestablishmentComplete( Sparams->choice.setup.mobilityStateParameters.n_CellChangeMedium = 5; Sparams->choice.setup.mobilityStateParameters.t_Evaluation = LTE_MobilityStateParameters__t_Evaluation_s60; Sparams->choice.setup.mobilityStateParameters.t_HystNormal = LTE_MobilityStateParameters__t_HystNormal_s120; - quantityConfig = CALLOC(1, sizeof(*quantityConfig)); memset((void *)quantityConfig, 0, sizeof(*quantityConfig)); quantityConfig->quantityConfigEUTRA = CALLOC(1, sizeof(struct LTE_QuantityConfigEUTRA)); @@ -1740,7 +1645,6 @@ rrc_eNB_process_RRCConnectionReestablishmentComplete( CALLOC(1, sizeof(*(quantityConfig->quantityConfigEUTRA->filterCoefficientRSRQ))); *quantityConfig->quantityConfigEUTRA->filterCoefficientRSRP = LTE_FilterCoefficient_fc4; *quantityConfig->quantityConfigEUTRA->filterCoefficientRSRQ = LTE_FilterCoefficient_fc4; - LOG_I(RRC, "[eNB %d] Frame %d: potential handover preparation: store the information in an intermediate structure in case of failure\n", ctxt_pP->module_id, ctxt_pP->frame); @@ -1754,15 +1658,14 @@ rrc_eNB_process_RRCConnectionReestablishmentComplete( ue_context_pP->ue_context.handover_info->as_config.sourceRadioResourceConfig.drb_ToReleaseList = NULL; ue_context_pP->ue_context.handover_info->as_config.sourceRadioResourceConfig.mac_MainConfig = CALLOC(1, sizeof(*ue_context_pP->ue_context.handover_info->as_config.sourceRadioResourceConfig.mac_MainConfig)); - memcpy((void*)ue_context_pP->ue_context.handover_info->as_config.sourceRadioResourceConfig.mac_MainConfig, + memcpy((void *)ue_context_pP->ue_context.handover_info->as_config.sourceRadioResourceConfig.mac_MainConfig, (void *)ue_context_pP->ue_context.mac_MainConfig, sizeof(LTE_MAC_MainConfig_t)); ue_context_pP->ue_context.handover_info->as_config.sourceRadioResourceConfig.physicalConfigDedicated = CALLOC(1, sizeof(LTE_PhysicalConfigDedicated_t)); - memcpy((void*)ue_context_pP->ue_context.handover_info->as_config.sourceRadioResourceConfig.physicalConfigDedicated, - (void*)ue_context_pP->ue_context.physicalConfigDedicated, sizeof(LTE_PhysicalConfigDedicated_t)); + memcpy((void *)ue_context_pP->ue_context.handover_info->as_config.sourceRadioResourceConfig.physicalConfigDedicated, + (void *)ue_context_pP->ue_context.physicalConfigDedicated, sizeof(LTE_PhysicalConfigDedicated_t)); ue_context_pP->ue_context.handover_info->as_config.sourceRadioResourceConfig.sps_Config = NULL; //memcpy((void *)rrc_inst->handover_info[ue_mod_idP]->as_config.sourceRadioResourceConfig.sps_Config,(void *)rrc_inst->sps_Config[ue_mod_idP],sizeof(SPS_Config_t)); - } #ifdef CBA @@ -1790,7 +1693,6 @@ rrc_eNB_process_RRCConnectionReestablishmentComplete( } #endif - #if defined(ENABLE_ITTI) /* Initialize NAS list */ dedicatedInfoNASList = CALLOC(1, sizeof(struct LTE_RRCConnectionReconfiguration_r8_IEs__dedicatedInfoNASList)); @@ -1801,7 +1703,7 @@ rrc_eNB_process_RRCConnectionReestablishmentComplete( dedicatedInfoNas = CALLOC(1, sizeof(LTE_DedicatedInfoNAS_t)); memset(dedicatedInfoNas, 0, sizeof(OCTET_STRING_t)); OCTET_STRING_fromBuf(dedicatedInfoNas, - (char*)ue_context_pP->ue_context.e_rab[i].param.nas_pdu.buffer, + (char *)ue_context_pP->ue_context.e_rab[i].param.nas_pdu.buffer, ue_context_pP->ue_context.e_rab[i].param.nas_pdu.length); LOG_D(RRC, "Add LTE_DedicatedInfoNAS(%d) to LTE_DedicatedInfoNASList\n", i); ASN_SEQUENCE_ADD(&dedicatedInfoNASList->list, dedicatedInfoNas); @@ -1813,11 +1715,10 @@ rrc_eNB_process_RRCConnectionReestablishmentComplete( // ue_context_pP->ue_context.e_rab[i].param.sgw_addr; // ue_context_pP->ue_context.e_rab[i].param.gtp_teid; } - /* TODO should test if e RAB are Ok before! */ ue_context_pP->ue_context.e_rab[i].status = E_RAB_STATUS_DONE; LOG_D(RRC, "setting the status for the default DRB (index %d) to (%d,%s)\n", - i, ue_context_pP->ue_context.e_rab[i].status, "E_RAB_STATUS_DONE"); + i, ue_context_pP->ue_context.e_rab[i].status, "E_RAB_STATUS_DONE"); } /* If list is empty free the list and reset the address */ @@ -1827,43 +1728,39 @@ rrc_eNB_process_RRCConnectionReestablishmentComplete( } #endif - // send LTE_RRCConnectionReconfiguration memset(buffer, 0, RRC_BUF_SIZE); - size = do_RRCConnectionReconfiguration(ctxt_pP, buffer, next_xid, //Transaction_id, - (LTE_SRB_ToAddModList_t*)*SRB_configList2, // SRB_configList - (LTE_DRB_ToAddModList_t*)DRB_configList, - (LTE_DRB_ToReleaseList_t*)NULL, // DRB2_list, - (struct LTE_SPS_Config*)NULL, // maybe ue_context_pP->ue_context.sps_Config, - (struct LTE_PhysicalConfigDedicated*)ue_context_pP->ue_context.physicalConfigDedicated, + (LTE_SRB_ToAddModList_t *)*SRB_configList2, // SRB_configList + (LTE_DRB_ToAddModList_t *)DRB_configList, + (LTE_DRB_ToReleaseList_t *)NULL, // DRB2_list, + (struct LTE_SPS_Config *)NULL, // maybe ue_context_pP->ue_context.sps_Config, + (struct LTE_PhysicalConfigDedicated *)ue_context_pP->ue_context.physicalConfigDedicated, #ifdef EXMIMO_IOT NULL, NULL, NULL,NULL, #else - (LTE_MeasObjectToAddModList_t*)MeasObj_list, // MeasObj_list, - (LTE_ReportConfigToAddModList_t*)ReportConfig_list, // ReportConfig_list, - (LTE_QuantityConfig_t*)quantityConfig, //quantityConfig, - (LTE_MeasIdToAddModList_t*)NULL, + (LTE_MeasObjectToAddModList_t *)MeasObj_list, // MeasObj_list, + (LTE_ReportConfigToAddModList_t *)ReportConfig_list, // ReportConfig_list, + (LTE_QuantityConfig_t *)quantityConfig, //quantityConfig, + (LTE_MeasIdToAddModList_t *)NULL, #endif - (LTE_MAC_MainConfig_t*)ue_context_pP->ue_context.mac_MainConfig, - (LTE_MeasGapConfig_t*)NULL, - (LTE_MobilityControlInfo_t*)NULL, - (struct LTE_MeasConfig__speedStatePars*)Sparams, // Sparams, - (LTE_RSRP_Range_t*)rsrp, // rsrp, - (LTE_C_RNTI_t*)cba_RNTI, // cba_RNTI - (struct LTE_RRCConnectionReconfiguration_r8_IEs__dedicatedInfoNASList*)dedicatedInfoNASList, //dedicatedInfoNASList - (LTE_SL_CommConfig_r12_t*)NULL, - (LTE_SL_DiscConfig_r12_t*)NULL + (LTE_MAC_MainConfig_t *)ue_context_pP->ue_context.mac_MainConfig, + (LTE_MeasGapConfig_t *)NULL, + (LTE_MobilityControlInfo_t *)NULL, + (struct LTE_MeasConfig__speedStatePars *)Sparams, // Sparams, + (LTE_RSRP_Range_t *)rsrp, // rsrp, + (LTE_C_RNTI_t *)cba_RNTI, // cba_RNTI + (struct LTE_RRCConnectionReconfiguration_r8_IEs__dedicatedInfoNASList *)dedicatedInfoNASList, //dedicatedInfoNASList + (LTE_SL_CommConfig_r12_t *)NULL, + (LTE_SL_DiscConfig_r12_t *)NULL #if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) - , (LTE_SCellToAddMod_r10_t*)NULL + , (LTE_SCellToAddMod_r10_t *)NULL #endif ); LOG_DUMPMSG(RRC,DEBUG_RRC,(char *)buffer,size, "[MSG] RRC Connection Reconfiguration\n"); - - #if defined(ENABLE_ITTI) /* Free all NAS PDUs */ @@ -1876,19 +1773,18 @@ rrc_eNB_process_RRCConnectionReestablishmentComplete( } #endif - if(size==65535){ + + if(size==65535) { LOG_E(RRC,"RRC decode err!!! do_RRCConnectionReconfiguration\n"); put_UE_in_freelist(ctxt_pP->module_id, reestablish_rnti, 0); return; - }else{ + } else { LOG_I(RRC, "[eNB %d] Frame %d, Logical Channel DL-DCCH, Generate LTE_RRCConnectionReconfiguration (bytes %d, UE id %x)\n", ctxt_pP->module_id, ctxt_pP->frame, size, ue_context_pP->ue_context.rnti); - LOG_D(RRC, "[FRAME %05d][RRC_eNB][MOD %u][][--- PDCP_DATA_REQ/%d Bytes (rrcConnectionReconfiguration to UE %x MUI %d) --->][PDCP][MOD %u][RB %u]\n", ctxt_pP->frame, ctxt_pP->module_id, size, ue_context_pP->ue_context.rnti, rrc_eNB_mui, ctxt_pP->module_id, DCCH); - MSC_LOG_TX_MESSAGE( MSC_RRC_ENB, MSC_RRC_UE, @@ -1899,55 +1795,55 @@ rrc_eNB_process_RRCConnectionReestablishmentComplete( ue_context_pP->ue_context.rnti, rrc_eNB_mui, size); - rrc_data_req( - ctxt_pP, - DCCH, - rrc_eNB_mui++, - SDU_CONFIRM_NO, - size, - buffer, - PDCP_TRANSMISSION_MODE_CONTROL); + ctxt_pP, + DCCH, + rrc_eNB_mui++, + SDU_CONFIRM_NO, + size, + buffer, + PDCP_TRANSMISSION_MODE_CONTROL); } + // delete UE data of prior RNTI. UE use current RNTI. -// protocol_ctxt_t ctxt_prior = *ctxt_pP; -// ctxt_prior.rnti = reestablish_rnti; -// -// LTE_eNB_ULSCH_t *ulsch = NULL; -// nfapi_ul_config_request_body_t *ul_req_tmp = NULL; -// PHY_VARS_eNB *eNB_PHY = NULL; -// eNB_MAC_INST *eNB_MAC = RC.mac[ctxt_prior.module_id]; -// for (int CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { -// eNB_PHY = RC.eNB[ctxt_prior.module_id][CC_id]; -// for (int i=0; iulsch[i]; -// if((ulsch != NULL) && (ulsch->rnti == ctxt_prior.rnti)){ -// void clean_eNb_ulsch(LTE_eNB_ULSCH_t *ulsch); -// LOG_I(RRC, "clean_eNb_ulsch UE %x \n", ctxt_prior.rnti); -// clean_eNb_ulsch(ulsch); -// break; -// } -// } -// -// for(int j = 0; j < 10; j++){ -// ul_req_tmp = &eNB_MAC->UL_req_tmp[CC_id][j].ul_config_request_body; -// if(ul_req_tmp){ -// int pdu_number = ul_req_tmp->number_of_pdus; -// for(int pdu_index = pdu_number-1; pdu_index >= 0; pdu_index--){ -// if(ul_req_tmp->ul_config_pdu_list[pdu_index].ulsch_pdu.ulsch_pdu_rel8.rnti == ctxt_prior.rnti){ -// LOG_I(RRC, "remove UE %x from ul_config_pdu_list %d/%d\n", ctxt_prior.rnti, pdu_index, pdu_number); -// if(pdu_index < pdu_number -1){ -// memcpy(&ul_req_tmp->ul_config_pdu_list[pdu_index], &ul_req_tmp->ul_config_pdu_list[pdu_index+1], (pdu_number-1-pdu_index) * sizeof(nfapi_ul_config_request_pdu_t)); -// } -// ul_req_tmp->number_of_pdus--; -// } -// } -// } -// } -// } -// rrc_mac_remove_ue(ctxt_prior.module_id, ctxt_prior.rnti); -// rrc_rlc_remove_ue(&ctxt_prior); -// pdcp_remove_UE(&ctxt_prior); + // protocol_ctxt_t ctxt_prior = *ctxt_pP; + // ctxt_prior.rnti = reestablish_rnti; + // + // LTE_eNB_ULSCH_t *ulsch = NULL; + // nfapi_ul_config_request_body_t *ul_req_tmp = NULL; + // PHY_VARS_eNB *eNB_PHY = NULL; + // eNB_MAC_INST *eNB_MAC = RC.mac[ctxt_prior.module_id]; + // for (int CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { + // eNB_PHY = RC.eNB[ctxt_prior.module_id][CC_id]; + // for (int i=0; iulsch[i]; + // if((ulsch != NULL) && (ulsch->rnti == ctxt_prior.rnti)){ + // void clean_eNb_ulsch(LTE_eNB_ULSCH_t *ulsch); + // LOG_I(RRC, "clean_eNb_ulsch UE %x \n", ctxt_prior.rnti); + // clean_eNb_ulsch(ulsch); + // break; + // } + // } + // + // for(int j = 0; j < 10; j++){ + // ul_req_tmp = &eNB_MAC->UL_req_tmp[CC_id][j].ul_config_request_body; + // if(ul_req_tmp){ + // int pdu_number = ul_req_tmp->number_of_pdus; + // for(int pdu_index = pdu_number-1; pdu_index >= 0; pdu_index--){ + // if(ul_req_tmp->ul_config_pdu_list[pdu_index].ulsch_pdu.ulsch_pdu_rel8.rnti == ctxt_prior.rnti){ + // LOG_I(RRC, "remove UE %x from ul_config_pdu_list %d/%d\n", ctxt_prior.rnti, pdu_index, pdu_number); + // if(pdu_index < pdu_number -1){ + // memcpy(&ul_req_tmp->ul_config_pdu_list[pdu_index], &ul_req_tmp->ul_config_pdu_list[pdu_index+1], (pdu_number-1-pdu_index) * sizeof(nfapi_ul_config_request_pdu_t)); + // } + // ul_req_tmp->number_of_pdus--; + // } + // } + // } + // } + // } + // rrc_mac_remove_ue(ctxt_prior.module_id, ctxt_prior.rnti); + // rrc_rlc_remove_ue(&ctxt_prior); + // pdcp_remove_UE(&ctxt_prior); // add UE info to freeList for RU_thread to remove the UE instead of remove it here LOG_I(RRC, "[RRCConnectionReestablishment]put UE %x into freeList\n", reestablish_rnti); put_UE_in_freelist(ctxt_pP->module_id, reestablish_rnti, 0); @@ -1956,34 +1852,32 @@ rrc_eNB_process_RRCConnectionReestablishmentComplete( //----------------------------------------------------------------------------- void rrc_eNB_generate_RRCConnectionReestablishmentReject( - const protocol_ctxt_t* const ctxt_pP, - rrc_eNB_ue_context_t* const ue_context_pP, + const protocol_ctxt_t *const ctxt_pP, + rrc_eNB_ue_context_t *const ue_context_pP, const int CC_id ) //----------------------------------------------------------------------------- { int UE_id = find_UE_id(ctxt_pP->module_id, ctxt_pP->rnti); - if(UE_id != -1){ + + if(UE_id != -1) { RC.mac[ctxt_pP->module_id]->UE_list.UE_sched_ctrl[UE_id].ue_reestablishment_reject_timer = 1; RC.mac[ctxt_pP->module_id]->UE_list.UE_sched_ctrl[UE_id].ue_reestablishment_reject_timer_thres = 20; - }else{ + } else { LOG_E(RRC, - PROTOCOL_RRC_CTXT_UE_FMT" Generating LTE_RRCConnectionReestablishmentReject without UE_id(MAC) rnti %x\n", - PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP),ctxt_pP->rnti); + PROTOCOL_RRC_CTXT_UE_FMT" Generating LTE_RRCConnectionReestablishmentReject without UE_id(MAC) rnti %x\n", + PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP),ctxt_pP->rnti); } T(T_ENB_RRC_CONNECTION_REESTABLISHMENT_REJECT, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame), T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti)); - RC.rrc[ctxt_pP->module_id]->carrier[CC_id].Srb0.Tx_buffer.payload_size = do_RRCConnectionReestablishmentReject(ctxt_pP->module_id, - (uint8_t*) RC.rrc[ctxt_pP->module_id]->carrier[CC_id].Srb0.Tx_buffer.Payload); - + (uint8_t *) RC.rrc[ctxt_pP->module_id]->carrier[CC_id].Srb0.Tx_buffer.Payload); LOG_DUMPMSG(RRC,DEBUG_RRC, (char *)(RC.rrc[ctxt_pP->module_id]->carrier[CC_id].Srb0.Tx_buffer.Payload), RC.rrc[ctxt_pP->module_id]->carrier[CC_id].Srb0.Tx_buffer.payload_size, "[MSG] RRCConnectionReestablishmentReject\n"); - MSC_LOG_TX_MESSAGE( MSC_RRC_ENB, MSC_RRC_UE, @@ -1993,7 +1887,6 @@ rrc_eNB_generate_RRCConnectionReestablishmentReject( MSC_AS_TIME_ARGS(ctxt_pP), ue_context_pP == NULL ? -1 : ue_context_pP->ue_context.rnti, RC.rrc[ctxt_pP->module_id]->carrier[CC_id].Srb0.Tx_buffer.payload_size); - LOG_I(RRC, PROTOCOL_RRC_CTXT_UE_FMT" [RAPROC] Logical Channel DL-CCCH, Generating LTE_RRCConnectionReestablishmentReject (bytes %d)\n", PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP), @@ -2007,36 +1900,30 @@ rrc_eNB_generate_RRCConnectionReestablishmentReject( */ void rrc_eNB_generate_RRCConnectionRelease( - const protocol_ctxt_t* const ctxt_pP, - rrc_eNB_ue_context_t* const ue_context_pP + const protocol_ctxt_t *const ctxt_pP, + rrc_eNB_ue_context_t *const ue_context_pP ) //----------------------------------------------------------------------------- { uint8_t buffer[RRC_BUF_SIZE]; uint16_t size = 0; - memset(buffer, 0, RRC_BUF_SIZE); - T(T_ENB_RRC_CONNECTION_RELEASE, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame), T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti)); - size = do_RRCConnectionRelease(ctxt_pP->module_id, buffer,rrc_eNB_get_next_transaction_identifier(ctxt_pP->module_id)); ue_context_pP->ue_context.ue_reestablishment_timer = 0; ue_context_pP->ue_context.ue_release_timer = 0; ue_context_pP->ue_context.ue_rrc_inactivity_timer = 0; - LOG_I(RRC, - PROTOCOL_RRC_CTXT_UE_FMT" Logical Channel DL-DCCH, Generate RRCConnectionRelease (bytes %d)\n", - PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP), - size); - + PROTOCOL_RRC_CTXT_UE_FMT" Logical Channel DL-DCCH, Generate RRCConnectionRelease (bytes %d)\n", + PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP), + size); LOG_D(RRC, - PROTOCOL_RRC_CTXT_UE_FMT" --- PDCP_DATA_REQ/%d Bytes (rrcConnectionRelease MUI %d) --->[PDCP][RB %u]\n", - PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP), - size, - rrc_eNB_mui, - DCCH); - + PROTOCOL_RRC_CTXT_UE_FMT" --- PDCP_DATA_REQ/%d Bytes (rrcConnectionRelease MUI %d) --->[PDCP][RB %u]\n", + PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP), + size, + rrc_eNB_mui, + DCCH); MSC_LOG_TX_MESSAGE( MSC_RRC_ENB, MSC_RRC_UE, @@ -2047,11 +1934,10 @@ rrc_eNB_generate_RRCConnectionRelease( ue_context_pP->ue_context.rnti, rrc_eNB_mui, size); - pthread_mutex_lock(&rrc_release_freelist); + for (uint16_t release_num = 0; release_num < NUMBER_OF_UE_MAX; release_num++) { if (rrc_release_info.RRC_release_ctrl[release_num].flag == 0) { - if (ue_context_pP->ue_context.ue_release_timer_s1 > 0) { rrc_release_info.RRC_release_ctrl[release_num].flag = 1; } else { @@ -2061,44 +1947,40 @@ rrc_eNB_generate_RRCConnectionRelease( rrc_release_info.RRC_release_ctrl[release_num].rnti = ctxt_pP->rnti; rrc_release_info.RRC_release_ctrl[release_num].rrc_eNB_mui = rrc_eNB_mui; rrc_release_info.num_UEs++; - LOG_D(RRC, "Generate DLSCH Release send: index %d rnti %x mui %d flag %d \n", - release_num, - ctxt_pP->rnti, - rrc_eNB_mui, - rrc_release_info.RRC_release_ctrl[release_num].flag); - + release_num, + ctxt_pP->rnti, + rrc_eNB_mui, + rrc_release_info.RRC_release_ctrl[release_num].flag); break; } } - pthread_mutex_unlock(&rrc_release_freelist); + pthread_mutex_unlock(&rrc_release_freelist); rrc_data_req(ctxt_pP, - DCCH, - rrc_eNB_mui++, - SDU_CONFIRM_NO, - size, - buffer, - PDCP_TRANSMISSION_MODE_CONTROL); + DCCH, + rrc_eNB_mui++, + SDU_CONFIRM_NO, + size, + buffer, + PDCP_TRANSMISSION_MODE_CONTROL); } -uint8_t qci_to_priority[9]={2,4,3,5,1,6,7,8,9}; +uint8_t qci_to_priority[9]= {2,4,3,5,1,6,7,8,9}; // TBD: this directive can be remived if we create a similar e_rab_param_t structure in RRC context -#if defined(ENABLE_ITTI) +#if defined(ENABLE_ITTI) //----------------------------------------------------------------------------- void -rrc_eNB_generate_dedicatedRRCConnectionReconfiguration(const protocol_ctxt_t* const ctxt_pP, - rrc_eNB_ue_context_t* const ue_context_pP, - const uint8_t ho_state - ) +rrc_eNB_generate_dedicatedRRCConnectionReconfiguration(const protocol_ctxt_t *const ctxt_pP, + rrc_eNB_ue_context_t *const ue_context_pP, + const uint8_t ho_state + ) //----------------------------------------------------------------------------- { - uint8_t buffer[RRC_BUF_SIZE]; uint16_t size; int i; - struct LTE_DRB_ToAddMod *DRB_config = NULL; struct LTE_RLC_Config *DRB_rlc_config = NULL; struct LTE_PDCP_Config *DRB_pdcp_config = NULL; @@ -2107,61 +1989,53 @@ rrc_eNB_generate_dedicatedRRCConnectionReconfiguration(const protocol_ctxt_t* co struct LTE_LogicalChannelConfig *DRB_lchan_config = NULL; struct LTE_LogicalChannelConfig__ul_SpecificParameters *DRB_ul_SpecificParameters = NULL; - // LTE_DRB_ToAddModList_t** DRB_configList=&ue_context_pP->ue_context.DRB_configList; - LTE_DRB_ToAddModList_t* DRB_configList=ue_context_pP->ue_context.DRB_configList; - LTE_DRB_ToAddModList_t** DRB_configList2=NULL; + // LTE_DRB_ToAddModList_t** DRB_configList=&ue_context_pP->ue_context.DRB_configList; + LTE_DRB_ToAddModList_t *DRB_configList=ue_context_pP->ue_context.DRB_configList; + LTE_DRB_ToAddModList_t **DRB_configList2=NULL; //DRB_ToAddModList_t** RRC_DRB_configList=&ue_context_pP->ue_context.DRB_configList; - struct LTE_RRCConnectionReconfiguration_r8_IEs__dedicatedInfoNASList *dedicatedInfoNASList = NULL; LTE_DedicatedInfoNAS_t *dedicatedInfoNas = NULL; /* for no gcc warnings */ (void)dedicatedInfoNas; - long *logicalchannelgroup_drb; -// int drb_identity_index=0; - + // int drb_identity_index=0; uint8_t xid = rrc_eNB_get_next_transaction_identifier(ctxt_pP->module_id); //Transaction_id, DRB_configList2=&ue_context_pP->ue_context.DRB_configList2[xid]; + if (*DRB_configList2) { free(*DRB_configList2); } + //*DRB_configList = CALLOC(1, sizeof(*DRB_configList)); - *DRB_configList2 = CALLOC(1, sizeof(**DRB_configList2)); + *DRB_configList2 = CALLOC(1, sizeof(**DRB_configList2)); /* Initialize NAS list */ dedicatedInfoNASList = CALLOC(1, sizeof(struct LTE_RRCConnectionReconfiguration_r8_IEs__dedicatedInfoNASList)); - int e_rab_done=0; - - for ( i = 0 ; - i < ue_context_pP->ue_context.setup_e_rabs ; - i++){ - if (e_rab_done >= ue_context_pP->ue_context.nb_of_e_rabs){ - break; + for ( i = 0 ; + i < ue_context_pP->ue_context.setup_e_rabs ; + i++) { + if (e_rab_done >= ue_context_pP->ue_context.nb_of_e_rabs) { + break; } - + // bypass the new and already configured erabs if (ue_context_pP->ue_context.e_rab[i].status >= E_RAB_STATUS_DONE) { -// drb_identity_index++; + // drb_identity_index++; continue; } - - DRB_config = CALLOC(1, sizeof(*DRB_config)); + DRB_config = CALLOC(1, sizeof(*DRB_config)); DRB_config->eps_BearerIdentity = CALLOC(1, sizeof(long)); // allowed value 5..15, value : x+4 - *(DRB_config->eps_BearerIdentity) = ue_context_pP->ue_context.e_rab[i].param.e_rab_id;//+ 4; // especial case generation - - // DRB_config->drb_Identity = 1 + drb_identity_index + e_rab_done;// + i ;// (LTE_DRB_Identity_t) ue_context_pP->ue_context.e_rab[i].param.e_rab_id; - // 1 + drb_identiy_index; + *(DRB_config->eps_BearerIdentity) = ue_context_pP->ue_context.e_rab[i].param.e_rab_id;//+ 4; // especial case generation + // DRB_config->drb_Identity = 1 + drb_identity_index + e_rab_done;// + i ;// (LTE_DRB_Identity_t) ue_context_pP->ue_context.e_rab[i].param.e_rab_id; + // 1 + drb_identiy_index; DRB_config->drb_Identity = i+1; - DRB_config->logicalChannelIdentity = CALLOC(1, sizeof(long)); *(DRB_config->logicalChannelIdentity) = DRB_config->drb_Identity + 2; //(long) (ue_context_pP->ue_context.e_rab[i].param.e_rab_id + 2); // value : x+2 - DRB_rlc_config = CALLOC(1, sizeof(*DRB_rlc_config)); DRB_config->rlc_Config = DRB_rlc_config; - DRB_pdcp_config = CALLOC(1, sizeof(*DRB_pdcp_config)); DRB_config->pdcp_Config = DRB_pdcp_config; DRB_pdcp_config->discardTimer = CALLOC(1, sizeof(long)); @@ -2169,123 +2043,114 @@ rrc_eNB_generate_dedicatedRRCConnectionReconfiguration(const protocol_ctxt_t* co DRB_pdcp_config->rlc_AM = NULL; DRB_pdcp_config->rlc_UM = NULL; - - switch (ue_context_pP->ue_context.e_rab[i].param.qos.qci){ + switch (ue_context_pP->ue_context.e_rab[i].param.qos.qci) { /* * type: realtime data with medium packer error rate * action: swtich to RLC UM */ - case 1: // 100ms, 10^-2, p2, GBR - case 2: // 150ms, 10^-3, p4, GBR - case 3: // 50ms, 10^-3, p3, GBR - case 4: // 300ms, 10^-6, p5 - case 7: // 100ms, 10^-3, p7, GBR - case 9: // 300ms, 10^-6, p9 - case 65: // 75ms, 10^-2, p0.7, mission critical voice, GBR - case 66: // 100ms, 10^-2, p2, non-mission critical voice , GBR - // RLC - DRB_rlc_config->present = LTE_RLC_Config_PR_um_Bi_Directional; - DRB_rlc_config->choice.um_Bi_Directional.ul_UM_RLC.sn_FieldLength = LTE_SN_FieldLength_size10; - DRB_rlc_config->choice.um_Bi_Directional.dl_UM_RLC.sn_FieldLength = LTE_SN_FieldLength_size10; - DRB_rlc_config->choice.um_Bi_Directional.dl_UM_RLC.t_Reordering = LTE_T_Reordering_ms35; - // PDCP - PDCP_rlc_UM = CALLOC(1, sizeof(*PDCP_rlc_UM)); - DRB_pdcp_config->rlc_UM = PDCP_rlc_UM; - PDCP_rlc_UM->pdcp_SN_Size = LTE_PDCP_Config__rlc_UM__pdcp_SN_Size_len12bits; - break; - + case 1: // 100ms, 10^-2, p2, GBR + case 2: // 150ms, 10^-3, p4, GBR + case 3: // 50ms, 10^-3, p3, GBR + case 4: // 300ms, 10^-6, p5 + case 7: // 100ms, 10^-3, p7, GBR + case 9: // 300ms, 10^-6, p9 + case 65: // 75ms, 10^-2, p0.7, mission critical voice, GBR + case 66: // 100ms, 10^-2, p2, non-mission critical voice , GBR + // RLC + DRB_rlc_config->present = LTE_RLC_Config_PR_um_Bi_Directional; + DRB_rlc_config->choice.um_Bi_Directional.ul_UM_RLC.sn_FieldLength = LTE_SN_FieldLength_size10; + DRB_rlc_config->choice.um_Bi_Directional.dl_UM_RLC.sn_FieldLength = LTE_SN_FieldLength_size10; + DRB_rlc_config->choice.um_Bi_Directional.dl_UM_RLC.t_Reordering = LTE_T_Reordering_ms35; + // PDCP + PDCP_rlc_UM = CALLOC(1, sizeof(*PDCP_rlc_UM)); + DRB_pdcp_config->rlc_UM = PDCP_rlc_UM; + PDCP_rlc_UM->pdcp_SN_Size = LTE_PDCP_Config__rlc_UM__pdcp_SN_Size_len12bits; + break; + /* * type: non-realtime data with low packer error rate * action: swtich to RLC AM */ - case 5: // 100ms, 10^-6, p1 , IMS signaling - case 6: // 300ms, 10^-6, p6 - case 8: // 300ms, 10^-6, p8 - case 69: // 60ms, 10^-6, p0.5, mission critical delay sensitive data, Lowest Priority - case 70: // 200ms, 10^-6, p5.5, mision critical data - // RLC - DRB_rlc_config->present = LTE_RLC_Config_PR_am; - DRB_rlc_config->choice.am.ul_AM_RLC.t_PollRetransmit = LTE_T_PollRetransmit_ms50; - DRB_rlc_config->choice.am.ul_AM_RLC.pollPDU = LTE_PollPDU_p16; - DRB_rlc_config->choice.am.ul_AM_RLC.pollByte = LTE_PollByte_kBinfinity; - DRB_rlc_config->choice.am.ul_AM_RLC.maxRetxThreshold = LTE_UL_AM_RLC__maxRetxThreshold_t8; - DRB_rlc_config->choice.am.dl_AM_RLC.t_Reordering = LTE_T_Reordering_ms35; - DRB_rlc_config->choice.am.dl_AM_RLC.t_StatusProhibit = LTE_T_StatusProhibit_ms25; + case 5: // 100ms, 10^-6, p1 , IMS signaling + case 6: // 300ms, 10^-6, p6 + case 8: // 300ms, 10^-6, p8 + case 69: // 60ms, 10^-6, p0.5, mission critical delay sensitive data, Lowest Priority + case 70: // 200ms, 10^-6, p5.5, mision critical data + // RLC + DRB_rlc_config->present = LTE_RLC_Config_PR_am; + DRB_rlc_config->choice.am.ul_AM_RLC.t_PollRetransmit = LTE_T_PollRetransmit_ms50; + DRB_rlc_config->choice.am.ul_AM_RLC.pollPDU = LTE_PollPDU_p16; + DRB_rlc_config->choice.am.ul_AM_RLC.pollByte = LTE_PollByte_kBinfinity; + DRB_rlc_config->choice.am.ul_AM_RLC.maxRetxThreshold = LTE_UL_AM_RLC__maxRetxThreshold_t8; + DRB_rlc_config->choice.am.dl_AM_RLC.t_Reordering = LTE_T_Reordering_ms35; + DRB_rlc_config->choice.am.dl_AM_RLC.t_StatusProhibit = LTE_T_StatusProhibit_ms25; + // PDCP + PDCP_rlc_AM = CALLOC(1, sizeof(*PDCP_rlc_AM)); + DRB_pdcp_config->rlc_AM = PDCP_rlc_AM; + PDCP_rlc_AM->statusReportRequired = FALSE; + break; - // PDCP - PDCP_rlc_AM = CALLOC(1, sizeof(*PDCP_rlc_AM)); - DRB_pdcp_config->rlc_AM = PDCP_rlc_AM; - PDCP_rlc_AM->statusReportRequired = FALSE; - - break; - default : - LOG_E(RRC,"not supported qci %d\n", ue_context_pP->ue_context.e_rab[i].param.qos.qci); - ue_context_pP->ue_context.e_rab[i].status = E_RAB_STATUS_FAILED; - ue_context_pP->ue_context.e_rab[i].xid = xid; - e_rab_done++; - continue; + default : + LOG_E(RRC,"not supported qci %d\n", ue_context_pP->ue_context.e_rab[i].param.qos.qci); + ue_context_pP->ue_context.e_rab[i].status = E_RAB_STATUS_FAILED; + ue_context_pP->ue_context.e_rab[i].xid = xid; + e_rab_done++; + continue; } DRB_pdcp_config->headerCompression.present = LTE_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; if (ue_context_pP->ue_context.e_rab[i].param.qos.qci < 9 ) - DRB_ul_SpecificParameters->priority = qci_to_priority[ue_context_pP->ue_context.e_rab[i].param.qos.qci-1] + 3; + DRB_ul_SpecificParameters->priority = qci_to_priority[ue_context_pP->ue_context.e_rab[i].param.qos.qci-1] + 3; // ue_context_pP->ue_context.e_rab[i].param.qos.allocation_retention_priority.priority_level; - else + else DRB_ul_SpecificParameters->priority= 4; DRB_ul_SpecificParameters->prioritisedBitRate = LTE_LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_kBps8; - //LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_infinity; + //LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_infinity; DRB_ul_SpecificParameters->bucketSizeDuration = LTE_LogicalChannelConfig__ul_SpecificParameters__bucketSizeDuration_ms50; - logicalchannelgroup_drb = CALLOC(1, sizeof(long)); *logicalchannelgroup_drb = 1;//(i+1) % 3; DRB_ul_SpecificParameters->logicalChannelGroup = logicalchannelgroup_drb; - ASN_SEQUENCE_ADD(&DRB_configList->list, DRB_config); ASN_SEQUENCE_ADD(&(*DRB_configList2)->list, DRB_config); //ue_context_pP->ue_context.DRB_configList2[drb_identity_index] = &(*DRB_configList); - LOG_I(RRC,"EPS ID %ld, DRB ID %ld (index %d), QCI %d, priority %ld, LCID %ld LCGID %ld \n", - *DRB_config->eps_BearerIdentity, - DRB_config->drb_Identity, i, - ue_context_pP->ue_context.e_rab[i].param.qos.qci, - DRB_ul_SpecificParameters->priority, - *(DRB_config->logicalChannelIdentity), - *DRB_ul_SpecificParameters->logicalChannelGroup - ); - + *DRB_config->eps_BearerIdentity, + DRB_config->drb_Identity, i, + ue_context_pP->ue_context.e_rab[i].param.qos.qci, + DRB_ul_SpecificParameters->priority, + *(DRB_config->logicalChannelIdentity), + *DRB_ul_SpecificParameters->logicalChannelGroup + ); e_rab_done++; - ue_context_pP->ue_context.e_rab[i].status = E_RAB_STATUS_DONE; + ue_context_pP->ue_context.e_rab[i].status = E_RAB_STATUS_DONE; ue_context_pP->ue_context.e_rab[i].xid = xid; - { if (ue_context_pP->ue_context.e_rab[i].param.nas_pdu.buffer != NULL) { - dedicatedInfoNas = CALLOC(1, sizeof(LTE_DedicatedInfoNAS_t)); - memset(dedicatedInfoNas, 0, sizeof(OCTET_STRING_t)); - OCTET_STRING_fromBuf(dedicatedInfoNas, - (char*)ue_context_pP->ue_context.e_rab[i].param.nas_pdu.buffer, - ue_context_pP->ue_context.e_rab[i].param.nas_pdu.length); - ASN_SEQUENCE_ADD(&dedicatedInfoNASList->list, dedicatedInfoNas); - LOG_I(RRC,"add NAS info with size %d (rab id %d)\n",ue_context_pP->ue_context.e_rab[i].param.nas_pdu.length, i); - } - else { - LOG_W(RRC,"Not received activate dedicated EPS bearer context request\n"); + dedicatedInfoNas = CALLOC(1, sizeof(LTE_DedicatedInfoNAS_t)); + memset(dedicatedInfoNas, 0, sizeof(OCTET_STRING_t)); + OCTET_STRING_fromBuf(dedicatedInfoNas, + (char *)ue_context_pP->ue_context.e_rab[i].param.nas_pdu.buffer, + ue_context_pP->ue_context.e_rab[i].param.nas_pdu.length); + ASN_SEQUENCE_ADD(&dedicatedInfoNASList->list, dedicatedInfoNas); + LOG_I(RRC,"add NAS info with size %d (rab id %d)\n",ue_context_pP->ue_context.e_rab[i].param.nas_pdu.length, i); + } else { + LOG_W(RRC,"Not received activate dedicated EPS bearer context request\n"); } + /* TODO parameters yet to process ... */ { - // ue_context_pP->ue_context.e_rab[i].param.qos; - // ue_context_pP->ue_context.e_rab[i].param.sgw_addr; - // ue_context_pP->ue_context.e_rab[i].param.gtp_teid; + // ue_context_pP->ue_context.e_rab[i].param.qos; + // ue_context_pP->ue_context.e_rab[i].param.sgw_addr; + // ue_context_pP->ue_context.e_rab[i].param.gtp_teid; } } - } /* If list is empty free the list and reset the address */ @@ -2294,33 +2159,29 @@ rrc_eNB_generate_dedicatedRRCConnectionReconfiguration(const protocol_ctxt_t* co free(dedicatedInfoNASList); dedicatedInfoNASList = NULL; LOG_W(RRC,"dedlicated NAS list is empty, free the list and reset the address\n"); - } + } } else { LOG_W(RRC,"dedlicated NAS list is empty\n"); } memset(buffer, 0, RRC_BUF_SIZE); - - size = do_RRCConnectionReconfiguration(ctxt_pP, - buffer, - xid, - (LTE_SRB_ToAddModList_t*)NULL, - (LTE_DRB_ToAddModList_t*)*DRB_configList2, - (LTE_DRB_ToReleaseList_t*)NULL, // DRB2_list, - (struct LTE_SPS_Config*)NULL, // *sps_Config, - NULL, NULL, NULL, NULL,NULL, - NULL, NULL, NULL, NULL, NULL, NULL, - (struct LTE_RRCConnectionReconfiguration_r8_IEs__dedicatedInfoNASList*)dedicatedInfoNASList, - (LTE_SL_CommConfig_r12_t*)NULL, - (LTE_SL_DiscConfig_r12_t*)NULL + size = do_RRCConnectionReconfiguration(ctxt_pP, + buffer, + xid, + (LTE_SRB_ToAddModList_t *)NULL, + (LTE_DRB_ToAddModList_t *)*DRB_configList2, + (LTE_DRB_ToReleaseList_t *)NULL, // DRB2_list, + (struct LTE_SPS_Config *)NULL, // *sps_Config, + NULL, NULL, NULL, NULL,NULL, + NULL, NULL, NULL, NULL, NULL, NULL, + (struct LTE_RRCConnectionReconfiguration_r8_IEs__dedicatedInfoNASList *)dedicatedInfoNASList, + (LTE_SL_CommConfig_r12_t *)NULL, + (LTE_SL_DiscConfig_r12_t *)NULL #if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) - , (LTE_SCellToAddMod_r10_t*)NULL + , (LTE_SCellToAddMod_r10_t *)NULL #endif ); - LOG_DUMPMSG(RRC,DEBUG_RRC,(char *)buffer,size,"[MSG] RRC Connection Reconfiguration\n"); - - #if defined(ENABLE_ITTI) /* Free all NAS PDUs */ @@ -2331,16 +2192,14 @@ rrc_eNB_generate_dedicatedRRCConnectionReconfiguration(const protocol_ctxt_t* co ue_context_pP->ue_context.e_rab[i].param.nas_pdu.buffer = NULL; } } -#endif - LOG_I(RRC, +#endif + LOG_I(RRC, "[eNB %d] Frame %d, Logical Channel DL-DCCH, Generate LTE_RRCConnectionReconfiguration (bytes %d, UE RNTI %x)\n", ctxt_pP->module_id, ctxt_pP->frame, size, ue_context_pP->ue_context.rnti); - LOG_D(RRC, "[FRAME %05d][RRC_eNB][MOD %u][][--- PDCP_DATA_REQ/%d Bytes (rrcConnectionReconfiguration to UE %x MUI %d) --->][PDCP][MOD %u][RB %u]\n", ctxt_pP->frame, ctxt_pP->module_id, size, ue_context_pP->ue_context.rnti, rrc_eNB_mui, ctxt_pP->module_id, DCCH); - MSC_LOG_TX_MESSAGE( MSC_RRC_ENB, MSC_RRC_UE, @@ -2351,7 +2210,6 @@ rrc_eNB_generate_dedicatedRRCConnectionReconfiguration(const protocol_ctxt_t* co ue_context_pP->ue_context.rnti, rrc_eNB_mui, size); - rrc_data_req( ctxt_pP, DCCH, @@ -2360,20 +2218,17 @@ rrc_eNB_generate_dedicatedRRCConnectionReconfiguration(const protocol_ctxt_t* co size, buffer, PDCP_TRANSMISSION_MODE_CONTROL); - - } int -rrc_eNB_modify_dedicatedRRCConnectionReconfiguration(const protocol_ctxt_t* const ctxt_pP, - rrc_eNB_ue_context_t* const ue_context_pP, - const uint8_t ho_state - ) +rrc_eNB_modify_dedicatedRRCConnectionReconfiguration(const protocol_ctxt_t *const ctxt_pP, + rrc_eNB_ue_context_t *const ue_context_pP, + const uint8_t ho_state + ) //----------------------------------------------------------------------------- { uint8_t buffer[RRC_BUF_SIZE]; uint16_t size; int i, j; - struct LTE_DRB_ToAddMod *DRB_config = NULL; struct LTE_RLC_Config *DRB_rlc_config = NULL; struct LTE_PDCP_Config *DRB_pdcp_config = NULL; @@ -2381,15 +2236,13 @@ rrc_eNB_modify_dedicatedRRCConnectionReconfiguration(const protocol_ctxt_t* cons struct LTE_PDCP_Config__rlc_UM *PDCP_rlc_UM = NULL; struct LTE_LogicalChannelConfig *DRB_lchan_config = NULL; struct LTE_LogicalChannelConfig__ul_SpecificParameters - *DRB_ul_SpecificParameters = NULL; - LTE_DRB_ToAddModList_t* DRB_configList = ue_context_pP->ue_context.DRB_configList; - LTE_DRB_ToAddModList_t* DRB_configList2 = NULL; - + *DRB_ul_SpecificParameters = NULL; + LTE_DRB_ToAddModList_t *DRB_configList = ue_context_pP->ue_context.DRB_configList; + LTE_DRB_ToAddModList_t *DRB_configList2 = NULL; struct LTE_RRCConnectionReconfiguration_r8_IEs__dedicatedInfoNASList *dedicatedInfoNASList = NULL; LTE_DedicatedInfoNAS_t *dedicatedInfoNas = NULL; /* for no gcc warnings */ (void)dedicatedInfoNas; - uint8_t xid = rrc_eNB_get_next_transaction_identifier(ctxt_pP->module_id); // Transaction_id, DRB_configList2 = CALLOC(1, sizeof(*DRB_configList2)); /* Initialize NAS list */ @@ -2410,6 +2263,7 @@ rrc_eNB_modify_dedicatedRRCConnectionReconfiguration(const protocol_ctxt_t* cons } DRB_config = NULL; + // search exist DRB_config for (j = 0; j < DRB_configList->list.count; j++) { if((uint8_t)*(DRB_configList->list.array[j]->eps_BearerIdentity) == ue_context_pP->ue_context.modify_e_rab[i].param.e_rab_id) { @@ -2417,6 +2271,7 @@ rrc_eNB_modify_dedicatedRRCConnectionReconfiguration(const protocol_ctxt_t* cons break; } } + if (NULL == DRB_config) { ue_context_pP->ue_context.modify_e_rab[i].xid = xid; ue_context_pP->ue_context.modify_e_rab[i].status = E_RAB_STATUS_FAILED; @@ -2428,85 +2283,89 @@ rrc_eNB_modify_dedicatedRRCConnectionReconfiguration(const protocol_ctxt_t* cons } DRB_rlc_config = DRB_config->rlc_Config; - DRB_pdcp_config = DRB_config->pdcp_Config; *DRB_pdcp_config->discardTimer = LTE_PDCP_Config__discardTimer_infinity; + switch (ue_context_pP->ue_context.modify_e_rab[i].param.qos.qci) { - /* - * type: realtime data with medium packer error rate - * action: swtich to RLC UM - */ - case 1: // 100ms, 10^-2, p2, GBR - case 2: // 150ms, 10^-3, p4, GBR - case 3: // 50ms, 10^-3, p3, GBR - case 4: // 300ms, 10^-6, p5 - case 7: // 100ms, 10^-3, p7, GBR - case 9: // 300ms, 10^-6, p9 - case 65: // 75ms, 10^-2, p0.7, mission critical voice, GBR - case 66: // 100ms, 10^-2, p2, non-mission critical voice , GBR - // RLC - DRB_rlc_config->present = LTE_RLC_Config_PR_um_Bi_Directional; - DRB_rlc_config->choice.um_Bi_Directional.ul_UM_RLC.sn_FieldLength = LTE_SN_FieldLength_size10; - DRB_rlc_config->choice.um_Bi_Directional.dl_UM_RLC.sn_FieldLength = LTE_SN_FieldLength_size10; - DRB_rlc_config->choice.um_Bi_Directional.dl_UM_RLC.t_Reordering = LTE_T_Reordering_ms35; - // PDCP - if (DRB_pdcp_config->rlc_AM) { - free(DRB_pdcp_config->rlc_AM); - DRB_pdcp_config->rlc_AM = NULL; - } - if (DRB_pdcp_config->rlc_UM) { - free(DRB_pdcp_config->rlc_UM); - DRB_pdcp_config->rlc_UM = NULL; - } - PDCP_rlc_UM = CALLOC(1, sizeof(*PDCP_rlc_UM)); - DRB_pdcp_config->rlc_UM = PDCP_rlc_UM; - PDCP_rlc_UM->pdcp_SN_Size = LTE_PDCP_Config__rlc_UM__pdcp_SN_Size_len12bits; - break; + /* + * type: realtime data with medium packer error rate + * action: swtich to RLC UM + */ + case 1: // 100ms, 10^-2, p2, GBR + case 2: // 150ms, 10^-3, p4, GBR + case 3: // 50ms, 10^-3, p3, GBR + case 4: // 300ms, 10^-6, p5 + case 7: // 100ms, 10^-3, p7, GBR + case 9: // 300ms, 10^-6, p9 + case 65: // 75ms, 10^-2, p0.7, mission critical voice, GBR + case 66: // 100ms, 10^-2, p2, non-mission critical voice , GBR + // RLC + DRB_rlc_config->present = LTE_RLC_Config_PR_um_Bi_Directional; + DRB_rlc_config->choice.um_Bi_Directional.ul_UM_RLC.sn_FieldLength = LTE_SN_FieldLength_size10; + DRB_rlc_config->choice.um_Bi_Directional.dl_UM_RLC.sn_FieldLength = LTE_SN_FieldLength_size10; + DRB_rlc_config->choice.um_Bi_Directional.dl_UM_RLC.t_Reordering = LTE_T_Reordering_ms35; - /* - * type: non-realtime data with low packer error rate - * action: swtich to RLC AM - */ - case 5: // 100ms, 10^-6, p1 , IMS signaling - case 6: // 300ms, 10^-6, p6 - case 8: // 300ms, 10^-6, p8 - case 69: // 60ms, 10^-6, p0.5, mission critical delay sensitive data, Lowest Priority - case 70: // 200ms, 10^-6, p5.5, mision critical data - // RLC - DRB_rlc_config->present = LTE_RLC_Config_PR_am; - DRB_rlc_config->choice.am.ul_AM_RLC.t_PollRetransmit = LTE_T_PollRetransmit_ms50; - DRB_rlc_config->choice.am.ul_AM_RLC.pollPDU = LTE_PollPDU_p16; - DRB_rlc_config->choice.am.ul_AM_RLC.pollByte = LTE_PollByte_kBinfinity; - DRB_rlc_config->choice.am.ul_AM_RLC.maxRetxThreshold = LTE_UL_AM_RLC__maxRetxThreshold_t8; - DRB_rlc_config->choice.am.dl_AM_RLC.t_Reordering = LTE_T_Reordering_ms35; - DRB_rlc_config->choice.am.dl_AM_RLC.t_StatusProhibit = LTE_T_StatusProhibit_ms25; + // PDCP + if (DRB_pdcp_config->rlc_AM) { + free(DRB_pdcp_config->rlc_AM); + DRB_pdcp_config->rlc_AM = NULL; + } - // PDCP - if (DRB_pdcp_config->rlc_AM) { - free(DRB_pdcp_config->rlc_AM); - DRB_pdcp_config->rlc_AM = NULL; - } - if (DRB_pdcp_config->rlc_UM) { - free(DRB_pdcp_config->rlc_UM); - DRB_pdcp_config->rlc_UM = NULL; - } - PDCP_rlc_AM = CALLOC(1, sizeof(*PDCP_rlc_AM)); - DRB_pdcp_config->rlc_AM = PDCP_rlc_AM; - PDCP_rlc_AM->statusReportRequired = FALSE; + if (DRB_pdcp_config->rlc_UM) { + free(DRB_pdcp_config->rlc_UM); + DRB_pdcp_config->rlc_UM = NULL; + } - break; - default : - LOG_E(RRC, "not supported qci %d\n", ue_context_pP->ue_context.modify_e_rab[i].param.qos.qci); - ue_context_pP->ue_context.modify_e_rab[i].status = E_RAB_STATUS_FAILED; - ue_context_pP->ue_context.modify_e_rab[i].xid = xid; - ue_context_pP->ue_context.modify_e_rab[i].cause = S1AP_CAUSE_RADIO_NETWORK; - ue_context_pP->ue_context.modify_e_rab[i].cause_value = 37;//S1ap_CauseRadioNetwork_not_supported_QCI_value; - ue_context_pP->ue_context.nb_of_failed_e_rabs++; - continue; + PDCP_rlc_UM = CALLOC(1, sizeof(*PDCP_rlc_UM)); + DRB_pdcp_config->rlc_UM = PDCP_rlc_UM; + PDCP_rlc_UM->pdcp_SN_Size = LTE_PDCP_Config__rlc_UM__pdcp_SN_Size_len12bits; + break; + + /* + * type: non-realtime data with low packer error rate + * action: swtich to RLC AM + */ + case 5: // 100ms, 10^-6, p1 , IMS signaling + case 6: // 300ms, 10^-6, p6 + case 8: // 300ms, 10^-6, p8 + case 69: // 60ms, 10^-6, p0.5, mission critical delay sensitive data, Lowest Priority + case 70: // 200ms, 10^-6, p5.5, mision critical data + // RLC + DRB_rlc_config->present = LTE_RLC_Config_PR_am; + DRB_rlc_config->choice.am.ul_AM_RLC.t_PollRetransmit = LTE_T_PollRetransmit_ms50; + DRB_rlc_config->choice.am.ul_AM_RLC.pollPDU = LTE_PollPDU_p16; + DRB_rlc_config->choice.am.ul_AM_RLC.pollByte = LTE_PollByte_kBinfinity; + DRB_rlc_config->choice.am.ul_AM_RLC.maxRetxThreshold = LTE_UL_AM_RLC__maxRetxThreshold_t8; + DRB_rlc_config->choice.am.dl_AM_RLC.t_Reordering = LTE_T_Reordering_ms35; + DRB_rlc_config->choice.am.dl_AM_RLC.t_StatusProhibit = LTE_T_StatusProhibit_ms25; + + // PDCP + if (DRB_pdcp_config->rlc_AM) { + free(DRB_pdcp_config->rlc_AM); + DRB_pdcp_config->rlc_AM = NULL; + } + + if (DRB_pdcp_config->rlc_UM) { + free(DRB_pdcp_config->rlc_UM); + DRB_pdcp_config->rlc_UM = NULL; + } + + PDCP_rlc_AM = CALLOC(1, sizeof(*PDCP_rlc_AM)); + DRB_pdcp_config->rlc_AM = PDCP_rlc_AM; + PDCP_rlc_AM->statusReportRequired = FALSE; + break; + + default : + LOG_E(RRC, "not supported qci %d\n", ue_context_pP->ue_context.modify_e_rab[i].param.qos.qci); + ue_context_pP->ue_context.modify_e_rab[i].status = E_RAB_STATUS_FAILED; + ue_context_pP->ue_context.modify_e_rab[i].xid = xid; + ue_context_pP->ue_context.modify_e_rab[i].cause = S1AP_CAUSE_RADIO_NETWORK; + ue_context_pP->ue_context.modify_e_rab[i].cause_value = 37;//S1ap_CauseRadioNetwork_not_supported_QCI_value; + ue_context_pP->ue_context.nb_of_failed_e_rabs++; + continue; } DRB_pdcp_config->headerCompression.present = LTE_PDCP_Config__headerCompression_PR_notUsed; - DRB_lchan_config = DRB_config->logicalChannelConfig; DRB_ul_SpecificParameters = DRB_lchan_config->ul_SpecificParameters; @@ -2516,36 +2375,30 @@ rrc_eNB_modify_dedicatedRRCConnectionReconfiguration(const protocol_ctxt_t* cons DRB_ul_SpecificParameters->priority= 4; DRB_ul_SpecificParameters->prioritisedBitRate = LTE_LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_kBps8; - DRB_ul_SpecificParameters->bucketSizeDuration = LTE_LogicalChannelConfig__ul_SpecificParameters__bucketSizeDuration_ms50; - ASN_SEQUENCE_ADD(&(DRB_configList2)->list, DRB_config); - LOG_I(RRC, "EPS ID %ld, DRB ID %ld (index %d), QCI %d, priority %ld, LCID %ld LCGID %ld \n", - *DRB_config->eps_BearerIdentity, - DRB_config->drb_Identity, i, - ue_context_pP->ue_context.modify_e_rab[i].param.qos.qci, - DRB_ul_SpecificParameters->priority, - *(DRB_config->logicalChannelIdentity), - *DRB_ul_SpecificParameters->logicalChannelGroup - ); - + *DRB_config->eps_BearerIdentity, + DRB_config->drb_Identity, i, + ue_context_pP->ue_context.modify_e_rab[i].param.qos.qci, + DRB_ul_SpecificParameters->priority, + *(DRB_config->logicalChannelIdentity), + *DRB_ul_SpecificParameters->logicalChannelGroup + ); //e_rab_done++; ue_context_pP->ue_context.modify_e_rab[i].status = E_RAB_STATUS_DONE; ue_context_pP->ue_context.modify_e_rab[i].xid = xid; - { if (ue_context_pP->ue_context.modify_e_rab[i].param.nas_pdu.buffer != NULL) { dedicatedInfoNas = CALLOC(1, sizeof(LTE_DedicatedInfoNAS_t)); memset(dedicatedInfoNas, 0, sizeof(OCTET_STRING_t)); OCTET_STRING_fromBuf(dedicatedInfoNas, - (char*)ue_context_pP->ue_context.modify_e_rab[i].param.nas_pdu.buffer, - ue_context_pP->ue_context.modify_e_rab[i].param.nas_pdu.length); + (char *)ue_context_pP->ue_context.modify_e_rab[i].param.nas_pdu.buffer, + ue_context_pP->ue_context.modify_e_rab[i].param.nas_pdu.length); ASN_SEQUENCE_ADD(&dedicatedInfoNASList->list, dedicatedInfoNas); LOG_I(RRC, "add NAS info with size %d (rab id %d)\n",ue_context_pP->ue_context.modify_e_rab[i].param.nas_pdu.length, i); - } - else { + } else { LOG_W(RRC, "Not received activate dedicated EPS bearer context request\n"); } } @@ -2563,27 +2416,24 @@ rrc_eNB_modify_dedicatedRRCConnectionReconfiguration(const protocol_ctxt_t* cons } memset(buffer, 0, RRC_BUF_SIZE); - - size = do_RRCConnectionReconfiguration(ctxt_pP, - buffer, - xid, - (LTE_SRB_ToAddModList_t*)NULL, - (LTE_DRB_ToAddModList_t*)DRB_configList2, - (LTE_DRB_ToReleaseList_t*)NULL, // DRB2_list, - (struct LTE_SPS_Config*)NULL, // *sps_Config, - NULL, NULL, NULL, NULL,NULL, - NULL, NULL, NULL, NULL, NULL, NULL, - (struct LTE_RRCConnectionReconfiguration_r8_IEs__dedicatedInfoNASList*)dedicatedInfoNASList, - (LTE_SL_CommConfig_r12_t*)NULL, - (LTE_SL_DiscConfig_r12_t*)NULL + size = do_RRCConnectionReconfiguration(ctxt_pP, + buffer, + xid, + (LTE_SRB_ToAddModList_t *)NULL, + (LTE_DRB_ToAddModList_t *)DRB_configList2, + (LTE_DRB_ToReleaseList_t *)NULL, // DRB2_list, + (struct LTE_SPS_Config *)NULL, // *sps_Config, + NULL, NULL, NULL, NULL,NULL, + NULL, NULL, NULL, NULL, NULL, NULL, + (struct LTE_RRCConnectionReconfiguration_r8_IEs__dedicatedInfoNASList *)dedicatedInfoNASList, + (LTE_SL_CommConfig_r12_t *)NULL, + (LTE_SL_DiscConfig_r12_t *)NULL #if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) - , (LTE_SCellToAddMod_r10_t*)NULL + , (LTE_SCellToAddMod_r10_t *)NULL #endif - ); - + ); LOG_DUMPMSG(RRC,DEBUG_RRC,(char *)buffer,size, "[MSG] RRC Connection Reconfiguration\n"); - #if defined(ENABLE_ITTI) /* Free all NAS PDUs */ @@ -2594,16 +2444,14 @@ rrc_eNB_modify_dedicatedRRCConnectionReconfiguration(const protocol_ctxt_t* cons ue_context_pP->ue_context.modify_e_rab[i].param.nas_pdu.buffer = NULL; } } -#endif - LOG_I(RRC, +#endif + LOG_I(RRC, "[eNB %d] Frame %d, Logical Channel DL-DCCH, Generate LTE_RRCConnectionReconfiguration (bytes %d, UE RNTI %x)\n", ctxt_pP->module_id, ctxt_pP->frame, size, ue_context_pP->ue_context.rnti); - LOG_D(RRC, "[FRAME %05d][RRC_eNB][MOD %u][][--- PDCP_DATA_REQ/%d Bytes (rrcConnectionReconfiguration to UE %x MUI %d) --->][PDCP][MOD %u][RB %u]\n", ctxt_pP->frame, ctxt_pP->module_id, size, ue_context_pP->ue_context.rnti, rrc_eNB_mui, ctxt_pP->module_id, DCCH); - MSC_LOG_TX_MESSAGE( MSC_RRC_ENB, MSC_RRC_UE, @@ -2614,7 +2462,6 @@ rrc_eNB_modify_dedicatedRRCConnectionReconfiguration(const protocol_ctxt_t* cons ue_context_pP->ue_context.rnti, rrc_eNB_mui, size); - rrc_data_req( ctxt_pP, DCCH, @@ -2628,96 +2475,95 @@ rrc_eNB_modify_dedicatedRRCConnectionReconfiguration(const protocol_ctxt_t* cons //----------------------------------------------------------------------------- void -rrc_eNB_generate_dedicatedRRCConnectionReconfiguration_release( const protocol_ctxt_t* const ctxt_pP, - rrc_eNB_ue_context_t* const ue_context_pP, - uint8_t xid, - uint32_t nas_length, - uint8_t* nas_buffer) +rrc_eNB_generate_dedicatedRRCConnectionReconfiguration_release( const protocol_ctxt_t *const ctxt_pP, + rrc_eNB_ue_context_t *const ue_context_pP, + uint8_t xid, + uint32_t nas_length, + uint8_t *nas_buffer) //----------------------------------------------------------------------------- { - uint8_t buffer[RRC_BUF_SIZE]; - int i; - uint16_t size = 0; - LTE_DRB_ToReleaseList_t** DRB_Release_configList2=NULL; - LTE_DRB_Identity_t* DRB_release; - struct LTE_RRCConnectionReconfiguration_r8_IEs__dedicatedInfoNASList *dedicatedInfoNASList = NULL; + uint8_t buffer[RRC_BUF_SIZE]; + int i; + uint16_t size = 0; + LTE_DRB_ToReleaseList_t **DRB_Release_configList2=NULL; + LTE_DRB_Identity_t *DRB_release; + struct LTE_RRCConnectionReconfiguration_r8_IEs__dedicatedInfoNASList *dedicatedInfoNASList = NULL; + DRB_Release_configList2=&ue_context_pP->ue_context.DRB_Release_configList2[xid]; - DRB_Release_configList2=&ue_context_pP->ue_context.DRB_Release_configList2[xid]; - if (*DRB_Release_configList2) { - free(*DRB_Release_configList2); + if (*DRB_Release_configList2) { + free(*DRB_Release_configList2); + } + + *DRB_Release_configList2 = CALLOC(1, sizeof(**DRB_Release_configList2)); + + for(i = 0; i < NB_RB_MAX; i++) { + if((ue_context_pP->ue_context.e_rab[i].status == E_RAB_STATUS_TORELEASE) && ue_context_pP->ue_context.e_rab[i].xid == xid) { + DRB_release = CALLOC(1, sizeof(LTE_DRB_Identity_t)); + *DRB_release = i+1; + ASN_SEQUENCE_ADD(&(*DRB_Release_configList2)->list, DRB_release); + //free(DRB_release); } - *DRB_Release_configList2 = CALLOC(1, sizeof(**DRB_Release_configList2)); + } - for(i = 0; i < NB_RB_MAX; i++){ - if((ue_context_pP->ue_context.e_rab[i].status == E_RAB_STATUS_TORELEASE) && ue_context_pP->ue_context.e_rab[i].xid == xid){ - DRB_release = CALLOC(1, sizeof(LTE_DRB_Identity_t)); - *DRB_release = i+1; - ASN_SEQUENCE_ADD(&(*DRB_Release_configList2)->list, DRB_release); - //free(DRB_release); - } - } + /* If list is empty free the list and reset the address */ + if (nas_length > 0) { + LTE_DedicatedInfoNAS_t *dedicatedInfoNas = NULL; + dedicatedInfoNASList = CALLOC(1, sizeof(struct LTE_RRCConnectionReconfiguration_r8_IEs__dedicatedInfoNASList)); + dedicatedInfoNas = CALLOC(1, sizeof(LTE_DedicatedInfoNAS_t)); + memset(dedicatedInfoNas, 0, sizeof(OCTET_STRING_t)); + OCTET_STRING_fromBuf(dedicatedInfoNas, + (char *)nas_buffer, + nas_length); + ASN_SEQUENCE_ADD(&dedicatedInfoNASList->list, dedicatedInfoNas); + LOG_I(RRC,"add NAS info with size %d\n",nas_length); + } else { + LOG_W(RRC,"dedlicated NAS list is empty\n"); + } - /* If list is empty free the list and reset the address */ - if (nas_length > 0) { - LTE_DedicatedInfoNAS_t *dedicatedInfoNas = NULL; - dedicatedInfoNASList = CALLOC(1, sizeof(struct LTE_RRCConnectionReconfiguration_r8_IEs__dedicatedInfoNASList)); - dedicatedInfoNas = CALLOC(1, sizeof(LTE_DedicatedInfoNAS_t)); - memset(dedicatedInfoNas, 0, sizeof(OCTET_STRING_t)); - OCTET_STRING_fromBuf(dedicatedInfoNas, - (char*)nas_buffer, - nas_length); - ASN_SEQUENCE_ADD(&dedicatedInfoNASList->list, dedicatedInfoNas); - LOG_I(RRC,"add NAS info with size %d\n",nas_length); - } else { - LOG_W(RRC,"dedlicated NAS list is empty\n"); - } - - memset(buffer, 0, RRC_BUF_SIZE); - size = do_RRCConnectionReconfiguration(ctxt_pP, - buffer, - xid, - NULL, - NULL, - (LTE_DRB_ToReleaseList_t*)*DRB_Release_configList2, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - (struct LTE_RRCConnectionReconfiguration_r8_IEs__dedicatedInfoNASList*)dedicatedInfoNASList, - (LTE_SL_CommConfig_r12_t*)NULL, - (LTE_SL_DiscConfig_r12_t*)NULL + memset(buffer, 0, RRC_BUF_SIZE); + size = do_RRCConnectionReconfiguration(ctxt_pP, + buffer, + xid, + NULL, + NULL, + (LTE_DRB_ToReleaseList_t *)*DRB_Release_configList2, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + (struct LTE_RRCConnectionReconfiguration_r8_IEs__dedicatedInfoNASList *)dedicatedInfoNASList, + (LTE_SL_CommConfig_r12_t *)NULL, + (LTE_SL_DiscConfig_r12_t *)NULL #if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) - , (LTE_SCellToAddMod_r10_t*)NULL + , (LTE_SCellToAddMod_r10_t *)NULL #endif - ); - ue_context_pP->ue_context.e_rab_release_command_flag = 1; - LOG_DUMPMSG(RRC,DEBUG_RRC,(char *)buffer,size, - "[MSG] RRC Connection Reconfiguration\n"); - + ); + ue_context_pP->ue_context.e_rab_release_command_flag = 1; + LOG_DUMPMSG(RRC,DEBUG_RRC,(char *)buffer,size, + "[MSG] RRC Connection Reconfiguration\n"); #if defined(ENABLE_ITTI) + /* Free all NAS PDUs */ if (nas_length > 0) { - /* Free the NAS PDU buffer and invalidate it */ - free(nas_buffer); + /* Free the NAS PDU buffer and invalidate it */ + free(nas_buffer); } -#endif +#endif LOG_I(RRC, "[eNB %d] Frame %d, Logical Channel DL-DCCH, Generate LTE_RRCConnectionReconfiguration (bytes %d, UE RNTI %x)\n", ctxt_pP->module_id, ctxt_pP->frame, size, ue_context_pP->ue_context.rnti); - LOG_D(RRC, "[FRAME %05d][RRC_eNB][MOD %u][][--- PDCP_DATA_REQ/%d Bytes (rrcConnectionReconfiguration to UE %x MUI %d) --->][PDCP][MOD %u][RB %u]\n", ctxt_pP->frame, ctxt_pP->module_id, size, ue_context_pP->ue_context.rnti, rrc_eNB_mui, ctxt_pP->module_id, DCCH); - MSC_LOG_TX_MESSAGE( MSC_RRC_ENB, MSC_RRC_UE, @@ -2728,7 +2574,6 @@ rrc_eNB_generate_dedicatedRRCConnectionReconfiguration_release( const protocol_ ue_context_pP->ue_context.rnti, rrc_eNB_mui, size); - rrc_data_req( ctxt_pP, DCCH, @@ -2737,33 +2582,29 @@ rrc_eNB_generate_dedicatedRRCConnectionReconfiguration_release( const protocol_ size, buffer, PDCP_TRANSMISSION_MODE_CONTROL); - } -#endif +#endif //----------------------------------------------------------------------------- void -rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt_t* const ctxt_pP, - rrc_eNB_ue_context_t* const ue_context_pP, - const uint8_t ho_state - ) +rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt_t *const ctxt_pP, + rrc_eNB_ue_context_t *const ue_context_pP, + const uint8_t ho_state + ) //----------------------------------------------------------------------------- { uint8_t buffer[RRC_BUF_SIZE]; uint16_t size; int i; - // configure SRB1/SRB2, PhysicalConfigDedicated, LTE_MAC_MainConfig for UE - eNB_RRC_INST* rrc_inst = RC.rrc[ctxt_pP->module_id]; - struct LTE_PhysicalConfigDedicated** physicalConfigDedicated = &ue_context_pP->ue_context.physicalConfigDedicated; - + eNB_RRC_INST *rrc_inst = RC.rrc[ctxt_pP->module_id]; + struct LTE_PhysicalConfigDedicated **physicalConfigDedicated = &ue_context_pP->ue_context.physicalConfigDedicated; struct LTE_SRB_ToAddMod *SRB2_config = NULL; struct LTE_SRB_ToAddMod__rlc_Config *SRB2_rlc_config = NULL; struct LTE_SRB_ToAddMod__logicalChannelConfig *SRB2_lchan_config = NULL; struct LTE_LogicalChannelConfig__ul_SpecificParameters - *SRB2_ul_SpecificParameters = NULL; - LTE_SRB_ToAddModList_t* SRB_configList = ue_context_pP->ue_context.SRB_configList; + *SRB2_ul_SpecificParameters = NULL; + LTE_SRB_ToAddModList_t *SRB_configList = ue_context_pP->ue_context.SRB_configList; LTE_SRB_ToAddModList_t **SRB_configList2 = NULL; - struct LTE_DRB_ToAddMod *DRB_config = NULL; struct LTE_RLC_Config *DRB_rlc_config = NULL; struct LTE_PDCP_Config *DRB_pdcp_config = NULL; @@ -2771,15 +2612,15 @@ rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt_t* cons struct LTE_PDCP_Config__rlc_UM *PDCP_rlc_UM = NULL; struct LTE_LogicalChannelConfig *DRB_lchan_config = NULL; struct LTE_LogicalChannelConfig__ul_SpecificParameters - *DRB_ul_SpecificParameters = NULL; - LTE_DRB_ToAddModList_t** DRB_configList = &ue_context_pP->ue_context.DRB_configList; - LTE_DRB_ToAddModList_t** DRB_configList2 = NULL; + *DRB_ul_SpecificParameters = NULL; + LTE_DRB_ToAddModList_t **DRB_configList = &ue_context_pP->ue_context.DRB_configList; + LTE_DRB_ToAddModList_t **DRB_configList2 = NULL; LTE_MAC_MainConfig_t *mac_MainConfig = NULL; LTE_MeasObjectToAddModList_t *MeasObj_list = NULL; LTE_MeasObjectToAddMod_t *MeasObj = NULL; LTE_ReportConfigToAddModList_t *ReportConfig_list = NULL; LTE_ReportConfigToAddMod_t *ReportConfig_per, *ReportConfig_A1, - *ReportConfig_A2, *ReportConfig_A3, *ReportConfig_A4, *ReportConfig_A5; + *ReportConfig_A2, *ReportConfig_A3, *ReportConfig_A4, *ReportConfig_A5; LTE_MeasIdToAddModList_t *MeasId_list = NULL; LTE_MeasIdToAddMod_t *MeasId0, *MeasId1, *MeasId2, *MeasId3, *MeasId4, *MeasId5; #if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) @@ -2787,10 +2628,8 @@ rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt_t* cons // uint8_t sCellIndexToAdd = rrc_find_free_SCell_index(enb_mod_idP, ue_mod_idP, 1); //uint8_t sCellIndexToAdd = 0; #endif - long *logicalchannelgroup, *logicalchannelgroup_drb; long *maxHARQ_Tx, *periodicBSR_Timer; - LTE_RSRP_Range_t *rsrp = NULL; struct LTE_MeasConfig__speedStatePars *Sparams = NULL; LTE_QuantityConfig_t *quantityConfig = NULL; @@ -2800,11 +2639,8 @@ rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt_t* cons LTE_DedicatedInfoNAS_t *dedicatedInfoNas = NULL; /* for no gcc warnings */ (void)dedicatedInfoNas; - LTE_C_RNTI_t *cba_RNTI = NULL; - uint8_t xid = rrc_eNB_get_next_transaction_identifier(ctxt_pP->module_id); //Transaction_id, - #ifdef CBA //struct PUSCH_CBAConfigDedicated_vlola *pusch_CBAConfigDedicated_vlola; uint8_t *cba_RNTI_buf; @@ -2830,24 +2666,22 @@ rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt_t* cons } #endif - T(T_ENB_RRC_CONNECTION_RECONFIGURATION, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame), T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti)); - // Configure SRB2 /// SRB2 SRB_configList2=&ue_context_pP->ue_context.SRB_configList2[xid]; + if (*SRB_configList2) { free(*SRB_configList2); } + *SRB_configList2 = CALLOC(1, sizeof(**SRB_configList2)); memset(*SRB_configList2, 0, sizeof(**SRB_configList2)); SRB2_config = CALLOC(1, sizeof(*SRB2_config)); - 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 = LTE_SRB_ToAddMod__rlc_Config_PR_explicitValue; SRB2_rlc_config->choice.explicitValue.present = LTE_RLC_Config_PR_am; SRB2_rlc_config->choice.explicitValue.choice.am.ul_AM_RLC.t_PollRetransmit = LTE_T_PollRetransmit_ms15; @@ -2856,26 +2690,19 @@ rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt_t* cons SRB2_rlc_config->choice.explicitValue.choice.am.ul_AM_RLC.maxRetxThreshold = LTE_UL_AM_RLC__maxRetxThreshold_t32; SRB2_rlc_config->choice.explicitValue.choice.am.dl_AM_RLC.t_Reordering = LTE_T_Reordering_ms35; SRB2_rlc_config->choice.explicitValue.choice.am.dl_AM_RLC.t_StatusProhibit = LTE_T_StatusProhibit_ms10; - SRB2_lchan_config = CALLOC(1, sizeof(*SRB2_lchan_config)); SRB2_config->logicalChannelConfig = SRB2_lchan_config; - SRB2_lchan_config->present = LTE_SRB_ToAddMod__logicalChannelConfig_PR_explicitValue; - SRB2_ul_SpecificParameters = CALLOC(1, sizeof(*SRB2_ul_SpecificParameters)); - SRB2_ul_SpecificParameters->priority = 3; // let some priority for SRB1 and dedicated DRBs SRB2_ul_SpecificParameters->prioritisedBitRate = LTE_LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_infinity; SRB2_ul_SpecificParameters->bucketSizeDuration = LTE_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; // this list has the configuration for SRB1 and SRB2 ASN_SEQUENCE_ADD(&SRB_configList->list, SRB2_config); @@ -2888,21 +2715,20 @@ rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt_t* cons if (*DRB_configList) { free(*DRB_configList); } + *DRB_configList = CALLOC(1, sizeof(**DRB_configList)); memset(*DRB_configList, 0, sizeof(**DRB_configList)); - // list for the configured DRB for a this xid DRB_configList2=&ue_context_pP->ue_context.DRB_configList2[xid]; + if (*DRB_configList2) { free(*DRB_configList2); } + *DRB_configList2 = CALLOC(1, sizeof(**DRB_configList2)); memset(*DRB_configList2, 0, sizeof(**DRB_configList2)); - - /// DRB DRB_config = CALLOC(1, sizeof(*DRB_config)); - DRB_config->eps_BearerIdentity = CALLOC(1, sizeof(long)); *(DRB_config->eps_BearerIdentity) = 5L; // LW set to first value, allowed value 5..15, value : x+4 // DRB_config->drb_Identity = (LTE_DRB_Identity_t) 1; //allowed values 1..32 @@ -2912,7 +2738,6 @@ rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt_t* cons *(DRB_config->logicalChannelIdentity) = (long)3; // value : x+2 DRB_rlc_config = CALLOC(1, sizeof(*DRB_rlc_config)); DRB_config->rlc_Config = DRB_rlc_config; - #ifdef RRC_DEFAULT_RAB_IS_AM DRB_rlc_config->present = LTE_RLC_Config_PR_am; DRB_rlc_config->choice.am.ul_AM_RLC.t_PollRetransmit = LTE_T_PollRetransmit_ms50; @@ -2931,18 +2756,15 @@ rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt_t* cons DRB_rlc_config->choice.um_Bi_Directional.dl_UM_RLC.t_Reordering = LTE_T_Reordering_ms35; #endif #endif - DRB_pdcp_config = CALLOC(1, sizeof(*DRB_pdcp_config)); DRB_config->pdcp_Config = DRB_pdcp_config; DRB_pdcp_config->discardTimer = CALLOC(1, sizeof(long)); *DRB_pdcp_config->discardTimer = LTE_PDCP_Config__discardTimer_infinity; DRB_pdcp_config->rlc_AM = NULL; DRB_pdcp_config->rlc_UM = NULL; - /* avoid gcc warnings */ (void)PDCP_rlc_AM; (void)PDCP_rlc_UM; - #ifdef RRC_DEFAULT_RAB_IS_AM // EXMIMO_IOT PDCP_rlc_AM = CALLOC(1, sizeof(*PDCP_rlc_AM)); DRB_pdcp_config->rlc_AM = PDCP_rlc_AM; @@ -2953,33 +2775,25 @@ rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt_t* cons PDCP_rlc_UM->pdcp_SN_Size = LTE_PDCP_Config__rlc_UM__pdcp_SN_Size_len12bits; #endif DRB_pdcp_config->headerCompression.present = LTE_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 = 12; // lower priority than srb1, srb2 and other dedicated bearer DRB_ul_SpecificParameters->prioritisedBitRate =LTE_LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_kBps8 ; - //LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_infinity; + //LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_infinity; DRB_ul_SpecificParameters->bucketSizeDuration = LTE_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); ASN_SEQUENCE_ADD(&(*DRB_configList2)->list, DRB_config); - //ue_context_pP->ue_context.DRB_configList2[0] = &(*DRB_configList); - mac_MainConfig = CALLOC(1, sizeof(*mac_MainConfig)); ue_context_pP->ue_context.mac_MainConfig = mac_MainConfig; - mac_MainConfig->ul_SCH_Config = CALLOC(1, sizeof(*mac_MainConfig->ul_SCH_Config)); - maxHARQ_Tx = CALLOC(1, sizeof(long)); *maxHARQ_Tx = LTE_MAC_MainConfig__ul_SCH_Config__maxHARQ_Tx_n5; mac_MainConfig->ul_SCH_Config->maxHARQ_Tx = maxHARQ_Tx; @@ -2988,20 +2802,13 @@ rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt_t* cons mac_MainConfig->ul_SCH_Config->periodicBSR_Timer = periodicBSR_Timer; mac_MainConfig->ul_SCH_Config->retxBSR_Timer = LTE_RetxBSR_Timer_r12_sf320; mac_MainConfig->ul_SCH_Config->ttiBundling = 0; // FALSE - mac_MainConfig->timeAlignmentTimerDedicated = LTE_TimeAlignmentTimer_infinity; - mac_MainConfig->drx_Config = NULL; - mac_MainConfig->phr_Config = CALLOC(1, sizeof(*mac_MainConfig->phr_Config)); - mac_MainConfig->phr_Config->present = LTE_MAC_MainConfig__phr_Config_PR_setup; mac_MainConfig->phr_Config->choice.setup.periodicPHR_Timer = LTE_MAC_MainConfig__phr_Config__setup__periodicPHR_Timer_sf20; // sf20 = 20 subframes - mac_MainConfig->phr_Config->choice.setup.prohibitPHR_Timer = LTE_MAC_MainConfig__phr_Config__setup__prohibitPHR_Timer_sf20; // sf20 = 20 subframes - mac_MainConfig->phr_Config->choice.setup.dl_PathlossChange = LTE_MAC_MainConfig__phr_Config__setup__dl_PathlossChange_dB1; // Value dB1 =1 dB, dB3 = 3 dB - #if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) 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 @@ -3017,124 +2824,108 @@ rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt_t* cons if ((*physicalConfigDedicated)->antennaInfo) { (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.transmissionMode = rrc_inst->configuration.ue_TransmissionMode[0]; LOG_D(RRC,"Setting transmission mode to %ld+1\n",rrc_inst->configuration.ue_TransmissionMode[0]); - if (rrc_inst->configuration.ue_TransmissionMode[0] == LTE_AntennaInfoDedicated__transmissionMode_tm3) { - (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction= - CALLOC(1,sizeof(LTE_AntennaInfoDedicated__codebookSubsetRestriction_PR)); - (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->present = - LTE_AntennaInfoDedicated__codebookSubsetRestriction_PR_n2TxAntenna_tm3; - (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm3.buf= MALLOC(1); - (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm3.buf[0] = 0xc0; - (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm3.size=1; - (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm3.bits_unused=6; - } - else if (rrc_inst->configuration.ue_TransmissionMode[0] == LTE_AntennaInfoDedicated__transmissionMode_tm4) { - (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction= - CALLOC(1,sizeof(LTE_AntennaInfoDedicated__codebookSubsetRestriction_PR)); - (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->present = - LTE_AntennaInfoDedicated__codebookSubsetRestriction_PR_n2TxAntenna_tm4; - (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm4.buf= MALLOC(1); - (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm4.buf[0] = 0xfc; - (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm4.size=1; - (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm4.bits_unused=2; + if (rrc_inst->configuration.ue_TransmissionMode[0] == LTE_AntennaInfoDedicated__transmissionMode_tm3) { + (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction= + CALLOC(1,sizeof(LTE_AntennaInfoDedicated__codebookSubsetRestriction_PR)); + (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->present = + LTE_AntennaInfoDedicated__codebookSubsetRestriction_PR_n2TxAntenna_tm3; + (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm3.buf= MALLOC(1); + (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm3.buf[0] = 0xc0; + (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm3.size=1; + (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm3.bits_unused=6; + } else if (rrc_inst->configuration.ue_TransmissionMode[0] == LTE_AntennaInfoDedicated__transmissionMode_tm4) { + (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction= + CALLOC(1,sizeof(LTE_AntennaInfoDedicated__codebookSubsetRestriction_PR)); + (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->present = + LTE_AntennaInfoDedicated__codebookSubsetRestriction_PR_n2TxAntenna_tm4; + (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm4.buf= MALLOC(1); + (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm4.buf[0] = 0xfc; + (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm4.size=1; + (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm4.bits_unused=2; + } else if (rrc_inst->configuration.ue_TransmissionMode[0] == LTE_AntennaInfoDedicated__transmissionMode_tm5) { + (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction= + CALLOC(1,sizeof(LTE_AntennaInfoDedicated__codebookSubsetRestriction_PR)); + (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->present = + LTE_AntennaInfoDedicated__codebookSubsetRestriction_PR_n2TxAntenna_tm5; + (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm5.buf= MALLOC(1); + (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm5.buf[0] = 0xf0; + (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm5.size=1; + (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm5.bits_unused=4; + } else if (rrc_inst->configuration.ue_TransmissionMode[0] == LTE_AntennaInfoDedicated__transmissionMode_tm6) { + (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction= + CALLOC(1,sizeof(LTE_AntennaInfoDedicated__codebookSubsetRestriction_PR)); + (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->present = + LTE_AntennaInfoDedicated__codebookSubsetRestriction_PR_n2TxAntenna_tm6; + (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm6.buf= MALLOC(1); + (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm6.buf[0] = 0xf0; + (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm6.size=1; + (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm6.bits_unused=4; } - else if (rrc_inst->configuration.ue_TransmissionMode[0] == LTE_AntennaInfoDedicated__transmissionMode_tm5) { - (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction= - CALLOC(1,sizeof(LTE_AntennaInfoDedicated__codebookSubsetRestriction_PR)); - (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->present = - LTE_AntennaInfoDedicated__codebookSubsetRestriction_PR_n2TxAntenna_tm5; - (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm5.buf= MALLOC(1); - (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm5.buf[0] = 0xf0; - (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm5.size=1; - (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm5.bits_unused=4; - } - else if (rrc_inst->configuration.ue_TransmissionMode[0] == LTE_AntennaInfoDedicated__transmissionMode_tm6) { - (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction= - CALLOC(1,sizeof(LTE_AntennaInfoDedicated__codebookSubsetRestriction_PR)); - (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->present = - LTE_AntennaInfoDedicated__codebookSubsetRestriction_PR_n2TxAntenna_tm6; - (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm6.buf= MALLOC(1); - (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm6.buf[0] = 0xf0; - (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm6.size=1; - (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm6.bits_unused=4; - } - } - else { + } else { LOG_E(RRC,"antenna_info not present in physical_config_dedicated. Not reconfiguring!\n"); } + if ((*physicalConfigDedicated)->cqi_ReportConfig) { if ((rrc_inst->configuration.ue_TransmissionMode[0] == LTE_AntennaInfoDedicated__transmissionMode_tm4) || - (rrc_inst->configuration.ue_TransmissionMode[0] == LTE_AntennaInfoDedicated__transmissionMode_tm5) || - (rrc_inst->configuration.ue_TransmissionMode[0] == LTE_AntennaInfoDedicated__transmissionMode_tm6)) { - //feedback mode needs to be set as well - //TODO: I think this is taken into account in the PHY automatically based on the transmission mode variable - printf("setting cqi reporting mode to rm31\n"); + (rrc_inst->configuration.ue_TransmissionMode[0] == LTE_AntennaInfoDedicated__transmissionMode_tm5) || + (rrc_inst->configuration.ue_TransmissionMode[0] == LTE_AntennaInfoDedicated__transmissionMode_tm6)) { + //feedback mode needs to be set as well + //TODO: I think this is taken into account in the PHY automatically based on the transmission mode variable + printf("setting cqi reporting mode to rm31\n"); #if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) - *((*physicalConfigDedicated)->cqi_ReportConfig->cqi_ReportModeAperiodic)=LTE_CQI_ReportModeAperiodic_rm31; + *((*physicalConfigDedicated)->cqi_ReportConfig->cqi_ReportModeAperiodic)=LTE_CQI_ReportModeAperiodic_rm31; #else - *((*physicalConfigDedicated)->cqi_ReportConfig->cqi_ReportModeAperiodic)=LTE_CQI_ReportConfig__cqi_ReportModeAperiodic_rm31; // HLC CQI, no PMI + *((*physicalConfigDedicated)->cqi_ReportConfig->cqi_ReportModeAperiodic)=LTE_CQI_ReportConfig__cqi_ReportModeAperiodic_rm31; // HLC CQI, no PMI #endif } - } - else { + } else { LOG_E(RRC,"cqi_ReportConfig not present in physical_config_dedicated. Not reconfiguring!\n"); } - } - else { + } else { LOG_E(RRC,"physical_config_dedicated not present in LTE_RRCConnectionReconfiguration. Not reconfiguring!\n"); } // 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); - // LTE_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 = LTE_MeasObjectToAddMod__measObject_PR_measObjectEUTRA; MeasObj->measObject.choice.measObjectEUTRA.carrierFreq = 3350; //band 7, 2.68GHz @@ -3146,10 +2937,8 @@ rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt_t* cons 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 = (LTE_CellsToAddModList_t *) CALLOC(1, sizeof(*CellsToAddModList)); - CellsToAddModList = MeasObj->measObject.choice.measObjectEUTRA.cellsToAddModList; // Add adjacent cell lists (6 per eNB) @@ -3158,28 +2947,19 @@ rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt_t* cons CellToAdd->cellIndex = i + 1; CellToAdd->physCellId = get_adjacent_cell_id(ctxt_pP->module_id, i); CellToAdd->cellIndividualOffset = LTE_Q_OffsetRange_dB0; - ASN_SEQUENCE_ADD(&CellsToAddModList->list, CellToAdd); } ASN_SEQUENCE_ADD(&MeasObj_list->list, MeasObj); // LTE_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)); - ReportConfig_per = CALLOC(1, sizeof(*ReportConfig_per)); - ReportConfig_A1 = CALLOC(1, sizeof(*ReportConfig_A1)); - ReportConfig_A2 = CALLOC(1, sizeof(*ReportConfig_A2)); - ReportConfig_A3 = CALLOC(1, sizeof(*ReportConfig_A3)); - ReportConfig_A4 = CALLOC(1, sizeof(*ReportConfig_A4)); - ReportConfig_A5 = CALLOC(1, sizeof(*ReportConfig_A5)); - ReportConfig_per->reportConfigId = 1; ReportConfig_per->reportConfig.present = LTE_ReportConfigToAddMod__reportConfig_PR_reportConfigEUTRA; ReportConfig_per->reportConfig.choice.reportConfigEUTRA.triggerType.present = @@ -3191,9 +2971,7 @@ rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt_t* cons ReportConfig_per->reportConfig.choice.reportConfigEUTRA.maxReportCells = 2; ReportConfig_per->reportConfig.choice.reportConfigEUTRA.reportInterval = LTE_ReportInterval_ms120; ReportConfig_per->reportConfig.choice.reportConfigEUTRA.reportAmount = LTE_ReportConfigEUTRA__reportAmount_infinity; - ASN_SEQUENCE_ADD(&ReportConfig_list->list, ReportConfig_per); - ReportConfig_A1->reportConfigId = 2; ReportConfig_A1->reportConfig.present = LTE_ReportConfigToAddMod__reportConfig_PR_reportConfigEUTRA; ReportConfig_A1->reportConfig.choice.reportConfigEUTRA.triggerType.present = @@ -3204,15 +2982,13 @@ rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt_t* cons a1_Threshold.present = LTE_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 = LTE_ReportConfigEUTRA__triggerQuantity_rsrp; ReportConfig_A1->reportConfig.choice.reportConfigEUTRA.reportQuantity = LTE_ReportConfigEUTRA__reportQuantity_both; ReportConfig_A1->reportConfig.choice.reportConfigEUTRA.maxReportCells = 2; ReportConfig_A1->reportConfig.choice.reportConfigEUTRA.reportInterval = LTE_ReportInterval_ms120; ReportConfig_A1->reportConfig.choice.reportConfigEUTRA.reportAmount = LTE_ReportConfigEUTRA__reportAmount_infinity; - ASN_SEQUENCE_ADD(&ReportConfig_list->list, ReportConfig_A1); - + if (ho_state == 1 /*HO_MEASURMENT */ ) { LOG_I(RRC, "[eNB %d] frame %d: requesting A2, A3, A4, A5, and A6 event reporting\n", ctxt_pP->module_id, ctxt_pP->frame); @@ -3226,39 +3002,32 @@ rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt_t* cons eventA2.a2_Threshold.present = LTE_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 = LTE_ReportConfigEUTRA__triggerQuantity_rsrp; ReportConfig_A2->reportConfig.choice.reportConfigEUTRA.reportQuantity = LTE_ReportConfigEUTRA__reportQuantity_both; ReportConfig_A2->reportConfig.choice.reportConfigEUTRA.maxReportCells = 2; ReportConfig_A2->reportConfig.choice.reportConfigEUTRA.reportInterval = LTE_ReportInterval_ms120; ReportConfig_A2->reportConfig.choice.reportConfigEUTRA.reportAmount = LTE_ReportConfigEUTRA__reportAmount_infinity; - ASN_SEQUENCE_ADD(&ReportConfig_list->list, ReportConfig_A2); - ReportConfig_A3->reportConfigId = 4; ReportConfig_A3->reportConfig.present = LTE_ReportConfigToAddMod__reportConfig_PR_reportConfigEUTRA; ReportConfig_A3->reportConfig.choice.reportConfigEUTRA.triggerType.present = LTE_ReportConfigEUTRA__triggerType_PR_event; ReportConfig_A3->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.present = LTE_ReportConfigEUTRA__triggerType__event__eventId_PR_eventA3; - 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 = LTE_ReportConfigEUTRA__triggerQuantity_rsrp; ReportConfig_A3->reportConfig.choice.reportConfigEUTRA.reportQuantity = LTE_ReportConfigEUTRA__reportQuantity_both; ReportConfig_A3->reportConfig.choice.reportConfigEUTRA.maxReportCells = 2; ReportConfig_A3->reportConfig.choice.reportConfigEUTRA.reportInterval = LTE_ReportInterval_ms120; ReportConfig_A3->reportConfig.choice.reportConfigEUTRA.reportAmount = LTE_ReportConfigEUTRA__reportAmount_infinity; - ReportConfig_A3->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.hysteresis = 0.5; // FIXME ...hysteresis is of type long! ReportConfig_A3->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.timeToTrigger = LTE_TimeToTrigger_ms40; ASN_SEQUENCE_ADD(&ReportConfig_list->list, ReportConfig_A3); - ReportConfig_A4->reportConfigId = 5; ReportConfig_A4->reportConfig.present = LTE_ReportConfigToAddMod__reportConfig_PR_reportConfigEUTRA; ReportConfig_A4->reportConfig.choice.reportConfigEUTRA.triggerType.present = @@ -3269,16 +3038,13 @@ rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt_t* cons eventA4.a4_Threshold.present = LTE_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 = LTE_ReportConfigEUTRA__triggerQuantity_rsrp; ReportConfig_A4->reportConfig.choice.reportConfigEUTRA.reportQuantity = LTE_ReportConfigEUTRA__reportQuantity_both; ReportConfig_A4->reportConfig.choice.reportConfigEUTRA.maxReportCells = 2; ReportConfig_A4->reportConfig.choice.reportConfigEUTRA.reportInterval = LTE_ReportInterval_ms120; ReportConfig_A4->reportConfig.choice.reportConfigEUTRA.reportAmount = LTE_ReportConfigEUTRA__reportAmount_infinity; - ASN_SEQUENCE_ADD(&ReportConfig_list->list, ReportConfig_A4); - ReportConfig_A5->reportConfigId = 6; ReportConfig_A5->reportConfig.present = LTE_ReportConfigToAddMod__reportConfig_PR_reportConfigEUTRA; ReportConfig_A5->reportConfig.choice.reportConfigEUTRA.triggerType.present = @@ -3293,20 +3059,16 @@ rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt_t* cons 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 = LTE_ReportConfigEUTRA__triggerQuantity_rsrp; ReportConfig_A5->reportConfig.choice.reportConfigEUTRA.reportQuantity = LTE_ReportConfigEUTRA__reportQuantity_both; ReportConfig_A5->reportConfig.choice.reportConfigEUTRA.maxReportCells = 2; ReportConfig_A5->reportConfig.choice.reportConfigEUTRA.reportInterval = LTE_ReportInterval_ms120; ReportConfig_A5->reportConfig.choice.reportConfigEUTRA.reportAmount = LTE_ReportConfigEUTRA__reportAmount_infinity; - ASN_SEQUENCE_ADD(&ReportConfig_list->list, ReportConfig_A5); // LTE_RRCConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.measConfig->reportConfigToAddModList = ReportConfig_list; - rsrp = CALLOC(1, sizeof(LTE_RSRP_Range_t)); *rsrp = 20; - Sparams = CALLOC(1, sizeof(*Sparams)); Sparams->present = LTE_MeasConfig__speedStatePars_PR_setup; Sparams->choice.setup.timeToTrigger_SF.sf_High = LTE_SpeedStateScaleFactors__sf_Medium_oDot75; @@ -3315,7 +3077,6 @@ rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt_t* cons Sparams->choice.setup.mobilityStateParameters.n_CellChangeMedium = 5; Sparams->choice.setup.mobilityStateParameters.t_Evaluation = LTE_MobilityStateParameters__t_Evaluation_s60; Sparams->choice.setup.mobilityStateParameters.t_HystNormal = LTE_MobilityStateParameters__t_HystNormal_s120; - quantityConfig = CALLOC(1, sizeof(*quantityConfig)); memset((void *)quantityConfig, 0, sizeof(*quantityConfig)); quantityConfig->quantityConfigEUTRA = CALLOC(1, sizeof(struct LTE_QuantityConfigEUTRA)); @@ -3329,7 +3090,6 @@ rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt_t* cons CALLOC(1, sizeof(*(quantityConfig->quantityConfigEUTRA->filterCoefficientRSRQ))); *quantityConfig->quantityConfigEUTRA->filterCoefficientRSRP = LTE_FilterCoefficient_fc4; *quantityConfig->quantityConfigEUTRA->filterCoefficientRSRQ = LTE_FilterCoefficient_fc4; - LOG_I(RRC, "[eNB %d] Frame %d: potential handover preparation: store the information in an intermediate structure in case of failure\n", ctxt_pP->module_id, ctxt_pP->frame); @@ -3343,15 +3103,14 @@ rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt_t* cons ue_context_pP->ue_context.handover_info->as_config.sourceRadioResourceConfig.drb_ToReleaseList = NULL; ue_context_pP->ue_context.handover_info->as_config.sourceRadioResourceConfig.mac_MainConfig = CALLOC(1, sizeof(*ue_context_pP->ue_context.handover_info->as_config.sourceRadioResourceConfig.mac_MainConfig)); - memcpy((void*)ue_context_pP->ue_context.handover_info->as_config.sourceRadioResourceConfig.mac_MainConfig, + memcpy((void *)ue_context_pP->ue_context.handover_info->as_config.sourceRadioResourceConfig.mac_MainConfig, (void *)mac_MainConfig, sizeof(LTE_MAC_MainConfig_t)); ue_context_pP->ue_context.handover_info->as_config.sourceRadioResourceConfig.physicalConfigDedicated = CALLOC(1, sizeof(LTE_PhysicalConfigDedicated_t)); - memcpy((void*)ue_context_pP->ue_context.handover_info->as_config.sourceRadioResourceConfig.physicalConfigDedicated, - (void*)ue_context_pP->ue_context.physicalConfigDedicated, sizeof(LTE_PhysicalConfigDedicated_t)); + memcpy((void *)ue_context_pP->ue_context.handover_info->as_config.sourceRadioResourceConfig.physicalConfigDedicated, + (void *)ue_context_pP->ue_context.physicalConfigDedicated, sizeof(LTE_PhysicalConfigDedicated_t)); ue_context_pP->ue_context.handover_info->as_config.sourceRadioResourceConfig.sps_Config = NULL; //memcpy((void *)rrc_inst->handover_info[ue_mod_idP]->as_config.sourceRadioResourceConfig.sps_Config,(void *)rrc_inst->sps_Config[ue_mod_idP],sizeof(SPS_Config_t)); - } #if defined(ENABLE_ITTI) @@ -3363,8 +3122,8 @@ rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt_t* cons if (ue_context_pP->ue_context.e_rab[i].param.nas_pdu.buffer != NULL) { dedicatedInfoNas = CALLOC(1, sizeof(LTE_DedicatedInfoNAS_t)); memset(dedicatedInfoNas, 0, sizeof(OCTET_STRING_t)); - OCTET_STRING_fromBuf(dedicatedInfoNas, - (char*)ue_context_pP->ue_context.e_rab[i].param.nas_pdu.buffer, + OCTET_STRING_fromBuf(dedicatedInfoNas, + (char *)ue_context_pP->ue_context.e_rab[i].param.nas_pdu.buffer, ue_context_pP->ue_context.e_rab[i].param.nas_pdu.length); ASN_SEQUENCE_ADD(&dedicatedInfoNASList->list, dedicatedInfoNas); } @@ -3375,11 +3134,10 @@ rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt_t* cons // ue_context_pP->ue_context.e_rab[i].param.sgw_addr; // ue_context_pP->ue_context.e_rab[i].param.gtp_teid; } - /* TODO should test if e RAB are Ok before! */ ue_context_pP->ue_context.e_rab[i].status = E_RAB_STATUS_DONE; - LOG_D(RRC, "setting the status for the default DRB (index %d) to (%d,%s)\n", - i, ue_context_pP->ue_context.e_rab[i].status, "E_RAB_STATUS_DONE"); + LOG_D(RRC, "setting the status for the default DRB (index %d) to (%d,%s)\n", + i, ue_context_pP->ue_context.e_rab[i].status, "E_RAB_STATUS_DONE"); } /* If list is empty free the list and reset the address */ @@ -3389,41 +3147,38 @@ rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt_t* cons } #endif - memset(buffer, 0, RRC_BUF_SIZE); - size = do_RRCConnectionReconfiguration(ctxt_pP, buffer, xid, //Transaction_id, - (LTE_SRB_ToAddModList_t*)*SRB_configList2, // SRB_configList - (LTE_DRB_ToAddModList_t*)*DRB_configList, - (LTE_DRB_ToReleaseList_t*)NULL, // DRB2_list, - (struct LTE_SPS_Config*)NULL, // *sps_Config, - (struct LTE_PhysicalConfigDedicated*)*physicalConfigDedicated, + (LTE_SRB_ToAddModList_t *)*SRB_configList2, // SRB_configList + (LTE_DRB_ToAddModList_t *)*DRB_configList, + (LTE_DRB_ToReleaseList_t *)NULL, // DRB2_list, + (struct LTE_SPS_Config *)NULL, // *sps_Config, + (struct LTE_PhysicalConfigDedicated *)*physicalConfigDedicated, #ifdef EXMIMO_IOT NULL, NULL, NULL,NULL, #else - (LTE_MeasObjectToAddModList_t*)MeasObj_list, - (LTE_ReportConfigToAddModList_t*)ReportConfig_list, - (LTE_QuantityConfig_t*)quantityConfig, - (LTE_MeasIdToAddModList_t*)MeasId_list, + (LTE_MeasObjectToAddModList_t *)MeasObj_list, + (LTE_ReportConfigToAddModList_t *)ReportConfig_list, + (LTE_QuantityConfig_t *)quantityConfig, + (LTE_MeasIdToAddModList_t *)MeasId_list, #endif - (LTE_MAC_MainConfig_t*)mac_MainConfig, - (LTE_MeasGapConfig_t*)NULL, - (LTE_MobilityControlInfo_t*)NULL, - (struct LTE_MeasConfig__speedStatePars*)Sparams, - (LTE_RSRP_Range_t*)rsrp, - (LTE_C_RNTI_t*)cba_RNTI, - (struct LTE_RRCConnectionReconfiguration_r8_IEs__dedicatedInfoNASList*)dedicatedInfoNASList, - (LTE_SL_CommConfig_r12_t*)NULL, - (LTE_SL_DiscConfig_r12_t*)NULL + (LTE_MAC_MainConfig_t *)mac_MainConfig, + (LTE_MeasGapConfig_t *)NULL, + (LTE_MobilityControlInfo_t *)NULL, + (struct LTE_MeasConfig__speedStatePars *)Sparams, + (LTE_RSRP_Range_t *)rsrp, + (LTE_C_RNTI_t *)cba_RNTI, + (struct LTE_RRCConnectionReconfiguration_r8_IEs__dedicatedInfoNASList *)dedicatedInfoNASList, + (LTE_SL_CommConfig_r12_t *)NULL, + (LTE_SL_DiscConfig_r12_t *)NULL #if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) - , (LTE_SCellToAddMod_r10_t*)NULL + , (LTE_SCellToAddMod_r10_t *)NULL #endif ); LOG_DUMPMSG(RRC,DEBUG_RRC,(char *)buffer,size, "[MSG] RRC Connection Reconfiguration\n"); - #if defined(ENABLE_ITTI) /* Free all NAS PDUs */ @@ -3436,15 +3191,12 @@ rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt_t* cons } #endif - LOG_I(RRC, "[eNB %d] Frame %d, Logical Channel DL-DCCH, Generate LTE_RRCConnectionReconfiguration (bytes %d, UE id %x)\n", ctxt_pP->module_id, ctxt_pP->frame, size, ue_context_pP->ue_context.rnti); - LOG_D(RRC, "[FRAME %05d][RRC_eNB][MOD %u][][--- PDCP_DATA_REQ/%d Bytes (rrcConnectionReconfiguration to UE %x MUI %d) --->][PDCP][MOD %u][RB %u]\n", ctxt_pP->frame, ctxt_pP->module_id, size, ue_context_pP->ue_context.rnti, rrc_eNB_mui, ctxt_pP->module_id, DCCH); - MSC_LOG_TX_MESSAGE( MSC_RRC_ENB, MSC_RRC_UE, @@ -3455,42 +3207,38 @@ rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt_t* cons ue_context_pP->ue_context.rnti, rrc_eNB_mui, size); - rrc_data_req( - ctxt_pP, - DCCH, - rrc_eNB_mui++, - SDU_CONFIRM_NO, - size, - buffer, - PDCP_TRANSMISSION_MODE_CONTROL); + ctxt_pP, + DCCH, + rrc_eNB_mui++, + SDU_CONFIRM_NO, + size, + buffer, + PDCP_TRANSMISSION_MODE_CONTROL); } //----------------------------------------------------------------------------- void -flexran_rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt_t* const ctxt_pP, - rrc_eNB_ue_context_t* const ue_context_pP, - const uint8_t ho_state, - agent_reconf_rrc * trig_param - ) +flexran_rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt_t *const ctxt_pP, + rrc_eNB_ue_context_t *const ue_context_pP, + const uint8_t ho_state, + agent_reconf_rrc *trig_param + ) //----------------------------------------------------------------------------- { uint8_t buffer[RRC_BUF_SIZE]; uint16_t size; int i; - // configure SRB1/SRB2, PhysicalConfigDedicated, LTE_MAC_MainConfig for UE - eNB_RRC_INST* rrc_inst = RC.rrc[ctxt_pP->module_id]; - struct LTE_PhysicalConfigDedicated** physicalConfigDedicated = &ue_context_pP->ue_context.physicalConfigDedicated; - + eNB_RRC_INST *rrc_inst = RC.rrc[ctxt_pP->module_id]; + struct LTE_PhysicalConfigDedicated **physicalConfigDedicated = &ue_context_pP->ue_context.physicalConfigDedicated; struct LTE_SRB_ToAddMod *SRB2_config = NULL; struct LTE_SRB_ToAddMod__rlc_Config *SRB2_rlc_config = NULL; struct LTE_SRB_ToAddMod__logicalChannelConfig *SRB2_lchan_config = NULL; struct LTE_LogicalChannelConfig__ul_SpecificParameters - *SRB2_ul_SpecificParameters = NULL; - LTE_SRB_ToAddModList_t* SRB_configList = ue_context_pP->ue_context.SRB_configList; + *SRB2_ul_SpecificParameters = NULL; + LTE_SRB_ToAddModList_t *SRB_configList = ue_context_pP->ue_context.SRB_configList; LTE_SRB_ToAddModList_t **SRB_configList2 = NULL; - struct LTE_DRB_ToAddMod *DRB_config = NULL; struct LTE_RLC_Config *DRB_rlc_config = NULL; struct LTE_PDCP_Config *DRB_pdcp_config = NULL; @@ -3498,15 +3246,15 @@ flexran_rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt struct LTE_PDCP_Config__rlc_UM *PDCP_rlc_UM = NULL; struct LTE_LogicalChannelConfig *DRB_lchan_config = NULL; struct LTE_LogicalChannelConfig__ul_SpecificParameters - *DRB_ul_SpecificParameters = NULL; - LTE_DRB_ToAddModList_t** DRB_configList = &ue_context_pP->ue_context.DRB_configList; - LTE_DRB_ToAddModList_t** DRB_configList2 = NULL; + *DRB_ul_SpecificParameters = NULL; + LTE_DRB_ToAddModList_t **DRB_configList = &ue_context_pP->ue_context.DRB_configList; + LTE_DRB_ToAddModList_t **DRB_configList2 = NULL; LTE_MAC_MainConfig_t *mac_MainConfig = NULL; LTE_MeasObjectToAddModList_t *MeasObj_list = NULL; LTE_MeasObjectToAddMod_t *MeasObj = NULL; LTE_ReportConfigToAddModList_t *ReportConfig_list = NULL; LTE_ReportConfigToAddMod_t *ReportConfig_per;//, *ReportConfig_A1, - // *ReportConfig_A2, *ReportConfig_A3, *ReportConfig_A4, *ReportConfig_A5; + // *ReportConfig_A2, *ReportConfig_A3, *ReportConfig_A4, *ReportConfig_A5; LTE_MeasIdToAddModList_t *MeasId_list = NULL; LTE_MeasIdToAddMod_t *MeasId0; //, *MeasId1, *MeasId2, *MeasId3, *MeasId4, *MeasId5; #if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) @@ -3514,10 +3262,8 @@ flexran_rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt // uint8_t sCellIndexToAdd = rrc_find_free_SCell_index(enb_mod_idP, ue_mod_idP, 1); //uint8_t sCellIndexToAdd = 0; #endif - long *logicalchannelgroup, *logicalchannelgroup_drb; long *maxHARQ_Tx, *periodicBSR_Timer; - LTE_RSRP_Range_t *rsrp = NULL; struct LTE_MeasConfig__speedStatePars *Sparams = NULL; LTE_QuantityConfig_t *quantityConfig = NULL; @@ -3527,11 +3273,8 @@ flexran_rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt LTE_DedicatedInfoNAS_t *dedicatedInfoNas = NULL; /* for no gcc warnings */ (void)dedicatedInfoNas; - LTE_C_RNTI_t *cba_RNTI = NULL; - uint8_t xid = rrc_eNB_get_next_transaction_identifier(ctxt_pP->module_id); //Transaction_id, - #ifdef CBA //struct PUSCH_CBAConfigDedicated_vlola *pusch_CBAConfigDedicated_vlola; uint8_t *cba_RNTI_buf; @@ -3557,24 +3300,22 @@ flexran_rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt } #endif - T(T_ENB_RRC_CONNECTION_RECONFIGURATION, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame), T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti)); - // Configure SRB2 /// SRB2 SRB_configList2=&ue_context_pP->ue_context.SRB_configList2[xid]; + if (*SRB_configList2) { free(*SRB_configList2); } + *SRB_configList2 = CALLOC(1, sizeof(**SRB_configList2)); memset(*SRB_configList2, 0, sizeof(**SRB_configList2)); SRB2_config = CALLOC(1, sizeof(*SRB2_config)); - 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 = LTE_SRB_ToAddMod__rlc_Config_PR_explicitValue; SRB2_rlc_config->choice.explicitValue.present = LTE_RLC_Config_PR_am; SRB2_rlc_config->choice.explicitValue.choice.am.ul_AM_RLC.t_PollRetransmit = LTE_T_PollRetransmit_ms15; @@ -3583,26 +3324,19 @@ flexran_rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt SRB2_rlc_config->choice.explicitValue.choice.am.ul_AM_RLC.maxRetxThreshold = LTE_UL_AM_RLC__maxRetxThreshold_t32; SRB2_rlc_config->choice.explicitValue.choice.am.dl_AM_RLC.t_Reordering = LTE_T_Reordering_ms35; SRB2_rlc_config->choice.explicitValue.choice.am.dl_AM_RLC.t_StatusProhibit = LTE_T_StatusProhibit_ms10; - SRB2_lchan_config = CALLOC(1, sizeof(*SRB2_lchan_config)); SRB2_config->logicalChannelConfig = SRB2_lchan_config; - SRB2_lchan_config->present = LTE_SRB_ToAddMod__logicalChannelConfig_PR_explicitValue; - SRB2_ul_SpecificParameters = CALLOC(1, sizeof(*SRB2_ul_SpecificParameters)); - SRB2_ul_SpecificParameters->priority = 3; // let some priority for SRB1 and dedicated DRBs SRB2_ul_SpecificParameters->prioritisedBitRate = LTE_LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_infinity; SRB2_ul_SpecificParameters->bucketSizeDuration = LTE_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; // this list has the configuration for SRB1 and SRB2 ASN_SEQUENCE_ADD(&SRB_configList->list, SRB2_config); @@ -3615,21 +3349,20 @@ flexran_rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt if (*DRB_configList) { free(*DRB_configList); } + *DRB_configList = CALLOC(1, sizeof(**DRB_configList)); memset(*DRB_configList, 0, sizeof(**DRB_configList)); - // list for the configured DRB for a this xid DRB_configList2=&ue_context_pP->ue_context.DRB_configList2[xid]; + if (*DRB_configList2) { free(*DRB_configList2); } + *DRB_configList2 = CALLOC(1, sizeof(**DRB_configList2)); memset(*DRB_configList2, 0, sizeof(**DRB_configList2)); - - /// DRB DRB_config = CALLOC(1, sizeof(*DRB_config)); - DRB_config->eps_BearerIdentity = CALLOC(1, sizeof(long)); *(DRB_config->eps_BearerIdentity) = 5L; // LW set to first value, allowed value 5..15, value : x+4 // DRB_config->drb_Identity = (LTE_DRB_Identity_t) 1; //allowed values 1..32 @@ -3639,7 +3372,6 @@ flexran_rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt *(DRB_config->logicalChannelIdentity) = (long)3; // value : x+2 DRB_rlc_config = CALLOC(1, sizeof(*DRB_rlc_config)); DRB_config->rlc_Config = DRB_rlc_config; - #ifdef RRC_DEFAULT_RAB_IS_AM DRB_rlc_config->present = LTE_RLC_Config_PR_am; DRB_rlc_config->choice.am.ul_AM_RLC.t_PollRetransmit = LTE_T_PollRetransmit_ms50; @@ -3658,18 +3390,15 @@ flexran_rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt DRB_rlc_config->choice.um_Bi_Directional.dl_UM_RLC.t_Reordering = LTE_T_Reordering_ms35; #endif #endif - DRB_pdcp_config = CALLOC(1, sizeof(*DRB_pdcp_config)); DRB_config->pdcp_Config = DRB_pdcp_config; DRB_pdcp_config->discardTimer = CALLOC(1, sizeof(long)); *DRB_pdcp_config->discardTimer = LTE_PDCP_Config__discardTimer_infinity; DRB_pdcp_config->rlc_AM = NULL; DRB_pdcp_config->rlc_UM = NULL; - /* avoid gcc warnings */ (void)PDCP_rlc_AM; (void)PDCP_rlc_UM; - #ifdef RRC_DEFAULT_RAB_IS_AM // EXMIMO_IOT PDCP_rlc_AM = CALLOC(1, sizeof(*PDCP_rlc_AM)); DRB_pdcp_config->rlc_AM = PDCP_rlc_AM; @@ -3680,33 +3409,25 @@ flexran_rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt PDCP_rlc_UM->pdcp_SN_Size = LTE_PDCP_Config__rlc_UM__pdcp_SN_Size_len12bits; #endif DRB_pdcp_config->headerCompression.present = LTE_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 = 12; // lower priority than srb1, srb2 and other dedicated bearer DRB_ul_SpecificParameters->prioritisedBitRate = LTE_LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_kBps8 ; - //LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_infinity; + //LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_infinity; DRB_ul_SpecificParameters->bucketSizeDuration = LTE_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); ASN_SEQUENCE_ADD(&(*DRB_configList2)->list, DRB_config); - //ue_context_pP->ue_context.DRB_configList2[0] = &(*DRB_configList); - mac_MainConfig = CALLOC(1, sizeof(*mac_MainConfig)); // ue_context_pP->ue_context.mac_MainConfig = LTE_MAC_MainConfig; - mac_MainConfig->ul_SCH_Config = CALLOC(1, sizeof(*mac_MainConfig->ul_SCH_Config)); - maxHARQ_Tx = CALLOC(1, sizeof(long)); *maxHARQ_Tx = LTE_MAC_MainConfig__ul_SCH_Config__maxHARQ_Tx_n5; mac_MainConfig->ul_SCH_Config->maxHARQ_Tx = maxHARQ_Tx; @@ -3715,20 +3436,13 @@ flexran_rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt mac_MainConfig->ul_SCH_Config->periodicBSR_Timer = periodicBSR_Timer; mac_MainConfig->ul_SCH_Config->retxBSR_Timer = LTE_RetxBSR_Timer_r12_sf320; mac_MainConfig->ul_SCH_Config->ttiBundling = 0; // FALSE - mac_MainConfig->timeAlignmentTimerDedicated = LTE_TimeAlignmentTimer_infinity; - mac_MainConfig->drx_Config = NULL; - mac_MainConfig->phr_Config = CALLOC(1, sizeof(*mac_MainConfig->phr_Config)); - mac_MainConfig->phr_Config->present = LTE_MAC_MainConfig__phr_Config_PR_setup; mac_MainConfig->phr_Config->choice.setup.periodicPHR_Timer = LTE_MAC_MainConfig__phr_Config__setup__periodicPHR_Timer_sf20; // sf20 = 20 subframes - mac_MainConfig->phr_Config->choice.setup.prohibitPHR_Timer = LTE_MAC_MainConfig__phr_Config__setup__prohibitPHR_Timer_sf20; // sf20 = 20 subframes - mac_MainConfig->phr_Config->choice.setup.dl_PathlossChange = LTE_MAC_MainConfig__phr_Config__setup__dl_PathlossChange_dB1; // Value dB1 =1 dB, dB3 = 3 dB - #if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) 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 @@ -3744,95 +3458,84 @@ flexran_rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt if ((*physicalConfigDedicated)->antennaInfo) { (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.transmissionMode = rrc_inst->configuration.ue_TransmissionMode[0]; LOG_D(RRC,"Setting transmission mode to %ld+1\n",rrc_inst->configuration.ue_TransmissionMode[0]); - if (rrc_inst->configuration.ue_TransmissionMode[0] == LTE_AntennaInfoDedicated__transmissionMode_tm3) { - (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction= - CALLOC(1,sizeof(LTE_AntennaInfoDedicated__codebookSubsetRestriction_PR)); - (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->present = - LTE_AntennaInfoDedicated__codebookSubsetRestriction_PR_n2TxAntenna_tm3; - (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm3.buf= MALLOC(1); - (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm3.buf[0] = 0xc0; - (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm3.size=1; - (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm3.bits_unused=6; - } - else if (rrc_inst->configuration.ue_TransmissionMode[0] == LTE_AntennaInfoDedicated__transmissionMode_tm4) { - (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction= - CALLOC(1,sizeof(LTE_AntennaInfoDedicated__codebookSubsetRestriction_PR)); - (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->present = - LTE_AntennaInfoDedicated__codebookSubsetRestriction_PR_n2TxAntenna_tm4; - (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm4.buf= MALLOC(1); - (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm4.buf[0] = 0xfc; - (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm4.size=1; - (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm4.bits_unused=2; + if (rrc_inst->configuration.ue_TransmissionMode[0] == LTE_AntennaInfoDedicated__transmissionMode_tm3) { + (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction= + CALLOC(1,sizeof(LTE_AntennaInfoDedicated__codebookSubsetRestriction_PR)); + (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->present = + LTE_AntennaInfoDedicated__codebookSubsetRestriction_PR_n2TxAntenna_tm3; + (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm3.buf= MALLOC(1); + (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm3.buf[0] = 0xc0; + (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm3.size=1; + (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm3.bits_unused=6; + } else if (rrc_inst->configuration.ue_TransmissionMode[0] == LTE_AntennaInfoDedicated__transmissionMode_tm4) { + (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction= + CALLOC(1,sizeof(LTE_AntennaInfoDedicated__codebookSubsetRestriction_PR)); + (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->present = + LTE_AntennaInfoDedicated__codebookSubsetRestriction_PR_n2TxAntenna_tm4; + (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm4.buf= MALLOC(1); + (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm4.buf[0] = 0xfc; + (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm4.size=1; + (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm4.bits_unused=2; + } else if (rrc_inst->configuration.ue_TransmissionMode[0] == LTE_AntennaInfoDedicated__transmissionMode_tm5) { + (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction= + CALLOC(1,sizeof(LTE_AntennaInfoDedicated__codebookSubsetRestriction_PR)); + (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->present = + LTE_AntennaInfoDedicated__codebookSubsetRestriction_PR_n2TxAntenna_tm5; + (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm5.buf= MALLOC(1); + (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm5.buf[0] = 0xf0; + (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm5.size=1; + (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm5.bits_unused=4; + } else if (rrc_inst->configuration.ue_TransmissionMode[0] == LTE_AntennaInfoDedicated__transmissionMode_tm6) { + (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction= + CALLOC(1,sizeof(LTE_AntennaInfoDedicated__codebookSubsetRestriction_PR)); + (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->present = + LTE_AntennaInfoDedicated__codebookSubsetRestriction_PR_n2TxAntenna_tm6; + (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm6.buf= MALLOC(1); + (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm6.buf[0] = 0xf0; + (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm6.size=1; + (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm6.bits_unused=4; } - else if (rrc_inst->configuration.ue_TransmissionMode[0] == LTE_AntennaInfoDedicated__transmissionMode_tm5) { - (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction= - CALLOC(1,sizeof(LTE_AntennaInfoDedicated__codebookSubsetRestriction_PR)); - (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->present = - LTE_AntennaInfoDedicated__codebookSubsetRestriction_PR_n2TxAntenna_tm5; - (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm5.buf= MALLOC(1); - (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm5.buf[0] = 0xf0; - (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm5.size=1; - (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm5.bits_unused=4; - } - else if (rrc_inst->configuration.ue_TransmissionMode[0] == LTE_AntennaInfoDedicated__transmissionMode_tm6) { - (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction= - CALLOC(1,sizeof(LTE_AntennaInfoDedicated__codebookSubsetRestriction_PR)); - (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->present = - LTE_AntennaInfoDedicated__codebookSubsetRestriction_PR_n2TxAntenna_tm6; - (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm6.buf= MALLOC(1); - (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm6.buf[0] = 0xf0; - (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm6.size=1; - (*physicalConfigDedicated)->antennaInfo->choice.explicitValue.codebookSubsetRestriction->choice.n2TxAntenna_tm6.bits_unused=4; - } - } - else { + } else { LOG_E(RRC,"antenna_info not present in physical_config_dedicated. Not reconfiguring!\n"); } + if ((*physicalConfigDedicated)->cqi_ReportConfig) { if ((rrc_inst->configuration.ue_TransmissionMode[0] == LTE_AntennaInfoDedicated__transmissionMode_tm4) || - (rrc_inst->configuration.ue_TransmissionMode[0] == LTE_AntennaInfoDedicated__transmissionMode_tm5) || - (rrc_inst->configuration.ue_TransmissionMode[0] == LTE_AntennaInfoDedicated__transmissionMode_tm6)) { - //feedback mode needs to be set as well - //TODO: I think this is taken into account in the PHY automatically based on the transmission mode variable - printf("setting cqi reporting mode to rm31\n"); + (rrc_inst->configuration.ue_TransmissionMode[0] == LTE_AntennaInfoDedicated__transmissionMode_tm5) || + (rrc_inst->configuration.ue_TransmissionMode[0] == LTE_AntennaInfoDedicated__transmissionMode_tm6)) { + //feedback mode needs to be set as well + //TODO: I think this is taken into account in the PHY automatically based on the transmission mode variable + printf("setting cqi reporting mode to rm31\n"); #if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) - *((*physicalConfigDedicated)->cqi_ReportConfig->cqi_ReportModeAperiodic)=LTE_CQI_ReportModeAperiodic_rm31; + *((*physicalConfigDedicated)->cqi_ReportConfig->cqi_ReportModeAperiodic)=LTE_CQI_ReportModeAperiodic_rm31; #else - *((*physicalConfigDedicated)->cqi_ReportConfig->cqi_ReportModeAperiodic)=LTE_CQI_ReportConfig__cqi_ReportModeAperiodic_rm31; // HLC CQI, no PMI + *((*physicalConfigDedicated)->cqi_ReportConfig->cqi_ReportModeAperiodic)=LTE_CQI_ReportConfig__cqi_ReportModeAperiodic_rm31; // HLC CQI, no PMI #endif } - } - else { + } else { LOG_E(RRC,"cqi_ReportConfig not present in physical_config_dedicated. Not reconfiguring!\n"); } - } - else { + } else { LOG_E(RRC,"physical_config_dedicated not present in LTE_RRCConnectionReconfiguration. Not reconfiguring!\n"); } // 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); - /* * Add one EUTRA Measurement Object */ - MeasObj_list = CALLOC(1, sizeof(*MeasObj_list)); memset((void *)MeasObj_list, 0, sizeof(*MeasObj_list)); - - // Configure MeasObject - + // Configure MeasObject MeasObj = CALLOC(1, sizeof(*MeasObj)); memset((void *)MeasObj, 0, sizeof(*MeasObj)); - MeasObj->measObjectId = 1; MeasObj->measObject.present = LTE_MeasObjectToAddMod__measObject_PR_measObjectEUTRA; MeasObj->measObject.choice.measObjectEUTRA.carrierFreq = 3350; //band 7, 2.68GHz @@ -3844,10 +3547,8 @@ flexran_rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt 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 = (LTE_CellsToAddModList_t *) CALLOC(1, sizeof(*CellsToAddModList)); - CellsToAddModList = MeasObj->measObject.choice.measObjectEUTRA.cellsToAddModList; // Add adjacent cell lists (6 per eNB) @@ -3856,7 +3557,6 @@ flexran_rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt CellToAdd->cellIndex = i + 1; CellToAdd->physCellId = get_adjacent_cell_id(ctxt_pP->module_id, i); CellToAdd->cellIndividualOffset = LTE_Q_OffsetRange_dB0; - ASN_SEQUENCE_ADD(&CellsToAddModList->list, CellToAdd); } @@ -3867,78 +3567,48 @@ flexran_rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt /* RRC Strategy Measurement */ - - if (strcmp("one_shot", trig_param->trigger_policy) == 0){ - - trig_param->report_interval = 0; - trig_param->report_amount = 0; - + if (strcmp("one_shot", trig_param->trigger_policy) == 0) { + trig_param->report_interval = 0; + trig_param->report_amount = 0; + } else if (strcmp("event_driven", trig_param->trigger_policy) == 0) { + trig_param->report_interval = 6; + trig_param->report_amount = 2; + } else if (strcmp("periodical", trig_param->trigger_policy) == 0) { + trig_param->report_interval = 1; + trig_param->report_amount = 7; + } else { + LOG_E(FLEXRAN_AGENT, "There is something wrong on RRC agent!"); } - else if (strcmp("event_driven", trig_param->trigger_policy) == 0){ - - trig_param->report_interval = 6; - trig_param->report_amount = 2; - - } - - else if (strcmp("periodical", trig_param->trigger_policy) == 0){ - - trig_param->report_interval = 1; - trig_param->report_amount = 7; - - } - - else { - - LOG_E(FLEXRAN_AGENT, "There is something wrong on RRC agent!"); - } - - - ReportConfig_list = CALLOC(1, sizeof(*ReportConfig_list)); - ReportConfig_per = CALLOC(1, sizeof(*ReportConfig_per)); - - // Periodical Measurement Report - + // Periodical Measurement Report ReportConfig_per->reportConfigId = 1; ReportConfig_per->reportConfig.present = LTE_ReportConfigToAddMod__reportConfig_PR_reportConfigEUTRA; - - ReportConfig_per->reportConfig.choice.reportConfigEUTRA.triggerType.present = - LTE_ReportConfigEUTRA__triggerType_PR_periodical; - - ReportConfig_per->reportConfig.choice.reportConfigEUTRA.triggerType.choice.periodical.purpose = - LTE_ReportConfigEUTRA__triggerType__periodical__purpose_reportStrongestCells; - - // ReportConfig_per->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.timeToTrigger = TimeToTrigger_ms40; - ReportConfig_per->reportConfig.choice.reportConfigEUTRA.triggerQuantity = LTE_ReportConfigEUTRA__triggerQuantity_rsrp; - ReportConfig_per->reportConfig.choice.reportConfigEUTRA.reportQuantity = LTE_ReportConfigEUTRA__reportQuantity_both; - ReportConfig_per->reportConfig.choice.reportConfigEUTRA.maxReportCells = 2; - ReportConfig_per->reportConfig.choice.reportConfigEUTRA.reportInterval = trig_param->report_interval ;//ReportInterval_ms2048; // RRC counter frame- ms1024 is 1ms - - ReportConfig_per->reportConfig.choice.reportConfigEUTRA.reportAmount = trig_param->report_amount; //ReportConfigEUTRA__reportAmount_r2; // put r1 to see once, r2 for 2 times and ... - - + ReportConfig_per->reportConfig.choice.reportConfigEUTRA.triggerType.present = + LTE_ReportConfigEUTRA__triggerType_PR_periodical; + ReportConfig_per->reportConfig.choice.reportConfigEUTRA.triggerType.choice.periodical.purpose = + LTE_ReportConfigEUTRA__triggerType__periodical__purpose_reportStrongestCells; + // ReportConfig_per->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.timeToTrigger = TimeToTrigger_ms40; + ReportConfig_per->reportConfig.choice.reportConfigEUTRA.triggerQuantity = LTE_ReportConfigEUTRA__triggerQuantity_rsrp; + ReportConfig_per->reportConfig.choice.reportConfigEUTRA.reportQuantity = LTE_ReportConfigEUTRA__reportQuantity_both; + ReportConfig_per->reportConfig.choice.reportConfigEUTRA.maxReportCells = 2; + ReportConfig_per->reportConfig.choice.reportConfigEUTRA.reportInterval = trig_param->report_interval ;//ReportInterval_ms2048; // RRC counter frame- ms1024 is 1ms + ReportConfig_per->reportConfig.choice.reportConfigEUTRA.reportAmount = trig_param->report_amount; //ReportConfigEUTRA__reportAmount_r2; // put r1 to see once, r2 for 2 times and ... ASN_SEQUENCE_ADD(&ReportConfig_list->list, ReportConfig_per); - - - - quantityConfig = CALLOC(1, sizeof(*quantityConfig)); - memset((void *)quantityConfig, 0, sizeof(*quantityConfig)); - quantityConfig->quantityConfigEUTRA = CALLOC(1, sizeof(struct LTE_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 = LTE_FilterCoefficient_fc4; - *quantityConfig->quantityConfigEUTRA->filterCoefficientRSRQ = LTE_FilterCoefficient_fc4; - - + quantityConfig = CALLOC(1, sizeof(*quantityConfig)); + memset((void *)quantityConfig, 0, sizeof(*quantityConfig)); + quantityConfig->quantityConfigEUTRA = CALLOC(1, sizeof(struct LTE_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 = LTE_FilterCoefficient_fc4; + *quantityConfig->quantityConfigEUTRA->filterCoefficientRSRQ = LTE_FilterCoefficient_fc4; #if defined(ENABLE_ITTI) /* Initialize NAS list */ dedicatedInfoNASList = CALLOC(1, sizeof(struct LTE_RRCConnectionReconfiguration_r8_IEs__dedicatedInfoNASList)); @@ -3948,23 +3618,22 @@ flexran_rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt if (ue_context_pP->ue_context.e_rab[i].param.nas_pdu.buffer != NULL) { dedicatedInfoNas = CALLOC(1, sizeof(LTE_DedicatedInfoNAS_t)); memset(dedicatedInfoNas, 0, sizeof(OCTET_STRING_t)); - OCTET_STRING_fromBuf(dedicatedInfoNas, - (char*)ue_context_pP->ue_context.e_rab[i].param.nas_pdu.buffer, + OCTET_STRING_fromBuf(dedicatedInfoNas, + (char *)ue_context_pP->ue_context.e_rab[i].param.nas_pdu.buffer, ue_context_pP->ue_context.e_rab[i].param.nas_pdu.length); ASN_SEQUENCE_ADD(&dedicatedInfoNASList->list, dedicatedInfoNas); } /* TODO parameters yet to process ... */ // { - // ue_context_pP->ue_context.e_rab[i].param.qos; - // ue_context_pP->ue_context.e_rab[i].param.sgw_addr; - // ue_context_pP->ue_context.e_rab[i].param.gtp_teid; + // ue_context_pP->ue_context.e_rab[i].param.qos; + // ue_context_pP->ue_context.e_rab[i].param.sgw_addr; + // ue_context_pP->ue_context.e_rab[i].param.gtp_teid; // } - /* TODO should test if e RAB are Ok before! */ ue_context_pP->ue_context.e_rab[i].status = E_RAB_STATUS_DONE; - LOG_D(RRC, "setting the status for the default DRB (index %d) to (%d,%s)\n", - i, ue_context_pP->ue_context.e_rab[i].status, "E_RAB_STATUS_DONE"); + LOG_D(RRC, "setting the status for the default DRB (index %d) to (%d,%s)\n", + i, ue_context_pP->ue_context.e_rab[i].status, "E_RAB_STATUS_DONE"); } /* If list is empty free the list and reset the address */ @@ -3974,41 +3643,38 @@ flexran_rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt } #endif - memset(buffer, 0, RRC_BUF_SIZE); - size = do_RRCConnectionReconfiguration(ctxt_pP, buffer, xid, //Transaction_id, - (LTE_SRB_ToAddModList_t*)NULL, // SRB_configList - (LTE_DRB_ToAddModList_t*)NULL, - (LTE_DRB_ToReleaseList_t*)NULL, // DRB2_list, - (struct LTE_SPS_Config*)NULL, // *sps_Config, - (struct LTE_PhysicalConfigDedicated*)*physicalConfigDedicated, -// #ifdef EXMIMO_IOT -// NULL, NULL, NULL,NULL, -// #else - (LTE_MeasObjectToAddModList_t*)MeasObj_list, - (LTE_ReportConfigToAddModList_t*)ReportConfig_list, - (LTE_QuantityConfig_t*)quantityConfig, - (LTE_MeasIdToAddModList_t*)MeasId_list, -// #endif - (LTE_MAC_MainConfig_t*)mac_MainConfig, - (LTE_MeasGapConfig_t*)NULL, - (LTE_MobilityControlInfo_t*)NULL, - (struct LTE_MeasConfig__speedStatePars*)Sparams, - (LTE_RSRP_Range_t*)rsrp, - (LTE_C_RNTI_t*)cba_RNTI, - (struct LTE_RRCConnectionReconfiguration_r8_IEs__dedicatedInfoNASList*)dedicatedInfoNASList, - (LTE_SL_CommConfig_r12_t*)NULL, - (LTE_SL_DiscConfig_r12_t*)NULL + (LTE_SRB_ToAddModList_t *)NULL, // SRB_configList + (LTE_DRB_ToAddModList_t *)NULL, + (LTE_DRB_ToReleaseList_t *)NULL, // DRB2_list, + (struct LTE_SPS_Config *)NULL, // *sps_Config, + (struct LTE_PhysicalConfigDedicated *)*physicalConfigDedicated, + // #ifdef EXMIMO_IOT + // NULL, NULL, NULL,NULL, + // #else + (LTE_MeasObjectToAddModList_t *)MeasObj_list, + (LTE_ReportConfigToAddModList_t *)ReportConfig_list, + (LTE_QuantityConfig_t *)quantityConfig, + (LTE_MeasIdToAddModList_t *)MeasId_list, + // #endif + (LTE_MAC_MainConfig_t *)mac_MainConfig, + (LTE_MeasGapConfig_t *)NULL, + (LTE_MobilityControlInfo_t *)NULL, + (struct LTE_MeasConfig__speedStatePars *)Sparams, + (LTE_RSRP_Range_t *)rsrp, + (LTE_C_RNTI_t *)cba_RNTI, + (struct LTE_RRCConnectionReconfiguration_r8_IEs__dedicatedInfoNASList *)dedicatedInfoNASList, + (LTE_SL_CommConfig_r12_t *)NULL, + (LTE_SL_DiscConfig_r12_t *)NULL #if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) - , (LTE_SCellToAddMod_r10_t*)NULL + , (LTE_SCellToAddMod_r10_t *)NULL #endif ); LOG_DUMPMSG(RRC,DEBUG_RRC,(char *)buffer,size, "[MSG] RRC Connection Reconfiguration\n"); - #if defined(ENABLE_ITTI) /* Free all NAS PDUs */ @@ -4021,15 +3687,12 @@ flexran_rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt } #endif - LOG_I(RRC, "[eNB %d] Frame %d, Logical Channel DL-DCCH, Generate LTE_RRCConnectionReconfiguration (bytes %d, UE id %x)\n", ctxt_pP->module_id, ctxt_pP->frame, size, ue_context_pP->ue_context.rnti); - LOG_D(RRC, "[FRAME %05d][RRC_eNB][MOD %u][][--- PDCP_DATA_REQ/%d Bytes (rrcConnectionReconfiguration to UE %x MUI %d) --->][PDCP][MOD %u][RB %u]\n", ctxt_pP->frame, ctxt_pP->module_id, size, ue_context_pP->ue_context.rnti, rrc_eNB_mui, ctxt_pP->module_id, DCCH); - MSC_LOG_TX_MESSAGE( MSC_RRC_ENB, MSC_RRC_UE, @@ -4040,31 +3703,28 @@ flexran_rrc_eNB_generate_defaultRRCConnectionReconfiguration(const protocol_ctxt ue_context_pP->ue_context.rnti, rrc_eNB_mui, size); - rrc_data_req( - ctxt_pP, - DCCH, - rrc_eNB_mui++, - SDU_CONFIRM_NO, - size, - buffer, - PDCP_TRANSMISSION_MODE_CONTROL); + ctxt_pP, + DCCH, + rrc_eNB_mui++, + SDU_CONFIRM_NO, + size, + buffer, + PDCP_TRANSMISSION_MODE_CONTROL); } //----------------------------------------------------------------------------- int rrc_eNB_generate_RRCConnectionReconfiguration_SCell( - const protocol_ctxt_t* const ctxt_pP, - rrc_eNB_ue_context_t* const ue_context_pP, + const protocol_ctxt_t *const ctxt_pP, + rrc_eNB_ue_context_t *const ue_context_pP, uint32_t dl_CarrierFreq_r10 ) //----------------------------------------------------------------------------- { - uint8_t size; uint8_t buffer[100]; - #if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) uint8_t sCellIndexToAdd = 0; //one SCell so far @@ -4082,32 +3742,30 @@ rrc_eNB_generate_RRCConnectionReconfiguration_SCell( size = do_RRCConnectionReconfiguration(ctxt_pP, buffer, rrc_eNB_get_next_transaction_identifier(ctxt_pP->module_id),//Transaction_id, - (LTE_SRB_ToAddModList_t*)NULL, - (LTE_DRB_ToAddModList_t*)NULL, - (LTE_DRB_ToReleaseList_t*)NULL, - (struct LTE_SPS_Config*)NULL, - (struct LTE_PhysicalConfigDedicated*)NULL, - (LTE_MeasObjectToAddModList_t*)NULL, - (LTE_ReportConfigToAddModList_t*)NULL, - (LTE_QuantityConfig_t*)NULL, - (LTE_MeasIdToAddModList_t*)NULL, - (LTE_MAC_MainConfig_t*)NULL, - (LTE_MeasGapConfig_t*)NULL, - (LTE_MobilityControlInfo_t*)NULL, - (struct LTE_MeasConfig__speedStatePars*)NULL, - (LTE_RSRP_Range_t*)NULL, - (LTE_C_RNTI_t*)NULL, - (struct LTE_RRCConnectionReconfiguration_r8_IEs__dedicatedInfoNASList*)NULL, - (LTE_SL_CommConfig_r12_t*)NULL, - (LTE_SL_DiscConfig_r12_t*)NULL - + (LTE_SRB_ToAddModList_t *)NULL, + (LTE_DRB_ToAddModList_t *)NULL, + (LTE_DRB_ToReleaseList_t *)NULL, + (struct LTE_SPS_Config *)NULL, + (struct LTE_PhysicalConfigDedicated *)NULL, + (LTE_MeasObjectToAddModList_t *)NULL, + (LTE_ReportConfigToAddModList_t *)NULL, + (LTE_QuantityConfig_t *)NULL, + (LTE_MeasIdToAddModList_t *)NULL, + (LTE_MAC_MainConfig_t *)NULL, + (LTE_MeasGapConfig_t *)NULL, + (LTE_MobilityControlInfo_t *)NULL, + (struct LTE_MeasConfig__speedStatePars *)NULL, + (LTE_RSRP_Range_t *)NULL, + (LTE_C_RNTI_t *)NULL, + (struct LTE_RRCConnectionReconfiguration_r8_IEs__dedicatedInfoNASList *)NULL, + (LTE_SL_CommConfig_r12_t *)NULL, + (LTE_SL_DiscConfig_r12_t *)NULL #if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) , ue_context_pP->ue_context.sCell_config #endif ); LOG_I(RRC,"[eNB %d] Frame %d, Logical Channel DL-DCCH, Generate LTE_RRCConnectionReconfiguration (bytes %d, UE id %x)\n", ctxt_pP->module_id,ctxt_pP->frame, size, ue_context_pP->ue_context.rnti); - MSC_LOG_TX_MESSAGE( MSC_RRC_ENB, MSC_RRC_UE, @@ -4118,15 +3776,14 @@ rrc_eNB_generate_RRCConnectionReconfiguration_SCell( ue_context_pP->ue_context.rnti, rrc_eNB_mui, size); - rrc_data_req( - ctxt_pP, - DCCH, - rrc_eNB_mui++, - SDU_CONFIRM_NO, - size, - buffer, - PDCP_TRANSMISSION_MODE_CONTROL); + ctxt_pP, + DCCH, + rrc_eNB_mui++, + SDU_CONFIRM_NO, + size, + buffer, + PDCP_TRANSMISSION_MODE_CONTROL); return(0); } @@ -4134,64 +3791,64 @@ rrc_eNB_generate_RRCConnectionReconfiguration_SCell( //----------------------------------------------------------------------------- void rrc_eNB_process_MeasurementReport( - const protocol_ctxt_t* const ctxt_pP, - rrc_eNB_ue_context_t* ue_context_pP, - const LTE_MeasResults_t* const measResults2 + const protocol_ctxt_t *const ctxt_pP, + rrc_eNB_ue_context_t *ue_context_pP, + const LTE_MeasResults_t *const measResults2 ) //----------------------------------------------------------------------------- { int i=0; int neighboring_cells=-1; - T(T_ENB_RRC_MEASUREMENT_REPORT, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame), T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti)); if (measResults2 == NULL ) return; - - if (measResults2->measId > 0 ){ - if (ue_context_pP->ue_context.measResults == NULL) { - ue_context_pP->ue_context.measResults = CALLOC(1, sizeof(LTE_MeasResults_t)); - } - ue_context_pP->ue_context.measResults->measId=measResults2->measId; - ue_context_pP->ue_context.measResults->measResultPCell.rsrpResult=measResults2->measResultPCell.rsrpResult; - ue_context_pP->ue_context.measResults->measResultPCell.rsrqResult=measResults2->measResultPCell.rsrqResult; - LOG_D(RRC, "[eNB %d]Frame %d: UE %x (Measurement Id %d): RSRP of Source %ld\n", ctxt_pP->module_id, ctxt_pP->frame, ctxt_pP->rnti, (int)measResults2->measId, ue_context_pP->ue_context.measResults->measResultPCell.rsrpResult-140); - LOG_D(RRC, "[eNB %d]Frame %d: UE %x (Measurement Id %d): RSRQ of Source %ld\n", ctxt_pP->module_id, ctxt_pP->frame, ctxt_pP->rnti, (int)measResults2->measId, ue_context_pP->ue_context.measResults->measResultPCell.rsrqResult/2 - 20); - } - if (measResults2->measResultNeighCells == NULL) - return; - if (measResults2->measResultNeighCells->choice.measResultListEUTRA.list.count > 0) { - neighboring_cells = measResults2->measResultNeighCells->choice.measResultListEUTRA.list.count; - - if (ue_context_pP->ue_context.measResults->measResultNeighCells == NULL) { - - ue_context_pP->ue_context.measResults->measResultNeighCells = CALLOC(1, sizeof(*measResults2->measResultNeighCells)*neighboring_cells); - } - ue_context_pP->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.count = neighboring_cells; - for (i=0; i < neighboring_cells; i++){ - memcpy (ue_context_pP->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.array[i], - measResults2->measResultNeighCells->choice.measResultListEUTRA.list.array[i], - sizeof(LTE_MeasResultListEUTRA_t)); - - LOG_D(RRC, "Physical Cell Id %d\n", - (int)ue_context_pP->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.array[i]->physCellId); - LOG_D(RRC, "RSRP of Target %d\n", - (int)*(ue_context_pP->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.array[i]->measResult.rsrpResult)); - LOG_D(RRC, "RSRQ of Target %d\n", - (int)*(ue_context_pP->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.array[i]->measResult.rsrqResult)); - } - } + if (measResults2->measId > 0 ) { + if (ue_context_pP->ue_context.measResults == NULL) { + ue_context_pP->ue_context.measResults = CALLOC(1, sizeof(LTE_MeasResults_t)); + } -// #if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) + ue_context_pP->ue_context.measResults->measId=measResults2->measId; + ue_context_pP->ue_context.measResults->measResultPCell.rsrpResult=measResults2->measResultPCell.rsrpResult; + ue_context_pP->ue_context.measResults->measResultPCell.rsrqResult=measResults2->measResultPCell.rsrqResult; + LOG_D(RRC, "[eNB %d]Frame %d: UE %x (Measurement Id %d): RSRP of Source %ld\n", ctxt_pP->module_id, ctxt_pP->frame, ctxt_pP->rnti, (int)measResults2->measId, + ue_context_pP->ue_context.measResults->measResultPCell.rsrpResult-140); + LOG_D(RRC, "[eNB %d]Frame %d: UE %x (Measurement Id %d): RSRQ of Source %ld\n", ctxt_pP->module_id, ctxt_pP->frame, ctxt_pP->rnti, (int)measResults2->measId, + ue_context_pP->ue_context.measResults->measResultPCell.rsrqResult/2 - 20); + } - -// #else + if (measResults2->measResultNeighCells == NULL) + return; + + if (measResults2->measResultNeighCells->choice.measResultListEUTRA.list.count > 0) { + neighboring_cells = measResults2->measResultNeighCells->choice.measResultListEUTRA.list.count; + + if (ue_context_pP->ue_context.measResults->measResultNeighCells == NULL) { + ue_context_pP->ue_context.measResults->measResultNeighCells = CALLOC(1, sizeof(*measResults2->measResultNeighCells)*neighboring_cells); + } + + ue_context_pP->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.count = neighboring_cells; + + for (i=0; i < neighboring_cells; i++) { + memcpy (ue_context_pP->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.array[i], + measResults2->measResultNeighCells->choice.measResultListEUTRA.list.array[i], + sizeof(LTE_MeasResultListEUTRA_t)); + LOG_D(RRC, "Physical Cell Id %d\n", + (int)ue_context_pP->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.array[i]->physCellId); + LOG_D(RRC, "RSRP of Target %d\n", + (int)*(ue_context_pP->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.array[i]->measResult.rsrpResult)); + LOG_D(RRC, "RSRQ of Target %d\n", + (int)*(ue_context_pP->ue_context.measResults->measResultNeighCells->choice.measResultListEUTRA.list.array[i]->measResult.rsrqResult)); + } + } + + // #if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) + // #else // LOG_I(RRC, "RSRP of Source %d\n", measResults2->measResultServCell.rsrpResult); // LOG_I(RRC, "RSRQ of Source %d\n", measResults2->measResultServCell.rsrqResult); -// #endif - + // #endif // if (ue_context_pP->ue_context.handover_info->ho_prepare != 0xF0) { // rrc_eNB_generate_HandoverPreparationInformation(ctxt_pP, // ue_context_pP, @@ -4201,33 +3858,29 @@ rrc_eNB_process_MeasurementReport( // LOG_D(RRC, "[eNB %d] Frame %d: Ignoring MeasReport from UE %x as Handover is in progress... \n", ctxt_pP->module_id, ctxt_pP->frame, // ctxt_pP->rnti); // } - //Look for IP address of the target eNB //Send Handover Request -> target eNB //Wait for Handover Acknowledgement <- target eNB //Send Handover Command - //x2delay(); // handover_request_x2(ue_mod_idP,enb_mod_idP,measResults2->measResultNeighCells->choice.measResultListEUTRA.list.array[0]->physCellId); - // uint8_t buffer[100]; // int size=rrc_eNB_generate_Handover_Command_TeNB(0,0,buffer); // // send_check_message((char*)buffer,size); //send_handover_command(); - } //----------------------------------------------------------------------------- void rrc_eNB_generate_HandoverPreparationInformation( - const protocol_ctxt_t* const ctxt_pP, - rrc_eNB_ue_context_t* const ue_context_pP, + const protocol_ctxt_t *const ctxt_pP, + rrc_eNB_ue_context_t *const ue_context_pP, LTE_PhysCellId_t targetPhyId ) //----------------------------------------------------------------------------- { - struct rrc_eNB_ue_context_s* ue_context_target_p = NULL; + struct rrc_eNB_ue_context_s *ue_context_target_p = NULL; //uint8_t UE_id_target = -1; uint8_t mod_id_target = get_adjacent_cell_mod_id(targetPhyId); HANDOVER_INFO *handoverInfo = CALLOC(1, sizeof(*handoverInfo)); @@ -4237,30 +3890,24 @@ rrc_eNB_generate_HandoverPreparationInformation( struct LTE_PhysicalConfigDedicated **physicalConfigDedicated = &RC.rrc[enb_mod_idP]->physicalConfigDedicated[ue_mod_idP]; RadioResourceConfigDedicated_t *radioResourceConfigDedicated = CALLOC(1,sizeof(RadioResourceConfigDedicated_t)); */ - T(T_ENB_RRC_HANDOVER_PREPARATION_INFORMATION, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame), T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti)); - 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*)&RC.rrc[ctxt_pP->module_id]->carrier[0] /* CROUX TBC */.mib, sizeof(LTE_MasterInformationBlock_t)); + (void *)&RC.rrc[ctxt_pP->module_id]->carrier[0] /* CROUX TBC */.mib, sizeof(LTE_MasterInformationBlock_t)); memcpy((void *)&handoverInfo->as_config.sourceMeasConfig, - (void*)ue_context_pP->ue_context.measConfig, sizeof(LTE_MeasConfig_t)); - + (void *)ue_context_pP->ue_context.measConfig, sizeof(LTE_MeasConfig_t)); // FIXME handoverInfo not used... free( handoverInfo ); handoverInfo = 0; - //to be configured - memset((void*)&ue_context_pP->ue_context.handover_info->as_config.sourceSecurityAlgorithmConfig, + memset((void *)&ue_context_pP->ue_context.handover_info->as_config.sourceSecurityAlgorithmConfig, 0, sizeof(LTE_SecurityAlgorithmConfig_t)); - - memcpy((void*)&ue_context_pP->ue_context.handover_info->as_config.sourceSystemInformationBlockType1, - (void*)&RC.rrc[ctxt_pP->module_id]->carrier[0] /* CROUX TBC */.SIB1, sizeof(LTE_SystemInformationBlockType1_t)); - memcpy((void*)&ue_context_pP->ue_context.handover_info->as_config.sourceSystemInformationBlockType2, - (void*)&RC.rrc[ctxt_pP->module_id]->carrier[0] /* CROUX TBC */.SIB23, sizeof(LTE_SystemInformationBlockType2_t)); + memcpy((void *)&ue_context_pP->ue_context.handover_info->as_config.sourceSystemInformationBlockType1, + (void *)&RC.rrc[ctxt_pP->module_id]->carrier[0] /* CROUX TBC */.SIB1, sizeof(LTE_SystemInformationBlockType1_t)); + memcpy((void *)&ue_context_pP->ue_context.handover_info->as_config.sourceSystemInformationBlockType2, + (void *)&RC.rrc[ctxt_pP->module_id]->carrier[0] /* CROUX TBC */.SIB23, sizeof(LTE_SystemInformationBlockType2_t)); ue_context_pP->ue_context.handover_info->as_context.reestablishmentInfo = CALLOC(1, sizeof(LTE_ReestablishmentInfo_t)); ue_context_pP->ue_context.handover_info->as_context.reestablishmentInfo->sourcePhysCellId = @@ -4299,11 +3946,11 @@ rrc_eNB_generate_HandoverPreparationInformation( mod_id_target); ue_context_target_p->ue_context.handover_info = CALLOC(1, sizeof(*(ue_context_target_p->ue_context.handover_info))); - memcpy((void*)&ue_context_target_p->ue_context.handover_info->as_context, - (void*)&ue_context_pP->ue_context.handover_info->as_context, + memcpy((void *)&ue_context_target_p->ue_context.handover_info->as_context, + (void *)&ue_context_pP->ue_context.handover_info->as_context, sizeof(LTE_AS_Context_t)); - memcpy((void*)&ue_context_target_p->ue_context.handover_info->as_config, - (void*)&ue_context_pP->ue_context.handover_info->as_config, + memcpy((void *)&ue_context_target_p->ue_context.handover_info->as_config, + (void *)&ue_context_pP->ue_context.handover_info->as_config, sizeof(LTE_AS_Config_t)); ue_context_target_p->ue_context.handover_info->ho_prepare = 0x00;// 0xFF; ue_context_target_p->ue_context.handover_info->ho_complete = 0; @@ -4313,11 +3960,9 @@ rrc_eNB_generate_HandoverPreparationInformation( ue_context_target_p->ue_context.handover_info->modid_t = mod_id_target; ue_context_target_p->ue_context.handover_info->modid_s = ctxt_pP->module_id; ue_context_target_p->ue_context.handover_info->ueid_t = ue_context_target_p->ue_context.rnti; - } else { LOG_E(RRC, "\nError in obtaining free UE id in target eNB %ld for handover \n", targetPhyId); } - } else { LOG_E(RRC, "\nError in obtaining Module ID of target eNB for handover \n"); } @@ -4326,15 +3971,13 @@ rrc_eNB_generate_HandoverPreparationInformation( //----------------------------------------------------------------------------- void rrc_eNB_process_handoverPreparationInformation( - const protocol_ctxt_t* const ctxt_pP, - rrc_eNB_ue_context_t* const ue_context_pP + const protocol_ctxt_t *const ctxt_pP, + rrc_eNB_ue_context_t *const ue_context_pP ) //----------------------------------------------------------------------------- { T(T_ENB_RRC_HANDOVER_PREPARATION_INFORMATION, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame), T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti)); - - LOG_I(RRC, "[eNB %d] Frame %d : Logical Channel UL-DCCH, processing RRCHandoverPreparationInformation, sending LTE_RRCConnectionReconfiguration to UE %d \n", ctxt_pP->module_id, ctxt_pP->frame, ue_context_pP->ue_context.rnti); @@ -4349,12 +3992,12 @@ rrc_eNB_process_handoverPreparationInformation( //----------------------------------------------------------------------------- void check_handovers( - protocol_ctxt_t* const ctxt_pP + protocol_ctxt_t *const ctxt_pP ) //----------------------------------------------------------------------------- { int result; - struct rrc_eNB_ue_context_s* ue_context_p; + struct rrc_eNB_ue_context_s *ue_context_p; RB_FOREACH(ue_context_p, rrc_ue_tree_s, &RC.rrc[ctxt_pP->module_id]->rrc_ue_head) { ctxt_pP->rnti = ue_context_p->ue_id_rnti; @@ -4394,13 +4037,14 @@ check_handovers( #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) ,NULL, NULL #endif - ); + ); + //AssertFatal(result == TRUE, "PDCP data request failed!\n"); - if(result != TRUE) - { + if(result != TRUE) { LOG_I(RRC, "PDCP data request failed!\n"); return; } + ue_context_p->ue_context.handover_info->ho_complete = 0xF2; } } @@ -4411,33 +4055,29 @@ check_handovers( //----------------------------------------------------------------------------- void rrc_eNB_generate_RRCConnectionReconfiguration_handover( - const protocol_ctxt_t* const ctxt_pP, - rrc_eNB_ue_context_t* const ue_context_pP, - uint8_t* const nas_pdu, + const protocol_ctxt_t *const ctxt_pP, + rrc_eNB_ue_context_t *const ue_context_pP, + uint8_t *const nas_pdu, const uint32_t nas_length ) //----------------------------------------------------------------------------- { T(T_ENB_RRC_CONNECTION_RECONFIGURATION, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame), T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti)); - - uint8_t buffer[RRC_BUF_SIZE]; int i; uint8_t rv[2]; uint16_t Idx; // configure SRB1/SRB2, PhysicalConfigDedicated, LTE_MAC_MainConfig for UE - eNB_RRC_INST* rrc_inst = RC.rrc[ctxt_pP->module_id]; - struct LTE_PhysicalConfigDedicated** physicalConfigDedicated = &ue_context_pP->ue_context.physicalConfigDedicated; - + eNB_RRC_INST *rrc_inst = RC.rrc[ctxt_pP->module_id]; + struct LTE_PhysicalConfigDedicated **physicalConfigDedicated = &ue_context_pP->ue_context.physicalConfigDedicated; struct LTE_SRB_ToAddMod *SRB2_config; struct LTE_SRB_ToAddMod__rlc_Config *SRB2_rlc_config; struct LTE_SRB_ToAddMod__logicalChannelConfig *SRB2_lchan_config; struct LTE_LogicalChannelConfig__ul_SpecificParameters *SRB2_ul_SpecificParameters; LTE_LogicalChannelConfig_t *SRB1_logicalChannelConfig = NULL; - LTE_SRB_ToAddModList_t* SRB_configList = ue_context_pP->ue_context.SRB_configList; // not used in this context: may be removed + LTE_SRB_ToAddModList_t *SRB_configList = ue_context_pP->ue_context.SRB_configList; // not used in this context: may be removed LTE_SRB_ToAddModList_t *SRB_configList2; - struct LTE_DRB_ToAddMod *DRB_config; struct LTE_RLC_Config *DRB_rlc_config; struct LTE_PDCP_Config *DRB_pdcp_config; @@ -4445,7 +4085,6 @@ rrc_eNB_generate_RRCConnectionReconfiguration_handover( struct LTE_LogicalChannelConfig *DRB_lchan_config; struct LTE_LogicalChannelConfig__ul_SpecificParameters *DRB_ul_SpecificParameters; LTE_DRB_ToAddModList_t *DRB_configList2; - LTE_MAC_MainConfig_t *mac_MainConfig; LTE_MeasObjectToAddModList_t *MeasObj_list; LTE_MeasObjectToAddMod_t *MeasObj; @@ -4462,10 +4101,8 @@ rrc_eNB_generate_RRCConnectionReconfiguration_handover( #if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) long *sr_ProhibitTimer_r9; #endif - long *logicalchannelgroup, *logicalchannelgroup_drb; long *maxHARQ_Tx, *periodicBSR_Timer; - // LTE_RSRP_Range_t *rsrp; struct LTE_MeasConfig__speedStatePars *Sparams; LTE_CellsToAddMod_t *CellToAdd; @@ -4479,7 +4116,6 @@ rrc_eNB_generate_RRCConnectionReconfiguration_handover( LTE_PhysicalConfigDedicated_t *physicalConfigDedicated2; struct LTE_RRCConnectionReconfiguration_r8_IEs__dedicatedInfoNASList *dedicatedInfoNASList; protocol_ctxt_t ctxt; - LOG_D(RRC, "[eNB %d] Frame %d: handover preparation: get the newSourceUEIdentity (C-RNTI): ", ctxt_pP->module_id, ctxt_pP->frame); @@ -4496,7 +4132,6 @@ rrc_eNB_generate_RRCConnectionReconfiguration_handover( 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 = LTE_SRB_ToAddMod__rlc_Config_PR_explicitValue; SRB1_rlc_config->choice.explicitValue.present = LTE_RLC_Config_PR_am; SRB1_rlc_config->choice.explicitValue.choice.am.ul_AM_RLC.t_PollRetransmit = LTE_T_PollRetransmit_ms15; @@ -4505,35 +4140,25 @@ rrc_eNB_generate_RRCConnectionReconfiguration_handover( SRB1_rlc_config->choice.explicitValue.choice.am.ul_AM_RLC.maxRetxThreshold = LTE_UL_AM_RLC__maxRetxThreshold_t16; SRB1_rlc_config->choice.explicitValue.choice.am.dl_AM_RLC.t_Reordering = LTE_T_Reordering_ms35; SRB1_rlc_config->choice.explicitValue.choice.am.dl_AM_RLC.t_StatusProhibit = LTE_T_StatusProhibit_ms10; - SRB1_lchan_config = CALLOC(1, sizeof(*SRB1_lchan_config)); SRB1_config->logicalChannelConfig = SRB1_lchan_config; - SRB1_lchan_config->present = LTE_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 = LTE_LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_infinity; - //assign_enum(&SRB1_ul_SpecificParameters->bucketSizeDuration,LogicalChannelConfig__ul_SpecificParameters__bucketSizeDuration_ms50); SRB1_ul_SpecificParameters->bucketSizeDuration = LTE_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 = @@ -4555,18 +4180,15 @@ rrc_eNB_generate_RRCConnectionReconfiguration_handover( //assign_enum(&physicalConfigDedicated2->pdsch_ConfigDedicated->p_a, // PDSCH_ConfigDedicated__p_a_dB0); physicalConfigDedicated2->pdsch_ConfigDedicated->p_a = LTE_PDSCH_ConfigDedicated__p_a_dB0; - // PUCCH physicalConfigDedicated2->pucch_ConfigDedicated->ackNackRepetition.present = LTE_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, @@ -4580,7 +4202,6 @@ rrc_eNB_generate_RRCConnectionReconfiguration_handover( CALLOC(1, sizeof(*physicalConfigDedicated2->uplinkPowerControlDedicated->filterCoefficient)); // assign_enum(physicalConfigDedicated2->uplinkPowerControlDedicated->filterCoefficient,FilterCoefficient_fc4); // fc4 dB *physicalConfigDedicated2->uplinkPowerControlDedicated->filterCoefficient = LTE_FilterCoefficient_fc4; // fc4 dB - // TPC-PDCCH-Config physicalConfigDedicated2->tpc_PDCCH_ConfigPUCCH->present = LTE_TPC_PDCCH_Config_PR_setup; physicalConfigDedicated2->tpc_PDCCH_ConfigPUCCH->choice.setup.tpc_Index.present = LTE_TPC_Index_PR_indexOfFormat3; @@ -4590,7 +4211,6 @@ rrc_eNB_generate_RRCConnectionReconfiguration_handover( physicalConfigDedicated2->tpc_PDCCH_ConfigPUCCH->choice.setup.tpc_RNTI.buf[0] = 0x12; physicalConfigDedicated2->tpc_PDCCH_ConfigPUCCH->choice.setup.tpc_RNTI.buf[1] = 0x34 + ue_context_pP->local_uid; physicalConfigDedicated2->tpc_PDCCH_ConfigPUCCH->choice.setup.tpc_RNTI.bits_unused = 0; - physicalConfigDedicated2->tpc_PDCCH_ConfigPUSCH->present = LTE_TPC_PDCCH_Config_PR_setup; physicalConfigDedicated2->tpc_PDCCH_ConfigPUSCH->choice.setup.tpc_Index.present = LTE_TPC_Index_PR_indexOfFormat3; physicalConfigDedicated2->tpc_PDCCH_ConfigPUSCH->choice.setup.tpc_Index.choice.indexOfFormat3 = 1; @@ -4599,7 +4219,6 @@ rrc_eNB_generate_RRCConnectionReconfiguration_handover( physicalConfigDedicated2->tpc_PDCCH_ConfigPUSCH->choice.setup.tpc_RNTI.buf[0] = 0x22; physicalConfigDedicated2->tpc_PDCCH_ConfigPUSCH->choice.setup.tpc_RNTI.buf[1] = 0x34 + ue_context_pP->local_uid; 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)); @@ -4616,7 +4235,6 @@ rrc_eNB_generate_RRCConnectionReconfiguration_handover( 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; @@ -4631,7 +4249,6 @@ rrc_eNB_generate_RRCConnectionReconfiguration_handover( 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 = LTE_PhysicalConfigDedicated__antennaInfo_PR_explicitValue; @@ -4659,7 +4276,6 @@ rrc_eNB_generate_RRCConnectionReconfiguration_handover( physicalConfigDedicated2->antennaInfo->choice.explicitValue.ue_TransmitAntennaSelection.present = LTE_AntennaInfoDedicated__ue_TransmitAntennaSelection_PR_release; physicalConfigDedicated2->antennaInfo->choice.explicitValue.ue_TransmitAntennaSelection.choice.release = 0; - // SchedulingRequestConfig physicalConfigDedicated2->schedulingRequestConfig->present = LTE_SchedulingRequestConfig_PR_setup; physicalConfigDedicated2->schedulingRequestConfig->choice.setup.sr_PUCCH_ResourceIndex = ue_context_pP->local_uid; @@ -4669,24 +4285,24 @@ rrc_eNB_generate_RRCConnectionReconfiguration_handover( 10); // Isr = 5 (every 10 subframes, offset=2+UE_id mod3) } else { switch (rrc_inst->carrier[0].sib1->tdd_Config->subframeAssignment) { - case 1: - physicalConfigDedicated2->schedulingRequestConfig->choice.setup.sr_ConfigIndex = 7 + (ue_context_pP->local_uid & 1) + (( - ue_context_pP->local_uid & 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 1: + physicalConfigDedicated2->schedulingRequestConfig->choice.setup.sr_ConfigIndex = 7 + (ue_context_pP->local_uid & 1) + (( + ue_context_pP->local_uid & 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_context_pP->local_uid % - 3); // Isr = 5 (every 10 subframes, offset=2 for UE0, 3 for UE1, 3 for UE2, 2 for UE3 , etc..) - break; + case 3: + physicalConfigDedicated2->schedulingRequestConfig->choice.setup.sr_ConfigIndex = 7 + (ue_context_pP->local_uid % + 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_context_pP->local_uid & - 1); // 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_context_pP->local_uid & + 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; + default: + physicalConfigDedicated2->schedulingRequestConfig->choice.setup.sr_ConfigIndex = 7; // Isr = 5 (every 10 subframes, offset=2 for all UE0 etc..) + break; } } @@ -4695,59 +4311,55 @@ rrc_eNB_generate_RRCConnectionReconfiguration_handover( // assign_enum(&physicalConfigDedicated2->schedulingRequestConfig->choice.setup.dsr_TransMax = SchedulingRequestConfig__setup__dsr_TransMax_n4; physicalConfigDedicated2->schedulingRequestConfig->choice.setup.dsr_TransMax = LTE_SchedulingRequestConfig__setup__dsr_TransMax_n4; - LOG_D(RRC, "handover_config [FRAME %05d][RRC_eNB][MOD %02d][][--- MAC_CONFIG_REQ (SRB1 UE %x) --->][MAC_eNB][MOD %02d][]\n", ctxt_pP->frame, ctxt_pP->module_id, ue_context_pP->ue_context.rnti, ctxt_pP->module_id); rrc_mac_config_req_eNB( - ctxt_pP->module_id, - ue_context_pP->ue_context.primaryCC_id, - 0,0,0,0,0, + ctxt_pP->module_id, + ue_context_pP->ue_context.primaryCC_id, + 0,0,0,0,0, #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) -0, -#endif - ue_context_pP->ue_context.rnti, - (LTE_BCCH_BCH_Message_t *) NULL, - (LTE_RadioResourceConfigCommonSIB_t*) NULL, -#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - (LTE_RadioResourceConfigCommonSIB_t*) NULL, + 0, #endif - ue_context_pP->ue_context.physicalConfigDedicated, + ue_context_pP->ue_context.rnti, + (LTE_BCCH_BCH_Message_t *) NULL, + (LTE_RadioResourceConfigCommonSIB_t *) NULL, +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + (LTE_RadioResourceConfigCommonSIB_t *) NULL, +#endif + ue_context_pP->ue_context.physicalConfigDedicated, #if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) - (LTE_SCellToAddMod_r10_t *)NULL, - //(struct LTE_PhysicalConfigDedicatedSCell_r10 *)NULL, + (LTE_SCellToAddMod_r10_t *)NULL, + //(struct LTE_PhysicalConfigDedicatedSCell_r10 *)NULL, #endif - (LTE_MeasObjectToAddMod_t **) NULL, - ue_context_pP->ue_context.mac_MainConfig, - 1, - SRB1_logicalChannelConfig, - ue_context_pP->ue_context.measGapConfig, - (LTE_TDD_Config_t*) NULL, - (LTE_MobilityControlInfo_t*) NULL, - (LTE_SchedulingInfoList_t*) NULL, - 0, - NULL, - NULL, - (LTE_MBSFN_SubframeConfigList_t *) NULL + (LTE_MeasObjectToAddMod_t **) NULL, + ue_context_pP->ue_context.mac_MainConfig, + 1, + SRB1_logicalChannelConfig, + ue_context_pP->ue_context.measGapConfig, + (LTE_TDD_Config_t *) NULL, + (LTE_MobilityControlInfo_t *) NULL, + (LTE_SchedulingInfoList_t *) NULL, + 0, + NULL, + NULL, + (LTE_MBSFN_SubframeConfigList_t *) NULL #if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) - , 0, (LTE_MBSFN_AreaInfoList_r9_t *) NULL, (LTE_PMCH_InfoList_r9_t *) NULL + , 0, (LTE_MBSFN_AreaInfoList_r9_t *) NULL, (LTE_PMCH_InfoList_r9_t *) NULL #endif #if (LTE_RRC_VERSION >= MAKE_VERSION(13, 0, 0)) - , - (LTE_SystemInformationBlockType1_v1310_IEs_t *)NULL + , + (LTE_SystemInformationBlockType1_v1310_IEs_t *)NULL #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 = LTE_SRB_ToAddMod__rlc_Config_PR_explicitValue; SRB2_rlc_config->choice.explicitValue.present = LTE_RLC_Config_PR_am; SRB2_rlc_config->choice.explicitValue.choice.am.ul_AM_RLC.t_PollRetransmit = LTE_T_PollRetransmit_ms15; @@ -4756,34 +4368,26 @@ rrc_eNB_generate_RRCConnectionReconfiguration_handover( SRB2_rlc_config->choice.explicitValue.choice.am.ul_AM_RLC.maxRetxThreshold = LTE_UL_AM_RLC__maxRetxThreshold_t32; SRB2_rlc_config->choice.explicitValue.choice.am.dl_AM_RLC.t_Reordering = LTE_T_Reordering_ms35; SRB2_rlc_config->choice.explicitValue.choice.am.dl_AM_RLC.t_StatusProhibit = LTE_T_StatusProhibit_ms10; - SRB2_lchan_config = CALLOC(1, sizeof(*SRB2_lchan_config)); SRB2_config->logicalChannelConfig = SRB2_lchan_config; - SRB2_lchan_config->present = LTE_SRB_ToAddMod__logicalChannelConfig_PR_explicitValue; - SRB2_ul_SpecificParameters = CALLOC(1, sizeof(*SRB2_ul_SpecificParameters)); - SRB2_ul_SpecificParameters->priority = 1; SRB2_ul_SpecificParameters->prioritisedBitRate = LTE_LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_infinity; SRB2_ul_SpecificParameters->bucketSizeDuration = LTE_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 = (LTE_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 = (LTE_DRB_Identity_t) 1; // (ue_mod_idP+1); //allowed values 1..32 @@ -4795,7 +4399,6 @@ rrc_eNB_generate_RRCConnectionReconfiguration_handover( DRB_rlc_config->choice.um_Bi_Directional.ul_UM_RLC.sn_FieldLength = LTE_SN_FieldLength_size10; DRB_rlc_config->choice.um_Bi_Directional.dl_UM_RLC.sn_FieldLength = LTE_SN_FieldLength_size10; DRB_rlc_config->choice.um_Bi_Directional.dl_UM_RLC.t_Reordering = LTE_T_Reordering_ms35; - DRB_pdcp_config = CALLOC(1, sizeof(*DRB_pdcp_config)); DRB_config->pdcp_Config = DRB_pdcp_config; DRB_pdcp_config->discardTimer = NULL; @@ -4804,53 +4407,37 @@ rrc_eNB_generate_RRCConnectionReconfiguration_handover( DRB_pdcp_config->rlc_UM = PDCP_rlc_UM; PDCP_rlc_UM->pdcp_SN_Size = LTE_PDCP_Config__rlc_UM__pdcp_SN_Size_len12bits; DRB_pdcp_config->headerCompression.present = LTE_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 = LTE_LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_infinity; DRB_ul_SpecificParameters->bucketSizeDuration = LTE_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)); ue_context_pP->ue_context.mac_MainConfig = mac_MainConfig; - mac_MainConfig->ul_SCH_Config = CALLOC(1, sizeof(*mac_MainConfig->ul_SCH_Config)); - maxHARQ_Tx = CALLOC(1, sizeof(long)); *maxHARQ_Tx = LTE_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 = LTE_PeriodicBSR_Timer_r12_sf64; mac_MainConfig->ul_SCH_Config->periodicBSR_Timer = periodicBSR_Timer; - mac_MainConfig->ul_SCH_Config->retxBSR_Timer = LTE_RetxBSR_Timer_r12_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 = LTE_MAC_MainConfig__phr_Config_PR_setup; mac_MainConfig->phr_Config->choice.setup.periodicPHR_Timer = LTE_MAC_MainConfig__phr_Config__setup__periodicPHR_Timer_sf20; // sf20 = 20 subframes - mac_MainConfig->phr_Config->choice.setup.prohibitPHR_Timer = LTE_MAC_MainConfig__phr_Config__setup__prohibitPHR_Timer_sf20; // sf20 = 20 subframes - mac_MainConfig->phr_Config->choice.setup.dl_PathlossChange = LTE_MAC_MainConfig__phr_Config__setup__dl_PathlossChange_dB1; // Value dB1 =1 dB, dB3 = 3 dB - #if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) 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 @@ -4861,54 +4448,43 @@ rrc_eNB_generate_RRCConnectionReconfiguration_handover( // 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); - // LTE_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 = LTE_MeasObjectToAddMod__measObject_PR_measObjectEUTRA; MeasObj->measObject.choice.measObjectEUTRA.carrierFreq = 36090; @@ -4919,7 +4495,6 @@ rrc_eNB_generate_RRCConnectionReconfiguration_handover( 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 = (LTE_CellsToAddModList_t *) CALLOC(1, sizeof(*CellsToAddModList)); CellsToAddModList = MeasObj->measObject.choice.measObjectEUTRA.cellsToAddModList; @@ -4930,28 +4505,19 @@ rrc_eNB_generate_RRCConnectionReconfiguration_handover( CellToAdd->cellIndex = i + 1; CellToAdd->physCellId = get_adjacent_cell_id(ctxt_pP->module_id, i); CellToAdd->cellIndividualOffset = LTE_Q_OffsetRange_dB0; - ASN_SEQUENCE_ADD(&CellsToAddModList->list, CellToAdd); } ASN_SEQUENCE_ADD(&MeasObj_list->list, MeasObj); // LTE_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)); - ReportConfig_per = CALLOC(1, sizeof(*ReportConfig_per)); - ReportConfig_A1 = CALLOC(1, sizeof(*ReportConfig_A1)); - ReportConfig_A2 = CALLOC(1, sizeof(*ReportConfig_A2)); - ReportConfig_A3 = CALLOC(1, sizeof(*ReportConfig_A3)); - ReportConfig_A4 = CALLOC(1, sizeof(*ReportConfig_A4)); - ReportConfig_A5 = CALLOC(1, sizeof(*ReportConfig_A5)); - ReportConfig_per->reportConfigId = 1; ReportConfig_per->reportConfig.present = LTE_ReportConfigToAddMod__reportConfig_PR_reportConfigEUTRA; ReportConfig_per->reportConfig.choice.reportConfigEUTRA.triggerType.present = @@ -4963,9 +4529,7 @@ rrc_eNB_generate_RRCConnectionReconfiguration_handover( ReportConfig_per->reportConfig.choice.reportConfigEUTRA.maxReportCells = 2; ReportConfig_per->reportConfig.choice.reportConfigEUTRA.reportInterval = LTE_ReportInterval_ms120; ReportConfig_per->reportConfig.choice.reportConfigEUTRA.reportAmount = LTE_ReportConfigEUTRA__reportAmount_infinity; - ASN_SEQUENCE_ADD(&ReportConfig_list->list, ReportConfig_per); - ReportConfig_A1->reportConfigId = 2; ReportConfig_A1->reportConfig.present = LTE_ReportConfigToAddMod__reportConfig_PR_reportConfigEUTRA; ReportConfig_A1->reportConfig.choice.reportConfigEUTRA.triggerType.present = @@ -4976,15 +4540,12 @@ rrc_eNB_generate_RRCConnectionReconfiguration_handover( a1_Threshold.present = LTE_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 = LTE_ReportConfigEUTRA__triggerQuantity_rsrp; ReportConfig_A1->reportConfig.choice.reportConfigEUTRA.reportQuantity = LTE_ReportConfigEUTRA__reportQuantity_both; ReportConfig_A1->reportConfig.choice.reportConfigEUTRA.maxReportCells = 2; ReportConfig_A1->reportConfig.choice.reportConfigEUTRA.reportInterval = LTE_ReportInterval_ms120; ReportConfig_A1->reportConfig.choice.reportConfigEUTRA.reportAmount = LTE_ReportConfigEUTRA__reportAmount_infinity; - ASN_SEQUENCE_ADD(&ReportConfig_list->list, ReportConfig_A1); - ReportConfig_A2->reportConfigId = 3; ReportConfig_A2->reportConfig.present = LTE_ReportConfigToAddMod__reportConfig_PR_reportConfigEUTRA; ReportConfig_A2->reportConfig.choice.reportConfigEUTRA.triggerType.present = @@ -4995,15 +4556,12 @@ rrc_eNB_generate_RRCConnectionReconfiguration_handover( a2_Threshold.present = LTE_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 = LTE_ReportConfigEUTRA__triggerQuantity_rsrp; ReportConfig_A2->reportConfig.choice.reportConfigEUTRA.reportQuantity = LTE_ReportConfigEUTRA__reportQuantity_both; ReportConfig_A2->reportConfig.choice.reportConfigEUTRA.maxReportCells = 2; ReportConfig_A2->reportConfig.choice.reportConfigEUTRA.reportInterval = LTE_ReportInterval_ms120; ReportConfig_A2->reportConfig.choice.reportConfigEUTRA.reportAmount = LTE_ReportConfigEUTRA__reportAmount_infinity; - ASN_SEQUENCE_ADD(&ReportConfig_list->list, ReportConfig_A2); - ReportConfig_A3->reportConfigId = 4; ReportConfig_A3->reportConfig.present = LTE_ReportConfigToAddMod__reportConfig_PR_reportConfigEUTRA; ReportConfig_A3->reportConfig.choice.reportConfigEUTRA.triggerType.present = @@ -5014,15 +4572,12 @@ rrc_eNB_generate_RRCConnectionReconfiguration_handover( 10; ReportConfig_A3->reportConfig.choice.reportConfigEUTRA.triggerType.choice.event.eventId.choice. eventA3.reportOnLeave = 1; - ReportConfig_A3->reportConfig.choice.reportConfigEUTRA.triggerQuantity = LTE_ReportConfigEUTRA__triggerQuantity_rsrp; ReportConfig_A3->reportConfig.choice.reportConfigEUTRA.reportQuantity = LTE_ReportConfigEUTRA__reportQuantity_both; ReportConfig_A3->reportConfig.choice.reportConfigEUTRA.maxReportCells = 2; ReportConfig_A3->reportConfig.choice.reportConfigEUTRA.reportInterval = LTE_ReportInterval_ms120; ReportConfig_A3->reportConfig.choice.reportConfigEUTRA.reportAmount = LTE_ReportConfigEUTRA__reportAmount_infinity; - ASN_SEQUENCE_ADD(&ReportConfig_list->list, ReportConfig_A3); - ReportConfig_A4->reportConfigId = 5; ReportConfig_A4->reportConfig.present = LTE_ReportConfigToAddMod__reportConfig_PR_reportConfigEUTRA; ReportConfig_A4->reportConfig.choice.reportConfigEUTRA.triggerType.present = @@ -5033,15 +4588,12 @@ rrc_eNB_generate_RRCConnectionReconfiguration_handover( a4_Threshold.present = LTE_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 = LTE_ReportConfigEUTRA__triggerQuantity_rsrp; ReportConfig_A4->reportConfig.choice.reportConfigEUTRA.reportQuantity = LTE_ReportConfigEUTRA__reportQuantity_both; ReportConfig_A4->reportConfig.choice.reportConfigEUTRA.maxReportCells = 2; ReportConfig_A4->reportConfig.choice.reportConfigEUTRA.reportInterval = LTE_ReportInterval_ms120; ReportConfig_A4->reportConfig.choice.reportConfigEUTRA.reportAmount = LTE_ReportConfigEUTRA__reportAmount_infinity; - ASN_SEQUENCE_ADD(&ReportConfig_list->list, ReportConfig_A4); - ReportConfig_A5->reportConfigId = 6; ReportConfig_A5->reportConfig.present = LTE_ReportConfigToAddMod__reportConfig_PR_reportConfigEUTRA; ReportConfig_A5->reportConfig.choice.reportConfigEUTRA.triggerType.present = @@ -5056,15 +4608,12 @@ rrc_eNB_generate_RRCConnectionReconfiguration_handover( 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 = LTE_ReportConfigEUTRA__triggerQuantity_rsrp; ReportConfig_A5->reportConfig.choice.reportConfigEUTRA.reportQuantity = LTE_ReportConfigEUTRA__reportQuantity_both; ReportConfig_A5->reportConfig.choice.reportConfigEUTRA.maxReportCells = 2; ReportConfig_A5->reportConfig.choice.reportConfigEUTRA.reportInterval = LTE_ReportInterval_ms120; ReportConfig_A5->reportConfig.choice.reportConfigEUTRA.reportAmount = LTE_ReportConfigEUTRA__reportAmount_infinity; - ASN_SEQUENCE_ADD(&ReportConfig_list->list, ReportConfig_A5); - Sparams = CALLOC(1, sizeof(*Sparams)); Sparams->present = LTE_MeasConfig__speedStatePars_PR_setup; Sparams->choice.setup.timeToTrigger_SF.sf_High = LTE_SpeedStateScaleFactors__sf_Medium_oDot75; @@ -5073,7 +4622,6 @@ rrc_eNB_generate_RRCConnectionReconfiguration_handover( Sparams->choice.setup.mobilityStateParameters.n_CellChangeMedium = 5; Sparams->choice.setup.mobilityStateParameters.t_Evaluation = LTE_MobilityStateParameters__t_Evaluation_s60; Sparams->choice.setup.mobilityStateParameters.t_HystNormal = LTE_MobilityStateParameters__t_HystNormal_s120; - quantityConfig = CALLOC(1, sizeof(*quantityConfig)); memset((void *)quantityConfig, 0, sizeof(*quantityConfig)); quantityConfig->quantityConfigEUTRA = CALLOC(1, sizeof(*quantityConfig->quantityConfigEUTRA)); @@ -5087,9 +4635,7 @@ rrc_eNB_generate_RRCConnectionReconfiguration_handover( CALLOC(1, sizeof(*quantityConfig->quantityConfigEUTRA->filterCoefficientRSRQ)); *quantityConfig->quantityConfigEUTRA->filterCoefficientRSRP = LTE_FilterCoefficient_fc4; *quantityConfig->quantityConfigEUTRA->filterCoefficientRSRQ = LTE_FilterCoefficient_fc4; - /* mobilityinfo */ - mobilityInfo = CALLOC(1, sizeof(*mobilityInfo)); memset((void *)mobilityInfo, 0, sizeof(*mobilityInfo)); mobilityInfo->targetPhysCellId = @@ -5100,22 +4646,17 @@ rrc_eNB_generate_RRCConnectionReconfiguration_handover( mobilityInfo->targetPhysCellId, ctxt_pP->module_id, ue_context_pP->ue_context.rnti); - mobilityInfo->additionalSpectrumEmission = CALLOC(1, sizeof(*mobilityInfo->additionalSpectrumEmission)); *mobilityInfo->additionalSpectrumEmission = 1; //Check this value! - mobilityInfo->t304 = LTE_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)); @@ -5126,7 +4667,6 @@ rrc_eNB_generate_RRCConnectionReconfiguration_handover( memcpy((void *)mobilityInfo->radioResourceConfigCommon.prach_Config.prach_ConfigInfo, (void *)&rrc_inst->carrier[0] /* CROUX TBC */.sib2->radioResourceConfigCommon.prach_Config.prach_ConfigInfo, sizeof(LTE_PRACH_ConfigInfo_t)); - mobilityInfo->radioResourceConfigCommon.prach_Config.rootSequenceIndex = rrc_inst->carrier[0] /* CROUX TBC */.sib2->radioResourceConfigCommon.prach_Config.rootSequenceIndex; mobilityInfo->radioResourceConfigCommon.pdsch_ConfigCommon = @@ -5158,31 +4698,27 @@ rrc_eNB_generate_RRCConnectionReconfiguration_handover( mobilityInfo->radioResourceConfigCommon.ul_CyclicPrefixLength = rrc_inst->carrier[0] /* CROUX TBC */.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 LTE_CarrierBandwidthEUTRA)); LTE_AllowedMeasBandwidth_mbw25 mobilityInfo->carrierBandwidth->dl_Bandwidth = LTE_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(ue_context_pP->ue_context.handover_info->as_config.sourceRadioResourceConfig.srb_ToAddModList, - (void*)SRB_configList2, + (void *)SRB_configList2, sizeof(LTE_SRB_ToAddModList_t)); - memcpy((void*)ue_context_pP->ue_context.handover_info->as_config.sourceRadioResourceConfig.drb_ToAddModList, - (void*)DRB_configList2, + memcpy((void *)ue_context_pP->ue_context.handover_info->as_config.sourceRadioResourceConfig.drb_ToAddModList, + (void *)DRB_configList2, sizeof(LTE_DRB_ToAddModList_t)); ue_context_pP->ue_context.handover_info->as_config.sourceRadioResourceConfig.drb_ToReleaseList = NULL; - memcpy((void*)ue_context_pP->ue_context.handover_info->as_config.sourceRadioResourceConfig.mac_MainConfig, - (void*)mac_MainConfig, + memcpy((void *)ue_context_pP->ue_context.handover_info->as_config.sourceRadioResourceConfig.mac_MainConfig, + (void *)mac_MainConfig, sizeof(LTE_MAC_MainConfig_t)); - memcpy((void*)ue_context_pP->ue_context.handover_info->as_config.sourceRadioResourceConfig.physicalConfigDedicated, - (void*)ue_context_pP->ue_context.physicalConfigDedicated, + memcpy((void *)ue_context_pP->ue_context.handover_info->as_config.sourceRadioResourceConfig.physicalConfigDedicated, + (void *)ue_context_pP->ue_context.physicalConfigDedicated, sizeof(LTE_PhysicalConfigDedicated_t)); /* memcpy((void *)rrc_inst->handover_info[ue_mod_idP]->as_config.sourceRadioResourceConfig.sps_Config, (void *)rrc_inst->sps_Config[ue_mod_idP], @@ -5197,19 +4733,15 @@ rrc_eNB_generate_RRCConnectionReconfiguration_handover( ue_context_pP->ue_context.Srb1.Srb_info.Srb_id = Idx; memcpy(&ue_context_pP->ue_context.Srb1.Srb_info.Lchan_desc[0], &DCCH_LCHAN_DESC, LCHAN_DESC_SIZE); memcpy(&ue_context_pP->ue_context.Srb1.Srb_info.Lchan_desc[1], &DCCH_LCHAN_DESC, LCHAN_DESC_SIZE); - - // SRB2 + // SRB2 ue_context_pP->ue_context.Srb2.Active = 1; ue_context_pP->ue_context.Srb2.Srb_info.Srb_id = Idx; memcpy(&ue_context_pP->ue_context.Srb2.Srb_info.Lchan_desc[0], &DCCH_LCHAN_DESC, LCHAN_DESC_SIZE); memcpy(&ue_context_pP->ue_context.Srb2.Srb_info.Lchan_desc[1], &DCCH_LCHAN_DESC, LCHAN_DESC_SIZE); - LOG_I(RRC, "[eNB %d] CALLING RLC CONFIG SRB1 (rbid %d) for UE %x\n", ctxt_pP->module_id, Idx, ue_context_pP->ue_context.rnti); - // rrc_pdcp_config_req (enb_mod_idP, frameP, 1, CONFIG_ACTION_ADD, idx, UNDEF_SECURITY_MODE); // rrc_rlc_config_req(enb_mod_idP,frameP,1,CONFIG_ACTION_ADD,Idx,SIGNALLING_RADIO_BEARER,Rlc_info_am_config); - rrc_pdcp_config_asn1_req(&ctxt, ue_context_pP->ue_context.SRB_configList, (LTE_DRB_ToAddModList_t *) NULL, (LTE_DRB_ToReleaseList_t *) NULL, 0xff, NULL, NULL, NULL @@ -5217,7 +4749,6 @@ rrc_eNB_generate_RRCConnectionReconfiguration_handover( , (LTE_PMCH_InfoList_r9_t *) NULL #endif ,NULL); - rrc_rlc_config_asn1_req(&ctxt, ue_context_pP->ue_context.SRB_configList, (LTE_DRB_ToAddModList_t *) NULL, (LTE_DRB_ToReleaseList_t *) NULL @@ -5226,47 +4757,46 @@ rrc_eNB_generate_RRCConnectionReconfiguration_handover( , 0, 0 #endif ); - /* Initialize NAS list */ dedicatedInfoNASList = NULL; - // LTE_RRCConnectionReconfiguration->criticalExtensions.choice.c1.choice.rrcConnectionReconfiguration_r8.measConfig->reportConfigToAddModList = ReportConfig_list; memset(buffer, 0, RRC_BUF_SIZE); - - int size=do_RRCConnectionReconfiguration( - ctxt_pP, - buffer, - rrc_eNB_get_next_transaction_identifier(ctxt_pP->module_id), //Transaction_id, - SRB_configList2, - DRB_configList2, - NULL, // DRB2_list, - NULL, //*sps_Config, - ue_context_pP->ue_context.physicalConfigDedicated, - MeasObj_list, - ReportConfig_list, - NULL, //quantityConfig, - MeasId_list, - mac_MainConfig, - NULL, - mobilityInfo, - Sparams, - NULL, - NULL, - dedicatedInfoNASList, - (LTE_SL_CommConfig_r12_t*)NULL, - (LTE_SL_DiscConfig_r12_t*)NULL + int size=do_RRCConnectionReconfiguration( + ctxt_pP, + buffer, + rrc_eNB_get_next_transaction_identifier(ctxt_pP->module_id), //Transaction_id, + SRB_configList2, + DRB_configList2, + NULL, // DRB2_list, + NULL, //*sps_Config, + ue_context_pP->ue_context.physicalConfigDedicated, + MeasObj_list, + ReportConfig_list, + NULL, //quantityConfig, + MeasId_list, + mac_MainConfig, + NULL, + mobilityInfo, + Sparams, + NULL, + NULL, + dedicatedInfoNASList, + (LTE_SL_CommConfig_r12_t *)NULL, + (LTE_SL_DiscConfig_r12_t *)NULL #if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) - , NULL // SCellToAddMod_r10_t + , NULL // SCellToAddMod_r10_t #endif - ); - if (size <= 0) - LOG_E(RRC, - "[eNB %d] Frame %d, Logical Channel DL-DCCH, Generate LTE_RRCConnectionReconfiguration for handover (bytes %d, UE rnti %x) failed\n", - ctxt_pP->module_id, ctxt_pP->frame, size, ue_context_pP->ue_context.rnti); - else - LOG_I(RRC, - "[eNB %d] Frame %d, Logical Channel DL-DCCH, Generate LTE_RRCConnectionReconfiguration for handover (bytes %d, UE rnti %x)\n", - ctxt_pP->module_id, ctxt_pP->frame, size, ue_context_pP->ue_context.rnti); + ); + + if (size <= 0) + LOG_E(RRC, + "[eNB %d] Frame %d, Logical Channel DL-DCCH, Generate LTE_RRCConnectionReconfiguration for handover (bytes %d, UE rnti %x) failed\n", + ctxt_pP->module_id, ctxt_pP->frame, size, ue_context_pP->ue_context.rnti); + else + LOG_I(RRC, + "[eNB %d] Frame %d, Logical Channel DL-DCCH, Generate LTE_RRCConnectionReconfiguration for handover (bytes %d, UE rnti %x)\n", + ctxt_pP->module_id, ctxt_pP->frame, size, ue_context_pP->ue_context.rnti); + // to be updated if needed /*if (RC.rrc[ctxt_pP->module_id]->SRB1_config[ue_mod_idP]->logicalChannelConfig) { if (RC.rrc[ctxt_pP->module_id]->SRB1_config[ue_mod_idP]->logicalChannelConfig->present == LTE_SRB_ToAddMod__logicalChannelConfig_PR_explicitValue) { @@ -5280,55 +4810,52 @@ rrc_eNB_generate_RRCConnectionReconfiguration_handover( SRB1_logicalChannelConfig = &SRB1_logicalChannelConfig_defaultValue; } */ - LOG_D(RRC, "[FRAME %05d][RRC_eNB][MOD %02d][][--- PDCP_DATA_REQ/%d Bytes (rrcConnectionReconfiguration_handover to UE %x MUI %d) --->][PDCP][MOD %02d][RB %02d]\n", ctxt_pP->frame, ctxt_pP->module_id, size, ue_context_pP->ue_context.rnti, rrc_eNB_mui, ctxt_pP->module_id, DCCH); //rrc_rlc_data_req(ctxt_pP->module_id,frameP, 1,(ue_mod_idP*NB_RB_MAX)+DCCH,rrc_eNB_mui++,0,size,(char*)buffer); //pdcp_data_req (ctxt_pP->module_id, frameP, 1, (ue_mod_idP * NB_RB_MAX) + DCCH,rrc_eNB_mui++, 0, size, (char *) buffer, 1); - rrc_mac_config_req_eNB( - ctxt_pP->module_id, - ue_context_pP->ue_context.primaryCC_id, - 0,0,0,0,0, + ctxt_pP->module_id, + ue_context_pP->ue_context.primaryCC_id, + 0,0,0,0,0, #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - 0, + 0, #endif - ue_context_pP->ue_context.rnti, - (LTE_BCCH_BCH_Message_t *) NULL, - (LTE_RadioResourceConfigCommonSIB_t *) NULL, + ue_context_pP->ue_context.rnti, + (LTE_BCCH_BCH_Message_t *) NULL, + (LTE_RadioResourceConfigCommonSIB_t *) NULL, #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - (LTE_RadioResourceConfigCommonSIB_t *) NULL, + (LTE_RadioResourceConfigCommonSIB_t *) NULL, #endif - ue_context_pP->ue_context.physicalConfigDedicated, + ue_context_pP->ue_context.physicalConfigDedicated, #if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) - (LTE_SCellToAddMod_r10_t *)NULL, - //(struct LTE_PhysicalConfigDedicatedSCell_r10 *)NULL, + (LTE_SCellToAddMod_r10_t *)NULL, + //(struct LTE_PhysicalConfigDedicatedSCell_r10 *)NULL, #endif - (LTE_MeasObjectToAddMod_t **) NULL, - ue_context_pP->ue_context.mac_MainConfig, - 1, - SRB1_logicalChannelConfig, - ue_context_pP->ue_context.measGapConfig, - (LTE_TDD_Config_t *) NULL, - (LTE_MobilityControlInfo_t *) mobilityInfo, - (LTE_SchedulingInfoList_t *) NULL, 0, NULL, NULL, (LTE_MBSFN_SubframeConfigList_t *) NULL + (LTE_MeasObjectToAddMod_t **) NULL, + ue_context_pP->ue_context.mac_MainConfig, + 1, + SRB1_logicalChannelConfig, + ue_context_pP->ue_context.measGapConfig, + (LTE_TDD_Config_t *) NULL, + (LTE_MobilityControlInfo_t *) mobilityInfo, + (LTE_SchedulingInfoList_t *) NULL, 0, NULL, NULL, (LTE_MBSFN_SubframeConfigList_t *) NULL #if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) - , 0, (LTE_MBSFN_AreaInfoList_r9_t *) NULL, (LTE_PMCH_InfoList_r9_t *) NULL + , 0, (LTE_MBSFN_AreaInfoList_r9_t *) NULL, (LTE_PMCH_InfoList_r9_t *) NULL #endif #if (LTE_RRC_VERSION >= MAKE_VERSION(13, 0, 0)) - , - (LTE_SystemInformationBlockType1_v1310_IEs_t *)NULL + , + (LTE_SystemInformationBlockType1_v1310_IEs_t *)NULL #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; */ -//#warning "COMPILATION PROBLEM" + //#warning "COMPILATION PROBLEM" #ifdef PROBLEM_COMPILATION_RESOLVED if (sourceModId != 0xFF) { @@ -5379,8 +4906,8 @@ rrc_eNB_generate_RRCConnectionReconfiguration_handover( */ void rrc_eNB_process_RRCConnectionReconfigurationComplete( - const protocol_ctxt_t* const ctxt_pP, - rrc_eNB_ue_context_t* ue_context_pP, + const protocol_ctxt_t *const ctxt_pP, + rrc_eNB_ue_context_t *ue_context_pP, const uint8_t xid ) //----------------------------------------------------------------------------- @@ -5393,20 +4920,16 @@ rrc_eNB_process_RRCConnectionReconfigurationComplete( (void)oip_ifup; (void)dest_ip_offset; #endif - uint8_t *kRRCenc = NULL; uint8_t *kRRCint = NULL; uint8_t *kUPenc = NULL; ue_context_pP->ue_context.ue_reestablishment_timer = 0; - - LTE_DRB_ToAddModList_t* DRB_configList = ue_context_pP->ue_context.DRB_configList2[xid]; - LTE_SRB_ToAddModList_t* SRB_configList = ue_context_pP->ue_context.SRB_configList2[xid]; - LTE_DRB_ToReleaseList_t* DRB_Release_configList2 = ue_context_pP->ue_context.DRB_Release_configList2[xid]; - LTE_DRB_Identity_t* drb_id_p = NULL; - + LTE_DRB_ToAddModList_t *DRB_configList = ue_context_pP->ue_context.DRB_configList2[xid]; + LTE_SRB_ToAddModList_t *SRB_configList = ue_context_pP->ue_context.SRB_configList2[xid]; + LTE_DRB_ToReleaseList_t *DRB_Release_configList2 = ue_context_pP->ue_context.DRB_Release_configList2[xid]; + LTE_DRB_Identity_t *drb_id_p = NULL; T(T_ENB_RRC_CONNECTION_RECONFIGURATION_COMPLETE, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame), T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti)); - #if defined(ENABLE_SECURITY) /* Derive the keys from kenb */ @@ -5419,9 +4942,7 @@ rrc_eNB_process_RRCConnectionReconfigurationComplete( ue_context_pP->ue_context.kenb, &kRRCenc); derive_key_rrc_int(ue_context_pP->ue_context.integrity_algorithm, ue_context_pP->ue_context.kenb, &kRRCint); - #endif - // Refresh SRBs/DRBs MSC_LOG_TX_MESSAGE( MSC_RRC_ENB, @@ -5431,12 +4952,11 @@ rrc_eNB_process_RRCConnectionReconfigurationComplete( MSC_AS_TIME_FMT" CONFIG_REQ UE %x DRB (security unchanged)", MSC_AS_TIME_ARGS(ctxt_pP), ue_context_pP->ue_context.rnti); - rrc_pdcp_config_asn1_req( ctxt_pP, SRB_configList, //NULL, //LG-RK 14/05/2014 SRB_configList, - DRB_configList, -// (LTE_DRB_ToReleaseList_t *) NULL, + DRB_configList, + // (LTE_DRB_ToReleaseList_t *) NULL, DRB_Release_configList2, /*RC.rrc[ctxt_pP->module_id]->ciphering_algorithm[ue_mod_idP] | (RC.rrc[ctxt_pP->module_id]->integrity_algorithm[ue_mod_idP] << 4), @@ -5454,45 +4974,45 @@ rrc_eNB_process_RRCConnectionReconfigurationComplete( ctxt_pP, SRB_configList, // NULL, //LG-RK 14/05/2014 SRB_configList, DRB_configList, -// (LTE_DRB_ToReleaseList_t *) NULL + // (LTE_DRB_ToReleaseList_t *) NULL DRB_Release_configList2 #if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) , (LTE_PMCH_InfoList_r9_t *) NULL , 0, 0 #endif ); - + // set the SRB active in Ue context if (SRB_configList != NULL) { for (i = 0; (i < SRB_configList->list.count) && (i < 3); i++) { - if (SRB_configList->list.array[i]->srb_Identity == 1 ){ - ue_context_pP->ue_context.Srb1.Active=1; - } - else if (SRB_configList->list.array[i]->srb_Identity == 2 ) { - ue_context_pP->ue_context.Srb2.Active=1; - ue_context_pP->ue_context.Srb2.Srb_info.Srb_id=2; - LOG_I(RRC,"[eNB %d] Frame %d CC %d : SRB2 is now active\n", - ctxt_pP->module_id, - ctxt_pP->frame, - ue_context_pP->ue_context.primaryCC_id); + if (SRB_configList->list.array[i]->srb_Identity == 1 ) { + ue_context_pP->ue_context.Srb1.Active=1; + } else if (SRB_configList->list.array[i]->srb_Identity == 2 ) { + ue_context_pP->ue_context.Srb2.Active=1; + ue_context_pP->ue_context.Srb2.Srb_info.Srb_id=2; + LOG_I(RRC,"[eNB %d] Frame %d CC %d : SRB2 is now active\n", + ctxt_pP->module_id, + ctxt_pP->frame, + ue_context_pP->ue_context.primaryCC_id); } else { - LOG_W(RRC,"[eNB %d] Frame %d CC %d : invalide SRB identity %ld\n", - ctxt_pP->module_id, - ctxt_pP->frame, + LOG_W(RRC,"[eNB %d] Frame %d CC %d : invalide SRB identity %ld\n", + ctxt_pP->module_id, + ctxt_pP->frame, ue_context_pP->ue_context.primaryCC_id, - SRB_configList->list.array[i]->srb_Identity); + SRB_configList->list.array[i]->srb_Identity); } } + free(SRB_configList); ue_context_pP->ue_context.SRB_configList2[xid] = NULL; } - + // Loop through DRBs and establish if necessary if (DRB_configList != NULL) { for (i = 0; i < DRB_configList->list.count; i++) { // num max DRB (11-3-8) if (DRB_configList->list.array[i]) { - drb_id = (int)DRB_configList->list.array[i]->drb_Identity; + drb_id = (int)DRB_configList->list.array[i]->drb_Identity; LOG_I(RRC, "[eNB %d] Frame %d : Logical Channel UL-DCCH, Received LTE_RRCConnectionReconfigurationComplete from UE rnti %x, reconfiguring DRB %d/LCID %d\n", ctxt_pP->module_id, @@ -5518,7 +5038,6 @@ rrc_eNB_process_RRCConnectionReconfigurationComplete( RADIO_ACCESS_BEARER,Rlc_info_um); */ ue_context_pP->ue_context.DRB_active[drb_id] = 1; - LOG_D(RRC, "[eNB %d] Frame %d: Establish RLC UM Bidirectional, DRB %d Active\n", ctxt_pP->module_id, ctxt_pP->frame, (int)DRB_configList->list.array[i]->drb_Identity); @@ -5534,7 +5053,7 @@ rrc_eNB_process_RRCConnectionReconfigurationComplete( ctxt_pP->module_id + 1); // fourth octet if (oip_ifup == 0) { // interface is up --> send a config the DRB - module_id_t ue_module_id; + module_id_t ue_module_id; dest_ip_offset = 8; LOG_I(OIP, "[eNB %d] Config the oai%d to send/receive pkt on DRB %ld to/from the protocol stack\n", @@ -5554,7 +5073,6 @@ rrc_eNB_process_RRCConnectionReconfigurationComplete( # endif #endif - LOG_D(RRC, PROTOCOL_RRC_CTXT_UE_FMT" RRC_eNB --- MAC_CONFIG_REQ (DRB) ---> MAC_eNB\n", PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP)); @@ -5564,43 +5082,41 @@ rrc_eNB_process_RRCConnectionReconfigurationComplete( } rrc_mac_config_req_eNB( - ctxt_pP->module_id, - ue_context_pP->ue_context.primaryCC_id, - 0,0,0,0,0, + ctxt_pP->module_id, + ue_context_pP->ue_context.primaryCC_id, + 0,0,0,0,0, #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - 0, + 0, #endif - ue_context_pP->ue_context.rnti, - (LTE_BCCH_BCH_Message_t *) NULL, - (LTE_RadioResourceConfigCommonSIB_t *) NULL, + ue_context_pP->ue_context.rnti, + (LTE_BCCH_BCH_Message_t *) NULL, + (LTE_RadioResourceConfigCommonSIB_t *) NULL, #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - (LTE_RadioResourceConfigCommonSIB_t *) NULL, + (LTE_RadioResourceConfigCommonSIB_t *) NULL, #endif - ue_context_pP->ue_context.physicalConfigDedicated, + ue_context_pP->ue_context.physicalConfigDedicated, #if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) - (LTE_SCellToAddMod_r10_t *)NULL, - //(struct LTE_PhysicalConfigDedicatedSCell_r10 *)NULL, + (LTE_SCellToAddMod_r10_t *)NULL, + //(struct LTE_PhysicalConfigDedicatedSCell_r10 *)NULL, #endif - (LTE_MeasObjectToAddMod_t **) NULL, - ue_context_pP->ue_context.mac_MainConfig, - DRB2LCHAN[i], - DRB_configList->list.array[i]->logicalChannelConfig, - ue_context_pP->ue_context.measGapConfig, - (LTE_TDD_Config_t *) NULL, - NULL, - (LTE_SchedulingInfoList_t *) NULL, - 0, NULL, NULL, (LTE_MBSFN_SubframeConfigList_t *) NULL + (LTE_MeasObjectToAddMod_t **) NULL, + ue_context_pP->ue_context.mac_MainConfig, + DRB2LCHAN[i], + DRB_configList->list.array[i]->logicalChannelConfig, + ue_context_pP->ue_context.measGapConfig, + (LTE_TDD_Config_t *) NULL, + NULL, + (LTE_SchedulingInfoList_t *) NULL, + 0, NULL, NULL, (LTE_MBSFN_SubframeConfigList_t *) NULL #if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) - , 0, (LTE_MBSFN_AreaInfoList_r9_t *) NULL, (LTE_PMCH_InfoList_r9_t *) NULL + , 0, (LTE_MBSFN_AreaInfoList_r9_t *) NULL, (LTE_PMCH_InfoList_r9_t *) NULL #endif #if (LTE_RRC_VERSION >= MAKE_VERSION(13, 0, 0)) - , - (LTE_SystemInformationBlockType1_v1310_IEs_t *)NULL + , + (LTE_SystemInformationBlockType1_v1310_IEs_t *)NULL #endif - ); - + ); } else { // remove LCHAN from MAC/PHY - if (ue_context_pP->ue_context.DRB_active[drb_id] == 1) { // DRB has just been removed so remove RLC + PDCP for DRB /* rrc_pdcp_config_req (ctxt_pP->module_id, frameP, 1, CONFIG_ACTION_REMOVE, @@ -5620,90 +5136,89 @@ rrc_eNB_process_RRCConnectionReconfigurationComplete( PROTOCOL_RRC_CTXT_UE_FMT" RRC_eNB --- MAC_CONFIG_REQ (DRB) ---> MAC_eNB\n", PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP)); rrc_mac_config_req_eNB(ctxt_pP->module_id, - ue_context_pP->ue_context.primaryCC_id, - 0,0,0,0,0, + ue_context_pP->ue_context.primaryCC_id, + 0,0,0,0,0, #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - 0, + 0, #endif - ue_context_pP->ue_context.rnti, - (LTE_BCCH_BCH_Message_t *) NULL, - (LTE_RadioResourceConfigCommonSIB_t *) NULL, + ue_context_pP->ue_context.rnti, + (LTE_BCCH_BCH_Message_t *) NULL, + (LTE_RadioResourceConfigCommonSIB_t *) NULL, #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - (LTE_RadioResourceConfigCommonSIB_t *) NULL, + (LTE_RadioResourceConfigCommonSIB_t *) NULL, #endif - ue_context_pP->ue_context.physicalConfigDedicated, + ue_context_pP->ue_context.physicalConfigDedicated, #if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) - (LTE_SCellToAddMod_r10_t *)NULL, - //(struct LTE_PhysicalConfigDedicatedSCell_r10 *)NULL, + (LTE_SCellToAddMod_r10_t *)NULL, + //(struct LTE_PhysicalConfigDedicatedSCell_r10 *)NULL, #endif - (LTE_MeasObjectToAddMod_t **) NULL, - ue_context_pP->ue_context.mac_MainConfig, - DRB2LCHAN[i], - (LTE_LogicalChannelConfig_t *) NULL, - (LTE_MeasGapConfig_t *) NULL, - (LTE_TDD_Config_t *) NULL, - NULL, - (LTE_SchedulingInfoList_t *) NULL, - 0, NULL, NULL, NULL + (LTE_MeasObjectToAddMod_t **) NULL, + ue_context_pP->ue_context.mac_MainConfig, + DRB2LCHAN[i], + (LTE_LogicalChannelConfig_t *) NULL, + (LTE_MeasGapConfig_t *) NULL, + (LTE_TDD_Config_t *) NULL, + NULL, + (LTE_SchedulingInfoList_t *) NULL, + 0, NULL, NULL, NULL #if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) - , 0, (LTE_MBSFN_AreaInfoList_r9_t *) NULL, (LTE_PMCH_InfoList_r9_t *) NULL + , 0, (LTE_MBSFN_AreaInfoList_r9_t *) NULL, (LTE_PMCH_InfoList_r9_t *) NULL #endif #if (LTE_RRC_VERSION >= MAKE_VERSION(13, 0, 0)) - , - (LTE_SystemInformationBlockType1_v1310_IEs_t *)NULL + , + (LTE_SystemInformationBlockType1_v1310_IEs_t *)NULL #endif - ); + ); } } } - free(DRB_configList); + + free(DRB_configList); ue_context_pP->ue_context.DRB_configList2[xid] = NULL; } - if(DRB_Release_configList2 != NULL){ - for (i = 0; i < DRB_Release_configList2->list.count; i++) { - if (DRB_Release_configList2->list.array[i]) { - drb_id_p = DRB_Release_configList2->list.array[i]; - drb_id = *drb_id_p; - if (ue_context_pP->ue_context.DRB_active[drb_id] == 1) { - ue_context_pP->ue_context.DRB_active[drb_id] = 0; - } - } + if(DRB_Release_configList2 != NULL) { + for (i = 0; i < DRB_Release_configList2->list.count; i++) { + if (DRB_Release_configList2->list.array[i]) { + drb_id_p = DRB_Release_configList2->list.array[i]; + drb_id = *drb_id_p; + + if (ue_context_pP->ue_context.DRB_active[drb_id] == 1) { + ue_context_pP->ue_context.DRB_active[drb_id] = 0; + } } - free(DRB_Release_configList2); - ue_context_pP->ue_context.DRB_Release_configList2[xid] = NULL; + } + + free(DRB_Release_configList2); + ue_context_pP->ue_context.DRB_Release_configList2[xid] = NULL; } } //----------------------------------------------------------------------------- void rrc_eNB_generate_RRCConnectionSetup( - const protocol_ctxt_t* const ctxt_pP, - rrc_eNB_ue_context_t* const ue_context_pP, + const protocol_ctxt_t *const ctxt_pP, + rrc_eNB_ue_context_t *const ue_context_pP, const int CC_id ) //----------------------------------------------------------------------------- { - LTE_LogicalChannelConfig_t *SRB1_logicalChannelConfig; //,*SRB2_logicalChannelConfig; LTE_SRB_ToAddModList_t **SRB_configList; LTE_SRB_ToAddMod_t *SRB1_config; int cnt; - T(T_ENB_RRC_CONNECTION_SETUP, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame), T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti)); - SRB_configList = &ue_context_pP->ue_context.SRB_configList; RC.rrc[ctxt_pP->module_id]->carrier[CC_id].Srb0.Tx_buffer.payload_size = do_RRCConnectionSetup(ctxt_pP, ue_context_pP, CC_id, - (uint8_t*) RC.rrc[ctxt_pP->module_id]->carrier[CC_id].Srb0.Tx_buffer.Payload, - (uint8_t) RC.rrc[ctxt_pP->module_id]->carrier[CC_id].p_eNB, //at this point we do not have the UE capability information, so it can only be TM1 or TM2 + (uint8_t *) RC.rrc[ctxt_pP->module_id]->carrier[CC_id].Srb0.Tx_buffer.Payload, + (uint8_t) RC.rrc[ctxt_pP->module_id]->carrier[CC_id].p_eNB, //at this point we do not have the UE capability information, so it can only be TM1 or TM2 rrc_eNB_get_next_transaction_identifier(ctxt_pP->module_id), SRB_configList, &ue_context_pP->ue_context.physicalConfigDedicated); - LOG_DUMPMSG(RRC,DEBUG_RRC, (char *)(RC.rrc[ctxt_pP->module_id]->carrier[CC_id].Srb0.Tx_buffer.Payload), RC.rrc[ctxt_pP->module_id]->carrier[CC_id].Srb0.Tx_buffer.payload_size, @@ -5731,40 +5246,40 @@ rrc_eNB_generate_RRCConnectionSetup( PROTOCOL_RRC_CTXT_UE_FMT" RRC_eNB --- MAC_CONFIG_REQ (SRB1) ---> MAC_eNB\n", PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP)); rrc_mac_config_req_eNB( - ctxt_pP->module_id, - ue_context_pP->ue_context.primaryCC_id, - 0,0,0,0,0, + ctxt_pP->module_id, + ue_context_pP->ue_context.primaryCC_id, + 0,0,0,0,0, #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - 0, + 0, #endif - ue_context_pP->ue_context.rnti, - (LTE_BCCH_BCH_Message_t *) NULL, - (LTE_RadioResourceConfigCommonSIB_t *) NULL, + ue_context_pP->ue_context.rnti, + (LTE_BCCH_BCH_Message_t *) NULL, + (LTE_RadioResourceConfigCommonSIB_t *) NULL, #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - (LTE_RadioResourceConfigCommonSIB_t *) NULL, + (LTE_RadioResourceConfigCommonSIB_t *) NULL, #endif - ue_context_pP->ue_context.physicalConfigDedicated, + ue_context_pP->ue_context.physicalConfigDedicated, #if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) - (LTE_SCellToAddMod_r10_t *)NULL, - //(struct LTE_PhysicalConfigDedicatedSCell_r10 *)NULL, + (LTE_SCellToAddMod_r10_t *)NULL, + //(struct LTE_PhysicalConfigDedicatedSCell_r10 *)NULL, #endif - (LTE_MeasObjectToAddMod_t **) NULL, - ue_context_pP->ue_context.mac_MainConfig, - 1, - SRB1_logicalChannelConfig, - ue_context_pP->ue_context.measGapConfig, - (LTE_TDD_Config_t *) NULL, - NULL, - (LTE_SchedulingInfoList_t *) NULL, - 0, NULL, NULL, (LTE_MBSFN_SubframeConfigList_t *) NULL + (LTE_MeasObjectToAddMod_t **) NULL, + ue_context_pP->ue_context.mac_MainConfig, + 1, + SRB1_logicalChannelConfig, + ue_context_pP->ue_context.measGapConfig, + (LTE_TDD_Config_t *) NULL, + NULL, + (LTE_SchedulingInfoList_t *) NULL, + 0, NULL, NULL, (LTE_MBSFN_SubframeConfigList_t *) NULL #if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) - , 0, (LTE_MBSFN_AreaInfoList_r9_t *) NULL, (LTE_PMCH_InfoList_r9_t *) NULL + , 0, (LTE_MBSFN_AreaInfoList_r9_t *) NULL, (LTE_PMCH_InfoList_r9_t *) NULL #endif #if (LTE_RRC_VERSION >= MAKE_VERSION(13, 0, 0)) - , - (LTE_SystemInformationBlockType1_v1310_IEs_t *)NULL + , + (LTE_SystemInformationBlockType1_v1310_IEs_t *)NULL #endif - ); + ); break; } } @@ -5779,18 +5294,15 @@ rrc_eNB_generate_RRCConnectionSetup( MSC_AS_TIME_ARGS(ctxt_pP), ue_context_pP->ue_context.rnti, RC.rrc[ctxt_pP->module_id]->carrier[CC_id].Srb0.Tx_buffer.payload_size); - - LOG_I(RRC, PROTOCOL_RRC_CTXT_UE_FMT" [RAPROC] Logical Channel DL-CCCH, Generating LTE_RRCConnectionSetup (bytes %d)\n", PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP), RC.rrc[ctxt_pP->module_id]->carrier[CC_id].Srb0.Tx_buffer.payload_size); - //ue_context_pP->ue_context.ue_release_timer_thres=100; - // activate release timer, if RRCSetupComplete not received after 100 frames, remove UE - ue_context_pP->ue_context.ue_release_timer=1; - // remove UE after 10 frames after LTE_RRCConnectionRelease is triggered - ue_context_pP->ue_context.ue_release_timer_thres=1000; + // activate release timer, if RRCSetupComplete not received after 100 frames, remove UE + ue_context_pP->ue_context.ue_release_timer=1; + // remove UE after 10 frames after LTE_RRCConnectionRelease is triggered + ue_context_pP->ue_context.ue_release_timer_thres=1000; } @@ -5799,7 +5311,7 @@ rrc_eNB_generate_RRCConnectionSetup( char openair_rrc_eNB_configuration( const module_id_t enb_mod_idP, - RrcConfigurationReq* configuration + RrcConfigurationReq *configuration ) #else char @@ -5811,18 +5323,18 @@ openair_rrc_eNB_init( { protocol_ctxt_t ctxt; int CC_id; - PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, enb_mod_idP, ENB_FLAG_YES, NOT_A_RNTI, 0, 0,enb_mod_idP); LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" Init...\n", PROTOCOL_RRC_CTXT_ARGS(&ctxt)); - #if OCP_FRAMEWORK + while ( RC.rrc[enb_mod_idP] == NULL ) { LOG_E(RRC, "RC.rrc not yet initialized, waiting 1 second\n"); sleep(1); } -#endif + +#endif AssertFatal(RC.rrc[enb_mod_idP] != NULL, "RC.rrc not initialized!"); AssertFatal(MAX_MOBILES_PER_ENB < (module_id_t)0xFFFFFFFFFFFFFFFF, " variable overflow"); #ifdef ENABLE_ITTI @@ -5854,22 +5366,15 @@ openair_rrc_eNB_init( // for (j = 0; j < (MAX_MOBILES_PER_ENB + 1); j++) { // RC.rrc[enb_mod_idP]->Srb2[j].Active = 0; // } - - RC.rrc[ctxt.module_id]->initial_id2_s1ap_ids = hashtable_create (MAX_MOBILES_PER_ENB * 2, NULL, NULL); RC.rrc[ctxt.module_id]->s1ap_id2_s1ap_ids = hashtable_create (MAX_MOBILES_PER_ENB * 2, NULL, NULL); - memcpy(&RC.rrc[ctxt.module_id]->configuration,configuration,sizeof(RrcConfigurationReq)); - /// System Information INIT - LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" Checking release \n", PROTOCOL_RRC_CTXT_ARGS(&ctxt)); #if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) - // can clear it at runtime RC.rrc[ctxt.module_id]->carrier[0].MBMS_flag = 0; - // This has to come from some top-level configuration // only CC_id 0 is logged #if (LTE_RRC_VERSION < MAKE_VERSION(10, 0, 0)) @@ -5879,7 +5384,6 @@ openair_rrc_eNB_init( #endif PROTOCOL_RRC_CTXT_ARGS(&ctxt), RC.rrc[ctxt.module_id]->carrier[0].MBMS_flag); - #else LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" Rel8 RRC\n", PROTOCOL_RRC_CTXT_ARGS(&ctxt)); #endif @@ -5903,7 +5407,6 @@ openair_rrc_eNB_init( RC.rrc[ctxt.module_id]->carrier[CC_id].cba_rnti[3], RC.rrc[ctxt.module_id]->carrier[CC_id].num_active_cba_groups); } - #endif for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { @@ -5913,32 +5416,33 @@ openair_rrc_eNB_init( , configuration #endif ); + for (int ue_id = 0; ue_id < MAX_MOBILES_PER_ENB; ue_id++) { - RC.rrc[ctxt.module_id]->carrier[CC_id].sizeof_paging[ue_id] = 0; - RC.rrc[ctxt.module_id]->carrier[CC_id].paging[ue_id] = (uint8_t*) malloc16(256); + RC.rrc[ctxt.module_id]->carrier[CC_id].sizeof_paging[ue_id] = 0; + RC.rrc[ctxt.module_id]->carrier[CC_id].paging[ue_id] = (uint8_t *) malloc16(256); } } - rrc_init_global_param(); + for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { - #if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) + switch (RC.rrc[ctxt.module_id]->carrier[CC_id].MBMS_flag) { - case 1: - case 2: - case 3: - LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" Configuring 1 MBSFN sync area\n", PROTOCOL_RRC_CTXT_ARGS(&ctxt)); - RC.rrc[ctxt.module_id]->carrier[CC_id].num_mbsfn_sync_area = 1; - break; + case 1: + case 2: + case 3: + LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" Configuring 1 MBSFN sync area\n", PROTOCOL_RRC_CTXT_ARGS(&ctxt)); + RC.rrc[ctxt.module_id]->carrier[CC_id].num_mbsfn_sync_area = 1; + break; - case 4: - LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" Configuring 2 MBSFN sync area\n", PROTOCOL_RRC_CTXT_ARGS(&ctxt)); - RC.rrc[ctxt.module_id]->carrier[CC_id].num_mbsfn_sync_area = 2; - break; + case 4: + LOG_I(RRC, PROTOCOL_RRC_CTXT_FMT" Configuring 2 MBSFN sync area\n", PROTOCOL_RRC_CTXT_ARGS(&ctxt)); + RC.rrc[ctxt.module_id]->carrier[CC_id].num_mbsfn_sync_area = 2; + break; - default: - RC.rrc[ctxt.module_id]->carrier[CC_id].num_mbsfn_sync_area = 0; - break; + default: + RC.rrc[ctxt.module_id]->carrier[CC_id].num_mbsfn_sync_area = 0; + break; } // if we are here the RC.rrc[enb_mod_idP]->MBMS_flag > 0, @@ -5948,21 +5452,19 @@ openair_rrc_eNB_init( /// MTCH data bearer init init_MBMS(ctxt.module_id, CC_id, 0); } -#endif +#endif openair_rrc_top_init_eNB(RC.rrc[ctxt.module_id]->carrier[CC_id].MBMS_flag,0); } openair_rrc_on(&ctxt); - return 0; - } /*------------------------------------------------------------------------------*/ int rrc_eNB_decode_ccch( - protocol_ctxt_t* const ctxt_pP, - const SRB_INFO* const Srb_info, + protocol_ctxt_t *const ctxt_pP, + const SRB_INFO *const Srb_info, const int CC_id ) //----------------------------------------------------------------------------- @@ -5970,21 +5472,18 @@ rrc_eNB_decode_ccch( module_id_t Idx; asn_dec_rval_t dec_rval; LTE_UL_CCCH_Message_t *ul_ccch_msg = NULL; - LTE_RRCConnectionRequest_r8_IEs_t* rrcConnectionRequest = NULL; - LTE_RRCConnectionReestablishmentRequest_r8_IEs_t* rrcConnectionReestablishmentRequest = NULL; + LTE_RRCConnectionRequest_r8_IEs_t *rrcConnectionRequest = NULL; + LTE_RRCConnectionReestablishmentRequest_r8_IEs_t *rrcConnectionReestablishmentRequest = NULL; int i, rval; - struct rrc_eNB_ue_context_s* ue_context_p = NULL; + struct rrc_eNB_ue_context_s *ue_context_p = NULL; uint64_t random_value = 0; int stmsi_received = 0; - T(T_ENB_RRC_UL_CCCH_DATA_IN, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame), T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti)); - //memset(ul_ccch_msg,0,sizeof(UL_CCCH_Message_t)); - LOG_I(RRC, PROTOCOL_RRC_CTXT_UE_FMT" Decoding UL CCCH %x.%x.%x.%x.%x.%x (%p)\n", PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP), - ((uint8_t*) Srb_info->Rx_buffer.Payload)[0], + ((uint8_t *) Srb_info->Rx_buffer.Payload)[0], ((uint8_t *) Srb_info->Rx_buffer.Payload)[1], ((uint8_t *) Srb_info->Rx_buffer.Payload)[2], ((uint8_t *) Srb_info->Rx_buffer.Payload)[3], @@ -5993,15 +5492,15 @@ rrc_eNB_decode_ccch( dec_rval = uper_decode( NULL, &asn_DEF_LTE_UL_CCCH_Message, - (void**)&ul_ccch_msg, - (uint8_t*) Srb_info->Rx_buffer.Payload, + (void **)&ul_ccch_msg, + (uint8_t *) Srb_info->Rx_buffer.Payload, 100, 0, 0); /* -#if defined(ENABLE_ITTI) -# if defined(DISABLE_ITTI_XER_PRINT) + #if defined(ENABLE_ITTI) + # if defined(DISABLE_ITTI_XER_PRINT) { MessageDef *message_p; @@ -6010,7 +5509,7 @@ rrc_eNB_decode_ccch( itti_send_msg_to_task(TASK_UNKNOWN, ctxt_pP->instance, message_p); } -# else + # else { char message_string[10000]; size_t message_string_size; @@ -6026,8 +5525,8 @@ rrc_eNB_decode_ccch( itti_send_msg_to_task(TASK_UNKNOWN, ctxt_pP->instance, msg_p); } } -# endif -#endif + # endif + #endif */ for (i = 0; i < 8; i++) { @@ -6042,467 +5541,454 @@ rrc_eNB_decode_ccch( } if (ul_ccch_msg->message.present == LTE_UL_CCCH_MessageType_PR_c1) { - switch (ul_ccch_msg->message.choice.c1.present) { + case LTE_UL_CCCH_MessageType__c1_PR_NOTHING: + LOG_I(RRC, + PROTOCOL_RRC_CTXT_FMT" Received PR_NOTHING on UL-CCCH-Message\n", + PROTOCOL_RRC_CTXT_ARGS(ctxt_pP)); + break; - case LTE_UL_CCCH_MessageType__c1_PR_NOTHING: - LOG_I(RRC, - PROTOCOL_RRC_CTXT_FMT" Received PR_NOTHING on UL-CCCH-Message\n", - PROTOCOL_RRC_CTXT_ARGS(ctxt_pP)); - break; - - case LTE_UL_CCCH_MessageType__c1_PR_rrcConnectionReestablishmentRequest: - T(T_ENB_RRC_CONNECTION_REESTABLISHMENT_REQUEST, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame), - T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti)); - - LOG_DUMPMSG(RRC,DEBUG_RRC,(char *)(Srb_info->Rx_buffer.Payload), - Srb_info->Rx_buffer.payload_size, - "[MSG] RRC Connection Reestablishment Request\n"); - - LOG_D(RRC, - PROTOCOL_RRC_CTXT_UE_FMT"MAC_eNB--- MAC_DATA_IND (rrcConnectionReestablishmentRequest on SRB0) --> RRC_eNB\n", - PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP)); - rrcConnectionReestablishmentRequest = - &ul_ccch_msg->message.choice.c1.choice.rrcConnectionReestablishmentRequest.criticalExtensions.choice.rrcConnectionReestablishmentRequest_r8; - LOG_I(RRC, - PROTOCOL_RRC_CTXT_UE_FMT" LTE_RRCConnectionReestablishmentRequest cause %s\n", - PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP), - ((rrcConnectionReestablishmentRequest->reestablishmentCause == LTE_ReestablishmentCause_otherFailure) ? "Other Failure" : - (rrcConnectionReestablishmentRequest->reestablishmentCause == LTE_ReestablishmentCause_handoverFailure) ? "Handover Failure" : - "reconfigurationFailure")); - /*{ - uint64_t c_rnti = 0; - - memcpy(((uint8_t *) & c_rnti) + 3, rrcConnectionReestablishmentRequest.UE_identity.c_RNTI.buf, - rrcConnectionReestablishmentRequest.UE_identity.c_RNTI.size); - ue_mod_id = rrc_eNB_get_UE_index(enb_mod_idP, c_rnti); - } - - if ((RC.rrc[enb_mod_idP]->phyCellId == rrcConnectionReestablishmentRequest.UE_identity.physCellId) && - (ue_mod_id != UE_INDEX_INVALID)){ - rrc_eNB_generate_RRCConnectionReestablishment(enb_mod_idP, frameP, ue_mod_id); - }else { - rrc_eNB_generate_RRCConnectionReestablishmentReject(enb_mod_idP, frameP, ue_mod_id); - } - */ - /* reject all reestablishment attempts for the moment */ -// rrc_eNB_generate_RRCConnectionReestablishmentReject(ctxt_pP, -// rrc_eNB_get_ue_context(RC.rrc[ctxt_pP->module_id], ctxt_pP->rnti), -// CC_id); -{ - uint16_t c_rnti = 0; - - if (rrcConnectionReestablishmentRequest->ue_Identity.physCellId != RC.rrc[ctxt_pP->module_id]->carrier[CC_id].physCellId) { - LOG_E(RRC, - PROTOCOL_RRC_CTXT_UE_FMT" LTE_RRCConnectionReestablishmentRequest ue_Identity.physCellId(%ld) is not equal to current physCellId(%d), let's reject the UE\n", + case LTE_UL_CCCH_MessageType__c1_PR_rrcConnectionReestablishmentRequest: + T(T_ENB_RRC_CONNECTION_REESTABLISHMENT_REQUEST, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame), + T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti)); + LOG_DUMPMSG(RRC,DEBUG_RRC,(char *)(Srb_info->Rx_buffer.Payload), + Srb_info->Rx_buffer.payload_size, + "[MSG] RRC Connection Reestablishment Request\n"); + LOG_D(RRC, + PROTOCOL_RRC_CTXT_UE_FMT"MAC_eNB--- MAC_DATA_IND (rrcConnectionReestablishmentRequest on SRB0) --> RRC_eNB\n", + PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP)); + rrcConnectionReestablishmentRequest = + &ul_ccch_msg->message.choice.c1.choice.rrcConnectionReestablishmentRequest.criticalExtensions.choice.rrcConnectionReestablishmentRequest_r8; + LOG_I(RRC, + PROTOCOL_RRC_CTXT_UE_FMT" LTE_RRCConnectionReestablishmentRequest cause %s\n", PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP), - rrcConnectionReestablishmentRequest->ue_Identity.physCellId, - RC.rrc[ctxt_pP->module_id]->carrier[CC_id].physCellId); - rrc_eNB_generate_RRCConnectionReestablishmentReject(ctxt_pP, ue_context_p, CC_id); - break; - } - LOG_D(RRC, "physCellId is %ld\n", rrcConnectionReestablishmentRequest->ue_Identity.physCellId); + ((rrcConnectionReestablishmentRequest->reestablishmentCause == LTE_ReestablishmentCause_otherFailure) ? "Other Failure" : + (rrcConnectionReestablishmentRequest->reestablishmentCause == LTE_ReestablishmentCause_handoverFailure) ? "Handover Failure" : + "reconfigurationFailure")); + /*{ + uint64_t c_rnti = 0; - for (i = 0; i < rrcConnectionReestablishmentRequest->ue_Identity.shortMAC_I.size; i++) { - LOG_D(RRC, "rrcConnectionReestablishmentRequest->ue_Identity.shortMAC_I.buf[%d] = %x\n", - i, rrcConnectionReestablishmentRequest->ue_Identity.shortMAC_I.buf[i]); - } - - if (rrcConnectionReestablishmentRequest->ue_Identity.c_RNTI.size == 0 || - rrcConnectionReestablishmentRequest->ue_Identity.c_RNTI.size > 2) { - LOG_E(RRC, - PROTOCOL_RRC_CTXT_UE_FMT" LTE_RRCConnectionReestablishmentRequest c_RNTI range error, let's reject the UE\n", - PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP)); - rrc_eNB_generate_RRCConnectionReestablishmentReject(ctxt_pP, ue_context_p, CC_id); - break; - - } - - c_rnti = BIT_STRING_to_uint16(&rrcConnectionReestablishmentRequest->ue_Identity.c_RNTI); - LOG_D(RRC, "c_rnti is %x\n", c_rnti); - - ue_context_p = rrc_eNB_get_ue_context(RC.rrc[ctxt_pP->module_id], c_rnti); - if (ue_context_p == NULL) { - LOG_E(RRC, - PROTOCOL_RRC_CTXT_UE_FMT" LTE_RRCConnectionReestablishmentRequest without UE context, let's reject the UE\n", - PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP)); - rrc_eNB_generate_RRCConnectionReestablishmentReject(ctxt_pP, ue_context_p, CC_id); - break; - } - int UE_id = find_UE_id(ctxt_pP->module_id, c_rnti); - if(UE_id == -1){ - LOG_E(RRC, - PROTOCOL_RRC_CTXT_UE_FMT" LTE_RRCConnectionReestablishmentRequest without UE_id(MAC) rnti %x, let's reject the UE\n", - PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP),c_rnti); - rrc_eNB_generate_RRCConnectionReestablishmentReject(ctxt_pP, ue_context_p, CC_id); - break; - } - - if((RC.mac[ctxt_pP->module_id]->UE_list.UE_sched_ctrl[UE_id].ue_reestablishment_reject_timer > 0) && - (RC.mac[ctxt_pP->module_id]->UE_list.UE_sched_ctrl[UE_id].ue_reestablishment_reject_timer_thres > 20)){ - LOG_E(RRC, - PROTOCOL_RRC_CTXT_UE_FMT" RCConnectionReestablishmentComplete(Previous) don't receive, delete the Previous UE\n", - PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP)); - RC.mac[ctxt_pP->module_id]->UE_list.UE_sched_ctrl[UE_id].ue_reestablishment_reject_timer = 1000; - ue_context_p->ue_context.ue_reestablishment_timer = 0; - } - - if(ue_context_p->ue_context.ue_reestablishment_timer > 0){ - LOG_E(RRC, - PROTOCOL_RRC_CTXT_UE_FMT" RRRCConnectionReconfigurationComplete(Previous) don't receive, delete the Previous UE\n", - PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP)); - ue_context_p->ue_context.Status = RRC_RECONFIGURED; - protocol_ctxt_t ctxt_old_p; - PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt_old_p, - ctxt_pP->instance, - ENB_FLAG_YES, - c_rnti, - ctxt_pP->frame, - ctxt_pP->subframe); - rrc_eNB_process_RRCConnectionReconfigurationComplete(&ctxt_old_p, - ue_context_p, - ue_context_p->ue_context.reestablishment_xid); - for (uint8_t e_rab = 0; e_rab < ue_context_p->ue_context.nb_of_e_rabs; e_rab++) { - if (ue_context_p->ue_context.e_rab[e_rab].status == E_RAB_STATUS_DONE) { - ue_context_p->ue_context.e_rab[e_rab].status = E_RAB_STATUS_ESTABLISHED; - } else { - ue_context_p->ue_context.e_rab[e_rab].status = E_RAB_STATUS_FAILED; - } - } - } - LOG_D(RRC, - PROTOCOL_RRC_CTXT_UE_FMT" UE context: %p\n", - PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP), - ue_context_p); - /* reset timers */ - ue_context_p->ue_context.ul_failure_timer = 0; - ue_context_p->ue_context.ue_release_timer = 0; - ue_context_p->ue_context.ue_reestablishment_timer = 0; - ue_context_p->ue_context.ue_release_timer_s1 = 0; - ue_context_p->ue_context.ue_release_timer_rrc = 0; - ue_context_p->ue_context.reestablishment_xid = -1; - - // insert C-RNTI to map - for (i = 0; i < MAX_MOBILES_PER_ENB; i++) { - if (reestablish_rnti_map[i][0] == 0) { - reestablish_rnti_map[i][0] = ctxt_pP->rnti; - reestablish_rnti_map[i][1] = c_rnti; - break; + memcpy(((uint8_t *) & c_rnti) + 3, rrcConnectionReestablishmentRequest.UE_identity.c_RNTI.buf, + rrcConnectionReestablishmentRequest.UE_identity.c_RNTI.size); + ue_mod_id = rrc_eNB_get_UE_index(enb_mod_idP, c_rnti); } - } - LOG_D(RRC, "reestablish_rnti_map[%d] [0] %x, [1] %x\n", - i, reestablish_rnti_map[i][0], reestablish_rnti_map[i][1]); -#if defined(ENABLE_ITTI) - ue_context_p->ue_context.reestablishment_cause = rrcConnectionReestablishmentRequest->reestablishmentCause; - LOG_D(RRC, PROTOCOL_RRC_CTXT_UE_FMT" Accept connection reestablishment request from UE physCellId %ld cause %ld\n", - PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP), - rrcConnectionReestablishmentRequest->ue_Identity.physCellId, - ue_context_p->ue_context.reestablishment_cause); -#else - LOG_D(RRC, PROTOCOL_RRC_CTXT_UE_FMT" Accept connection restablishment request for UE\n", - PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP)); -#endif - -#ifndef NO_RRM - send_msg(&S_rrc, msg_rrc_MR_attach_ind(ctxt_pP->module_id, Mac_id)); -#else - - ue_context_p->ue_context.primaryCC_id = CC_id; - - //LG COMMENT Idx = (ue_mod_idP * NB_RB_MAX) + DCCH; - Idx = DCCH; - // SRB1 - ue_context_p->ue_context.Srb1.Active = 1; - ue_context_p->ue_context.Srb1.Srb_info.Srb_id = Idx; - memcpy(&ue_context_p->ue_context.Srb1.Srb_info.Lchan_desc[0], - &DCCH_LCHAN_DESC, - LCHAN_DESC_SIZE); - memcpy(&ue_context_p->ue_context.Srb1.Srb_info.Lchan_desc[1], - &DCCH_LCHAN_DESC, - LCHAN_DESC_SIZE); - - // SRB2: set it to go through SRB1 with id 1 (DCCH) - ue_context_p->ue_context.Srb2.Active = 1; - ue_context_p->ue_context.Srb2.Srb_info.Srb_id = Idx; - memcpy(&ue_context_p->ue_context.Srb2.Srb_info.Lchan_desc[0], - &DCCH_LCHAN_DESC, - LCHAN_DESC_SIZE); - memcpy(&ue_context_p->ue_context.Srb2.Srb_info.Lchan_desc[1], - &DCCH_LCHAN_DESC, - LCHAN_DESC_SIZE); - - rrc_eNB_generate_RRCConnectionReestablishment(ctxt_pP, ue_context_p, CC_id); - LOG_I(RRC, PROTOCOL_RRC_CTXT_UE_FMT"CALLING RLC CONFIG SRB1 (rbid %d)\n", - PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP), - Idx); - - MSC_LOG_TX_MESSAGE(MSC_RRC_ENB, - MSC_PDCP_ENB, - NULL, - 0, - MSC_AS_TIME_FMT" CONFIG_REQ UE %x SRB", - MSC_AS_TIME_ARGS(ctxt_pP), - ue_context_p->ue_context.rnti); - - rrc_pdcp_config_asn1_req(ctxt_pP, - ue_context_p->ue_context.SRB_configList, - (LTE_DRB_ToAddModList_t *) NULL, - (LTE_DRB_ToReleaseList_t*) NULL, - 0xff, - NULL, - NULL, - NULL -#if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) - , (LTE_PMCH_InfoList_r9_t *) NULL -#endif - ,NULL); - - rrc_rlc_config_asn1_req(ctxt_pP, - ue_context_p->ue_context.SRB_configList, - (LTE_DRB_ToAddModList_t*) NULL, - (LTE_DRB_ToReleaseList_t*) NULL -#if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) - , (LTE_PMCH_InfoList_r9_t *) NULL, - 0,0 -# endif - ); -#endif //NO_RRM - } - break; - - case LTE_UL_CCCH_MessageType__c1_PR_rrcConnectionRequest: - T(T_ENB_RRC_CONNECTION_REQUEST, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame), - T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti)); - - LOG_DUMPMSG(RRC,DEBUG_RRC,(char *)(Srb_info->Rx_buffer.Payload), - Srb_info->Rx_buffer.payload_size, - "[MSG] RRC Connection Request\n"); - - LOG_D(RRC, - PROTOCOL_RRC_CTXT_UE_FMT"MAC_eNB --- MAC_DATA_IND (rrcConnectionRequest on SRB0) --> RRC_eNB\n", - PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP)); - ue_context_p = rrc_eNB_get_ue_context( - RC.rrc[ctxt_pP->module_id], - ctxt_pP->rnti); - - if (ue_context_p != NULL) { - // erase content - rrc_eNB_free_mem_UE_context(ctxt_pP, ue_context_p); - - MSC_LOG_RX_DISCARDED_MESSAGE( - MSC_RRC_ENB, - MSC_RRC_UE, - Srb_info->Rx_buffer.Payload, - dec_rval.consumed, - MSC_AS_TIME_FMT" LTE_RRCConnectionRequest UE %x size %u (UE already in context)", - MSC_AS_TIME_ARGS(ctxt_pP), - ue_context_p->ue_context.rnti, - dec_rval.consumed); - } else { - rrcConnectionRequest = &ul_ccch_msg->message.choice.c1.choice.rrcConnectionRequest.criticalExtensions.choice.rrcConnectionRequest_r8; + if ((RC.rrc[enb_mod_idP]->phyCellId == rrcConnectionReestablishmentRequest.UE_identity.physCellId) && + (ue_mod_id != UE_INDEX_INVALID)){ + rrc_eNB_generate_RRCConnectionReestablishment(enb_mod_idP, frameP, ue_mod_id); + }else { + rrc_eNB_generate_RRCConnectionReestablishmentReject(enb_mod_idP, frameP, ue_mod_id); + } + */ + /* reject all reestablishment attempts for the moment */ + // rrc_eNB_generate_RRCConnectionReestablishmentReject(ctxt_pP, + // rrc_eNB_get_ue_context(RC.rrc[ctxt_pP->module_id], ctxt_pP->rnti), + // CC_id); { - if (LTE_InitialUE_Identity_PR_randomValue == rrcConnectionRequest->ue_Identity.present) { - if(rrcConnectionRequest->ue_Identity.choice.randomValue.size != 5) - { - LOG_I(RRC, "wrong InitialUE-Identity randomValue size, expected 5, provided %lu", - (long unsigned int)rrcConnectionRequest->ue_Identity.choice.randomValue.size); - return -1; - } - memcpy(((uint8_t*) & random_value) + 3, - rrcConnectionRequest->ue_Identity.choice.randomValue.buf, - rrcConnectionRequest->ue_Identity.choice.randomValue.size); - /* if there is already a registered UE (with another RNTI) with this random_value, - * the current one must be removed from MAC/PHY (zombie UE) - */ - if ((ue_context_p = rrc_eNB_ue_context_random_exist(ctxt_pP, random_value))) { - LOG_W(RRC, "new UE rnti %x (coming with random value) is already there as UE %x, removing %x from MAC/PHY\n", - ctxt_pP->rnti, ue_context_p->ue_context.rnti, ue_context_p->ue_context.rnti); - ue_context_p->ue_context.ul_failure_timer = 20000; - } - ue_context_p = rrc_eNB_get_next_free_ue_context(ctxt_pP, random_value); - } else if (LTE_InitialUE_Identity_PR_s_TMSI == rrcConnectionRequest->ue_Identity.present) { - /* Save s-TMSI */ - LTE_S_TMSI_t s_TMSI = rrcConnectionRequest->ue_Identity.choice.s_TMSI; - mme_code_t mme_code = BIT_STRING_to_uint8(&s_TMSI.mmec); - m_tmsi_t m_tmsi = BIT_STRING_to_uint32(&s_TMSI.m_TMSI); - random_value = (((uint64_t)mme_code) << 32) | m_tmsi; - if ((ue_context_p = rrc_eNB_ue_context_stmsi_exist(ctxt_pP, mme_code, m_tmsi))) { - LOG_I(RRC," S-TMSI exists, ue_context_p %p, old rnti %x => %x\n",ue_context_p,ue_context_p->ue_context.rnti,ctxt_pP->rnti); - rrc_mac_remove_ue(ctxt_pP->module_id, ue_context_p->ue_context.rnti); - stmsi_received=1; - /* replace rnti in the context */ - /* for that, remove the context from the RB tree */ - RB_REMOVE(rrc_ue_tree_s, &RC.rrc[ctxt_pP->module_id]->rrc_ue_head, ue_context_p); - /* and insert again, after changing rnti everywhere it has to be changed */ - ue_context_p->ue_id_rnti = ctxt_pP->rnti; - ue_context_p->ue_context.rnti = ctxt_pP->rnti; - RB_INSERT(rrc_ue_tree_s, &RC.rrc[ctxt_pP->module_id]->rrc_ue_head, ue_context_p); - /* reset timers */ - ue_context_p->ue_context.ul_failure_timer = 0; - ue_context_p->ue_context.ue_release_timer = 0; - ue_context_p->ue_context.ue_reestablishment_timer = 0; - ue_context_p->ue_context.ue_release_timer_s1 = 0; - ue_context_p->ue_context.ue_release_timer_rrc = 0; - ue_context_p->ue_context.reestablishment_xid = -1; - } else { - LOG_I(RRC," S-TMSI doesn't exist, setting Initialue_identity_s_TMSI.m_tmsi to %p => %x\n",ue_context_p,m_tmsi); -// ue_context_p = rrc_eNB_get_next_free_ue_context(ctxt_pP, NOT_A_RANDOM_UE_IDENTITY); - ue_context_p = rrc_eNB_get_next_free_ue_context(ctxt_pP,random_value); - if (ue_context_p == NULL) - LOG_E(RRC, "%s:%d:%s: rrc_eNB_get_next_free_ue_context returned NULL\n", __FILE__, __LINE__, __FUNCTION__); - if (ue_context_p != NULL) { - ue_context_p->ue_context.Initialue_identity_s_TMSI.presence = TRUE; - ue_context_p->ue_context.Initialue_identity_s_TMSI.mme_code = mme_code; - ue_context_p->ue_context.Initialue_identity_s_TMSI.m_tmsi = m_tmsi; - } else { - /* TODO: do we have to break here? */ - //break; - } - } + uint16_t c_rnti = 0; - MSC_LOG_RX_MESSAGE( - MSC_RRC_ENB, - MSC_RRC_UE, - Srb_info->Rx_buffer.Payload, - dec_rval.consumed, - MSC_AS_TIME_FMT" RRCConnectionRequest UE %x size %u (s-TMSI mmec %u m_TMSI %u random UE id (0x%" PRIx64 ")", - MSC_AS_TIME_ARGS(ctxt_pP), - ue_context_p->ue_context.rnti, - dec_rval.consumed, - ue_context_p->ue_context.Initialue_identity_s_TMSI.mme_code, - ue_context_p->ue_context.Initialue_identity_s_TMSI.m_tmsi, - ue_context_p->ue_context.random_ue_identity); - } else { + if (rrcConnectionReestablishmentRequest->ue_Identity.physCellId != RC.rrc[ctxt_pP->module_id]->carrier[CC_id].physCellId) { LOG_E(RRC, - PROTOCOL_RRC_CTXT_UE_FMT" RRCConnectionRequest without random UE identity or S-TMSI not supported, let's reject the UE\n", - PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP)); - rrc_eNB_generate_RRCConnectionReject(ctxt_pP, - rrc_eNB_get_ue_context(RC.rrc[ctxt_pP->module_id], ctxt_pP->rnti), - CC_id); + PROTOCOL_RRC_CTXT_UE_FMT" LTE_RRCConnectionReestablishmentRequest ue_Identity.physCellId(%ld) is not equal to current physCellId(%d), let's reject the UE\n", + PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP), + rrcConnectionReestablishmentRequest->ue_Identity.physCellId, + RC.rrc[ctxt_pP->module_id]->carrier[CC_id].physCellId); + rrc_eNB_generate_RRCConnectionReestablishmentReject(ctxt_pP, ue_context_p, CC_id); break; } + LOG_D(RRC, "physCellId is %ld\n", rrcConnectionReestablishmentRequest->ue_Identity.physCellId); + + for (i = 0; i < rrcConnectionReestablishmentRequest->ue_Identity.shortMAC_I.size; i++) { + LOG_D(RRC, "rrcConnectionReestablishmentRequest->ue_Identity.shortMAC_I.buf[%d] = %x\n", + i, rrcConnectionReestablishmentRequest->ue_Identity.shortMAC_I.buf[i]); + } + + if (rrcConnectionReestablishmentRequest->ue_Identity.c_RNTI.size == 0 || + rrcConnectionReestablishmentRequest->ue_Identity.c_RNTI.size > 2) { + LOG_E(RRC, + PROTOCOL_RRC_CTXT_UE_FMT" LTE_RRCConnectionReestablishmentRequest c_RNTI range error, let's reject the UE\n", + PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP)); + rrc_eNB_generate_RRCConnectionReestablishmentReject(ctxt_pP, ue_context_p, CC_id); + break; + } + + c_rnti = BIT_STRING_to_uint16(&rrcConnectionReestablishmentRequest->ue_Identity.c_RNTI); + LOG_D(RRC, "c_rnti is %x\n", c_rnti); + ue_context_p = rrc_eNB_get_ue_context(RC.rrc[ctxt_pP->module_id], c_rnti); + + if (ue_context_p == NULL) { + LOG_E(RRC, + PROTOCOL_RRC_CTXT_UE_FMT" LTE_RRCConnectionReestablishmentRequest without UE context, let's reject the UE\n", + PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP)); + rrc_eNB_generate_RRCConnectionReestablishmentReject(ctxt_pP, ue_context_p, CC_id); + break; + } + + int UE_id = find_UE_id(ctxt_pP->module_id, c_rnti); + + if(UE_id == -1) { + LOG_E(RRC, + PROTOCOL_RRC_CTXT_UE_FMT" LTE_RRCConnectionReestablishmentRequest without UE_id(MAC) rnti %x, let's reject the UE\n", + PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP),c_rnti); + rrc_eNB_generate_RRCConnectionReestablishmentReject(ctxt_pP, ue_context_p, CC_id); + break; + } + + if((RC.mac[ctxt_pP->module_id]->UE_list.UE_sched_ctrl[UE_id].ue_reestablishment_reject_timer > 0) && + (RC.mac[ctxt_pP->module_id]->UE_list.UE_sched_ctrl[UE_id].ue_reestablishment_reject_timer_thres > 20)) { + LOG_E(RRC, + PROTOCOL_RRC_CTXT_UE_FMT" RCConnectionReestablishmentComplete(Previous) don't receive, delete the Previous UE\n", + PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP)); + RC.mac[ctxt_pP->module_id]->UE_list.UE_sched_ctrl[UE_id].ue_reestablishment_reject_timer = 1000; + ue_context_p->ue_context.ue_reestablishment_timer = 0; + } + + if(ue_context_p->ue_context.ue_reestablishment_timer > 0) { + LOG_E(RRC, + PROTOCOL_RRC_CTXT_UE_FMT" RRRCConnectionReconfigurationComplete(Previous) don't receive, delete the Previous UE\n", + PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP)); + ue_context_p->ue_context.Status = RRC_RECONFIGURED; + protocol_ctxt_t ctxt_old_p; + PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt_old_p, + ctxt_pP->instance, + ENB_FLAG_YES, + c_rnti, + ctxt_pP->frame, + ctxt_pP->subframe); + rrc_eNB_process_RRCConnectionReconfigurationComplete(&ctxt_old_p, + ue_context_p, + ue_context_p->ue_context.reestablishment_xid); + + for (uint8_t e_rab = 0; e_rab < ue_context_p->ue_context.nb_of_e_rabs; e_rab++) { + if (ue_context_p->ue_context.e_rab[e_rab].status == E_RAB_STATUS_DONE) { + ue_context_p->ue_context.e_rab[e_rab].status = E_RAB_STATUS_ESTABLISHED; + } else { + ue_context_p->ue_context.e_rab[e_rab].status = E_RAB_STATUS_FAILED; + } + } + } + + LOG_D(RRC, + PROTOCOL_RRC_CTXT_UE_FMT" UE context: %p\n", + PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP), + ue_context_p); + /* reset timers */ + ue_context_p->ue_context.ul_failure_timer = 0; + ue_context_p->ue_context.ue_release_timer = 0; + ue_context_p->ue_context.ue_reestablishment_timer = 0; + ue_context_p->ue_context.ue_release_timer_s1 = 0; + ue_context_p->ue_context.ue_release_timer_rrc = 0; + ue_context_p->ue_context.reestablishment_xid = -1; + + // insert C-RNTI to map + for (i = 0; i < MAX_MOBILES_PER_ENB; i++) { + if (reestablish_rnti_map[i][0] == 0) { + reestablish_rnti_map[i][0] = ctxt_pP->rnti; + reestablish_rnti_map[i][1] = c_rnti; + break; + } + } + + LOG_D(RRC, "reestablish_rnti_map[%d] [0] %x, [1] %x\n", + i, reestablish_rnti_map[i][0], reestablish_rnti_map[i][1]); +#if defined(ENABLE_ITTI) + ue_context_p->ue_context.reestablishment_cause = rrcConnectionReestablishmentRequest->reestablishmentCause; + LOG_D(RRC, PROTOCOL_RRC_CTXT_UE_FMT" Accept connection reestablishment request from UE physCellId %ld cause %ld\n", + PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP), + rrcConnectionReestablishmentRequest->ue_Identity.physCellId, + ue_context_p->ue_context.reestablishment_cause); +#else + LOG_D(RRC, PROTOCOL_RRC_CTXT_UE_FMT" Accept connection restablishment request for UE\n", + PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP)); +#endif +#ifndef NO_RRM + send_msg(&S_rrc, msg_rrc_MR_attach_ind(ctxt_pP->module_id, Mac_id)); +#else + ue_context_p->ue_context.primaryCC_id = CC_id; + //LG COMMENT Idx = (ue_mod_idP * NB_RB_MAX) + DCCH; + Idx = DCCH; + // SRB1 + ue_context_p->ue_context.Srb1.Active = 1; + ue_context_p->ue_context.Srb1.Srb_info.Srb_id = Idx; + memcpy(&ue_context_p->ue_context.Srb1.Srb_info.Lchan_desc[0], + &DCCH_LCHAN_DESC, + LCHAN_DESC_SIZE); + memcpy(&ue_context_p->ue_context.Srb1.Srb_info.Lchan_desc[1], + &DCCH_LCHAN_DESC, + LCHAN_DESC_SIZE); + // SRB2: set it to go through SRB1 with id 1 (DCCH) + ue_context_p->ue_context.Srb2.Active = 1; + ue_context_p->ue_context.Srb2.Srb_info.Srb_id = Idx; + memcpy(&ue_context_p->ue_context.Srb2.Srb_info.Lchan_desc[0], + &DCCH_LCHAN_DESC, + LCHAN_DESC_SIZE); + memcpy(&ue_context_p->ue_context.Srb2.Srb_info.Lchan_desc[1], + &DCCH_LCHAN_DESC, + LCHAN_DESC_SIZE); + rrc_eNB_generate_RRCConnectionReestablishment(ctxt_pP, ue_context_p, CC_id); + LOG_I(RRC, PROTOCOL_RRC_CTXT_UE_FMT"CALLING RLC CONFIG SRB1 (rbid %d)\n", + PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP), + Idx); + MSC_LOG_TX_MESSAGE(MSC_RRC_ENB, + MSC_PDCP_ENB, + NULL, + 0, + MSC_AS_TIME_FMT" CONFIG_REQ UE %x SRB", + MSC_AS_TIME_ARGS(ctxt_pP), + ue_context_p->ue_context.rnti); + rrc_pdcp_config_asn1_req(ctxt_pP, + ue_context_p->ue_context.SRB_configList, + (LTE_DRB_ToAddModList_t *) NULL, + (LTE_DRB_ToReleaseList_t *) NULL, + 0xff, + NULL, + NULL, + NULL +#if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) + , (LTE_PMCH_InfoList_r9_t *) NULL +#endif + ,NULL); + rrc_rlc_config_asn1_req(ctxt_pP, + ue_context_p->ue_context.SRB_configList, + (LTE_DRB_ToAddModList_t *) NULL, + (LTE_DRB_ToReleaseList_t *) NULL +#if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) + , (LTE_PMCH_InfoList_r9_t *) NULL, + 0,0 +# endif + ); +#endif //NO_RRM } + break; + + case LTE_UL_CCCH_MessageType__c1_PR_rrcConnectionRequest: + T(T_ENB_RRC_CONNECTION_REQUEST, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame), + T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti)); + LOG_DUMPMSG(RRC,DEBUG_RRC,(char *)(Srb_info->Rx_buffer.Payload), + Srb_info->Rx_buffer.payload_size, + "[MSG] RRC Connection Request\n"); LOG_D(RRC, - PROTOCOL_RRC_CTXT_UE_FMT" UE context: %p\n", - PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP), - ue_context_p); + PROTOCOL_RRC_CTXT_UE_FMT"MAC_eNB --- MAC_DATA_IND (rrcConnectionRequest on SRB0) --> RRC_eNB\n", + PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP)); + ue_context_p = rrc_eNB_get_ue_context( + RC.rrc[ctxt_pP->module_id], + ctxt_pP->rnti); if (ue_context_p != NULL) { - -#if defined(ENABLE_ITTI) - ue_context_p->ue_context.establishment_cause = rrcConnectionRequest->establishmentCause; - ue_context_p->ue_context.reestablishment_cause = LTE_ReestablishmentCause_spare1; - if (stmsi_received==0) - LOG_I(RRC, PROTOCOL_RRC_CTXT_UE_FMT" Accept new connection from UE random UE identity (0x%" PRIx64 ") MME code %u TMSI %u cause %ld\n", - PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP), - ue_context_p->ue_context.random_ue_identity, - ue_context_p->ue_context.Initialue_identity_s_TMSI.mme_code, - ue_context_p->ue_context.Initialue_identity_s_TMSI.m_tmsi, - ue_context_p->ue_context.establishment_cause); - else - LOG_I(RRC, PROTOCOL_RRC_CTXT_UE_FMT" Accept new connection from UE MME code %u TMSI %u cause %ld\n", - PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP), - ue_context_p->ue_context.Initialue_identity_s_TMSI.mme_code, - ue_context_p->ue_context.Initialue_identity_s_TMSI.m_tmsi, - ue_context_p->ue_context.establishment_cause); -#else - LOG_I(RRC, PROTOCOL_RRC_CTXT_UE_FMT" Accept new connection for UE random UE identity (0x%" PRIx64 ")\n", - PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP), - ue_context_p->ue_context.random_ue_identity); -#endif - if (stmsi_received == 0) - RC.rrc[ctxt_pP->module_id]->Nb_ue++; - + // erase content + rrc_eNB_free_mem_UE_context(ctxt_pP, ue_context_p); + MSC_LOG_RX_DISCARDED_MESSAGE( + MSC_RRC_ENB, + MSC_RRC_UE, + Srb_info->Rx_buffer.Payload, + dec_rval.consumed, + MSC_AS_TIME_FMT" LTE_RRCConnectionRequest UE %x size %u (UE already in context)", + MSC_AS_TIME_ARGS(ctxt_pP), + ue_context_p->ue_context.rnti, + dec_rval.consumed); } else { - // no context available - if (rrc_agent_registered[ctxt_pP->module_id]) { - agent_rrc_xface[ctxt_pP->module_id]->flexran_agent_notify_ue_state_change(ctxt_pP->module_id, - ctxt_pP->rnti, - PROTOCOL__FLEX_UE_STATE_CHANGE_TYPE__FLUESC_DEACTIVATED); - } - LOG_I(RRC, PROTOCOL_RRC_CTXT_UE_FMT" Can't create new context for UE random UE identity (0x%" PRIx64 ")\n", + rrcConnectionRequest = &ul_ccch_msg->message.choice.c1.choice.rrcConnectionRequest.criticalExtensions.choice.rrcConnectionRequest_r8; + { + if (LTE_InitialUE_Identity_PR_randomValue == rrcConnectionRequest->ue_Identity.present) { + if(rrcConnectionRequest->ue_Identity.choice.randomValue.size != 5) { + LOG_I(RRC, "wrong InitialUE-Identity randomValue size, expected 5, provided %lu", + (long unsigned int)rrcConnectionRequest->ue_Identity.choice.randomValue.size); + return -1; + } + + memcpy(((uint8_t *) & random_value) + 3, + rrcConnectionRequest->ue_Identity.choice.randomValue.buf, + rrcConnectionRequest->ue_Identity.choice.randomValue.size); + + /* if there is already a registered UE (with another RNTI) with this random_value, + * the current one must be removed from MAC/PHY (zombie UE) + */ + if ((ue_context_p = rrc_eNB_ue_context_random_exist(ctxt_pP, random_value))) { + LOG_W(RRC, "new UE rnti %x (coming with random value) is already there as UE %x, removing %x from MAC/PHY\n", + ctxt_pP->rnti, ue_context_p->ue_context.rnti, ue_context_p->ue_context.rnti); + ue_context_p->ue_context.ul_failure_timer = 20000; + } + + ue_context_p = rrc_eNB_get_next_free_ue_context(ctxt_pP, random_value); + } else if (LTE_InitialUE_Identity_PR_s_TMSI == rrcConnectionRequest->ue_Identity.present) { + /* Save s-TMSI */ + LTE_S_TMSI_t s_TMSI = rrcConnectionRequest->ue_Identity.choice.s_TMSI; + mme_code_t mme_code = BIT_STRING_to_uint8(&s_TMSI.mmec); + m_tmsi_t m_tmsi = BIT_STRING_to_uint32(&s_TMSI.m_TMSI); + random_value = (((uint64_t)mme_code) << 32) | m_tmsi; + + if ((ue_context_p = rrc_eNB_ue_context_stmsi_exist(ctxt_pP, mme_code, m_tmsi))) { + LOG_I(RRC," S-TMSI exists, ue_context_p %p, old rnti %x => %x\n",ue_context_p,ue_context_p->ue_context.rnti,ctxt_pP->rnti); + rrc_mac_remove_ue(ctxt_pP->module_id, ue_context_p->ue_context.rnti); + stmsi_received=1; + /* replace rnti in the context */ + /* for that, remove the context from the RB tree */ + RB_REMOVE(rrc_ue_tree_s, &RC.rrc[ctxt_pP->module_id]->rrc_ue_head, ue_context_p); + /* and insert again, after changing rnti everywhere it has to be changed */ + ue_context_p->ue_id_rnti = ctxt_pP->rnti; + ue_context_p->ue_context.rnti = ctxt_pP->rnti; + RB_INSERT(rrc_ue_tree_s, &RC.rrc[ctxt_pP->module_id]->rrc_ue_head, ue_context_p); + /* reset timers */ + ue_context_p->ue_context.ul_failure_timer = 0; + ue_context_p->ue_context.ue_release_timer = 0; + ue_context_p->ue_context.ue_reestablishment_timer = 0; + ue_context_p->ue_context.ue_release_timer_s1 = 0; + ue_context_p->ue_context.ue_release_timer_rrc = 0; + ue_context_p->ue_context.reestablishment_xid = -1; + } else { + LOG_I(RRC," S-TMSI doesn't exist, setting Initialue_identity_s_TMSI.m_tmsi to %p => %x\n",ue_context_p,m_tmsi); + // ue_context_p = rrc_eNB_get_next_free_ue_context(ctxt_pP, NOT_A_RANDOM_UE_IDENTITY); + ue_context_p = rrc_eNB_get_next_free_ue_context(ctxt_pP,random_value); + + if (ue_context_p == NULL) + LOG_E(RRC, "%s:%d:%s: rrc_eNB_get_next_free_ue_context returned NULL\n", __FILE__, __LINE__, __FUNCTION__); + + if (ue_context_p != NULL) { + ue_context_p->ue_context.Initialue_identity_s_TMSI.presence = TRUE; + ue_context_p->ue_context.Initialue_identity_s_TMSI.mme_code = mme_code; + ue_context_p->ue_context.Initialue_identity_s_TMSI.m_tmsi = m_tmsi; + } else { + /* TODO: do we have to break here? */ + //break; + } + } + + MSC_LOG_RX_MESSAGE( + MSC_RRC_ENB, + MSC_RRC_UE, + Srb_info->Rx_buffer.Payload, + dec_rval.consumed, + MSC_AS_TIME_FMT" RRCConnectionRequest UE %x size %u (s-TMSI mmec %u m_TMSI %u random UE id (0x%" PRIx64 ")", + MSC_AS_TIME_ARGS(ctxt_pP), + ue_context_p->ue_context.rnti, + dec_rval.consumed, + ue_context_p->ue_context.Initialue_identity_s_TMSI.mme_code, + ue_context_p->ue_context.Initialue_identity_s_TMSI.m_tmsi, + ue_context_p->ue_context.random_ue_identity); + } else { + LOG_E(RRC, + PROTOCOL_RRC_CTXT_UE_FMT" RRCConnectionRequest without random UE identity or S-TMSI not supported, let's reject the UE\n", + PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP)); + rrc_eNB_generate_RRCConnectionReject(ctxt_pP, + rrc_eNB_get_ue_context(RC.rrc[ctxt_pP->module_id], ctxt_pP->rnti), + CC_id); + break; + } + } + LOG_D(RRC, + PROTOCOL_RRC_CTXT_UE_FMT" UE context: %p\n", PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP), - random_value); - rrc_mac_remove_ue(ctxt_pP->module_id,ctxt_pP->rnti); - return -1; + ue_context_p); + + if (ue_context_p != NULL) { +#if defined(ENABLE_ITTI) + ue_context_p->ue_context.establishment_cause = rrcConnectionRequest->establishmentCause; + ue_context_p->ue_context.reestablishment_cause = LTE_ReestablishmentCause_spare1; + + if (stmsi_received==0) + LOG_I(RRC, PROTOCOL_RRC_CTXT_UE_FMT" Accept new connection from UE random UE identity (0x%" PRIx64 ") MME code %u TMSI %u cause %ld\n", + PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP), + ue_context_p->ue_context.random_ue_identity, + ue_context_p->ue_context.Initialue_identity_s_TMSI.mme_code, + ue_context_p->ue_context.Initialue_identity_s_TMSI.m_tmsi, + ue_context_p->ue_context.establishment_cause); + else + LOG_I(RRC, PROTOCOL_RRC_CTXT_UE_FMT" Accept new connection from UE MME code %u TMSI %u cause %ld\n", + PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP), + ue_context_p->ue_context.Initialue_identity_s_TMSI.mme_code, + ue_context_p->ue_context.Initialue_identity_s_TMSI.m_tmsi, + ue_context_p->ue_context.establishment_cause); + +#else + LOG_I(RRC, PROTOCOL_RRC_CTXT_UE_FMT" Accept new connection for UE random UE identity (0x%" PRIx64 ")\n", + PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP), + ue_context_p->ue_context.random_ue_identity); +#endif + + if (stmsi_received == 0) + RC.rrc[ctxt_pP->module_id]->Nb_ue++; + } else { + // no context available + if (rrc_agent_registered[ctxt_pP->module_id]) { + agent_rrc_xface[ctxt_pP->module_id]->flexran_agent_notify_ue_state_change(ctxt_pP->module_id, + ctxt_pP->rnti, + PROTOCOL__FLEX_UE_STATE_CHANGE_TYPE__FLUESC_DEACTIVATED); + } + + LOG_I(RRC, PROTOCOL_RRC_CTXT_UE_FMT" Can't create new context for UE random UE identity (0x%" PRIx64 ")\n", + PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP), + random_value); + rrc_mac_remove_ue(ctxt_pP->module_id,ctxt_pP->rnti); + return -1; + } } - } #ifndef NO_RRM - send_msg(&S_rrc, msg_rrc_MR_attach_ind(ctxt_pP->module_id, Mac_id)); + send_msg(&S_rrc, msg_rrc_MR_attach_ind(ctxt_pP->module_id, Mac_id)); #else - - ue_context_p->ue_context.primaryCC_id = CC_id; - - //LG COMMENT Idx = (ue_mod_idP * NB_RB_MAX) + DCCH; - Idx = DCCH; - // SRB1 - ue_context_p->ue_context.Srb1.Active = 1; - ue_context_p->ue_context.Srb1.Srb_info.Srb_id = Idx; - memcpy(&ue_context_p->ue_context.Srb1.Srb_info.Lchan_desc[0], - &DCCH_LCHAN_DESC, - LCHAN_DESC_SIZE); - memcpy(&ue_context_p->ue_context.Srb1.Srb_info.Lchan_desc[1], - &DCCH_LCHAN_DESC, - LCHAN_DESC_SIZE); - - // SRB2: set it to go through SRB1 with id 1 (DCCH) - ue_context_p->ue_context.Srb2.Active = 1; - ue_context_p->ue_context.Srb2.Srb_info.Srb_id = Idx; - memcpy(&ue_context_p->ue_context.Srb2.Srb_info.Lchan_desc[0], - &DCCH_LCHAN_DESC, - LCHAN_DESC_SIZE); - memcpy(&ue_context_p->ue_context.Srb2.Srb_info.Lchan_desc[1], - &DCCH_LCHAN_DESC, - LCHAN_DESC_SIZE); - - rrc_eNB_generate_RRCConnectionSetup(ctxt_pP, ue_context_p, CC_id); - LOG_I(RRC, PROTOCOL_RRC_CTXT_UE_FMT"CALLING RLC CONFIG SRB1 (rbid %d)\n", - PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP), - Idx); - - MSC_LOG_TX_MESSAGE( - MSC_RRC_ENB, - MSC_PDCP_ENB, - NULL, - 0, - MSC_AS_TIME_FMT" CONFIG_REQ UE %x SRB", - MSC_AS_TIME_ARGS(ctxt_pP), - ue_context_p->ue_context.rnti); - - rrc_pdcp_config_asn1_req(ctxt_pP, - ue_context_p->ue_context.SRB_configList, - (LTE_DRB_ToAddModList_t *) NULL, - (LTE_DRB_ToReleaseList_t*) NULL, - 0xff, - NULL, - NULL, - NULL + ue_context_p->ue_context.primaryCC_id = CC_id; + //LG COMMENT Idx = (ue_mod_idP * NB_RB_MAX) + DCCH; + Idx = DCCH; + // SRB1 + ue_context_p->ue_context.Srb1.Active = 1; + ue_context_p->ue_context.Srb1.Srb_info.Srb_id = Idx; + memcpy(&ue_context_p->ue_context.Srb1.Srb_info.Lchan_desc[0], + &DCCH_LCHAN_DESC, + LCHAN_DESC_SIZE); + memcpy(&ue_context_p->ue_context.Srb1.Srb_info.Lchan_desc[1], + &DCCH_LCHAN_DESC, + LCHAN_DESC_SIZE); + // SRB2: set it to go through SRB1 with id 1 (DCCH) + ue_context_p->ue_context.Srb2.Active = 1; + ue_context_p->ue_context.Srb2.Srb_info.Srb_id = Idx; + memcpy(&ue_context_p->ue_context.Srb2.Srb_info.Lchan_desc[0], + &DCCH_LCHAN_DESC, + LCHAN_DESC_SIZE); + memcpy(&ue_context_p->ue_context.Srb2.Srb_info.Lchan_desc[1], + &DCCH_LCHAN_DESC, + LCHAN_DESC_SIZE); + rrc_eNB_generate_RRCConnectionSetup(ctxt_pP, ue_context_p, CC_id); + LOG_I(RRC, PROTOCOL_RRC_CTXT_UE_FMT"CALLING RLC CONFIG SRB1 (rbid %d)\n", + PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP), + Idx); + MSC_LOG_TX_MESSAGE( + MSC_RRC_ENB, + MSC_PDCP_ENB, + NULL, + 0, + MSC_AS_TIME_FMT" CONFIG_REQ UE %x SRB", + MSC_AS_TIME_ARGS(ctxt_pP), + ue_context_p->ue_context.rnti); + rrc_pdcp_config_asn1_req(ctxt_pP, + ue_context_p->ue_context.SRB_configList, + (LTE_DRB_ToAddModList_t *) NULL, + (LTE_DRB_ToReleaseList_t *) NULL, + 0xff, + NULL, + NULL, + NULL #if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) - , (LTE_PMCH_InfoList_r9_t *) NULL + , (LTE_PMCH_InfoList_r9_t *) NULL #endif - ,NULL); - - rrc_rlc_config_asn1_req(ctxt_pP, - ue_context_p->ue_context.SRB_configList, - (LTE_DRB_ToAddModList_t*) NULL, - (LTE_DRB_ToReleaseList_t*) NULL + ,NULL); + rrc_rlc_config_asn1_req(ctxt_pP, + ue_context_p->ue_context.SRB_configList, + (LTE_DRB_ToAddModList_t *) NULL, + (LTE_DRB_ToReleaseList_t *) NULL #if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) - , (LTE_PMCH_InfoList_r9_t *) NULL - , 0, 0 + , (LTE_PMCH_InfoList_r9_t *) NULL + , 0, 0 #endif - ); + ); #endif //NO_RRM + break; - break; - - default: - LOG_E(RRC, PROTOCOL_RRC_CTXT_UE_FMT" Unknown message\n", - PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP)); - rval = -1; - break; + default: + LOG_E(RRC, PROTOCOL_RRC_CTXT_UE_FMT" Unknown message\n", + PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP)); + rval = -1; + break; } rval = 0; @@ -6518,28 +6004,25 @@ rrc_eNB_decode_ccch( //----------------------------------------------------------------------------- int rrc_eNB_decode_dcch( - const protocol_ctxt_t* const ctxt_pP, + const protocol_ctxt_t *const ctxt_pP, const rb_id_t Srb_id, - const uint8_t* const Rx_sdu, + const uint8_t *const Rx_sdu, const sdu_size_t sdu_sizeP ) //----------------------------------------------------------------------------- { - asn_dec_rval_t dec_rval; //UL_DCCH_Message_t uldcchmsg; LTE_UL_DCCH_Message_t *ul_dcch_msg = NULL; //&uldcchmsg; int i; - struct rrc_eNB_ue_context_s* ue_context_p = NULL; + struct rrc_eNB_ue_context_s *ue_context_p = NULL; #if defined(ENABLE_ITTI) # if defined(ENABLE_USE_MME) - MessageDef * msg_delete_tunnels_p = NULL; + MessageDef *msg_delete_tunnels_p = NULL; uint8_t xid; #endif #endif - - int dedicated_DRB=0; - + int dedicated_DRB=0; T(T_ENB_RRC_UL_DCCH_DATA_IN, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame), T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti)); @@ -6552,19 +6035,18 @@ rrc_eNB_decode_dcch( PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP), Srb_id); } - //memset(ul_dcch_msg,0,sizeof(UL_DCCH_Message_t)); + //memset(ul_dcch_msg,0,sizeof(UL_DCCH_Message_t)); LOG_D(RRC, PROTOCOL_RRC_CTXT_UE_FMT" Decoding UL-DCCH Message\n", PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP)); dec_rval = uper_decode( NULL, &asn_DEF_LTE_UL_DCCH_Message, - (void**)&ul_dcch_msg, + (void **)&ul_dcch_msg, Rx_sdu, sdu_sizeP, 0, 0); - { for (i = 0; i < sdu_sizeP; i++) { LOG_T(RRC, "%x.", Rx_sdu[i]); @@ -6585,162 +6067,170 @@ rrc_eNB_decode_dcch( ctxt_pP->rnti); if (ul_dcch_msg->message.present == LTE_UL_DCCH_MessageType_PR_c1) { - switch (ul_dcch_msg->message.choice.c1.present) { - case LTE_UL_DCCH_MessageType__c1_PR_NOTHING: /* No components present */ - break; - - case LTE_UL_DCCH_MessageType__c1_PR_csfbParametersRequestCDMA2000: - break; - - case LTE_UL_DCCH_MessageType__c1_PR_measurementReport: - // to avoid segmentation fault - if(!ue_context_p){ - LOG_I(RRC, "Processing measurementReport UE %x, ue_context_p is NULL\n", ctxt_pP->rnti); + case LTE_UL_DCCH_MessageType__c1_PR_NOTHING: /* No components present */ break; - } - LOG_D(RRC, - PROTOCOL_RRC_CTXT_UE_FMT" RLC RB %02d --- RLC_DATA_IND " - "%d bytes (measurementReport) ---> RRC_eNB\n", - PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP), - DCCH, - sdu_sizeP); - rrc_eNB_process_MeasurementReport( - ctxt_pP, - ue_context_p, - &ul_dcch_msg->message.choice.c1.choice.measurementReport. - criticalExtensions.choice.c1.choice.measurementReport_r8.measResults); - break; - case LTE_UL_DCCH_MessageType__c1_PR_rrcConnectionReconfigurationComplete: - // to avoid segmentation fault - if(!ue_context_p){ - LOG_I(RRC, "Processing LTE_RRCConnectionReconfigurationComplete UE %x, ue_context_p is NULL\n", ctxt_pP->rnti); + case LTE_UL_DCCH_MessageType__c1_PR_csfbParametersRequestCDMA2000: break; - } - LOG_DUMPMSG(RRC,DEBUG_RRC,(char *)(Rx_sdu),sdu_sizeP, - "[MSG] RRC Connection Reconfiguration Complete\n"); - MSC_LOG_RX_MESSAGE( - MSC_RRC_ENB, - MSC_RRC_UE, - Rx_sdu, - sdu_sizeP, - MSC_AS_TIME_FMT" LTE_RRCConnectionReconfigurationComplete UE %x size %u", - MSC_AS_TIME_ARGS(ctxt_pP), - ue_context_p->ue_context.rnti, - sdu_sizeP); + case LTE_UL_DCCH_MessageType__c1_PR_measurementReport: - LOG_D(RRC, - PROTOCOL_RRC_CTXT_UE_FMT" RLC RB %02d --- RLC_DATA_IND %d bytes " - "(RRCConnectionReconfigurationComplete) ---> RRC_eNB]\n", - PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP), - DCCH, - sdu_sizeP); + // to avoid segmentation fault + if(!ue_context_p) { + LOG_I(RRC, "Processing measurementReport UE %x, ue_context_p is NULL\n", ctxt_pP->rnti); + break; + } - if (ul_dcch_msg->message.choice.c1.choice.rrcConnectionReconfigurationComplete.criticalExtensions. - present == - LTE_RRCConnectionReconfigurationComplete__criticalExtensions_PR_rrcConnectionReconfigurationComplete_r8) { - /*NN: revise the condition */ - /*FK: left the condition as is for the case MME is used (S1 mode) but setting dedicated_DRB = 1 otherwise (noS1 mode) so that no second RRCReconfiguration message activationg more DRB is sent as this causes problems with the nasmesh driver.*/ - if (EPC_MODE_ENABLED) { - if (ue_context_p->ue_context.Status == RRC_RECONFIGURED){ - dedicated_DRB = 1; - LOG_I(RRC, - PROTOCOL_RRC_CTXT_UE_FMT" UE State = RRC_RECONFIGURED (dedicated DRB, xid %ld)\n", - PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP),ul_dcch_msg->message.choice.c1.choice.rrcConnectionReconfigurationComplete.rrc_TransactionIdentifier); - //clear - int16_t UE_id = find_UE_id(ctxt_pP->module_id, ctxt_pP->rnti); - if(UE_id == -1){ - LOG_E(RRC, - PROTOCOL_RRC_CTXT_UE_FMT" RRCConnectionReconfigurationComplete without rnti %x, fault\n", - PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP),ctxt_pP->rnti); - break; - } - if(RC.mac[ctxt_pP->module_id]->UE_list.UE_sched_ctrl[UE_id].crnti_reconfigurationcomplete_flag == 1){ - LOG_I(RRC, - PROTOCOL_RRC_CTXT_UE_FMT" UE State = RRC_RECONFIGURED (dedicated DRB, xid %ld) C-RNTI Complete\n", - PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP),ul_dcch_msg->message.choice.c1.choice.rrcConnectionReconfigurationComplete.rrc_TransactionIdentifier); - dedicated_DRB = 2; - RC.mac[ctxt_pP->module_id]->UE_list.UE_sched_ctrl[UE_id].crnti_reconfigurationcomplete_flag = 0; - } - } else { - dedicated_DRB = 0; - ue_context_p->ue_context.Status = RRC_RECONFIGURED; - LOG_I(RRC, - PROTOCOL_RRC_CTXT_UE_FMT" UE State = RRC_RECONFIGURED (default DRB, xid %ld)\n", - PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP),ul_dcch_msg->message.choice.c1.choice.rrcConnectionReconfigurationComplete.rrc_TransactionIdentifier); - } - ue_context_p->ue_context.reestablishment_xid = -1; - } else { - dedicated_DRB = 1; - ue_context_p->ue_context.Status = RRC_RECONFIGURED; - LOG_I(RRC, - PROTOCOL_RRC_CTXT_UE_FMT" UE State = RRC_RECONFIGURED (dedicated DRB, xid %ld)\n", - PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP),ul_dcch_msg->message.choice.c1.choice.rrcConnectionReconfigurationComplete.rrc_TransactionIdentifier); - } - - rrc_eNB_process_RRCConnectionReconfigurationComplete( + LOG_D(RRC, + PROTOCOL_RRC_CTXT_UE_FMT" RLC RB %02d --- RLC_DATA_IND " + "%d bytes (measurementReport) ---> RRC_eNB\n", + PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP), + DCCH, + sdu_sizeP); + rrc_eNB_process_MeasurementReport( ctxt_pP, ue_context_p, - ul_dcch_msg->message.choice.c1.choice.rrcConnectionReconfigurationComplete.rrc_TransactionIdentifier); + &ul_dcch_msg->message.choice.c1.choice.measurementReport. + criticalExtensions.choice.c1.choice.measurementReport_r8.measResults); + break; + + case LTE_UL_DCCH_MessageType__c1_PR_rrcConnectionReconfigurationComplete: + + // to avoid segmentation fault + if(!ue_context_p) { + LOG_I(RRC, "Processing LTE_RRCConnectionReconfigurationComplete UE %x, ue_context_p is NULL\n", ctxt_pP->rnti); + break; + } + + LOG_DUMPMSG(RRC,DEBUG_RRC,(char *)(Rx_sdu),sdu_sizeP, + "[MSG] RRC Connection Reconfiguration Complete\n"); + MSC_LOG_RX_MESSAGE( + MSC_RRC_ENB, + MSC_RRC_UE, + Rx_sdu, + sdu_sizeP, + MSC_AS_TIME_FMT" LTE_RRCConnectionReconfigurationComplete UE %x size %u", + MSC_AS_TIME_ARGS(ctxt_pP), + ue_context_p->ue_context.rnti, + sdu_sizeP); + LOG_D(RRC, + PROTOCOL_RRC_CTXT_UE_FMT" RLC RB %02d --- RLC_DATA_IND %d bytes " + "(RRCConnectionReconfigurationComplete) ---> RRC_eNB]\n", + PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP), + DCCH, + sdu_sizeP); + + if (ul_dcch_msg->message.choice.c1.choice.rrcConnectionReconfigurationComplete.criticalExtensions. + present == + LTE_RRCConnectionReconfigurationComplete__criticalExtensions_PR_rrcConnectionReconfigurationComplete_r8) { + /*NN: revise the condition */ + /*FK: left the condition as is for the case MME is used (S1 mode) but setting dedicated_DRB = 1 otherwise (noS1 mode) so that no second RRCReconfiguration message activationg more DRB is sent as this causes problems with the nasmesh driver.*/ + if (EPC_MODE_ENABLED) { + if (ue_context_p->ue_context.Status == RRC_RECONFIGURED) { + dedicated_DRB = 1; + LOG_I(RRC, + PROTOCOL_RRC_CTXT_UE_FMT" UE State = RRC_RECONFIGURED (dedicated DRB, xid %ld)\n", + PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP),ul_dcch_msg->message.choice.c1.choice.rrcConnectionReconfigurationComplete.rrc_TransactionIdentifier); + //clear + int16_t UE_id = find_UE_id(ctxt_pP->module_id, ctxt_pP->rnti); + + if(UE_id == -1) { + LOG_E(RRC, + PROTOCOL_RRC_CTXT_UE_FMT" RRCConnectionReconfigurationComplete without rnti %x, fault\n", + PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP),ctxt_pP->rnti); + break; + } + + if(RC.mac[ctxt_pP->module_id]->UE_list.UE_sched_ctrl[UE_id].crnti_reconfigurationcomplete_flag == 1) { + LOG_I(RRC, + PROTOCOL_RRC_CTXT_UE_FMT" UE State = RRC_RECONFIGURED (dedicated DRB, xid %ld) C-RNTI Complete\n", + PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP),ul_dcch_msg->message.choice.c1.choice.rrcConnectionReconfigurationComplete.rrc_TransactionIdentifier); + dedicated_DRB = 2; + RC.mac[ctxt_pP->module_id]->UE_list.UE_sched_ctrl[UE_id].crnti_reconfigurationcomplete_flag = 0; + } + } else { + dedicated_DRB = 0; + ue_context_p->ue_context.Status = RRC_RECONFIGURED; + LOG_I(RRC, + PROTOCOL_RRC_CTXT_UE_FMT" UE State = RRC_RECONFIGURED (default DRB, xid %ld)\n", + PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP),ul_dcch_msg->message.choice.c1.choice.rrcConnectionReconfigurationComplete.rrc_TransactionIdentifier); + } + + ue_context_p->ue_context.reestablishment_xid = -1; + } else { + dedicated_DRB = 1; + ue_context_p->ue_context.Status = RRC_RECONFIGURED; + LOG_I(RRC, + PROTOCOL_RRC_CTXT_UE_FMT" UE State = RRC_RECONFIGURED (dedicated DRB, xid %ld)\n", + PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP),ul_dcch_msg->message.choice.c1.choice.rrcConnectionReconfigurationComplete.rrc_TransactionIdentifier); + } + + rrc_eNB_process_RRCConnectionReconfigurationComplete( + ctxt_pP, + ue_context_p, + ul_dcch_msg->message.choice.c1.choice.rrcConnectionReconfigurationComplete.rrc_TransactionIdentifier); + + //WARNING:Inform the controller about the UE activation. Should be moved to RRC agent in the future + if (rrc_agent_registered[ctxt_pP->module_id]) { + agent_rrc_xface[ctxt_pP->module_id]->flexran_agent_notify_ue_state_change(ctxt_pP->module_id, + ue_context_p->ue_id_rnti, + PROTOCOL__FLEX_UE_STATE_CHANGE_TYPE__FLUESC_UPDATED); + } + } - //WARNING:Inform the controller about the UE activation. Should be moved to RRC agent in the future - if (rrc_agent_registered[ctxt_pP->module_id]) { - agent_rrc_xface[ctxt_pP->module_id]->flexran_agent_notify_ue_state_change(ctxt_pP->module_id, - ue_context_p->ue_id_rnti, - PROTOCOL__FLEX_UE_STATE_CHANGE_TYPE__FLUESC_UPDATED); - } - } #if defined(ENABLE_ITTI) #if defined(ENABLE_USE_MME) - if (dedicated_DRB == 1){ -// rrc_eNB_send_S1AP_E_RAB_SETUP_RESP(ctxt_pP, -// ue_context_p, -// ul_dcch_msg->message.choice.c1.choice.rrcConnectionReconfigurationComplete.rrc_TransactionIdentifier); -if (ue_context_p->ue_context.nb_of_modify_e_rabs > 0) { - rrc_eNB_send_S1AP_E_RAB_MODIFY_RESP(ctxt_pP, - ue_context_p, - ul_dcch_msg->message.choice.c1.choice.rrcConnectionReconfigurationComplete.rrc_TransactionIdentifier); + if (dedicated_DRB == 1) { + // rrc_eNB_send_S1AP_E_RAB_SETUP_RESP(ctxt_pP, + // ue_context_p, + // ul_dcch_msg->message.choice.c1.choice.rrcConnectionReconfigurationComplete.rrc_TransactionIdentifier); + if (ue_context_p->ue_context.nb_of_modify_e_rabs > 0) { + rrc_eNB_send_S1AP_E_RAB_MODIFY_RESP(ctxt_pP, + ue_context_p, + ul_dcch_msg->message.choice.c1.choice.rrcConnectionReconfigurationComplete.rrc_TransactionIdentifier); ue_context_p->ue_context.nb_of_modify_e_rabs = 0; ue_context_p->ue_context.nb_of_failed_e_rabs = 0; memset(ue_context_p->ue_context.modify_e_rab, 0, sizeof(ue_context_p->ue_context.modify_e_rab)); + for(int i = 0; i < NB_RB_MAX; i++) { ue_context_p->ue_context.modify_e_rab[i].xid = -1; } - - } else if(ue_context_p->ue_context.e_rab_release_command_flag == 1){ + } else if(ue_context_p->ue_context.e_rab_release_command_flag == 1) { xid = ul_dcch_msg->message.choice.c1.choice.rrcConnectionReconfigurationComplete.rrc_TransactionIdentifier; ue_context_p->ue_context.e_rab_release_command_flag = 0; //gtp tunnel delete msg_delete_tunnels_p = itti_alloc_new_message(TASK_RRC_ENB, GTPV1U_ENB_DELETE_TUNNEL_REQ); memset(>PV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p), 0, sizeof(GTPV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p))); GTPV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p).rnti = ue_context_p->ue_context.rnti; - for(i = 0; i < NB_RB_MAX; i++){ - if(xid == ue_context_p->ue_context.e_rab[i].xid){ - GTPV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p).eps_bearer_id[GTPV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p).num_erab++] = ue_context_p->ue_context.enb_gtp_ebi[i]; - ue_context_p->ue_context.enb_gtp_teid[i] = 0; - memset(&ue_context_p->ue_context.enb_gtp_addrs[i], 0, sizeof(ue_context_p->ue_context.enb_gtp_addrs[i])); - ue_context_p->ue_context.enb_gtp_ebi[i] = 0; - } + + for(i = 0; i < NB_RB_MAX; i++) { + if(xid == ue_context_p->ue_context.e_rab[i].xid) { + GTPV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p).eps_bearer_id[GTPV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p).num_erab++] = ue_context_p->ue_context.enb_gtp_ebi[i]; + ue_context_p->ue_context.enb_gtp_teid[i] = 0; + memset(&ue_context_p->ue_context.enb_gtp_addrs[i], 0, sizeof(ue_context_p->ue_context.enb_gtp_addrs[i])); + ue_context_p->ue_context.enb_gtp_ebi[i] = 0; + } } + itti_send_msg_to_task(TASK_GTPV1_U, ctxt_pP->instance, msg_delete_tunnels_p); //S1AP_E_RAB_RELEASE_RESPONSE rrc_eNB_send_S1AP_E_RAB_RELEASE_RESPONSE(ctxt_pP, - ue_context_p, - xid); + ue_context_p, + xid); } else { - rrc_eNB_send_S1AP_E_RAB_SETUP_RESP(ctxt_pP, - ue_context_p, - ul_dcch_msg->message.choice.c1.choice.rrcConnectionReconfigurationComplete.rrc_TransactionIdentifier); + rrc_eNB_send_S1AP_E_RAB_SETUP_RESP(ctxt_pP, + ue_context_p, + ul_dcch_msg->message.choice.c1.choice.rrcConnectionReconfigurationComplete.rrc_TransactionIdentifier); } - }else if(dedicated_DRB == 0){ - if(ue_context_p->ue_context.reestablishment_cause == LTE_ReestablishmentCause_spare1){ - rrc_eNB_send_S1AP_INITIAL_CONTEXT_SETUP_RESP(ctxt_pP, - ue_context_p); + } else if(dedicated_DRB == 0) { + if(ue_context_p->ue_context.reestablishment_cause == LTE_ReestablishmentCause_spare1) { + rrc_eNB_send_S1AP_INITIAL_CONTEXT_SETUP_RESP(ctxt_pP, + ue_context_p); } else { ue_context_p->ue_context.reestablishment_cause = LTE_ReestablishmentCause_spare1; + for (uint8_t e_rab = 0; e_rab < ue_context_p->ue_context.nb_of_e_rabs; e_rab++) { if (ue_context_p->ue_context.e_rab[e_rab].status == E_RAB_STATUS_DONE) { ue_context_p->ue_context.e_rab[e_rab].status = E_RAB_STATUS_ESTABLISHED; @@ -6749,442 +6239,443 @@ if (ue_context_p->ue_context.nb_of_modify_e_rabs > 0) { } } } - }else if(dedicated_DRB == 2){ - for (uint8_t e_rab = 0; e_rab < ue_context_p->ue_context.nb_of_e_rabs; e_rab++) { - if (ue_context_p->ue_context.e_rab[e_rab].status == E_RAB_STATUS_DONE) { - ue_context_p->ue_context.e_rab[e_rab].status = E_RAB_STATUS_ESTABLISHED; - } else { - ue_context_p->ue_context.e_rab[e_rab].status = E_RAB_STATUS_FAILED; - } - } - } -#endif + } else if(dedicated_DRB == 2) { + for (uint8_t e_rab = 0; e_rab < ue_context_p->ue_context.nb_of_e_rabs; e_rab++) { + if (ue_context_p->ue_context.e_rab[e_rab].status == E_RAB_STATUS_DONE) { + ue_context_p->ue_context.e_rab[e_rab].status = E_RAB_STATUS_ESTABLISHED; + } else { + ue_context_p->ue_context.e_rab[e_rab].status = E_RAB_STATUS_FAILED; + } + } + } + +#endif #else // establish a dedicated bearer - if (dedicated_DRB == 0 ) { - // ue_context_p->ue_context.e_rab[0].status = E_RAB_STATUS_ESTABLISHED; - rrc_eNB_reconfigure_DRBs(ctxt_pP,ue_context_p); - } -#endif - break; - case LTE_UL_DCCH_MessageType__c1_PR_rrcConnectionReestablishmentComplete: - T(T_ENB_RRC_CONNECTION_REESTABLISHMENT_COMPLETE, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame), - T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti)); + if (dedicated_DRB == 0 ) { + // ue_context_p->ue_context.e_rab[0].status = E_RAB_STATUS_ESTABLISHED; + rrc_eNB_reconfigure_DRBs(ctxt_pP,ue_context_p); + } - LOG_DUMPMSG(RRC,DEBUG_RRC,(char *)Rx_sdu,sdu_sizeP, - "[MSG] RRC Connection Reestablishment Complete\n"); +#endif + break; - MSC_LOG_RX_MESSAGE( - MSC_RRC_ENB, - MSC_RRC_UE, - Rx_sdu, - sdu_sizeP, - MSC_AS_TIME_FMT" LTE_RRCConnectionReestablishmentComplete UE %x size %u", - MSC_AS_TIME_ARGS(ctxt_pP), - ue_context_p->ue_context.rnti, - sdu_sizeP); + case LTE_UL_DCCH_MessageType__c1_PR_rrcConnectionReestablishmentComplete: + T(T_ENB_RRC_CONNECTION_REESTABLISHMENT_COMPLETE, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame), + T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti)); + LOG_DUMPMSG(RRC,DEBUG_RRC,(char *)Rx_sdu,sdu_sizeP, + "[MSG] RRC Connection Reestablishment Complete\n"); + MSC_LOG_RX_MESSAGE( + MSC_RRC_ENB, + MSC_RRC_UE, + Rx_sdu, + sdu_sizeP, + MSC_AS_TIME_FMT" LTE_RRCConnectionReestablishmentComplete UE %x size %u", + MSC_AS_TIME_ARGS(ctxt_pP), + ue_context_p->ue_context.rnti, + sdu_sizeP); + LOG_I(RRC, + PROTOCOL_RRC_CTXT_UE_FMT" RLC RB %02d --- RLC_DATA_IND %d bytes " + "(rrcConnectionReestablishmentComplete) ---> RRC_eNB\n", + PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP), + DCCH, + sdu_sizeP); + { + rnti_t reestablish_rnti = 0; - LOG_I(RRC, - PROTOCOL_RRC_CTXT_UE_FMT" RLC RB %02d --- RLC_DATA_IND %d bytes " - "(rrcConnectionReestablishmentComplete) ---> RRC_eNB\n", - PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP), - DCCH, - sdu_sizeP); - { - rnti_t reestablish_rnti = 0; - // select C-RNTI from map - for (i = 0; i < MAX_MOBILES_PER_ENB; i++) { - if (reestablish_rnti_map[i][0] == ctxt_pP->rnti) { - reestablish_rnti = reestablish_rnti_map[i][1]; - ue_context_p = rrc_eNB_get_ue_context( - RC.rrc[ctxt_pP->module_id], - reestablish_rnti); - // clear currentC-RNTI from map - reestablish_rnti_map[i][0] = 0; - reestablish_rnti_map[i][1] = 0; + // select C-RNTI from map + for (i = 0; i < MAX_MOBILES_PER_ENB; i++) { + if (reestablish_rnti_map[i][0] == ctxt_pP->rnti) { + reestablish_rnti = reestablish_rnti_map[i][1]; + ue_context_p = rrc_eNB_get_ue_context( + RC.rrc[ctxt_pP->module_id], + reestablish_rnti); + // clear currentC-RNTI from map + reestablish_rnti_map[i][0] = 0; + reestablish_rnti_map[i][1] = 0; + break; + } + } + + LOG_D(RRC, "reestablish_rnti_map[%d] [0] %x, [1] %x\n", + i, reestablish_rnti_map[i][0], reestablish_rnti_map[i][1]); + + if (!ue_context_p) { + LOG_E(RRC, + PROTOCOL_RRC_CTXT_UE_FMT" LTE_RRCConnectionReestablishmentComplete without UE context, falt\n", + PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP)); break; } - } - LOG_D(RRC, "reestablish_rnti_map[%d] [0] %x, [1] %x\n", - i, reestablish_rnti_map[i][0], reestablish_rnti_map[i][1]); - if (!ue_context_p) { - LOG_E(RRC, - PROTOCOL_RRC_CTXT_UE_FMT" LTE_RRCConnectionReestablishmentComplete without UE context, falt\n", - PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP)); + //clear + int UE_id = find_UE_id(ctxt_pP->module_id, ctxt_pP->rnti); + + if(UE_id == -1) { + LOG_E(RRC, + PROTOCOL_RRC_CTXT_UE_FMT" LTE_RRCConnectionReestablishmentComplete without UE_id(MAC) rnti %x, fault\n", + PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP),ctxt_pP->rnti); + break; + } + + RC.mac[ctxt_pP->module_id]->UE_list.UE_sched_ctrl[UE_id].ue_reestablishment_reject_timer = 0; + ue_context_p->ue_context.ue_reestablishment_timer = 0; + + if (ul_dcch_msg->message.choice.c1.choice.rrcConnectionReestablishmentComplete.criticalExtensions.present == + LTE_RRCConnectionReestablishmentComplete__criticalExtensions_PR_rrcConnectionReestablishmentComplete_r8) { + rrc_eNB_process_RRCConnectionReestablishmentComplete(ctxt_pP, reestablish_rnti, ue_context_p, + ul_dcch_msg->message.choice.c1.choice.rrcConnectionReestablishmentComplete.rrc_TransactionIdentifier, + &ul_dcch_msg->message.choice.c1.choice.rrcConnectionReestablishmentComplete.criticalExtensions.choice.rrcConnectionReestablishmentComplete_r8); + + //WARNING:Inform the controller about the UE activation. Should be moved to RRC agent in the future + if (mac_agent_registered[ctxt_pP->module_id]) { + agent_rrc_xface[ctxt_pP->module_id]->flexran_agent_notify_ue_state_change(ctxt_pP->module_id, + ue_context_p->ue_id_rnti, + PROTOCOL__FLEX_UE_STATE_CHANGE_TYPE__FLUESC_ACTIVATED); + } + } + + //ue_context_p->ue_context.ue_release_timer = 0; + ue_context_p->ue_context.ue_reestablishment_timer = 1; + // remove UE after 100 frames after LTE_RRCConnectionReestablishmentRelease is triggered + ue_context_p->ue_context.ue_reestablishment_timer_thres = 1000; + } + break; + + case LTE_UL_DCCH_MessageType__c1_PR_rrcConnectionSetupComplete: + + // to avoid segmentation fault + if(!ue_context_p) { + LOG_I(RRC, "Processing LTE_RRCConnectionSetupComplete UE %x, ue_context_p is NULL\n", ctxt_pP->rnti); break; } - //clear - int UE_id = find_UE_id(ctxt_pP->module_id, ctxt_pP->rnti); - if(UE_id == -1){ - LOG_E(RRC, - PROTOCOL_RRC_CTXT_UE_FMT" LTE_RRCConnectionReestablishmentComplete without UE_id(MAC) rnti %x, fault\n", - PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP),ctxt_pP->rnti); - break; - } - RC.mac[ctxt_pP->module_id]->UE_list.UE_sched_ctrl[UE_id].ue_reestablishment_reject_timer = 0; - ue_context_p->ue_context.ue_reestablishment_timer = 0; - if (ul_dcch_msg->message.choice.c1.choice.rrcConnectionReestablishmentComplete.criticalExtensions.present == - LTE_RRCConnectionReestablishmentComplete__criticalExtensions_PR_rrcConnectionReestablishmentComplete_r8) { - rrc_eNB_process_RRCConnectionReestablishmentComplete(ctxt_pP, reestablish_rnti, ue_context_p, - ul_dcch_msg->message.choice.c1.choice.rrcConnectionReestablishmentComplete.rrc_TransactionIdentifier, - &ul_dcch_msg->message.choice.c1.choice.rrcConnectionReestablishmentComplete.criticalExtensions.choice.rrcConnectionReestablishmentComplete_r8); + LOG_DUMPMSG(RRC,DEBUG_RRC,(char *)Rx_sdu,sdu_sizeP, + "[MSG] RRC Connection SetupComplete\n"); + MSC_LOG_RX_MESSAGE( + MSC_RRC_ENB, + MSC_RRC_UE, + Rx_sdu, + sdu_sizeP, + MSC_AS_TIME_FMT" LTE_RRCConnectionSetupComplete UE %x size %u", + MSC_AS_TIME_ARGS(ctxt_pP), + ue_context_p->ue_context.rnti, + sdu_sizeP); + LOG_D(RRC, + PROTOCOL_RRC_CTXT_UE_FMT" RLC RB %02d --- RLC_DATA_IND %d bytes " + "(RRCConnectionSetupComplete) ---> RRC_eNB\n", + PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP), + DCCH, + sdu_sizeP); - //WARNING:Inform the controller about the UE activation. Should be moved to RRC agent in the future - if (mac_agent_registered[ctxt_pP->module_id]) { - agent_rrc_xface[ctxt_pP->module_id]->flexran_agent_notify_ue_state_change(ctxt_pP->module_id, - ue_context_p->ue_id_rnti, - PROTOCOL__FLEX_UE_STATE_CHANGE_TYPE__FLUESC_ACTIVATED); + if (ul_dcch_msg->message.choice.c1.choice.rrcConnectionSetupComplete.criticalExtensions.present == + LTE_RRCConnectionSetupComplete__criticalExtensions_PR_c1) { + if (ul_dcch_msg->message.choice.c1.choice.rrcConnectionSetupComplete.criticalExtensions.choice.c1. + present == + LTE_RRCConnectionSetupComplete__criticalExtensions__c1_PR_rrcConnectionSetupComplete_r8) { + rrc_eNB_process_RRCConnectionSetupComplete( + ctxt_pP, + ue_context_p, + &ul_dcch_msg->message.choice.c1.choice.rrcConnectionSetupComplete.criticalExtensions.choice.c1.choice.rrcConnectionSetupComplete_r8); + LOG_I(RRC, PROTOCOL_RRC_CTXT_UE_FMT" UE State = RRC_CONNECTED \n", + PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP)); + + //WARNING:Inform the controller about the UE activation. Should be moved to RRC agent in the future + if (rrc_agent_registered[ctxt_pP->module_id]) { + agent_rrc_xface[ctxt_pP->module_id]->flexran_agent_notify_ue_state_change(ctxt_pP->module_id, + ue_context_p->ue_id_rnti, + PROTOCOL__FLEX_UE_STATE_CHANGE_TYPE__FLUESC_ACTIVATED); + } } } - //ue_context_p->ue_context.ue_release_timer = 0; - ue_context_p->ue_context.ue_reestablishment_timer = 1; - // remove UE after 100 frames after LTE_RRCConnectionReestablishmentRelease is triggered - ue_context_p->ue_context.ue_reestablishment_timer_thres = 1000; - } - break; - case LTE_UL_DCCH_MessageType__c1_PR_rrcConnectionSetupComplete: - // to avoid segmentation fault - if(!ue_context_p){ - LOG_I(RRC, "Processing LTE_RRCConnectionSetupComplete UE %x, ue_context_p is NULL\n", ctxt_pP->rnti); + ue_context_p->ue_context.ue_release_timer=0; break; - } - LOG_DUMPMSG(RRC,DEBUG_RRC,(char *)Rx_sdu,sdu_sizeP, - "[MSG] RRC Connection SetupComplete\n"); - MSC_LOG_RX_MESSAGE( - MSC_RRC_ENB, - MSC_RRC_UE, - Rx_sdu, - sdu_sizeP, - MSC_AS_TIME_FMT" LTE_RRCConnectionSetupComplete UE %x size %u", - MSC_AS_TIME_ARGS(ctxt_pP), - ue_context_p->ue_context.rnti, - sdu_sizeP); + case LTE_UL_DCCH_MessageType__c1_PR_securityModeComplete: + T(T_ENB_RRC_SECURITY_MODE_COMPLETE, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame), + T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti)); - LOG_D(RRC, - PROTOCOL_RRC_CTXT_UE_FMT" RLC RB %02d --- RLC_DATA_IND %d bytes " - "(RRCConnectionSetupComplete) ---> RRC_eNB\n", - PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP), - DCCH, - sdu_sizeP); - - if (ul_dcch_msg->message.choice.c1.choice.rrcConnectionSetupComplete.criticalExtensions.present == - LTE_RRCConnectionSetupComplete__criticalExtensions_PR_c1) { - if (ul_dcch_msg->message.choice.c1.choice.rrcConnectionSetupComplete.criticalExtensions.choice.c1. - present == - LTE_RRCConnectionSetupComplete__criticalExtensions__c1_PR_rrcConnectionSetupComplete_r8) { - rrc_eNB_process_RRCConnectionSetupComplete( - ctxt_pP, - ue_context_p, - &ul_dcch_msg->message.choice.c1.choice.rrcConnectionSetupComplete.criticalExtensions.choice.c1.choice.rrcConnectionSetupComplete_r8); - LOG_I(RRC, PROTOCOL_RRC_CTXT_UE_FMT" UE State = RRC_CONNECTED \n", - PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP)); - - //WARNING:Inform the controller about the UE activation. Should be moved to RRC agent in the future - if (rrc_agent_registered[ctxt_pP->module_id]) { - agent_rrc_xface[ctxt_pP->module_id]->flexran_agent_notify_ue_state_change(ctxt_pP->module_id, - ue_context_p->ue_id_rnti, - PROTOCOL__FLEX_UE_STATE_CHANGE_TYPE__FLUESC_ACTIVATED); - } + // to avoid segmentation fault + if(!ue_context_p) { + LOG_I(RRC, "Processing securityModeComplete UE %x, ue_context_p is NULL\n", ctxt_pP->rnti); + break; } - } - ue_context_p->ue_context.ue_release_timer=0; - break; + LOG_DUMPMSG(RRC,DEBUG_RRC,(char *)Rx_sdu,sdu_sizeP, + "[MSG] RRC Security Mode Complete\n"); + MSC_LOG_RX_MESSAGE( + MSC_RRC_ENB, + MSC_RRC_UE, + Rx_sdu, + sdu_sizeP, + MSC_AS_TIME_FMT" securityModeComplete UE %x size %u", + MSC_AS_TIME_ARGS(ctxt_pP), + ue_context_p->ue_context.rnti, + sdu_sizeP); + LOG_I(RRC, + PROTOCOL_RRC_CTXT_UE_FMT" received securityModeComplete on UL-DCCH %d from UE\n", + PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP), + DCCH); + LOG_D(RRC, + PROTOCOL_RRC_CTXT_UE_FMT" RLC RB %02d --- RLC_DATA_IND %d bytes " + "(securityModeComplete) ---> RRC_eNB\n", + PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP), + DCCH, + sdu_sizeP); - case LTE_UL_DCCH_MessageType__c1_PR_securityModeComplete: - T(T_ENB_RRC_SECURITY_MODE_COMPLETE, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame), - T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti)); - // to avoid segmentation fault - if(!ue_context_p){ - LOG_I(RRC, "Processing securityModeComplete UE %x, ue_context_p is NULL\n", ctxt_pP->rnti); + if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) { + xer_fprint(stdout, &asn_DEF_LTE_UL_DCCH_Message, (void *)ul_dcch_msg); + } + + // confirm with PDCP about the security mode for DCCH + //rrc_pdcp_config_req (enb_mod_idP, frameP, 1,CONFIG_ACTION_SET_SECURITY_MODE, (ue_mod_idP * NB_RB_MAX) + DCCH, 0x77); + // continue the procedure + rrc_eNB_generate_UECapabilityEnquiry( + ctxt_pP, + ue_context_p); break; - } - LOG_DUMPMSG(RRC,DEBUG_RRC,(char *)Rx_sdu,sdu_sizeP, - "[MSG] RRC Security Mode Complete\n"); + case LTE_UL_DCCH_MessageType__c1_PR_securityModeFailure: + T(T_ENB_RRC_SECURITY_MODE_FAILURE, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame), + T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti)); + LOG_DUMPMSG(RRC,DEBUG_RRC,(char *)Rx_sdu,sdu_sizeP, + "[MSG] RRC Security Mode Failure\n"); + MSC_LOG_RX_MESSAGE( + MSC_RRC_ENB, + MSC_RRC_UE, + Rx_sdu, + sdu_sizeP, + MSC_AS_TIME_FMT" securityModeFailure UE %x size %u", + MSC_AS_TIME_ARGS(ctxt_pP), + ue_context_p->ue_context.rnti, + sdu_sizeP); + LOG_W(RRC, + PROTOCOL_RRC_CTXT_UE_FMT" RLC RB %02d --- RLC_DATA_IND %d bytes " + "(securityModeFailure) ---> RRC_eNB\n", + PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP), + DCCH, + sdu_sizeP); - MSC_LOG_RX_MESSAGE( - MSC_RRC_ENB, - MSC_RRC_UE, - Rx_sdu, - sdu_sizeP, - MSC_AS_TIME_FMT" securityModeComplete UE %x size %u", - MSC_AS_TIME_ARGS(ctxt_pP), - ue_context_p->ue_context.rnti, - sdu_sizeP); + if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) { + xer_fprint(stdout, &asn_DEF_LTE_UL_DCCH_Message, (void *)ul_dcch_msg); + } - LOG_I(RRC, - PROTOCOL_RRC_CTXT_UE_FMT" received securityModeComplete on UL-DCCH %d from UE\n", - PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP), - DCCH); - LOG_D(RRC, - PROTOCOL_RRC_CTXT_UE_FMT" RLC RB %02d --- RLC_DATA_IND %d bytes " - "(securityModeComplete) ---> RRC_eNB\n", - PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP), - DCCH, - sdu_sizeP); - if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) { - xer_fprint(stdout, &asn_DEF_LTE_UL_DCCH_Message, (void *)ul_dcch_msg); - } - // confirm with PDCP about the security mode for DCCH - //rrc_pdcp_config_req (enb_mod_idP, frameP, 1,CONFIG_ACTION_SET_SECURITY_MODE, (ue_mod_idP * NB_RB_MAX) + DCCH, 0x77); - // continue the procedure - rrc_eNB_generate_UECapabilityEnquiry( - ctxt_pP, - ue_context_p); - break; + // cancel the security mode in PDCP + // followup with the remaining procedure + //#warning "LG Removed rrc_eNB_generate_UECapabilityEnquiry after receiving securityModeFailure" + rrc_eNB_generate_UECapabilityEnquiry(ctxt_pP, ue_context_p); + break; - case LTE_UL_DCCH_MessageType__c1_PR_securityModeFailure: - T(T_ENB_RRC_SECURITY_MODE_FAILURE, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame), - T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti)); + case LTE_UL_DCCH_MessageType__c1_PR_ueCapabilityInformation: + T(T_ENB_RRC_UE_CAPABILITY_INFORMATION, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame), + T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti)); - LOG_DUMPMSG(RRC,DEBUG_RRC,(char *)Rx_sdu,sdu_sizeP, - "[MSG] RRC Security Mode Failure\n"); - - MSC_LOG_RX_MESSAGE( - MSC_RRC_ENB, - MSC_RRC_UE, - Rx_sdu, - sdu_sizeP, - MSC_AS_TIME_FMT" securityModeFailure UE %x size %u", - MSC_AS_TIME_ARGS(ctxt_pP), - ue_context_p->ue_context.rnti, - sdu_sizeP); - - LOG_W(RRC, - PROTOCOL_RRC_CTXT_UE_FMT" RLC RB %02d --- RLC_DATA_IND %d bytes " - "(securityModeFailure) ---> RRC_eNB\n", - PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP), - DCCH, - sdu_sizeP); - if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) { - xer_fprint(stdout, &asn_DEF_LTE_UL_DCCH_Message, (void *)ul_dcch_msg); - } - // cancel the security mode in PDCP - - // followup with the remaining procedure -//#warning "LG Removed rrc_eNB_generate_UECapabilityEnquiry after receiving securityModeFailure" - rrc_eNB_generate_UECapabilityEnquiry(ctxt_pP, ue_context_p); - break; - - case LTE_UL_DCCH_MessageType__c1_PR_ueCapabilityInformation: - T(T_ENB_RRC_UE_CAPABILITY_INFORMATION, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame), - T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti)); - // to avoid segmentation fault - if(!ue_context_p){ + // to avoid segmentation fault + if(!ue_context_p) { LOG_I(RRC, "Processing ueCapabilityInformation UE %x, ue_context_p is NULL\n", ctxt_pP->rnti); break; - } + } - LOG_DUMPMSG(RRC,DEBUG_RRC,(char *)Rx_sdu,sdu_sizeP, - "[MSG] RRC UECapablility Information\n"); - - MSC_LOG_RX_MESSAGE( - MSC_RRC_ENB, - MSC_RRC_UE, - Rx_sdu, - sdu_sizeP, - MSC_AS_TIME_FMT" ueCapabilityInformation UE %x size %u", - MSC_AS_TIME_ARGS(ctxt_pP), - ue_context_p->ue_context.rnti, - sdu_sizeP); - - LOG_I(RRC, - PROTOCOL_RRC_CTXT_UE_FMT" received ueCapabilityInformation on UL-DCCH %d from UE\n", - PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP), - DCCH); - LOG_D(RRC, - PROTOCOL_RRC_CTXT_UE_FMT" RLC RB %02d --- RLC_DATA_IND %d bytes " - "(UECapabilityInformation) ---> RRC_eNB\n", - PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP), - DCCH, - sdu_sizeP); - if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) { - xer_fprint(stdout, &asn_DEF_LTE_UL_DCCH_Message, (void *)ul_dcch_msg); - } - LOG_I(RRC, "got UE capabilities for UE %x\n", ctxt_pP->rnti); - if (ue_context_p->ue_context.UE_Capability) { - LOG_I(RRC, "freeing old UE capabilities for UE %x\n", ctxt_pP->rnti); - ASN_STRUCT_FREE(asn_DEF_LTE_UE_EUTRA_Capability, - ue_context_p->ue_context.UE_Capability); - ue_context_p->ue_context.UE_Capability = 0; - } - dec_rval = uper_decode(NULL, - &asn_DEF_LTE_UE_EUTRA_Capability, - (void **)&ue_context_p->ue_context.UE_Capability, - ul_dcch_msg->message.choice.c1.choice.ueCapabilityInformation.criticalExtensions. - choice.c1.choice.ueCapabilityInformation_r8.ue_CapabilityRAT_ContainerList.list. - array[0]->ueCapabilityRAT_Container.buf, - ul_dcch_msg->message.choice.c1.choice.ueCapabilityInformation.criticalExtensions. - choice.c1.choice.ueCapabilityInformation_r8.ue_CapabilityRAT_ContainerList.list. - array[0]->ueCapabilityRAT_Container.size, 0, 0); - if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) { - xer_fprint(stdout, &asn_DEF_LTE_UE_EUTRA_Capability, ue_context_p->ue_context.UE_Capability); - } - - if ((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)) { - LOG_E(RRC, PROTOCOL_RRC_CTXT_UE_FMT" Failed to decode UE capabilities (%zu bytes)\n", + LOG_DUMPMSG(RRC,DEBUG_RRC,(char *)Rx_sdu,sdu_sizeP, + "[MSG] RRC UECapablility Information\n"); + MSC_LOG_RX_MESSAGE( + MSC_RRC_ENB, + MSC_RRC_UE, + Rx_sdu, + sdu_sizeP, + MSC_AS_TIME_FMT" ueCapabilityInformation UE %x size %u", + MSC_AS_TIME_ARGS(ctxt_pP), + ue_context_p->ue_context.rnti, + sdu_sizeP); + LOG_I(RRC, + PROTOCOL_RRC_CTXT_UE_FMT" received ueCapabilityInformation on UL-DCCH %d from UE\n", PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP), - dec_rval.consumed); - ASN_STRUCT_FREE(asn_DEF_LTE_UE_EUTRA_Capability, - ue_context_p->ue_context.UE_Capability); - ue_context_p->ue_context.UE_Capability = 0; - } + DCCH); + LOG_D(RRC, + PROTOCOL_RRC_CTXT_UE_FMT" RLC RB %02d --- RLC_DATA_IND %d bytes " + "(UECapabilityInformation) ---> RRC_eNB\n", + PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP), + DCCH, + sdu_sizeP); - if (EPC_MODE_ENABLED) { + if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) { + xer_fprint(stdout, &asn_DEF_LTE_UL_DCCH_Message, (void *)ul_dcch_msg); + } - if (EPC_MODE_ENABLED == 1) { - rrc_eNB_send_S1AP_UE_CAPABILITIES_IND(ctxt_pP, - ue_context_p, - ul_dcch_msg); - } - } else { - ue_context_p->ue_context.nb_of_e_rabs = 1; - for (i = 0; i < ue_context_p->ue_context.nb_of_e_rabs; i++){ - ue_context_p->ue_context.e_rab[i].status = E_RAB_STATUS_NEW; - ue_context_p->ue_context.e_rab[i].param.e_rab_id = 1+i; - ue_context_p->ue_context.e_rab[i].param.qos.qci=9; - } - ue_context_p->ue_context.setup_e_rabs =ue_context_p->ue_context.nb_of_e_rabs; - } + LOG_I(RRC, "got UE capabilities for UE %x\n", ctxt_pP->rnti); - rrc_eNB_generate_defaultRRCConnectionReconfiguration(ctxt_pP, - ue_context_p, - RC.rrc[ctxt_pP->module_id]->HO_flag); - break; + if (ue_context_p->ue_context.UE_Capability) { + LOG_I(RRC, "freeing old UE capabilities for UE %x\n", ctxt_pP->rnti); + ASN_STRUCT_FREE(asn_DEF_LTE_UE_EUTRA_Capability, + ue_context_p->ue_context.UE_Capability); + ue_context_p->ue_context.UE_Capability = 0; + } - case LTE_UL_DCCH_MessageType__c1_PR_ulHandoverPreparationTransfer: - T(T_ENB_RRC_UL_HANDOVER_PREPARATION_TRANSFER, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame), - T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti)); + dec_rval = uper_decode(NULL, + &asn_DEF_LTE_UE_EUTRA_Capability, + (void **)&ue_context_p->ue_context.UE_Capability, + ul_dcch_msg->message.choice.c1.choice.ueCapabilityInformation.criticalExtensions. + choice.c1.choice.ueCapabilityInformation_r8.ue_CapabilityRAT_ContainerList.list. + array[0]->ueCapabilityRAT_Container.buf, + ul_dcch_msg->message.choice.c1.choice.ueCapabilityInformation.criticalExtensions. + choice.c1.choice.ueCapabilityInformation_r8.ue_CapabilityRAT_ContainerList.list. + array[0]->ueCapabilityRAT_Container.size, 0, 0); - break; + if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) { + xer_fprint(stdout, &asn_DEF_LTE_UE_EUTRA_Capability, ue_context_p->ue_context.UE_Capability); + } - case LTE_UL_DCCH_MessageType__c1_PR_ulInformationTransfer: - T(T_ENB_RRC_UL_INFORMATION_TRANSFER, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame), - T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti)); - // to avoid segmentation fault - if(!ue_context_p){ + if ((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)) { + LOG_E(RRC, PROTOCOL_RRC_CTXT_UE_FMT" Failed to decode UE capabilities (%zu bytes)\n", + PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP), + dec_rval.consumed); + ASN_STRUCT_FREE(asn_DEF_LTE_UE_EUTRA_Capability, + ue_context_p->ue_context.UE_Capability); + ue_context_p->ue_context.UE_Capability = 0; + } + + if (EPC_MODE_ENABLED) { + if (EPC_MODE_ENABLED == 1) { + rrc_eNB_send_S1AP_UE_CAPABILITIES_IND(ctxt_pP, + ue_context_p, + ul_dcch_msg); + } + } else { + ue_context_p->ue_context.nb_of_e_rabs = 1; + + for (i = 0; i < ue_context_p->ue_context.nb_of_e_rabs; i++) { + ue_context_p->ue_context.e_rab[i].status = E_RAB_STATUS_NEW; + ue_context_p->ue_context.e_rab[i].param.e_rab_id = 1+i; + ue_context_p->ue_context.e_rab[i].param.qos.qci=9; + } + + ue_context_p->ue_context.setup_e_rabs =ue_context_p->ue_context.nb_of_e_rabs; + } + + rrc_eNB_generate_defaultRRCConnectionReconfiguration(ctxt_pP, + ue_context_p, + RC.rrc[ctxt_pP->module_id]->HO_flag); + break; + + case LTE_UL_DCCH_MessageType__c1_PR_ulHandoverPreparationTransfer: + T(T_ENB_RRC_UL_HANDOVER_PREPARATION_TRANSFER, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame), + T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti)); + break; + + case LTE_UL_DCCH_MessageType__c1_PR_ulInformationTransfer: + T(T_ENB_RRC_UL_INFORMATION_TRANSFER, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame), + T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti)); + + // to avoid segmentation fault + if(!ue_context_p) { LOG_I(RRC, "Processing ulInformationTransfer UE %x, ue_context_p is NULL\n", ctxt_pP->rnti); break; - } + } - LOG_D(RRC,"[MSG] RRC UL Information Transfer \n"); - LOG_DUMPMSG(RRC,DEBUG_RRC,(char *)Rx_sdu,sdu_sizeP, - "[MSG] RRC UL Information Transfer \n"); + LOG_D(RRC,"[MSG] RRC UL Information Transfer \n"); + LOG_DUMPMSG(RRC,DEBUG_RRC,(char *)Rx_sdu,sdu_sizeP, + "[MSG] RRC UL Information Transfer \n"); + MSC_LOG_RX_MESSAGE( + MSC_RRC_ENB, + MSC_RRC_UE, + Rx_sdu, + sdu_sizeP, + MSC_AS_TIME_FMT" ulInformationTransfer UE %x size %u", + MSC_AS_TIME_ARGS(ctxt_pP), + ue_context_p->ue_context.rnti, + sdu_sizeP); - MSC_LOG_RX_MESSAGE( - MSC_RRC_ENB, - MSC_RRC_UE, - Rx_sdu, - sdu_sizeP, - MSC_AS_TIME_FMT" ulInformationTransfer UE %x size %u", - MSC_AS_TIME_ARGS(ctxt_pP), - ue_context_p->ue_context.rnti, - sdu_sizeP); + if (EPC_MODE_ENABLED == 1) { + rrc_eNB_send_S1AP_UPLINK_NAS(ctxt_pP, + ue_context_p, + ul_dcch_msg); + } - if (EPC_MODE_ENABLED == 1) { - rrc_eNB_send_S1AP_UPLINK_NAS(ctxt_pP, - ue_context_p, - ul_dcch_msg); - } - break; - - case LTE_UL_DCCH_MessageType__c1_PR_counterCheckResponse: - T(T_ENB_RRC_COUNTER_CHECK_RESPONSE, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame), - T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti)); - - break; + break; + case LTE_UL_DCCH_MessageType__c1_PR_counterCheckResponse: + T(T_ENB_RRC_COUNTER_CHECK_RESPONSE, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame), + T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti)); + break; #if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) - case LTE_UL_DCCH_MessageType__c1_PR_ueInformationResponse_r9: - T(T_ENB_RRC_UE_INFORMATION_RESPONSE_R9, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame), - T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti)); + case LTE_UL_DCCH_MessageType__c1_PR_ueInformationResponse_r9: + T(T_ENB_RRC_UE_INFORMATION_RESPONSE_R9, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame), + T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti)); + break; - break; - - case LTE_UL_DCCH_MessageType__c1_PR_proximityIndication_r9: - T(T_ENB_RRC_PROXIMITY_INDICATION_R9, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame), - T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti)); - - break; + case LTE_UL_DCCH_MessageType__c1_PR_proximityIndication_r9: + T(T_ENB_RRC_PROXIMITY_INDICATION_R9, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame), + T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti)); + break; #endif - #if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) - case LTE_UL_DCCH_MessageType__c1_PR_rnReconfigurationComplete_r10: - T(T_ENB_RRC_RECONFIGURATION_COMPLETE_R10, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame), - T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti)); - break; + case LTE_UL_DCCH_MessageType__c1_PR_rnReconfigurationComplete_r10: + T(T_ENB_RRC_RECONFIGURATION_COMPLETE_R10, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame), + T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti)); + break; - case LTE_UL_DCCH_MessageType__c1_PR_mbmsCountingResponse_r10: - T(T_ENB_RRC_MBMS_COUNTING_RESPONSE_R10, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame), - T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti)); + case LTE_UL_DCCH_MessageType__c1_PR_mbmsCountingResponse_r10: + T(T_ENB_RRC_MBMS_COUNTING_RESPONSE_R10, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame), + T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti)); + break; - break; - - case LTE_UL_DCCH_MessageType__c1_PR_interFreqRSTDMeasurementIndication_r10: - T(T_ENB_RRC_INTER_FREQ_RSTD_MEASUREMENT_INDICATION, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame), - T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti)); - - break; + case LTE_UL_DCCH_MessageType__c1_PR_interFreqRSTDMeasurementIndication_r10: + T(T_ENB_RRC_INTER_FREQ_RSTD_MEASUREMENT_INDICATION, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame), + T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti)); + break; #endif - default: - T(T_ENB_RRC_UNKNOW_MESSAGE, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame), - T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti)); - - LOG_E(RRC, PROTOCOL_RRC_CTXT_UE_FMT" Unknown message %s:%u\n", - PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP), - __FILE__, __LINE__); - return -1; + default: + T(T_ENB_RRC_UNKNOW_MESSAGE, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame), + T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti)); + LOG_E(RRC, PROTOCOL_RRC_CTXT_UE_FMT" Unknown message %s:%u\n", + PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP), + __FILE__, __LINE__); + return -1; } return 0; //TTN for D2D - } else if (ul_dcch_msg->message.present == LTE_UL_DCCH_MessageType_PR_messageClassExtension){ - LOG_I(RRC, "THINH [UL_DCCH_MessageType_PR_messageClassExtension]\n"); + } else if (ul_dcch_msg->message.present == LTE_UL_DCCH_MessageType_PR_messageClassExtension) { + LOG_I(RRC, "THINH [UL_DCCH_MessageType_PR_messageClassExtension]\n"); - switch (ul_dcch_msg->message.choice.messageClassExtension.present) { - case LTE_UL_DCCH_MessageType__messageClassExtension_PR_NOTHING: /* No components present */ + switch (ul_dcch_msg->message.choice.messageClassExtension.present) { + case LTE_UL_DCCH_MessageType__messageClassExtension_PR_NOTHING: /* No components present */ break; - case LTE_UL_DCCH_MessageType__messageClassExtension_PR_c2: //SidelinkUEInformation - //case UL_DCCH_MessageType__messageClassExtension__c2_PR_sidelinkUEInformation_r12: //SidelinkUEInformation - LOG_I(RRC,"THINH [UL_DCCH_MessageType__messageClassExtension_PR_c2]\n"); + case LTE_UL_DCCH_MessageType__messageClassExtension_PR_c2: //SidelinkUEInformation + //case UL_DCCH_MessageType__messageClassExtension__c2_PR_sidelinkUEInformation_r12: //SidelinkUEInformation + LOG_I(RRC,"THINH [UL_DCCH_MessageType__messageClassExtension_PR_c2]\n"); LOG_DUMPMSG(RRC,DEBUG_RRC,(char *)Rx_sdu,sdu_sizeP, "[MSG] RRC SidelinkUEInformation \n"); - MSC_LOG_RX_MESSAGE( - MSC_RRC_ENB, - MSC_RRC_UE, - Rx_sdu, - sdu_sizeP, - MSC_AS_TIME_FMT" SidelinkUEInformation UE %x size %u", - MSC_AS_TIME_ARGS(ctxt_pP), - ue_context_p->ue_context.rnti, - sdu_sizeP); - + MSC_RRC_ENB, + MSC_RRC_UE, + Rx_sdu, + sdu_sizeP, + MSC_AS_TIME_FMT" SidelinkUEInformation UE %x size %u", + MSC_AS_TIME_ARGS(ctxt_pP), + ue_context_p->ue_context.rnti, + sdu_sizeP); LOG_I(RRC, PROTOCOL_RRC_CTXT_UE_FMT" RLC RB %02d --- RLC_DATA_IND %d bytes " "(SidelinkUEInformation) ---> RRC_eNB\n", PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP), DCCH, sdu_sizeP); - rrc_eNB_process_SidelinkUEInformation( - ctxt_pP, - ue_context_p, - &ul_dcch_msg->message.choice.messageClassExtension.choice.c2.choice.sidelinkUEInformation_r12); + ctxt_pP, + ue_context_p, + &ul_dcch_msg->message.choice.messageClassExtension.choice.c2.choice.sidelinkUEInformation_r12); break; - default: + + default: break; - } - //end TTN + } + + //end TTN } else { LOG_E(RRC, PROTOCOL_RRC_CTXT_UE_FMT" Unknown error %s:%u\n", PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP), @@ -7196,16 +6687,15 @@ if (ue_context_p->ue_context.nb_of_modify_e_rabs > 0) { } #if defined(ENABLE_ITTI) -void rrc_eNB_reconfigure_DRBs (const protocol_ctxt_t* const ctxt_pP, - rrc_eNB_ue_context_t* ue_context_pP){ - +void rrc_eNB_reconfigure_DRBs (const protocol_ctxt_t *const ctxt_pP, + rrc_eNB_ue_context_t *ue_context_pP) { int i; int e_rab_done=0; - for (i = 0; + + for (i = 0; i < 3;//NB_RB_MAX - 3; // S1AP_MAX_E_RAB i++) { - - if ( ue_context_pP->ue_context.e_rab[i].status < E_RAB_STATUS_DONE){ + if ( ue_context_pP->ue_context.e_rab[i].status < E_RAB_STATUS_DONE) { ue_context_pP->ue_context.e_rab[i].status = E_RAB_STATUS_NEW; ue_context_pP->ue_context.e_rab[i].param.e_rab_id = i + 1; ue_context_pP->ue_context.e_rab[i].param.qos.qci = i % 9; @@ -7214,18 +6704,17 @@ void rrc_eNB_reconfigure_DRBs (const protocol_ctxt_t* const ctxt_pP, ue_context_pP->ue_context.e_rab[i].param.qos.allocation_retention_priority.pre_emp_vulnerability= PRE_EMPTION_VULNERABILITY_DISABLED; ue_context_pP->ue_context.e_rab[i].param.nas_pdu.buffer = NULL; ue_context_pP->ue_context.e_rab[i].param.nas_pdu.length = 0; - // memset (ue_context_pP->ue_context.e_rab[i].param.sgw_addr.buffer,0,20); + // memset (ue_context_pP->ue_context.e_rab[i].param.sgw_addr.buffer,0,20); ue_context_pP->ue_context.e_rab[i].param.sgw_addr.length = 0; ue_context_pP->ue_context.e_rab[i].param.gtp_teid=0; - ue_context_pP->ue_context.nb_of_e_rabs++; e_rab_done++; - LOG_I(RRC,"setting up the dedicated DRBs %d (index %d) status %d \n", - ue_context_pP->ue_context.e_rab[i].param.e_rab_id, i, ue_context_pP->ue_context.e_rab[i].status); + LOG_I(RRC,"setting up the dedicated DRBs %d (index %d) status %d \n", + ue_context_pP->ue_context.e_rab[i].param.e_rab_id, i, ue_context_pP->ue_context.e_rab[i].status); } } + ue_context_pP->ue_context.setup_e_rabs+=e_rab_done; - rrc_eNB_generate_dedicatedRRCConnectionReconfiguration(ctxt_pP, ue_context_pP, 0); } @@ -7238,23 +6727,20 @@ void rrc_enb_init(void) { //----------------------------------------------------------------------------- void *rrc_enb_process_itti_msg(void *notUsed) { - MessageDef *msg_p; - const char *msg_name_p; - instance_t instance; - int result; - SRB_INFO *srb_info_p; - int CC_id; - - protocol_ctxt_t ctxt; + MessageDef *msg_p; + const char *msg_name_p; + instance_t instance; + int result; + SRB_INFO *srb_info_p; + int CC_id; + protocol_ctxt_t ctxt; + // Wait for a message + itti_receive_msg(TASK_RRC_ENB, &msg_p); + msg_name_p = ITTI_MSG_NAME(msg_p); + instance = ITTI_MSG_INSTANCE(msg_p); + LOG_I(RRC,"Received message %s\n",msg_name_p); - // Wait for a message - itti_receive_msg(TASK_RRC_ENB, &msg_p); - - msg_name_p = ITTI_MSG_NAME(msg_p); - instance = ITTI_MSG_INSTANCE(msg_p); - LOG_I(RRC,"Received message %s\n",msg_name_p); - - switch (ITTI_MSG_ID(msg_p)) { + switch (ITTI_MSG_ID(msg_p)) { case TERMINATE_MESSAGE: LOG_W(RRC, " *** Exiting RRC thread\n"); itti_exit_task(); @@ -7264,7 +6750,7 @@ void *rrc_enb_process_itti_msg(void *notUsed) { LOG_I(RRC, "[eNB %d] Received %s\n", instance, msg_name_p); break; - /* Messages from MAC */ + /* Messages from MAC */ case RRC_MAC_CCCH_DATA_IND: PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt, instance, @@ -7275,25 +6761,24 @@ void *rrc_enb_process_itti_msg(void *notUsed) { LOG_I(RRC, PROTOCOL_RRC_CTXT_UE_FMT" Received %s\n", PROTOCOL_RRC_CTXT_UE_ARGS(&ctxt), msg_name_p); - CC_id = RRC_MAC_CCCH_DATA_IND(msg_p).CC_id; srb_info_p = &RC.rrc[instance]->carrier[CC_id].Srb0; - LOG_I(RRC,"Decoding CCCH : inst %d, CC_id %d, ctxt %p, sib_info_p->Rx_buffer.payload_size %d\n", - instance,CC_id,&ctxt, RRC_MAC_CCCH_DATA_IND(msg_p).sdu_size); + instance,CC_id,&ctxt, RRC_MAC_CCCH_DATA_IND(msg_p).sdu_size); + if (RRC_MAC_CCCH_DATA_IND(msg_p).sdu_size >= RRC_BUFFER_SIZE_MAX) { - LOG_I(RRC, "CCCH message has size %d > %d\n",RRC_MAC_CCCH_DATA_IND(msg_p).sdu_size,RRC_BUFFER_SIZE_MAX); - break; + LOG_I(RRC, "CCCH message has size %d > %d\n",RRC_MAC_CCCH_DATA_IND(msg_p).sdu_size,RRC_BUFFER_SIZE_MAX); + break; } + memcpy(srb_info_p->Rx_buffer.Payload, RRC_MAC_CCCH_DATA_IND(msg_p).sdu, RRC_MAC_CCCH_DATA_IND(msg_p).sdu_size); srb_info_p->Rx_buffer.payload_size = RRC_MAC_CCCH_DATA_IND(msg_p).sdu_size; - rrc_eNB_decode_ccch(&ctxt, srb_info_p, CC_id); break; - - /* Messages from PDCP */ + + /* Messages from PDCP */ case RRC_DCCH_DATA_IND: PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt, instance, @@ -7309,18 +6794,18 @@ void *rrc_enb_process_itti_msg(void *notUsed) { RRC_DCCH_DATA_IND(msg_p).dcch_index, RRC_DCCH_DATA_IND(msg_p).sdu_p, RRC_DCCH_DATA_IND(msg_p).sdu_size); - // Message buffer has been processed, free it now. result = itti_free(ITTI_MSG_ORIGIN_ID(msg_p), RRC_DCCH_DATA_IND(msg_p).sdu_p); - if (result != EXIT_SUCCESS) { - LOG_I(RRC, "Failed to free memory (%d)!\n",result); - break; - } - break; + if (result != EXIT_SUCCESS) { + LOG_I(RRC, "Failed to free memory (%d)!\n",result); + break; + } + + break; # if defined(ENABLE_USE_MME) - /* Messages from S1AP */ + /* Messages from S1AP */ case S1AP_DOWNLINK_NAS: rrc_eNB_process_S1AP_DOWNLINK_NAS(msg_p, msg_name_p, instance, &rrc_eNB_mui); break; @@ -7337,8 +6822,8 @@ void *rrc_enb_process_itti_msg(void *notUsed) { LOG_D(RRC, "[eNB %d] Received Paging message from S1AP: %s\n", instance, msg_name_p); rrc_eNB_process_PAGING_IND(msg_p, msg_name_p, instance); break; - - case S1AP_E_RAB_SETUP_REQ: + + case S1AP_E_RAB_SETUP_REQ: rrc_eNB_process_S1AP_E_RAB_SETUP_REQ(msg_p, msg_name_p, instance); LOG_D(RRC, "[eNB %d] Received the message %s\n", instance, msg_name_p); break; @@ -7350,7 +6835,7 @@ void *rrc_enb_process_itti_msg(void *notUsed) { case S1AP_E_RAB_RELEASE_COMMAND: rrc_eNB_process_S1AP_E_RAB_RELEASE_COMMAND(msg_p, msg_name_p, instance); break; - + case S1AP_UE_CONTEXT_RELEASE_REQ: rrc_eNB_process_S1AP_UE_CONTEXT_RELEASE_REQ(msg_p, msg_name_p, instance); break; @@ -7360,19 +6845,20 @@ void *rrc_enb_process_itti_msg(void *notUsed) { break; case GTPV1U_ENB_DELETE_TUNNEL_RESP: + /* Nothing to do. Apparently everything is done in S1AP processing */ //LOG_I(RRC, "[eNB %d] Received message %s, not processed because procedure not synched\n", //instance, msg_name_p); - if (rrc_eNB_get_ue_context(RC.rrc[instance], GTPV1U_ENB_DELETE_TUNNEL_RESP(msg_p).rnti) - && rrc_eNB_get_ue_context(RC.rrc[instance], GTPV1U_ENB_DELETE_TUNNEL_RESP(msg_p).rnti)->ue_context.ue_release_timer_rrc > 0) { + if (rrc_eNB_get_ue_context(RC.rrc[instance], GTPV1U_ENB_DELETE_TUNNEL_RESP(msg_p).rnti) + && rrc_eNB_get_ue_context(RC.rrc[instance], GTPV1U_ENB_DELETE_TUNNEL_RESP(msg_p).rnti)->ue_context.ue_release_timer_rrc > 0) { rrc_eNB_get_ue_context(RC.rrc[instance], GTPV1U_ENB_DELETE_TUNNEL_RESP(msg_p).rnti)->ue_context.ue_release_timer_rrc = - rrc_eNB_get_ue_context(RC.rrc[instance], GTPV1U_ENB_DELETE_TUNNEL_RESP(msg_p).rnti)->ue_context.ue_release_timer_thres_rrc; + rrc_eNB_get_ue_context(RC.rrc[instance], GTPV1U_ENB_DELETE_TUNNEL_RESP(msg_p).rnti)->ue_context.ue_release_timer_thres_rrc; } - break; + break; # endif - /* Messages from eNB app */ + /* Messages from eNB app */ case RRC_CONFIGURATION_REQ: LOG_I(RRC, "[eNB %d] Received %s : %p\n", instance, msg_name_p,&RRC_CONFIGURATION_REQ(msg_p)); openair_rrc_eNB_configuration(ENB_INSTANCE_TO_MODULE_ID(instance), &RRC_CONFIGURATION_REQ(msg_p)); @@ -7381,33 +6867,31 @@ void *rrc_enb_process_itti_msg(void *notUsed) { default: LOG_E(RRC, "[eNB %d] Received unexpected message %s\n", instance, msg_name_p); break; - } + } - result = itti_free(ITTI_MSG_ORIGIN_ID(msg_p), msg_p); - if (result != EXIT_SUCCESS) { - LOG_I(RRC, "Failed to free memory (%d)!\n",result); - } - msg_p = NULL; - return NULL; + result = itti_free(ITTI_MSG_ORIGIN_ID(msg_p), msg_p); + + if (result != EXIT_SUCCESS) { + LOG_I(RRC, "Failed to free memory (%d)!\n",result); + } + + msg_p = NULL; + return NULL; } //----------------------------------------------------------------------------- -void* +void * rrc_enb_task( - void* args_p + void *args_p ) //----------------------------------------------------------------------------- { rrc_enb_init(); - itti_mark_task_ready(TASK_RRC_ENB); LOG_I(RRC,"Entering main loop of RRC message task\n"); - while (1) { - (void) rrc_enb_process_itti_msg(NULL); - } } #endif @@ -7417,13 +6901,10 @@ void openair_rrc_top_init_eNB(int eMBMS_active,uint8_t HO_active) //----------------------------------------------------------------------------- { - module_id_t module_id; int CC_id; - /* for no gcc warnings */ (void)CC_id; - LOG_D(RRC, "[OPENAIR][INIT] Init function start: NB_eNB_INST=%d\n", RC.nb_inst); if (RC.nb_inst > 0) { @@ -7452,9 +6933,7 @@ openair_rrc_top_init_eNB(int eMBMS_active,uint8_t HO_active) } #endif - } - - + } } //----------------------------------------------------------------------------- @@ -7464,8 +6943,8 @@ rrc_top_cleanup_eNB( ) //----------------------------------------------------------------------------- { + for (int i=0; icriticalExtensions.present == LTE_SidelinkUEInformation_r12__criticalExtensions_PR_c1){ - if (sidelinkUEInformation->criticalExtensions.choice.c1.present == LTE_SidelinkUEInformation_r12__criticalExtensions__c1_PR_sidelinkUEInformation_r12){ - // express its interest to receive SL communication - if (sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.commRxInterestedFreq_r12 != NULL){ - - } - - // express its interest to transmit non-relay one-to-many SL communication - if ((sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.commTxResourceReq_r12 != NULL) && (sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.commTxResourceReq_r12->carrierFreq_r12 != NULL)){ - n_destinations = sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.commTxResourceReq_r12->destinationInfoList_r12.list.count; - destinationInfoList = CALLOC(1, sizeof(LTE_SL_DestinationInfoList_r12_t)); - for (int i=0; i< n_destinations; i++ ){ - //sl_DestinationIdentityList[i] = *(sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.commTxResourceReq_r12->destinationInfoList_r12.list.array[i]); - ASN_SEQUENCE_ADD(&destinationInfoList->list, sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.commTxResourceReq_r12->destinationInfoList_r12.list.array[i]); - } - //generate RRC Reconfiguration - rrc_eNB_generate_RRCConnectionReconfiguration_Sidelink(ctxt_pP, ue_context_pP, destinationInfoList, 0); - return 0; - - } - - // express its interest to transmit non-relay one-to-one SL communication - if ((sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.nonCriticalExtension != NULL) && (sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.nonCriticalExtension->commTxResourceReqUC_r13 != NULL)) { - if (sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.nonCriticalExtension->commTxResourceReqUC_r13->carrierFreq_r12 != NULL){ - n_destinations = sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.nonCriticalExtension->commTxResourceReqUC_r13->destinationInfoList_r12.list.count; - destinationInfoList = CALLOC(1, sizeof(LTE_SL_DestinationInfoList_r12_t)); - for (int i=0; i< n_destinations; i++ ){ - //sl_DestinationIdentityList[i] = *(sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.nonCriticalExtension->commTxResourceReqUC_r13->destinationInfoList_r12.list.array[i]); - ASN_SEQUENCE_ADD(&destinationInfoList->list,sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.nonCriticalExtension->commTxResourceReqUC_r13->destinationInfoList_r12.list.array[i]); - } - //generate RRC Reconfiguration - rrc_eNB_generate_RRCConnectionReconfiguration_Sidelink(ctxt_pP, ue_context_pP, destinationInfoList, 0); - return 0; - } - } - - // express its interest to transmit relay related one-to-one SL communication - if ((sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.nonCriticalExtension != NULL) &&(sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.nonCriticalExtension->commTxResourceInfoReqRelay_r13->commTxResourceReqRelayUC_r13 != NULL)) { - if (sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.nonCriticalExtension->commTxResourceInfoReqRelay_r13->commTxResourceReqRelayUC_r13->destinationInfoList_r12.list.count > 0) { - n_destinations = sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.nonCriticalExtension->commTxResourceInfoReqRelay_r13->commTxResourceReqRelayUC_r13->destinationInfoList_r12.list.count; - destinationInfoList = CALLOC(1, sizeof(LTE_SL_DestinationInfoList_r12_t)); - for (int i=0; i< n_destinations; i++ ){ - //sl_DestinationIdentityList[i] = *(sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.nonCriticalExtension->commTxResourceInfoReqRelay_r13->commTxResourceReqRelayUC_r13->destinationInfoList_r12.list.array[i]); - ASN_SEQUENCE_ADD(&destinationInfoList->list, sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.nonCriticalExtension->commTxResourceInfoReqRelay_r13->commTxResourceReqRelayUC_r13->destinationInfoList_r12.list.array[i]); - } - //generate RRC Reconfiguration - rrc_eNB_generate_RRCConnectionReconfiguration_Sidelink(ctxt_pP, ue_context_pP, destinationInfoList, 0); - return 0; - } - } - - //express its interest to transmit relay related one-to-many SL communication - if ((sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.nonCriticalExtension != NULL) && (sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.nonCriticalExtension->commTxResourceInfoReqRelay_r13 != NULL)) { - if (sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.nonCriticalExtension->commTxResourceInfoReqRelay_r13->commTxResourceReqRelay_r13->destinationInfoList_r12.list.count > 0){ - n_destinations = sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.nonCriticalExtension->commTxResourceInfoReqRelay_r13->commTxResourceReqRelay_r13->destinationInfoList_r12.list.count; - destinationInfoList = CALLOC(1, sizeof(LTE_SL_DestinationInfoList_r12_t)); - for (int i=0; i< n_destinations; i++ ){ - //sl_DestinationIdentityList[i] = *(sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.nonCriticalExtension->commTxResourceInfoReqRelay_r13->commTxResourceReqRelay_r13->destinationInfoList_r12.list.array[i]); - ASN_SEQUENCE_ADD(&destinationInfoList->list,sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.nonCriticalExtension->commTxResourceInfoReqRelay_r13->commTxResourceReqRelay_r13->destinationInfoList_r12.list.array[i]); - } - //generate RRC Reconfiguration - rrc_eNB_generate_RRCConnectionReconfiguration_Sidelink(ctxt_pP, ue_context_pP, destinationInfoList, 0); - return 0; - } - } - - //For SL Discovery - //express its interest to receive SL discovery announcements - //express its interest to transmit non-PS related discovery announcements - if (sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.discTxResourceReq_r12 != NULL){ - n_discoveryMessages = *(sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.discTxResourceReq_r12); - //generate RRC Reconfiguration - rrc_eNB_generate_RRCConnectionReconfiguration_Sidelink(ctxt_pP, ue_context_pP, NULL, n_discoveryMessages); - return 0; - } - //express its interest to transmit PS related discovery announcements - if ((sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.nonCriticalExtension != NULL) && (sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.nonCriticalExtension->discTxResourceReqPS_r13 !=NULL)) { - if (sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.nonCriticalExtension->discTxResourceReqPS_r13->discTxResourceReq_r13 > 0){ - n_discoveryMessages = sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.nonCriticalExtension->discTxResourceReqPS_r13->discTxResourceReq_r13; - //generate RRC Reconfiguration - rrc_eNB_generate_RRCConnectionReconfiguration_Sidelink(ctxt_pP, ue_context_pP, NULL, n_discoveryMessages); - return 0; - } - } + //For SL Communication + if (sidelinkUEInformation->criticalExtensions.present == LTE_SidelinkUEInformation_r12__criticalExtensions_PR_c1) { + if (sidelinkUEInformation->criticalExtensions.choice.c1.present == LTE_SidelinkUEInformation_r12__criticalExtensions__c1_PR_sidelinkUEInformation_r12) { + // express its interest to receive SL communication + if (sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.commRxInterestedFreq_r12 != NULL) { } - } - return 0; + + // express its interest to transmit non-relay one-to-many SL communication + if ((sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.commTxResourceReq_r12 != NULL) && + (sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.commTxResourceReq_r12->carrierFreq_r12 != NULL)) { + n_destinations = sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.commTxResourceReq_r12->destinationInfoList_r12.list.count; + destinationInfoList = CALLOC(1, sizeof(LTE_SL_DestinationInfoList_r12_t)); + + for (int i=0; i< n_destinations; i++ ) { + //sl_DestinationIdentityList[i] = *(sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.commTxResourceReq_r12->destinationInfoList_r12.list.array[i]); + ASN_SEQUENCE_ADD(&destinationInfoList->list, sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.commTxResourceReq_r12->destinationInfoList_r12.list.array[i]); + } + + //generate RRC Reconfiguration + rrc_eNB_generate_RRCConnectionReconfiguration_Sidelink(ctxt_pP, ue_context_pP, destinationInfoList, 0); + return 0; + } + + // express its interest to transmit non-relay one-to-one SL communication + if ((sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.nonCriticalExtension != NULL) && + (sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.nonCriticalExtension->commTxResourceReqUC_r13 != NULL)) { + if (sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.nonCriticalExtension->commTxResourceReqUC_r13->carrierFreq_r12 != NULL) { + n_destinations = sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.nonCriticalExtension->commTxResourceReqUC_r13->destinationInfoList_r12.list.count; + destinationInfoList = CALLOC(1, sizeof(LTE_SL_DestinationInfoList_r12_t)); + + for (int i=0; i< n_destinations; i++ ) { + //sl_DestinationIdentityList[i] = *(sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.nonCriticalExtension->commTxResourceReqUC_r13->destinationInfoList_r12.list.array[i]); + ASN_SEQUENCE_ADD(&destinationInfoList->list, + sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.nonCriticalExtension->commTxResourceReqUC_r13->destinationInfoList_r12.list.array[i]); + } + + //generate RRC Reconfiguration + rrc_eNB_generate_RRCConnectionReconfiguration_Sidelink(ctxt_pP, ue_context_pP, destinationInfoList, 0); + return 0; + } + } + + // express its interest to transmit relay related one-to-one SL communication + if ((sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.nonCriticalExtension != NULL) && + (sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.nonCriticalExtension->commTxResourceInfoReqRelay_r13->commTxResourceReqRelayUC_r13 != NULL)) { + if (sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.nonCriticalExtension->commTxResourceInfoReqRelay_r13->commTxResourceReqRelayUC_r13->destinationInfoList_r12.list.count + > 0) { + n_destinations = + sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.nonCriticalExtension->commTxResourceInfoReqRelay_r13->commTxResourceReqRelayUC_r13->destinationInfoList_r12.list.count; + destinationInfoList = CALLOC(1, sizeof(LTE_SL_DestinationInfoList_r12_t)); + + for (int i=0; i< n_destinations; i++ ) { + //sl_DestinationIdentityList[i] = *(sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.nonCriticalExtension->commTxResourceInfoReqRelay_r13->commTxResourceReqRelayUC_r13->destinationInfoList_r12.list.array[i]); + ASN_SEQUENCE_ADD(&destinationInfoList->list, + sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.nonCriticalExtension->commTxResourceInfoReqRelay_r13->commTxResourceReqRelayUC_r13->destinationInfoList_r12.list.array[i]); + } + + //generate RRC Reconfiguration + rrc_eNB_generate_RRCConnectionReconfiguration_Sidelink(ctxt_pP, ue_context_pP, destinationInfoList, 0); + return 0; + } + } + + //express its interest to transmit relay related one-to-many SL communication + if ((sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.nonCriticalExtension != NULL) && + (sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.nonCriticalExtension->commTxResourceInfoReqRelay_r13 != NULL)) { + if (sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.nonCriticalExtension->commTxResourceInfoReqRelay_r13->commTxResourceReqRelay_r13->destinationInfoList_r12.list.count + > 0) { + n_destinations = + sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.nonCriticalExtension->commTxResourceInfoReqRelay_r13->commTxResourceReqRelay_r13->destinationInfoList_r12.list.count; + destinationInfoList = CALLOC(1, sizeof(LTE_SL_DestinationInfoList_r12_t)); + + for (int i=0; i< n_destinations; i++ ) { + //sl_DestinationIdentityList[i] = *(sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.nonCriticalExtension->commTxResourceInfoReqRelay_r13->commTxResourceReqRelay_r13->destinationInfoList_r12.list.array[i]); + ASN_SEQUENCE_ADD(&destinationInfoList->list, + sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.nonCriticalExtension->commTxResourceInfoReqRelay_r13->commTxResourceReqRelay_r13->destinationInfoList_r12.list.array[i]); + } + + //generate RRC Reconfiguration + rrc_eNB_generate_RRCConnectionReconfiguration_Sidelink(ctxt_pP, ue_context_pP, destinationInfoList, 0); + return 0; + } + } + + //For SL Discovery + //express its interest to receive SL discovery announcements + //express its interest to transmit non-PS related discovery announcements + if (sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.discTxResourceReq_r12 != NULL) { + n_discoveryMessages = *(sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.discTxResourceReq_r12); + //generate RRC Reconfiguration + rrc_eNB_generate_RRCConnectionReconfiguration_Sidelink(ctxt_pP, ue_context_pP, NULL, n_discoveryMessages); + return 0; + } + + //express its interest to transmit PS related discovery announcements + if ((sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.nonCriticalExtension != NULL) && + (sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.nonCriticalExtension->discTxResourceReqPS_r13 !=NULL)) { + if (sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.nonCriticalExtension->discTxResourceReqPS_r13->discTxResourceReq_r13 > 0) { + n_discoveryMessages = sidelinkUEInformation->criticalExtensions.choice.c1.choice.sidelinkUEInformation_r12.nonCriticalExtension->discTxResourceReqPS_r13->discTxResourceReq_r13; + //generate RRC Reconfiguration + rrc_eNB_generate_RRCConnectionReconfiguration_Sidelink(ctxt_pP, ue_context_pP, NULL, n_discoveryMessages); + return 0; + } + } + } + } + + return 0; } //----------------------------------------------------------------------------- int rrc_eNB_generate_RRCConnectionReconfiguration_Sidelink( - const protocol_ctxt_t* const ctxt_pP, - rrc_eNB_ue_context_t* const ue_context_pP, + const protocol_ctxt_t *const ctxt_pP, + rrc_eNB_ue_context_t *const ue_context_pP, LTE_SL_DestinationInfoList_r12_t *destinationInfoList, int n_discoveryMessages ) //----------------------------------------------------------------------------- { - uint8_t buffer[RRC_BUF_SIZE]; uint16_t size = -1; memset(buffer, 0, RRC_BUF_SIZE); @@ -7596,58 +7093,56 @@ rrc_eNB_generate_RRCConnectionReconfiguration_Sidelink( // allocate dedicated pools for UE -sl-CommConfig/sl-DiscConfig (sl-V2X-ConfigDedicated) //populate dedicated resources for SL communication (sl-CommConfig) if ((destinationInfoList != NULL) && (destinationInfoList->list.count > 0)) { - - LOG_I(RRC,"[eNB %d] Frame %d, Generate LTE_RRCConnectionReconfiguration_Sidelink (bytes %d, UE id %x), number of destinations %d\n", - ctxt_pP->module_id,ctxt_pP->frame, size, ue_context_pP->ue_context.rnti,destinationInfoList->list.count ); - //get dedicated resources from available pool and assign to the UE - LTE_SL_CommConfig_r12_t sl_CommConfig[destinationInfoList->list.count]; - //get a RP from the available RPs - sl_CommConfig[0] = rrc_eNB_get_sidelink_commTXPool(ctxt_pP, ue_context_pP, destinationInfoList); - - size = do_RRCConnectionReconfiguration(ctxt_pP, - buffer, - rrc_eNB_get_next_transaction_identifier(ctxt_pP->module_id), //Transaction_id - (LTE_SRB_ToAddModList_t*)NULL, - (LTE_DRB_ToAddModList_t*)NULL, - (LTE_DRB_ToReleaseList_t*)NULL, // DRB2_list, - (struct LTE_SPS_Config*)NULL, // *sps_Config, - NULL, NULL, NULL, NULL,NULL, - NULL, NULL, NULL, NULL, NULL, NULL, - (struct LTE_RRCConnectionReconfiguration_r8_IEs__dedicatedInfoNASList*)NULL, - (LTE_SL_CommConfig_r12_t*)&sl_CommConfig, - (LTE_SL_DiscConfig_r12_t*)NULL - #if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) - , (LTE_SCellToAddMod_r10_t*)NULL - #endif - ); - // + LOG_I(RRC,"[eNB %d] Frame %d, Generate LTE_RRCConnectionReconfiguration_Sidelink (bytes %d, UE id %x), number of destinations %d\n", + ctxt_pP->module_id,ctxt_pP->frame, size, ue_context_pP->ue_context.rnti,destinationInfoList->list.count ); + //get dedicated resources from available pool and assign to the UE + LTE_SL_CommConfig_r12_t sl_CommConfig[destinationInfoList->list.count]; + //get a RP from the available RPs + sl_CommConfig[0] = rrc_eNB_get_sidelink_commTXPool(ctxt_pP, ue_context_pP, destinationInfoList); + size = do_RRCConnectionReconfiguration(ctxt_pP, + buffer, + rrc_eNB_get_next_transaction_identifier(ctxt_pP->module_id), //Transaction_id + (LTE_SRB_ToAddModList_t *)NULL, + (LTE_DRB_ToAddModList_t *)NULL, + (LTE_DRB_ToReleaseList_t *)NULL, // DRB2_list, + (struct LTE_SPS_Config *)NULL, // *sps_Config, + NULL, NULL, NULL, NULL,NULL, + NULL, NULL, NULL, NULL, NULL, NULL, + (struct LTE_RRCConnectionReconfiguration_r8_IEs__dedicatedInfoNASList *)NULL, + (LTE_SL_CommConfig_r12_t *)&sl_CommConfig, + (LTE_SL_DiscConfig_r12_t *)NULL +#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) + , (LTE_SCellToAddMod_r10_t *)NULL +#endif + ); + // } + //populate dedicated resources for SL discovery (sl-DiscConfig) if (n_discoveryMessages > 0) { - LTE_SL_DiscConfig_r12_t sl_DiscConfig[n_discoveryMessages]; - //get a RP from the available RPs - sl_DiscConfig[0] = rrc_eNB_get_sidelink_discTXPool(ctxt_pP, ue_context_pP, n_discoveryMessages ); - size = do_RRCConnectionReconfiguration(ctxt_pP, - buffer, - rrc_eNB_get_next_transaction_identifier(ctxt_pP->module_id), //Transaction_id - (LTE_SRB_ToAddModList_t*)NULL, - (LTE_DRB_ToAddModList_t*)NULL, - (LTE_DRB_ToReleaseList_t*)NULL, // DRB2_list, - (struct LTE_SPS_Config*)NULL, // *sps_Config, - NULL, NULL, NULL, NULL,NULL, - NULL, NULL, NULL, NULL, NULL, NULL, - (struct LTE_RRCConnectionReconfiguration_r8_IEs__dedicatedInfoNASList*)NULL, - (LTE_SL_CommConfig_r12_t*)NULL, - (LTE_SL_DiscConfig_r12_t*)&sl_DiscConfig - #if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) - , (LTE_SCellToAddMod_r10_t*)NULL - #endif - ); + LTE_SL_DiscConfig_r12_t sl_DiscConfig[n_discoveryMessages]; + //get a RP from the available RPs + sl_DiscConfig[0] = rrc_eNB_get_sidelink_discTXPool(ctxt_pP, ue_context_pP, n_discoveryMessages ); + size = do_RRCConnectionReconfiguration(ctxt_pP, + buffer, + rrc_eNB_get_next_transaction_identifier(ctxt_pP->module_id), //Transaction_id + (LTE_SRB_ToAddModList_t *)NULL, + (LTE_DRB_ToAddModList_t *)NULL, + (LTE_DRB_ToReleaseList_t *)NULL, // DRB2_list, + (struct LTE_SPS_Config *)NULL, // *sps_Config, + NULL, NULL, NULL, NULL,NULL, + NULL, NULL, NULL, NULL, NULL, NULL, + (struct LTE_RRCConnectionReconfiguration_r8_IEs__dedicatedInfoNASList *)NULL, + (LTE_SL_CommConfig_r12_t *)NULL, + (LTE_SL_DiscConfig_r12_t *)&sl_DiscConfig +#if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) + , (LTE_SCellToAddMod_r10_t *)NULL +#endif + ); } LOG_I(RRC,"[eNB %d] Frame %d, Logical Channel DL-DCCH, Generate LTE_RRCConnectionReconfiguration_Sidelink (bytes %d, UE id %x)\n", ctxt_pP->module_id,ctxt_pP->frame, size, ue_context_pP->ue_context.rnti); - rrc_data_req( ctxt_pP, DCCH, @@ -7656,99 +7151,91 @@ rrc_eNB_generate_RRCConnectionReconfiguration_Sidelink( size, buffer, PDCP_TRANSMISSION_MODE_CONTROL); - // rrc_data_req(); - return size; } -LTE_SL_CommConfig_r12_t rrc_eNB_get_sidelink_commTXPool( const protocol_ctxt_t* const ctxt_pP, rrc_eNB_ue_context_t* const ue_context_pP, LTE_SL_DestinationInfoList_r12_t *destinationInfoList ){ - // for the moment, use scheduled resource allocation - LTE_SL_CommConfig_r12_t *sl_CommConfig; - LTE_SL_CommResourcePool_r12_t *sc_CommTxConfig; - - sl_CommConfig = CALLOC(1, sizeof(struct LTE_SL_CommConfig_r12)); - sl_CommConfig->commTxResources_r12 = CALLOC(1, sizeof(*sl_CommConfig->commTxResources_r12)); - sl_CommConfig->commTxResources_r12->present = LTE_SL_CommConfig_r12__commTxResources_r12_PR_setup; - - sl_CommConfig->commTxResources_r12->choice.setup.present = LTE_SL_CommConfig_r12__commTxResources_r12__setup_PR_scheduled_r12; - sl_CommConfig->commTxResources_r12->choice.setup.choice.scheduled_r12.sl_RNTI_r12.size = 2; - sl_CommConfig->commTxResources_r12->choice.setup.choice.scheduled_r12.sl_RNTI_r12.buf = CALLOC(1,2); - sl_CommConfig->commTxResources_r12->choice.setup.choice.scheduled_r12.sl_RNTI_r12.buf[0] = 0x00; - sl_CommConfig->commTxResources_r12->choice.setup.choice.scheduled_r12.sl_RNTI_r12.buf[1] = 0x01;//ctxt_pP->rnti;//rnti - sl_CommConfig->commTxResources_r12->choice.setup.choice.scheduled_r12.sl_RNTI_r12.bits_unused = 0; - sl_CommConfig->commTxResources_r12->choice.setup.choice.scheduled_r12.mcs_r12 = CALLOC(1,sizeof(*sl_CommConfig->commTxResources_r12->choice.setup.choice.scheduled_r12.mcs_r12)); - //*sl_CommConfig_test->commTxResources_r12->choice.setup.choice.scheduled_r12.mcs_r12 = 12; //Msc - sl_CommConfig->commTxResources_r12->choice.setup.choice.scheduled_r12.mac_MainConfig_r12.retx_BSR_TimerSL = LTE_RetxBSR_Timer_r12_sf320; //MacConfig, for testing only - //sl_CommConfig_test->commTxResources_r12->choice.setup.choice.scheduled_r12.sc_CommTxConfig_r12; - - sc_CommTxConfig = & sl_CommConfig->commTxResources_r12->choice.setup.choice.scheduled_r12.sc_CommTxConfig_r12; - - sc_CommTxConfig->sc_CP_Len_r12 = LTE_SL_CP_Len_r12_normal; - sc_CommTxConfig->sc_Period_r12 = LTE_SL_PeriodComm_r12_sf40; - sc_CommTxConfig->data_CP_Len_r12 = LTE_SL_CP_Len_r12_normal; - //sc_TF_ResourceConfig_r12 - sc_CommTxConfig->sc_TF_ResourceConfig_r12.prb_Num_r12 = 20; - sc_CommTxConfig->sc_TF_ResourceConfig_r12.prb_Start_r12 = 5; - sc_CommTxConfig->sc_TF_ResourceConfig_r12.prb_End_r12 = 44; - sc_CommTxConfig->sc_TF_ResourceConfig_r12.offsetIndicator_r12.present = LTE_SL_OffsetIndicator_r12_PR_small_r12; - sc_CommTxConfig->sc_TF_ResourceConfig_r12.offsetIndicator_r12.choice.small_r12 = 0; - - sc_CommTxConfig->sc_TF_ResourceConfig_r12.subframeBitmap_r12.present = LTE_SubframeBitmapSL_r12_PR_bs40_r12; - sc_CommTxConfig->sc_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs40_r12.size = 5; - sc_CommTxConfig->sc_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs40_r12.buf = CALLOC(1,5); - sc_CommTxConfig->sc_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs40_r12.bits_unused = 0; - //dataHoppingConfig_r12 - sc_CommTxConfig->dataHoppingConfig_r12.hoppingParameter_r12 = 0; - sc_CommTxConfig->dataHoppingConfig_r12.numSubbands_r12 = LTE_SL_HoppingConfigComm_r12__numSubbands_r12_ns1; - sc_CommTxConfig->dataHoppingConfig_r12.rb_Offset_r12 = 0; - //ue_SelectedResourceConfig_r12 - sc_CommTxConfig->ue_SelectedResourceConfig_r12 = CALLOC (1, sizeof (*sc_CommTxConfig->ue_SelectedResourceConfig_r12)); - sc_CommTxConfig->ue_SelectedResourceConfig_r12->data_TF_ResourceConfig_r12.prb_Num_r12 = 20; - sc_CommTxConfig->ue_SelectedResourceConfig_r12->data_TF_ResourceConfig_r12.prb_Start_r12 = 5; - sc_CommTxConfig->ue_SelectedResourceConfig_r12->data_TF_ResourceConfig_r12.prb_End_r12 = 44; - sc_CommTxConfig->ue_SelectedResourceConfig_r12->data_TF_ResourceConfig_r12.offsetIndicator_r12.present = LTE_SL_OffsetIndicator_r12_PR_small_r12; - sc_CommTxConfig->ue_SelectedResourceConfig_r12->data_TF_ResourceConfig_r12.offsetIndicator_r12.choice.small_r12 = 0 ; - sc_CommTxConfig->ue_SelectedResourceConfig_r12->data_TF_ResourceConfig_r12.subframeBitmap_r12.present = LTE_SubframeBitmapSL_r12_PR_bs40_r12; - sc_CommTxConfig->ue_SelectedResourceConfig_r12->data_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs4_r12.size = 5; - sc_CommTxConfig->ue_SelectedResourceConfig_r12->data_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs4_r12.buf = CALLOC(1,5); - sc_CommTxConfig->ue_SelectedResourceConfig_r12->data_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs4_r12.bits_unused = 0; - sc_CommTxConfig->ue_SelectedResourceConfig_r12->data_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs4_r12.buf[0] = 0xF0; - sc_CommTxConfig->ue_SelectedResourceConfig_r12->data_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs4_r12.buf[1] = 0xFF; - sc_CommTxConfig->ue_SelectedResourceConfig_r12->data_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs4_r12.buf[2] = 0xFF; - sc_CommTxConfig->ue_SelectedResourceConfig_r12->data_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs4_r12.buf[3] = 0xFF; - sc_CommTxConfig->ue_SelectedResourceConfig_r12->data_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs4_r12.buf[4] = 0xFF; - //rxParametersNCell_r12 - sc_CommTxConfig->rxParametersNCell_r12 = CALLOC (1, sizeof (*sc_CommTxConfig->rxParametersNCell_r12)); - sc_CommTxConfig->rxParametersNCell_r12->tdd_Config_r12 = CALLOC (1, sizeof (*sc_CommTxConfig->rxParametersNCell_r12->tdd_Config_r12 )); - sc_CommTxConfig->rxParametersNCell_r12->tdd_Config_r12->subframeAssignment = 0 ; - sc_CommTxConfig->rxParametersNCell_r12->tdd_Config_r12->specialSubframePatterns = 0; - sc_CommTxConfig->rxParametersNCell_r12->syncConfigIndex_r12 = 0; - //txParameters_r12 - sc_CommTxConfig->txParameters_r12 = CALLOC (1, sizeof (*sc_CommTxConfig->txParameters_r12)); - sc_CommTxConfig->txParameters_r12->sc_TxParameters_r12.alpha_r12 = LTE_Alpha_r12_al0; - sc_CommTxConfig->txParameters_r12->sc_TxParameters_r12.p0_r12 = 0; - sc_CommTxConfig->ext1 = NULL ; - - return *sl_CommConfig; +LTE_SL_CommConfig_r12_t rrc_eNB_get_sidelink_commTXPool( const protocol_ctxt_t *const ctxt_pP, rrc_eNB_ue_context_t *const ue_context_pP, LTE_SL_DestinationInfoList_r12_t *destinationInfoList ) { + // for the moment, use scheduled resource allocation + LTE_SL_CommConfig_r12_t *sl_CommConfig; + LTE_SL_CommResourcePool_r12_t *sc_CommTxConfig; + sl_CommConfig = CALLOC(1, sizeof(struct LTE_SL_CommConfig_r12)); + sl_CommConfig->commTxResources_r12 = CALLOC(1, sizeof(*sl_CommConfig->commTxResources_r12)); + sl_CommConfig->commTxResources_r12->present = LTE_SL_CommConfig_r12__commTxResources_r12_PR_setup; + sl_CommConfig->commTxResources_r12->choice.setup.present = LTE_SL_CommConfig_r12__commTxResources_r12__setup_PR_scheduled_r12; + sl_CommConfig->commTxResources_r12->choice.setup.choice.scheduled_r12.sl_RNTI_r12.size = 2; + sl_CommConfig->commTxResources_r12->choice.setup.choice.scheduled_r12.sl_RNTI_r12.buf = CALLOC(1,2); + sl_CommConfig->commTxResources_r12->choice.setup.choice.scheduled_r12.sl_RNTI_r12.buf[0] = 0x00; + sl_CommConfig->commTxResources_r12->choice.setup.choice.scheduled_r12.sl_RNTI_r12.buf[1] = 0x01;//ctxt_pP->rnti;//rnti + sl_CommConfig->commTxResources_r12->choice.setup.choice.scheduled_r12.sl_RNTI_r12.bits_unused = 0; + sl_CommConfig->commTxResources_r12->choice.setup.choice.scheduled_r12.mcs_r12 = CALLOC(1,sizeof(*sl_CommConfig->commTxResources_r12->choice.setup.choice.scheduled_r12.mcs_r12)); + //*sl_CommConfig_test->commTxResources_r12->choice.setup.choice.scheduled_r12.mcs_r12 = 12; //Msc + sl_CommConfig->commTxResources_r12->choice.setup.choice.scheduled_r12.mac_MainConfig_r12.retx_BSR_TimerSL = LTE_RetxBSR_Timer_r12_sf320; //MacConfig, for testing only + //sl_CommConfig_test->commTxResources_r12->choice.setup.choice.scheduled_r12.sc_CommTxConfig_r12; + sc_CommTxConfig = & sl_CommConfig->commTxResources_r12->choice.setup.choice.scheduled_r12.sc_CommTxConfig_r12; + sc_CommTxConfig->sc_CP_Len_r12 = LTE_SL_CP_Len_r12_normal; + sc_CommTxConfig->sc_Period_r12 = LTE_SL_PeriodComm_r12_sf40; + sc_CommTxConfig->data_CP_Len_r12 = LTE_SL_CP_Len_r12_normal; + //sc_TF_ResourceConfig_r12 + sc_CommTxConfig->sc_TF_ResourceConfig_r12.prb_Num_r12 = 20; + sc_CommTxConfig->sc_TF_ResourceConfig_r12.prb_Start_r12 = 5; + sc_CommTxConfig->sc_TF_ResourceConfig_r12.prb_End_r12 = 44; + sc_CommTxConfig->sc_TF_ResourceConfig_r12.offsetIndicator_r12.present = LTE_SL_OffsetIndicator_r12_PR_small_r12; + sc_CommTxConfig->sc_TF_ResourceConfig_r12.offsetIndicator_r12.choice.small_r12 = 0; + sc_CommTxConfig->sc_TF_ResourceConfig_r12.subframeBitmap_r12.present = LTE_SubframeBitmapSL_r12_PR_bs40_r12; + sc_CommTxConfig->sc_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs40_r12.size = 5; + sc_CommTxConfig->sc_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs40_r12.buf = CALLOC(1,5); + sc_CommTxConfig->sc_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs40_r12.bits_unused = 0; + //dataHoppingConfig_r12 + sc_CommTxConfig->dataHoppingConfig_r12.hoppingParameter_r12 = 0; + sc_CommTxConfig->dataHoppingConfig_r12.numSubbands_r12 = LTE_SL_HoppingConfigComm_r12__numSubbands_r12_ns1; + sc_CommTxConfig->dataHoppingConfig_r12.rb_Offset_r12 = 0; + //ue_SelectedResourceConfig_r12 + sc_CommTxConfig->ue_SelectedResourceConfig_r12 = CALLOC (1, sizeof (*sc_CommTxConfig->ue_SelectedResourceConfig_r12)); + sc_CommTxConfig->ue_SelectedResourceConfig_r12->data_TF_ResourceConfig_r12.prb_Num_r12 = 20; + sc_CommTxConfig->ue_SelectedResourceConfig_r12->data_TF_ResourceConfig_r12.prb_Start_r12 = 5; + sc_CommTxConfig->ue_SelectedResourceConfig_r12->data_TF_ResourceConfig_r12.prb_End_r12 = 44; + sc_CommTxConfig->ue_SelectedResourceConfig_r12->data_TF_ResourceConfig_r12.offsetIndicator_r12.present = LTE_SL_OffsetIndicator_r12_PR_small_r12; + sc_CommTxConfig->ue_SelectedResourceConfig_r12->data_TF_ResourceConfig_r12.offsetIndicator_r12.choice.small_r12 = 0 ; + sc_CommTxConfig->ue_SelectedResourceConfig_r12->data_TF_ResourceConfig_r12.subframeBitmap_r12.present = LTE_SubframeBitmapSL_r12_PR_bs40_r12; + sc_CommTxConfig->ue_SelectedResourceConfig_r12->data_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs4_r12.size = 5; + sc_CommTxConfig->ue_SelectedResourceConfig_r12->data_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs4_r12.buf = CALLOC(1,5); + sc_CommTxConfig->ue_SelectedResourceConfig_r12->data_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs4_r12.bits_unused = 0; + sc_CommTxConfig->ue_SelectedResourceConfig_r12->data_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs4_r12.buf[0] = 0xF0; + sc_CommTxConfig->ue_SelectedResourceConfig_r12->data_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs4_r12.buf[1] = 0xFF; + sc_CommTxConfig->ue_SelectedResourceConfig_r12->data_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs4_r12.buf[2] = 0xFF; + sc_CommTxConfig->ue_SelectedResourceConfig_r12->data_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs4_r12.buf[3] = 0xFF; + sc_CommTxConfig->ue_SelectedResourceConfig_r12->data_TF_ResourceConfig_r12.subframeBitmap_r12.choice.bs4_r12.buf[4] = 0xFF; + //rxParametersNCell_r12 + sc_CommTxConfig->rxParametersNCell_r12 = CALLOC (1, sizeof (*sc_CommTxConfig->rxParametersNCell_r12)); + sc_CommTxConfig->rxParametersNCell_r12->tdd_Config_r12 = CALLOC (1, sizeof (*sc_CommTxConfig->rxParametersNCell_r12->tdd_Config_r12 )); + sc_CommTxConfig->rxParametersNCell_r12->tdd_Config_r12->subframeAssignment = 0 ; + sc_CommTxConfig->rxParametersNCell_r12->tdd_Config_r12->specialSubframePatterns = 0; + sc_CommTxConfig->rxParametersNCell_r12->syncConfigIndex_r12 = 0; + //txParameters_r12 + sc_CommTxConfig->txParameters_r12 = CALLOC (1, sizeof (*sc_CommTxConfig->txParameters_r12)); + sc_CommTxConfig->txParameters_r12->sc_TxParameters_r12.alpha_r12 = LTE_Alpha_r12_al0; + sc_CommTxConfig->txParameters_r12->sc_TxParameters_r12.p0_r12 = 0; + sc_CommTxConfig->ext1 = NULL ; + return *sl_CommConfig; } -LTE_SL_DiscConfig_r12_t rrc_eNB_get_sidelink_discTXPool( const protocol_ctxt_t* const ctxt_pP, rrc_eNB_ue_context_t* const ue_context_pP, int n_discoveryMessages ){ - //TODO - LTE_SL_DiscConfig_r12_t sl_DiscConfig; - sl_DiscConfig.discTxResources_r12 = CALLOC(1,sizeof(*sl_DiscConfig.discTxResources_r12)); - sl_DiscConfig.discTxResources_r12->present = LTE_SL_DiscConfig_r12__discTxResources_r12_PR_setup; - sl_DiscConfig.discTxResources_r12->choice.setup.present = LTE_SL_DiscConfig_r12__discTxResources_r12__setup_PR_scheduled_r12; - //sl_DiscConfig.discTxResources_r12->choice.setup.choice.scheduled_r12.discHoppingConfig_r12; - //sl_DiscConfig.discTxResources_r12->choice.setup.choice.scheduled_r12.discTF_IndexList_r12; - //sl_DiscConfig.discTxResources_r12->choice.setup.choice.scheduled_r12.discTxConfig_r12; - return sl_DiscConfig; +LTE_SL_DiscConfig_r12_t rrc_eNB_get_sidelink_discTXPool( const protocol_ctxt_t *const ctxt_pP, rrc_eNB_ue_context_t *const ue_context_pP, int n_discoveryMessages ) { + //TODO + LTE_SL_DiscConfig_r12_t sl_DiscConfig; + sl_DiscConfig.discTxResources_r12 = CALLOC(1,sizeof(*sl_DiscConfig.discTxResources_r12)); + sl_DiscConfig.discTxResources_r12->present = LTE_SL_DiscConfig_r12__discTxResources_r12_PR_setup; + sl_DiscConfig.discTxResources_r12->choice.setup.present = LTE_SL_DiscConfig_r12__discTxResources_r12__setup_PR_scheduled_r12; + //sl_DiscConfig.discTxResources_r12->choice.setup.choice.scheduled_r12.discHoppingConfig_r12; + //sl_DiscConfig.discTxResources_r12->choice.setup.choice.scheduled_r12.discTF_IndexList_r12; + //sl_DiscConfig.discTxResources_r12->choice.setup.choice.scheduled_r12.discTxConfig_r12; + return sl_DiscConfig; } RRC_status_t rrc_rx_tx( - protocol_ctxt_t* const ctxt_pP, + protocol_ctxt_t *const ctxt_pP, const int CC_id ) //----------------------------------------------------------------------------- @@ -7758,267 +7245,230 @@ rrc_rx_tx( struct timeval ts; struct rrc_eNB_ue_context_s *ue_context_p = NULL; struct rrc_eNB_ue_context_s *ue_to_be_removed = NULL; - #ifdef LOCALIZATION - double estimated_distance = 0; protocol_ctxt_t ctxt; - #endif - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RRC_RX_TX, VCD_FUNCTION_IN); + check_handovers(ctxt_pP); // counter, get the value and aggregate + // check for UL failure or for UE to be released + RB_FOREACH(ue_context_p, rrc_ue_tree_s, &(RC.rrc[ctxt_pP->module_id]->rrc_ue_head)) { + ctxt_pP->rnti = ue_context_p->ue_id_rnti; - check_handovers(ctxt_pP); // counter, get the value and aggregate - - // check for UL failure or for UE to be released - RB_FOREACH(ue_context_p, rrc_ue_tree_s, &(RC.rrc[ctxt_pP->module_id]->rrc_ue_head)) { - ctxt_pP->rnti = ue_context_p->ue_id_rnti; - - if ((ctxt_pP->frame == 0) && (ctxt_pP->subframe == 0)) { - if (ue_context_p->ue_context.Initialue_identity_s_TMSI.presence == TRUE) { - LOG_I(RRC, "UE rnti %x: S-TMSI %x failure timer %d/8\n", - ue_context_p->ue_context.rnti, - ue_context_p->ue_context.Initialue_identity_s_TMSI.m_tmsi, - ue_context_p->ue_context.ul_failure_timer); - } else { - LOG_I(RRC, "UE rnti %x failure timer %d/8\n", - ue_context_p->ue_context.rnti, - ue_context_p->ue_context.ul_failure_timer); - } - } - - if (ue_context_p->ue_context.ul_failure_timer > 0) { - ue_context_p->ue_context.ul_failure_timer++; - - if (ue_context_p->ue_context.ul_failure_timer >= 20000) { - // remove UE after 20 seconds after MAC (or else) has indicated UL failure - LOG_I(RRC, "Removing UE %x instance, because of uplink failure timer timeout\n", - ue_context_p->ue_context.rnti); - - ue_to_be_removed = ue_context_p; - break; // break RB_FOREACH - } - } - - if (ue_context_p->ue_context.ue_release_timer_s1 > 0) { - ue_context_p->ue_context.ue_release_timer_s1++; - - if (ue_context_p->ue_context.ue_release_timer_s1 >= ue_context_p->ue_context.ue_release_timer_thres_s1) { - LOG_I(RRC, "Removing UE %x instance, because of UE_CONTEXT_RELEASE_COMMAND not received after %d ms from sending request\n", - ue_context_p->ue_context.rnti, - ue_context_p->ue_context.ue_release_timer_thres_s1); - -#if defined(ENABLE_USE_MME) -#if defined(ENABLE_ITTI) - - rrc_eNB_generate_RRCConnectionRelease(ctxt_pP, ue_context_p); - -#endif -#else - - ue_to_be_removed = ue_context_p; - -#endif - ue_context_p->ue_context.ue_release_timer_s1 = 0; - break; // break RB_FOREACH - } // end if timer_s1 timeout - } // end if timer_s1 > 0 (S1 UE_CONTEXT_RELEASE_REQ ongoing) - - if (ue_context_p->ue_context.ue_release_timer_rrc > 0) { - ue_context_p->ue_context.ue_release_timer_rrc++; - - if (ue_context_p->ue_context.ue_release_timer_rrc >= ue_context_p->ue_context.ue_release_timer_thres_rrc) { - LOG_I(RRC, "Removing UE %x instance after UE_CONTEXT_RELEASE_Complete (ue_release_timer_rrc timeout)\n", - ue_context_p->ue_context.rnti); - - ue_context_p->ue_context.ue_release_timer_rrc = 0; - ue_to_be_removed = ue_context_p; - break; // break RB_FOREACH - } - } - - pthread_mutex_lock(&rrc_release_freelist); - if (rrc_release_info.num_UEs > 0) { - uint16_t release_total = 0; - - for (uint16_t release_num = 0; release_num < NUMBER_OF_UE_MAX; release_num++) { - if (rrc_release_info.RRC_release_ctrl[release_num].flag > 0) { - release_total++; - } - - if ((rrc_release_info.RRC_release_ctrl[release_num].flag > 2) && - (rrc_release_info.RRC_release_ctrl[release_num].rnti == ue_context_p->ue_context.rnti)) { - - ue_context_p->ue_context.ue_release_timer_rrc = 1; - ue_context_p->ue_context.ue_release_timer_thres_rrc = 100; - -#if defined(ENABLE_USE_MME) -#if defined(ENABLE_ITTI) - - int e_rab = 0; - MessageDef *msg_complete_p = NULL; - MessageDef *msg_delete_tunnels_p = NULL; - uint32_t eNB_ue_s1ap_id = ue_context_p->ue_context.eNB_ue_s1ap_id; - - if (rrc_release_info.RRC_release_ctrl[release_num].flag == 4) { // if timer_s1 == 0 - MSC_LOG_TX_MESSAGE(MSC_RRC_ENB, MSC_S1AP_ENB, NULL, 0, - "0 S1AP_UE_CONTEXT_RELEASE_COMPLETE eNB_ue_s1ap_id 0x%06"PRIX32" ", - eNB_ue_s1ap_id); - - msg_complete_p = itti_alloc_new_message(TASK_RRC_ENB, S1AP_UE_CONTEXT_RELEASE_COMPLETE); - S1AP_UE_CONTEXT_RELEASE_COMPLETE(msg_complete_p).eNB_ue_s1ap_id = eNB_ue_s1ap_id; - itti_send_msg_to_task(TASK_S1AP, ctxt_pP->module_id, msg_complete_p); - } - - MSC_LOG_TX_MESSAGE(MSC_RRC_ENB, MSC_GTPU_ENB, NULL,0, "0 GTPV1U_ENB_DELETE_TUNNEL_REQ rnti %x ", eNB_ue_s1ap_id); - - msg_delete_tunnels_p = itti_alloc_new_message(TASK_RRC_ENB, GTPV1U_ENB_DELETE_TUNNEL_REQ); - memset(>PV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p), 0, sizeof(GTPV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p))); - - // do not wait response - GTPV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p).rnti = ue_context_p->ue_context.rnti; - - for (e_rab = 0; e_rab < ue_context_p->ue_context.nb_of_e_rabs; e_rab++) { - GTPV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p).eps_bearer_id[GTPV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p).num_erab++] = - ue_context_p->ue_context.enb_gtp_ebi[e_rab]; - - // erase data - ue_context_p->ue_context.enb_gtp_teid[e_rab] = 0; - memset(&ue_context_p->ue_context.enb_gtp_addrs[e_rab], 0, sizeof(ue_context_p->ue_context.enb_gtp_addrs[e_rab])); - ue_context_p->ue_context.enb_gtp_ebi[e_rab] = 0; - } - - itti_send_msg_to_task(TASK_GTPV1_U, ctxt_pP->module_id, msg_delete_tunnels_p); - - struct rrc_ue_s1ap_ids_s *rrc_ue_s1ap_ids = NULL; - - rrc_ue_s1ap_ids = rrc_eNB_S1AP_get_ue_ids(RC.rrc[ctxt_pP->module_id], 0, eNB_ue_s1ap_id); - - if (rrc_ue_s1ap_ids != NULL) { - rrc_eNB_S1AP_remove_ue_ids(RC.rrc[ctxt_pP->module_id], rrc_ue_s1ap_ids); - } - -#endif -#endif - - rrc_release_info.RRC_release_ctrl[release_num].flag = 0; - rrc_release_info.num_UEs--; - break; // break for (release_num) - } // end if ((rrc_release_info.RRC_release_ctrl[release_num].flag > 2) && ... - - if (release_total >= rrc_release_info.num_UEs) { - break; // break for (release_num) - } - } // end for (release_num) - } // end if (rrc_release_info.num_UEs > 0) - pthread_mutex_unlock(&rrc_release_freelist); - - if (ue_context_p->ue_context.ue_rrc_inactivity_timer > 0) { - // ue_context_p->ue_context.ue_rrc_inactivity_timer++; // (un)comment this line to (de)activate the RRC inactivity timer - - if (ue_context_p->ue_context.ue_rrc_inactivity_timer >= ue_context_p->ue_context.ue_rrc_inactivity_timer_thres) { - LOG_I(RRC, "Removing UE %x instance because of rrc_inactivity_timer timeout\n", - ue_context_p->ue_context.rnti); - - ue_to_be_removed = ue_context_p; - break; // break RB_FOREACH - } - } - - if (ue_context_p->ue_context.ue_reestablishment_timer > 0) { - ue_context_p->ue_context.ue_reestablishment_timer++; - - if (ue_context_p->ue_context.ue_reestablishment_timer >= ue_context_p->ue_context.ue_reestablishment_timer_thres) { - LOG_I(RRC, "Removing UE %x instance because of reestablishment_timer timeout\n", - ue_context_p->ue_context.rnti); - - ue_context_p->ue_context.ul_failure_timer = 20000; // lead to send S1 UE_CONTEXT_RELEASE_REQ - ue_to_be_removed = ue_context_p; - ue_context_p->ue_context.ue_reestablishment_timer = 0; - break; // break RB_FOREACH - } - } - - if (ue_context_p->ue_context.ue_release_timer > 0) { - ue_context_p->ue_context.ue_release_timer++; - - if (ue_context_p->ue_context.ue_release_timer >= ue_context_p->ue_context.ue_release_timer_thres) { - LOG_I(RRC, "Removing UE %x instance because of RRC Connection Setup timer timeout\n", - ue_context_p->ue_context.rnti); - /* - * TODO: Naming problem here: ue_release_timer seems to have been used when RRC Connection Release was sent. - * It is no more the case. - * The timer should be renamed. - */ - - ue_to_be_removed = ue_context_p; - ue_context_p->ue_context.ue_release_timer = 0; - break; // break RB_FOREACH - } - } - } // end RB_FOREACH - - if (ue_to_be_removed) { - if ((ue_to_be_removed->ue_context.ul_failure_timer >= 20000) || - (ue_to_be_removed->ue_context.ue_rrc_inactivity_timer >= ue_to_be_removed->ue_context.ue_rrc_inactivity_timer_thres)) { - ue_to_be_removed->ue_context.ue_release_timer_s1 = 1; - ue_to_be_removed->ue_context.ue_release_timer_thres_s1 = 100; - ue_to_be_removed->ue_context.ue_release_timer = 0; - ue_to_be_removed->ue_context.ue_reestablishment_timer = 0; - } - - rrc_eNB_free_UE(ctxt_pP->module_id, ue_to_be_removed); - - if (ue_to_be_removed->ue_context.ul_failure_timer >= 20000) { - ue_to_be_removed->ue_context.ul_failure_timer = 0; - } - - if (ue_to_be_removed->ue_context.ue_rrc_inactivity_timer >= ue_to_be_removed->ue_context.ue_rrc_inactivity_timer_thres) { - ue_to_be_removed->ue_context.ue_rrc_inactivity_timer = 0; //reset timer after S1 command UE context release request is sent + if ((ctxt_pP->frame == 0) && (ctxt_pP->subframe == 0)) { + if (ue_context_p->ue_context.Initialue_identity_s_TMSI.presence == TRUE) { + LOG_I(RRC, "UE rnti %x: S-TMSI %x failure timer %d/8\n", + ue_context_p->ue_context.rnti, + ue_context_p->ue_context.Initialue_identity_s_TMSI.m_tmsi, + ue_context_p->ue_context.ul_failure_timer); + } else { + LOG_I(RRC, "UE rnti %x failure timer %d/8\n", + ue_context_p->ue_context.rnti, + ue_context_p->ue_context.ul_failure_timer); } } -#ifdef RRC_LOCALIZATION + if (ue_context_p->ue_context.ul_failure_timer > 0) { + ue_context_p->ue_context.ul_failure_timer++; - /* for the localization, only primary CC_id might be relevant*/ - gettimeofday(&ts, NULL); + if (ue_context_p->ue_context.ul_failure_timer >= 20000) { + // remove UE after 20 seconds after MAC (or else) has indicated UL failure + LOG_I(RRC, "Removing UE %x instance, because of uplink failure timer timeout\n", + ue_context_p->ue_context.rnti); + ue_to_be_removed = ue_context_p; + break; // break RB_FOREACH + } + } - current_timestamp_ms = ts.tv_sec * 1000 + ts.tv_usec / 1000; - ref_timestamp_ms = RC.rrc[ctxt_pP->module_id]->reference_timestamp_ms; + if (ue_context_p->ue_context.ue_release_timer_s1 > 0) { + ue_context_p->ue_context.ue_release_timer_s1++; - RB_FOREACH(ue_context_p, rrc_ue_tree_s, &(RC.rrc[ctxt_pP->module_id]->rrc_ue_head)) { - ctxt = *ctxt_pP; - ctxt.rnti = ue_context_p->ue_context.rnti; + if (ue_context_p->ue_context.ue_release_timer_s1 >= ue_context_p->ue_context.ue_release_timer_thres_s1) { + LOG_I(RRC, "Removing UE %x instance, because of UE_CONTEXT_RELEASE_COMMAND not received after %d ms from sending request\n", + ue_context_p->ue_context.rnti, + ue_context_p->ue_context.ue_release_timer_thres_s1); +#if defined(ENABLE_USE_MME) +#if defined(ENABLE_ITTI) + rrc_eNB_generate_RRCConnectionRelease(ctxt_pP, ue_context_p); +#endif +#else + ue_to_be_removed = ue_context_p; +#endif + ue_context_p->ue_context.ue_release_timer_s1 = 0; + break; // break RB_FOREACH + } // end if timer_s1 timeout + } // end if timer_s1 > 0 (S1 UE_CONTEXT_RELEASE_REQ ongoing) - estimated_distance = rrc_get_estimated_ue_distance(&ctxt, CC_id, RC.rrc[ctxt_pP->module_id]->loc_type); + if (ue_context_p->ue_context.ue_release_timer_rrc > 0) { + ue_context_p->ue_context.ue_release_timer_rrc++; - if ((current_timestamp_ms - ref_timestamp_ms > RC.rrc[ctxt_pP->module_id]->aggregation_period_ms) && - estimated_distance != -1) { + if (ue_context_p->ue_context.ue_release_timer_rrc >= ue_context_p->ue_context.ue_release_timer_thres_rrc) { + LOG_I(RRC, "Removing UE %x instance after UE_CONTEXT_RELEASE_Complete (ue_release_timer_rrc timeout)\n", + ue_context_p->ue_context.rnti); + ue_context_p->ue_context.ue_release_timer_rrc = 0; + ue_to_be_removed = ue_context_p; + break; // break RB_FOREACH + } + } - LOG_D(LOCALIZE, "RRC [UE/id %d -> eNB/id %d] timestamp %d frame %d estimated r = %f\n", - ctxt.rnti, - ctxt_pP->module_id, - current_timestamp_ms, - ctxt_pP->frame, - estimated_distance); + pthread_mutex_lock(&rrc_release_freelist); - LOG_D(LOCALIZE, "RRC status %d\n", - ue_context_p->ue_context.Status); + if (rrc_release_info.num_UEs > 0) { + uint16_t release_total = 0; - push_front(&RC.rrc[ctxt_pP->module_id]->loc_list, estimated_distance); + for (uint16_t release_num = 0; release_num < NUMBER_OF_UE_MAX; release_num++) { + if (rrc_release_info.RRC_release_ctrl[release_num].flag > 0) { + release_total++; + } - RC.rrc[ctxt_pP->module_id]->reference_timestamp_ms = current_timestamp_ms; - } // end if - } // end RB_FOREACH + if ((rrc_release_info.RRC_release_ctrl[release_num].flag > 2) && + (rrc_release_info.RRC_release_ctrl[release_num].rnti == ue_context_p->ue_context.rnti)) { + ue_context_p->ue_context.ue_release_timer_rrc = 1; + ue_context_p->ue_context.ue_release_timer_thres_rrc = 100; +#if defined(ENABLE_USE_MME) +#if defined(ENABLE_ITTI) + int e_rab = 0; + MessageDef *msg_complete_p = NULL; + MessageDef *msg_delete_tunnels_p = NULL; + uint32_t eNB_ue_s1ap_id = ue_context_p->ue_context.eNB_ue_s1ap_id; + + if (rrc_release_info.RRC_release_ctrl[release_num].flag == 4) { // if timer_s1 == 0 + MSC_LOG_TX_MESSAGE(MSC_RRC_ENB, MSC_S1AP_ENB, NULL, 0, + "0 S1AP_UE_CONTEXT_RELEASE_COMPLETE eNB_ue_s1ap_id 0x%06"PRIX32" ", + eNB_ue_s1ap_id); + msg_complete_p = itti_alloc_new_message(TASK_RRC_ENB, S1AP_UE_CONTEXT_RELEASE_COMPLETE); + S1AP_UE_CONTEXT_RELEASE_COMPLETE(msg_complete_p).eNB_ue_s1ap_id = eNB_ue_s1ap_id; + itti_send_msg_to_task(TASK_S1AP, ctxt_pP->module_id, msg_complete_p); + } + + MSC_LOG_TX_MESSAGE(MSC_RRC_ENB, MSC_GTPU_ENB, NULL,0, "0 GTPV1U_ENB_DELETE_TUNNEL_REQ rnti %x ", eNB_ue_s1ap_id); + msg_delete_tunnels_p = itti_alloc_new_message(TASK_RRC_ENB, GTPV1U_ENB_DELETE_TUNNEL_REQ); + memset(>PV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p), 0, sizeof(GTPV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p))); + // do not wait response + GTPV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p).rnti = ue_context_p->ue_context.rnti; + + for (e_rab = 0; e_rab < ue_context_p->ue_context.nb_of_e_rabs; e_rab++) { + GTPV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p).eps_bearer_id[GTPV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p).num_erab++] = + ue_context_p->ue_context.enb_gtp_ebi[e_rab]; + // erase data + ue_context_p->ue_context.enb_gtp_teid[e_rab] = 0; + memset(&ue_context_p->ue_context.enb_gtp_addrs[e_rab], 0, sizeof(ue_context_p->ue_context.enb_gtp_addrs[e_rab])); + ue_context_p->ue_context.enb_gtp_ebi[e_rab] = 0; + } + + itti_send_msg_to_task(TASK_GTPV1_U, ctxt_pP->module_id, msg_delete_tunnels_p); + struct rrc_ue_s1ap_ids_s *rrc_ue_s1ap_ids = NULL; + rrc_ue_s1ap_ids = rrc_eNB_S1AP_get_ue_ids(RC.rrc[ctxt_pP->module_id], 0, eNB_ue_s1ap_id); + + if (rrc_ue_s1ap_ids != NULL) { + rrc_eNB_S1AP_remove_ue_ids(RC.rrc[ctxt_pP->module_id], rrc_ue_s1ap_ids); + } #endif +#endif + rrc_release_info.RRC_release_ctrl[release_num].flag = 0; + rrc_release_info.num_UEs--; + break; // break for (release_num) + } // end if ((rrc_release_info.RRC_release_ctrl[release_num].flag > 2) && ... - (void)ts; /* remove gcc warning "unused variable" */ - (void)ref_timestamp_ms; /* remove gcc warning "unused variable" */ - (void)current_timestamp_ms; /* remove gcc warning "unused variable" */ + if (release_total >= rrc_release_info.num_UEs) { + break; // break for (release_num) + } + } // end for (release_num) + } // end if (rrc_release_info.num_UEs > 0) + pthread_mutex_unlock(&rrc_release_freelist); + + if (ue_context_p->ue_context.ue_rrc_inactivity_timer > 0) { + // ue_context_p->ue_context.ue_rrc_inactivity_timer++; // (un)comment this line to (de)activate the RRC inactivity timer + if (ue_context_p->ue_context.ue_rrc_inactivity_timer >= ue_context_p->ue_context.ue_rrc_inactivity_timer_thres) { + LOG_I(RRC, "Removing UE %x instance because of rrc_inactivity_timer timeout\n", + ue_context_p->ue_context.rnti); + ue_to_be_removed = ue_context_p; + break; // break RB_FOREACH + } + } + + if (ue_context_p->ue_context.ue_reestablishment_timer > 0) { + ue_context_p->ue_context.ue_reestablishment_timer++; + + if (ue_context_p->ue_context.ue_reestablishment_timer >= ue_context_p->ue_context.ue_reestablishment_timer_thres) { + LOG_I(RRC, "Removing UE %x instance because of reestablishment_timer timeout\n", + ue_context_p->ue_context.rnti); + ue_context_p->ue_context.ul_failure_timer = 20000; // lead to send S1 UE_CONTEXT_RELEASE_REQ + ue_to_be_removed = ue_context_p; + ue_context_p->ue_context.ue_reestablishment_timer = 0; + break; // break RB_FOREACH + } + } + + if (ue_context_p->ue_context.ue_release_timer > 0) { + ue_context_p->ue_context.ue_release_timer++; + + if (ue_context_p->ue_context.ue_release_timer >= ue_context_p->ue_context.ue_release_timer_thres) { + LOG_I(RRC, "Removing UE %x instance because of RRC Connection Setup timer timeout\n", + ue_context_p->ue_context.rnti); + /* + * TODO: Naming problem here: ue_release_timer seems to have been used when RRC Connection Release was sent. + * It is no more the case. + * The timer should be renamed. + */ + ue_to_be_removed = ue_context_p; + ue_context_p->ue_context.ue_release_timer = 0; + break; // break RB_FOREACH + } + } + } // end RB_FOREACH + + if (ue_to_be_removed) { + if ((ue_to_be_removed->ue_context.ul_failure_timer >= 20000) || + (ue_to_be_removed->ue_context.ue_rrc_inactivity_timer >= ue_to_be_removed->ue_context.ue_rrc_inactivity_timer_thres)) { + ue_to_be_removed->ue_context.ue_release_timer_s1 = 1; + ue_to_be_removed->ue_context.ue_release_timer_thres_s1 = 100; + ue_to_be_removed->ue_context.ue_release_timer = 0; + ue_to_be_removed->ue_context.ue_reestablishment_timer = 0; + } + + rrc_eNB_free_UE(ctxt_pP->module_id, ue_to_be_removed); + + if (ue_to_be_removed->ue_context.ul_failure_timer >= 20000) { + ue_to_be_removed->ue_context.ul_failure_timer = 0; + } + + if (ue_to_be_removed->ue_context.ue_rrc_inactivity_timer >= ue_to_be_removed->ue_context.ue_rrc_inactivity_timer_thres) { + ue_to_be_removed->ue_context.ue_rrc_inactivity_timer = 0; //reset timer after S1 command UE context release request is sent + } + } + +#ifdef RRC_LOCALIZATION + /* for the localization, only primary CC_id might be relevant*/ + gettimeofday(&ts, NULL); + current_timestamp_ms = ts.tv_sec * 1000 + ts.tv_usec / 1000; + ref_timestamp_ms = RC.rrc[ctxt_pP->module_id]->reference_timestamp_ms; + RB_FOREACH(ue_context_p, rrc_ue_tree_s, &(RC.rrc[ctxt_pP->module_id]->rrc_ue_head)) { + ctxt = *ctxt_pP; + ctxt.rnti = ue_context_p->ue_context.rnti; + estimated_distance = rrc_get_estimated_ue_distance(&ctxt, CC_id, RC.rrc[ctxt_pP->module_id]->loc_type); + + if ((current_timestamp_ms - ref_timestamp_ms > RC.rrc[ctxt_pP->module_id]->aggregation_period_ms) && + estimated_distance != -1) { + LOG_D(LOCALIZE, "RRC [UE/id %d -> eNB/id %d] timestamp %d frame %d estimated r = %f\n", + ctxt.rnti, + ctxt_pP->module_id, + current_timestamp_ms, + ctxt_pP->frame, + estimated_distance); + LOG_D(LOCALIZE, "RRC status %d\n", + ue_context_p->ue_context.Status); + push_front(&RC.rrc[ctxt_pP->module_id]->loc_list, estimated_distance); + RC.rrc[ctxt_pP->module_id]->reference_timestamp_ms = current_timestamp_ms; + } // end if + } // end RB_FOREACH +#endif + (void)ts; /* remove gcc warning "unused variable" */ + (void)ref_timestamp_ms; /* remove gcc warning "unused variable" */ + (void)current_timestamp_ms; /* remove gcc warning "unused variable" */ VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RRC_RX_TX, VCD_FUNCTION_OUT); - return RRC_OK; } diff --git a/openair2/RRC/LTE/rrc_eNB_S1AP.c b/openair2/RRC/LTE/rrc_eNB_S1AP.c index b7d15da58d..2c2ab0ec49 100644 --- a/openair2/RRC/LTE/rrc_eNB_S1AP.c +++ b/openair2/RRC/LTE/rrc_eNB_S1AP.c @@ -41,18 +41,18 @@ # include "s1ap_eNB_management_procedures.h" # include "s1ap_eNB_ue_context.h" -# if defined(ENABLE_ITTI) -# include "asn1_conversions.h" -# include "intertask_interface.h" -# include "pdcp.h" -# include "pdcp_primitives.h" -# include "s1ap_eNB.h" -# else -# include "../../S1AP/s1ap_eNB.h" -# endif +#if defined(ENABLE_ITTI) + #include "asn1_conversions.h" + #include "intertask_interface.h" + #include "pdcp.h" + #include "pdcp_primitives.h" + #include "s1ap_eNB.h" +#else + #include "../../S1AP/s1ap_eNB.h" +#endif #if defined(ENABLE_SECURITY) -# include "UTIL/OSA/osa_defs.h" + #include "UTIL/OSA/osa_defs.h" #endif #include "msc.h" @@ -79,32 +79,29 @@ static const uint16_t S1AP_INTEGRITY_EIA1_MASK = 0x8000; static const uint16_t S1AP_INTEGRITY_EIA2_MASK = 0x4000; #if (LTE_RRC_VERSION >= MAKE_VERSION(9, 2, 0)) -# define INTEGRITY_ALGORITHM_NONE LTE_SecurityAlgorithmConfig__integrityProtAlgorithm_eia0_v920 + #define INTEGRITY_ALGORITHM_NONE LTE_SecurityAlgorithmConfig__integrityProtAlgorithm_eia0_v920 #else -#ifdef EXMIMO_IOT -# define INTEGRITY_ALGORITHM_NONE LTE_SecurityAlgorithmConfig__integrityProtAlgorithm_eia2 -#else -# define INTEGRITY_ALGORITHM_NONE LTE_SecurityAlgorithmConfig__integrityProtAlgorithm_reserved -#endif + #ifdef EXMIMO_IOT + #define INTEGRITY_ALGORITHM_NONE LTE_SecurityAlgorithmConfig__integrityProtAlgorithm_eia2 + #else + #define INTEGRITY_ALGORITHM_NONE LTE_SecurityAlgorithmConfig__integrityProtAlgorithm_reserved + #endif #endif -void extract_imsi(uint8_t *pdu_buf, uint32_t pdu_len, rrc_eNB_ue_context_t *ue_context_pP) -{ +void extract_imsi(uint8_t *pdu_buf, uint32_t pdu_len, rrc_eNB_ue_context_t *ue_context_pP) { /* Process NAS message locally to get the IMSI */ nas_message_t nas_msg; memset(&nas_msg, 0, sizeof(nas_message_t)); - int size = 0; - nas_message_security_header_t *header = &nas_msg.header; /* Decode the first octet of the header (security header type or EPS * bearer identity, and protocol discriminator) */ - DECODE_U8((char *) pdu_buf, *(uint8_t*) (header), size); + DECODE_U8((char *) pdu_buf, *(uint8_t *) (header), size); /* Decode NAS message only if decodable*/ if (!(header->security_header_type <= SECURITY_HEADER_TYPE_INTEGRITY_PROTECTED - && header->protocol_discriminator == EPS_MOBILITY_MANAGEMENT_MESSAGE - && pdu_len > NAS_MESSAGE_SECURITY_HEADER_SIZE)) + && header->protocol_discriminator == EPS_MOBILITY_MANAGEMENT_MESSAGE + && pdu_len > NAS_MESSAGE_SECURITY_HEADER_SIZE)) return; if (header->security_header_type != SECURITY_HEADER_TYPE_NOT_PROTECTED) { @@ -118,11 +115,9 @@ void extract_imsi(uint8_t *pdu_buf, uint32_t pdu_len, rrc_eNB_ue_context_t *ue_c * can modify it as we want. The callee retains the original address! */ pdu_buf += size; pdu_len -= size; - /* Decode plain NAS message */ EMM_msg *e_msg = &nas_msg.plain.emm; emm_msg_header_t *emm_header = &e_msg->header; - /* First decode the EMM message header */ int e_head_size = 0; @@ -169,9 +164,9 @@ void extract_imsi(uint8_t *pdu_buf, uint32_t pdu_len, rrc_eNB_ue_context_t *ue_c * Get the UE S1 struct containing hashtables S1_id/UE_id. * Is also used to set the S1_id of the UE, depending on inputs. */ -struct rrc_ue_s1ap_ids_s* +struct rrc_ue_s1ap_ids_s * rrc_eNB_S1AP_get_ue_ids( - eNB_RRC_INST* const rrc_instance_pP, + eNB_RRC_INST *const rrc_instance_pP, const uint16_t ue_initial_id, const uint32_t eNB_ue_s1ap_id ) @@ -188,114 +183,88 @@ rrc_eNB_S1AP_get_ue_ids( hashtable_rc_t h_rc; if (ue_initial_id != UE_INITIAL_ID_INVALID) { - h_rc = hashtable_get(rrc_instance_pP->initial_id2_s1ap_ids, (hash_key_t)ue_initial_id, (void**)&result); + h_rc = hashtable_get(rrc_instance_pP->initial_id2_s1ap_ids, (hash_key_t)ue_initial_id, (void **)&result); if (h_rc == HASH_TABLE_OK) { - if (eNB_ue_s1ap_id > 0) { - h_rc = hashtable_get(rrc_instance_pP->s1ap_id2_s1ap_ids, (hash_key_t)eNB_ue_s1ap_id, (void**)&result2); - + h_rc = hashtable_get(rrc_instance_pP->s1ap_id2_s1ap_ids, (hash_key_t)eNB_ue_s1ap_id, (void **)&result2); + if (h_rc != HASH_TABLE_OK) { // this case is equivalent to associate eNB_ue_s1ap_id and ue_initial_id result2 = malloc(sizeof(*result2)); - + if (NULL != result2) { *result2 = *result; - result2->eNB_ue_s1ap_id = eNB_ue_s1ap_id; result->eNB_ue_s1ap_id = eNB_ue_s1ap_id; - h_rc = hashtable_insert(rrc_instance_pP->s1ap_id2_s1ap_ids, (hash_key_t)eNB_ue_s1ap_id, result2); if (h_rc != HASH_TABLE_OK) { - LOG_E(S1AP, "[eNB %ld] Error while hashtable_insert in s1ap_id2_s1ap_ids eNB_ue_s1ap_id %"PRIu32"\n", - rrc_instance_pP - RC.rrc[0], - eNB_ue_s1ap_id); + LOG_E(S1AP, "[eNB %ld] Error while hashtable_insert in s1ap_id2_s1ap_ids eNB_ue_s1ap_id %"PRIu32"\n", + rrc_instance_pP - RC.rrc[0], + eNB_ue_s1ap_id); } } - } else { // here we should check that the association was done correctly - if ((result->ue_initial_id != result2->ue_initial_id) || (result->eNB_ue_s1ap_id != result2->eNB_ue_s1ap_id)) { - LOG_E(S1AP, "[eNB %ld] Error while hashtable_get, two rrc_ue_s1ap_ids_t that should be equal, are not:\n \ ue_initial_id 1 = %"PRIu16",\n \ ue_initial_id 2 = %"PRIu16",\n \ eNB_ue_s1ap_id 1 = %"PRIu32",\n \ eNB_ue_s1ap_id 2 = %"PRIu32"\n", - rrc_instance_pP - RC.rrc[0], - result->ue_initial_id, - result2->ue_initial_id, - result->eNB_ue_s1ap_id, - result2->eNB_ue_s1ap_id); - + rrc_instance_pP - RC.rrc[0], + result->ue_initial_id, + result2->ue_initial_id, + result->eNB_ue_s1ap_id, + result2->eNB_ue_s1ap_id); } - } } // end if if (eNB_ue_s1ap_id > 0) - } else { // end if (h_rc == HASH_TABLE_OK) - - LOG_E(S1AP, "[eNB %ld] In hashtable_get, couldn't find in initial_id2_s1ap_ids ue_initial_id %"PRIu16"\n", - rrc_instance_pP - RC.rrc[0], - ue_initial_id); + LOG_E(S1AP, "[eNB %ld] In hashtable_get, couldn't find in initial_id2_s1ap_ids ue_initial_id %"PRIu16"\n", + rrc_instance_pP - RC.rrc[0], + ue_initial_id); /* * At the moment this is written, this case shouldn't (cannot) happen and is equivalent to an error. * One could try to find the struct instance based on s1ap_id2_s1ap_ids and eNB_ue_s1ap_id (if > 0), * but this behavior is not expected at the moment. */ - } // end else (h_rc != HASH_TABLE_OK) - } else { // end if (ue_initial_id != UE_INITIAL_ID_INVALID) - if (eNB_ue_s1ap_id > 0) { - h_rc = hashtable_get(rrc_instance_pP->s1ap_id2_s1ap_ids, (hash_key_t)eNB_ue_s1ap_id, (void**)&result); + h_rc = hashtable_get(rrc_instance_pP->s1ap_id2_s1ap_ids, (hash_key_t)eNB_ue_s1ap_id, (void **)&result); if (h_rc != HASH_TABLE_OK) { /* * This case is uncommon, but can happen when: - * -> if the first NAS message was a Detach Request (non exhaustiv), the UE RRC context exist + * -> if the first NAS message was a Detach Request (non exhaustiv), the UE RRC context exist * but is not associated with eNB_ue_s1ap_id * -> ... (?) */ - LOG_E(S1AP, "[eNB %ld] In hashtable_get, couldn't find in s1ap_id2_s1ap_ids eNB_ue_s1ap_id %"PRIu32", trying to find it through S1AP context\n", - rrc_instance_pP - RC.rrc[0], - eNB_ue_s1ap_id); - + LOG_E(S1AP, "[eNB %ld] In hashtable_get, couldn't find in s1ap_id2_s1ap_ids eNB_ue_s1ap_id %"PRIu32", trying to find it through S1AP context\n", + rrc_instance_pP - RC.rrc[0], + eNB_ue_s1ap_id); instance = ENB_MODULE_ID_TO_INSTANCE(rrc_instance_pP - RC.rrc[0]); // get eNB instance - s1ap_eNB_instance_p = s1ap_eNB_get_instance(instance); // get s1ap_eNB_instance - ue_desc_p = s1ap_eNB_get_ue_context(s1ap_eNB_instance_p, eNB_ue_s1ap_id); // get s1ap_eNB_ue_context if (ue_desc_p != NULL) { - result = rrc_eNB_S1AP_get_ue_ids(rrc_instance_pP, ue_desc_p->ue_initial_id, eNB_ue_s1ap_id); - ue_context_p = rrc_eNB_get_ue_context(RC.rrc[ENB_INSTANCE_TO_MODULE_ID(instance)], result->ue_rnti); if ((ue_context_p != NULL) && (ue_context_p->ue_context.eNB_ue_s1ap_id == 0)) { - ue_context_p->ue_context.eNB_ue_s1ap_id = eNB_ue_s1ap_id; - } else { - LOG_E(RRC, "[eNB %ld] Incoherence between RRC context and S1AP context (%d != %d) for UE RNTI %d or UE RRC context doesn't exist\n", - rrc_instance_pP - RC.rrc[0], - ue_context_p->ue_context.eNB_ue_s1ap_id, - eNB_ue_s1ap_id, - result->ue_rnti); - + rrc_instance_pP - RC.rrc[0], + ue_context_p->ue_context.eNB_ue_s1ap_id, + eNB_ue_s1ap_id, + result->ue_rnti); } - } else { - - LOG_E(S1AP, "[eNB %ld] In hashtable_get, couldn't find in s1ap_id2_s1ap_ids eNB_ue_s1ap_id %"PRIu32", even when looking at S1AP context\n", - rrc_instance_pP - RC.rrc[0], - eNB_ue_s1ap_id); - + LOG_E(S1AP, "[eNB %ld] In hashtable_get, couldn't find in s1ap_id2_s1ap_ids eNB_ue_s1ap_id %"PRIu32", even when looking at S1AP context\n", + rrc_instance_pP - RC.rrc[0], + eNB_ue_s1ap_id); } - } // end if (h_rc != HASH_TABLE_OK) } // end if (eNB_ue_s1ap_id > 0) } // end else (ue_initial_id == UE_INITIAL_ID_INVALID) @@ -316,7 +285,6 @@ rrc_eNB_S1AP_remove_ue_ids( { const uint16_t ue_initial_id = ue_ids_pP->ue_initial_id; const uint32_t eNB_ue_s1ap_id = ue_ids_pP->eNB_ue_s1ap_id; - hashtable_rc_t h_rc; if (rrc_instance_pP == NULL) { @@ -330,18 +298,18 @@ rrc_eNB_S1AP_remove_ue_ids( } if (eNB_ue_s1ap_id > 0) { - h_rc = hashtable_remove(rrc_instance_pP->s1ap_id2_s1ap_ids, (hash_key_t)eNB_ue_s1ap_id); - + h_rc = hashtable_remove(rrc_instance_pP->s1ap_id2_s1ap_ids, (hash_key_t)eNB_ue_s1ap_id); + if (h_rc != HASH_TABLE_OK) { - LOG_W(RRC, "S1AP Did not find entry in hashtable s1ap_id2_s1ap_ids for eNB_ue_s1ap_id %u\n", eNB_ue_s1ap_id); - } else { - LOG_W(RRC, "S1AP removed entry in hashtable s1ap_id2_s1ap_ids for eNB_ue_s1ap_id %u\n", eNB_ue_s1ap_id); - } + LOG_W(RRC, "S1AP Did not find entry in hashtable s1ap_id2_s1ap_ids for eNB_ue_s1ap_id %u\n", eNB_ue_s1ap_id); + } else { + LOG_W(RRC, "S1AP removed entry in hashtable s1ap_id2_s1ap_ids for eNB_ue_s1ap_id %u\n", eNB_ue_s1ap_id); + } } if (ue_initial_id != UE_INITIAL_ID_INVALID) { h_rc = hashtable_remove(rrc_instance_pP->initial_id2_s1ap_ids, (hash_key_t)ue_initial_id); - + if (h_rc != HASH_TABLE_OK) { LOG_W(RRC, "S1AP Did not find entry in hashtable initial_id2_s1ap_ids for ue_initial_id %u\n", ue_initial_id); } else { @@ -384,15 +352,13 @@ get_next_ue_initial_id( *\param eNB_ue_s1ap_id The value sent by S1AP. *\return the UE index or UE_INDEX_INVALID if not found. */ -static struct rrc_eNB_ue_context_s* +static struct rrc_eNB_ue_context_s * rrc_eNB_get_ue_context_from_s1ap_ids( const instance_t instanceP, const uint16_t ue_initial_idP, const uint32_t eNB_ue_s1ap_idP -) -{ - rrc_ue_s1ap_ids_t* temp = NULL; - +) { + rrc_ue_s1ap_ids_t *temp = NULL; temp = rrc_eNB_S1AP_get_ue_ids(RC.rrc[ENB_INSTANCE_TO_MODULE_ID(instanceP)], ue_initial_idP, eNB_ue_s1ap_idP); if (temp != NULL) { @@ -407,10 +373,8 @@ rrc_eNB_get_ue_context_from_s1ap_ids( *\param algorithms The bit mask of available algorithms received from S1AP. *\return the selected algorithm. */ -static LTE_CipheringAlgorithm_r12_t rrc_eNB_select_ciphering(uint16_t algorithms) -{ - -//#warning "Forced return SecurityAlgorithmConfig__cipheringAlgorithm_eea0, to be deleted in future" +static LTE_CipheringAlgorithm_r12_t rrc_eNB_select_ciphering(uint16_t algorithms) { + //#warning "Forced return SecurityAlgorithmConfig__cipheringAlgorithm_eea0, to be deleted in future" return LTE_CipheringAlgorithm_r12_eea0; if (algorithms & S1AP_ENCRYPTION_EEA2_MASK) { @@ -429,9 +393,7 @@ static LTE_CipheringAlgorithm_r12_t rrc_eNB_select_ciphering(uint16_t algorithms *\param algorithms The bit mask of available algorithms received from S1AP. *\return the selected algorithm. */ -static e_LTE_SecurityAlgorithmConfig__integrityProtAlgorithm rrc_eNB_select_integrity(uint16_t algorithms) -{ - +static e_LTE_SecurityAlgorithmConfig__integrityProtAlgorithm rrc_eNB_select_integrity(uint16_t algorithms) { if (algorithms & S1AP_INTEGRITY_EIA2_MASK) { return LTE_SecurityAlgorithmConfig__integrityProtAlgorithm_eia2; } @@ -452,18 +414,15 @@ static e_LTE_SecurityAlgorithmConfig__integrityProtAlgorithm rrc_eNB_select_inte */ static int rrc_eNB_process_security( - const protocol_ctxt_t* const ctxt_pP, - rrc_eNB_ue_context_t* const ue_context_pP, - security_capabilities_t* security_capabilities_pP -) -{ + const protocol_ctxt_t *const ctxt_pP, + rrc_eNB_ue_context_t *const ue_context_pP, + security_capabilities_t *security_capabilities_pP +) { boolean_t changed = FALSE; LTE_CipheringAlgorithm_r12_t cipheringAlgorithm; e_LTE_SecurityAlgorithmConfig__integrityProtAlgorithm integrityProtAlgorithm; - /* Save security parameters */ ue_context_pP->ue_context.security_capabilities = *security_capabilities_pP; - // translation LOG_D(RRC, "[eNB %d] NAS security_capabilities.encryption_algorithms %u AS ciphering_algorithm %lu NAS security_capabilities.integrity_algorithms %u AS integrity_algorithm %u\n", @@ -494,7 +453,6 @@ rrc_eNB_process_security( (unsigned long)cipheringAlgorithm, integrityProtAlgorithm, changed ? "changed" : "same"); - return changed; } @@ -506,16 +464,15 @@ rrc_eNB_process_security( */ //------------------------------------------------------------------------------ static void process_eNB_security_key ( - const protocol_ctxt_t* const ctxt_pP, - rrc_eNB_ue_context_t* const ue_context_pP, - uint8_t* security_key_pP + const protocol_ctxt_t *const ctxt_pP, + rrc_eNB_ue_context_t *const ue_context_pP, + uint8_t *security_key_pP ) //------------------------------------------------------------------------------ { #if defined(ENABLE_SECURITY) char ascii_buffer[65]; uint8_t i; - /* Saves the security key */ memcpy (ue_context_pP->ue_context.kenb, security_key_pP, SECURITY_KEY_LENGTH); memset (ue_context_pP->ue_context.nh, 0, SECURITY_KEY_LENGTH); @@ -526,7 +483,6 @@ static void process_eNB_security_key ( } ascii_buffer[2 * i] = '\0'; - LOG_I (RRC, "[eNB %d][UE %x] Saved security key %s\n", ctxt_pP->module_id, ue_context_pP->ue_context.rnti, ascii_buffer); #endif } @@ -535,17 +491,14 @@ static void process_eNB_security_key ( //------------------------------------------------------------------------------ void rrc_pdcp_config_security( - const protocol_ctxt_t* const ctxt_pP, - rrc_eNB_ue_context_t* const ue_context_pP, + const protocol_ctxt_t *const ctxt_pP, + rrc_eNB_ue_context_t *const ue_context_pP, const uint8_t send_security_mode_command ) //------------------------------------------------------------------------------ { - #if defined(ENABLE_SECURITY) - - - LTE_SRB_ToAddModList_t* SRB_configList = ue_context_pP->ue_context.SRB_configList; + LTE_SRB_ToAddModList_t *SRB_configList = ue_context_pP->ue_context.SRB_configList; uint8_t *kRRCenc = NULL; uint8_t *kRRCint = NULL; uint8_t *kUPenc = NULL; @@ -567,16 +520,13 @@ rrc_pdcp_config_security( derive_key_rrc_int(ue_context_pP->ue_context.integrity_algorithm, ue_context_pP->ue_context.kenb, &kRRCint); - #if !defined(USRP_REC_PLAY) SET_LOG_DUMP(DEBUG_SECURITY) ; #endif - if ( LOG_DUMPFLAG( DEBUG_SECURITY ) ) { if (print_keys ==1 ) { print_keys =0; - LOG_DUMPMSG(RRC, DEBUG_SECURITY, ue_context_pP->ue_context.kenb, 32,"\nKeNB:" ); LOG_DUMPMSG(RRC, DEBUG_SECURITY, kRRCenc, 32,"\nKRRCenc:" ); LOG_DUMPMSG(RRC, DEBUG_SECURITY, kRRCint, 32,"\nKRRCint:" ); @@ -584,8 +534,7 @@ rrc_pdcp_config_security( } key = PDCP_COLL_KEY_VALUE(ctxt_pP->module_id, ctxt_pP->rnti, ctxt_pP->enb_flag, DCCH, SRB_FLAG_YES); - h_rc = hashtable_get(pdcp_coll_p, key, (void**)&pdcp_p); - + h_rc = hashtable_get(pdcp_coll_p, key, (void **)&pdcp_p); if (h_rc == HASH_TABLE_OK) { pdcp_config_set_security( @@ -613,8 +562,8 @@ rrc_pdcp_config_security( //------------------------------------------------------------------------------ void rrc_eNB_send_S1AP_INITIAL_CONTEXT_SETUP_RESP( - const protocol_ctxt_t* const ctxt_pP, - rrc_eNB_ue_context_t* const ue_context_pP + const protocol_ctxt_t *const ctxt_pP, + rrc_eNB_ue_context_t *const ue_context_pP ) //------------------------------------------------------------------------------ { @@ -622,7 +571,6 @@ rrc_eNB_send_S1AP_INITIAL_CONTEXT_SETUP_RESP( int e_rab; int e_rabs_done = 0; int e_rabs_failed = 0; - msg_p = itti_alloc_new_message (TASK_RRC_ENB, S1AP_INITIAL_CONTEXT_SETUP_RESP); S1AP_INITIAL_CONTEXT_SETUP_RESP (msg_p).eNB_ue_s1ap_id = ue_context_pP->ue_context.eNB_ue_s1ap_id; @@ -653,11 +601,8 @@ rrc_eNB_send_S1AP_INITIAL_CONTEXT_SETUP_RESP( ue_context_pP->ue_id_rnti, S1AP_INITIAL_CONTEXT_SETUP_RESP (msg_p).eNB_ue_s1ap_id, e_rabs_done, e_rabs_failed); - - S1AP_INITIAL_CONTEXT_SETUP_RESP (msg_p).nb_of_e_rabs = e_rabs_done; S1AP_INITIAL_CONTEXT_SETUP_RESP (msg_p).nb_of_e_rabs_failed = e_rabs_failed; - itti_send_msg_to_task (TASK_S1AP, ctxt_pP->instance, msg_p); } # endif @@ -665,9 +610,9 @@ rrc_eNB_send_S1AP_INITIAL_CONTEXT_SETUP_RESP( //------------------------------------------------------------------------------ void rrc_eNB_send_S1AP_UPLINK_NAS( - const protocol_ctxt_t* const ctxt_pP, - rrc_eNB_ue_context_t* const ue_context_pP, - LTE_UL_DCCH_Message_t* const ul_dcch_msg + const protocol_ctxt_t *const ctxt_pP, + rrc_eNB_ue_context_t *const ue_context_pP, + LTE_UL_DCCH_Message_t *const ul_dcch_msg ) //------------------------------------------------------------------------------ { @@ -676,29 +621,25 @@ rrc_eNB_send_S1AP_UPLINK_NAS( LTE_ULInformationTransfer_t *ulInformationTransfer = &ul_dcch_msg->message.choice.c1.choice.ulInformationTransfer; if ((ulInformationTransfer->criticalExtensions.present == LTE_ULInformationTransfer__criticalExtensions_PR_c1) - && (ulInformationTransfer->criticalExtensions.choice.c1.present - == LTE_ULInformationTransfer__criticalExtensions__c1_PR_ulInformationTransfer_r8) - && (ulInformationTransfer->criticalExtensions.choice.c1.choice.ulInformationTransfer_r8.dedicatedInfoType.present - == LTE_ULInformationTransfer_r8_IEs__dedicatedInfoType_PR_dedicatedInfoNAS)) { + && (ulInformationTransfer->criticalExtensions.choice.c1.present + == LTE_ULInformationTransfer__criticalExtensions__c1_PR_ulInformationTransfer_r8) + && (ulInformationTransfer->criticalExtensions.choice.c1.choice.ulInformationTransfer_r8.dedicatedInfoType.present + == LTE_ULInformationTransfer_r8_IEs__dedicatedInfoType_PR_dedicatedInfoNAS)) { /* This message hold a dedicated info NAS payload, forward it to NAS */ struct LTE_ULInformationTransfer_r8_IEs__dedicatedInfoType *dedicatedInfoType = - &ulInformationTransfer->criticalExtensions.choice.c1.choice.ulInformationTransfer_r8.dedicatedInfoType; + &ulInformationTransfer->criticalExtensions.choice.c1.choice.ulInformationTransfer_r8.dedicatedInfoType; uint32_t pdu_length; uint8_t *pdu_buffer; MessageDef *msg_p; - pdu_length = dedicatedInfoType->choice.dedicatedInfoNAS.size; pdu_buffer = dedicatedInfoType->choice.dedicatedInfoNAS.buf; - msg_p = itti_alloc_new_message (TASK_RRC_ENB, S1AP_UPLINK_NAS); S1AP_UPLINK_NAS (msg_p).eNB_ue_s1ap_id = ue_context_pP->ue_context.eNB_ue_s1ap_id; S1AP_UPLINK_NAS (msg_p).nas_pdu.length = pdu_length; S1AP_UPLINK_NAS (msg_p).nas_pdu.buffer = pdu_buffer; - extract_imsi(S1AP_UPLINK_NAS (msg_p).nas_pdu.buffer, S1AP_UPLINK_NAS (msg_p).nas_pdu.length, ue_context_pP); - itti_send_msg_to_task (TASK_S1AP, ctxt_pP->instance, msg_p); } } @@ -710,10 +651,9 @@ rrc_eNB_send_S1AP_UPLINK_NAS( ulInformationTransfer; if (ulInformationTransfer->criticalExtensions.present == - LTE_ULInformationTransfer__criticalExtensions_PR_c1) { + LTE_ULInformationTransfer__criticalExtensions_PR_c1) { if (ulInformationTransfer->criticalExtensions.choice.c1.present == - LTE_ULInformationTransfer__criticalExtensions__c1_PR_ulInformationTransfer_r8) { - + LTE_ULInformationTransfer__criticalExtensions__c1_PR_ulInformationTransfer_r8) { ULInformationTransfer_r8_IEs_t *ulInformationTransferR8; ulInformationTransferR8 = @@ -722,14 +662,12 @@ rrc_eNB_send_S1AP_UPLINK_NAS( if (ulInformationTransferR8->dedicatedInfoType.present == LTE_ULInformationTransfer_r8_IEs__dedicatedInfoType_PR_dedicatedInfoNAS) { - extract_imsi(ulInformationTransferR8->dedicatedInfoType.choice.dedicatedInfoNAS.buf, ulInformationTransferR8->dedicatedInfoType.choice.dedicatedInfoNAS.size, ue_context_pP); - s1ap_eNB_new_data_request (mod_id, ue_index, - ulInformationTransferR8->dedicatedInfoType.choice.dedicatedInfoNAS.buf, - ulInformationTransferR8->dedicatedInfoType.choice.dedicatedInfoNAS.size); + ulInformationTransferR8->dedicatedInfoType.choice.dedicatedInfoNAS.buf, + ulInformationTransferR8->dedicatedInfoType.choice.dedicatedInfoNAS.size); } } } @@ -739,9 +677,9 @@ rrc_eNB_send_S1AP_UPLINK_NAS( //------------------------------------------------------------------------------ void rrc_eNB_send_S1AP_UE_CAPABILITIES_IND( - const protocol_ctxt_t* const ctxt_pP, - rrc_eNB_ue_context_t* const ue_context_pP, - LTE_UL_DCCH_Message_t* ul_dcch_msg + const protocol_ctxt_t *const ctxt_pP, + rrc_eNB_ue_context_t *const ue_context_pP, + LTE_UL_DCCH_Message_t *ul_dcch_msg ) //------------------------------------------------------------------------------ { @@ -762,15 +700,14 @@ void rrc_eNB_send_S1AP_UE_CAPABILITIES_IND( if (ret.encoded == -1) abort(); memset(&rac, 0, sizeof(LTE_UERadioAccessCapabilityInformation_t)); - rac.criticalExtensions.present = LTE_UERadioAccessCapabilityInformation__criticalExtensions_PR_c1; rac.criticalExtensions.choice.c1.present = LTE_UERadioAccessCapabilityInformation__criticalExtensions__c1_PR_ueRadioAccessCapabilityInformation_r8; rac.criticalExtensions.choice.c1.choice.ueRadioAccessCapabilityInformation_r8.ue_RadioAccessCapabilityInfo.buf = buf; rac.criticalExtensions.choice.c1.choice.ueRadioAccessCapabilityInformation_r8.ue_RadioAccessCapabilityInfo.size = (ret.encoded+7)/8; rac.criticalExtensions.choice.c1.choice.ueRadioAccessCapabilityInformation_r8.nonCriticalExtension = NULL; - /* 8192 is arbitrary, should be big enough */ buf2 = malloc16(8192); + if (buf2 == NULL) abort(); ret = uper_encode_to_buffer(&asn_DEF_LTE_UERadioAccessCapabilityInformation, NULL, &rac, buf2, 8192); @@ -778,12 +715,10 @@ void rrc_eNB_send_S1AP_UE_CAPABILITIES_IND( if (ret.encoded == -1) abort(); MessageDef *msg_p; - msg_p = itti_alloc_new_message (TASK_RRC_ENB, S1AP_UE_CAPABILITIES_IND); S1AP_UE_CAPABILITIES_IND (msg_p).eNB_ue_s1ap_id = ue_context_pP->ue_context.eNB_ue_s1ap_id; S1AP_UE_CAPABILITIES_IND (msg_p).ue_radio_cap.length = (ret.encoded+7)/8; S1AP_UE_CAPABILITIES_IND (msg_p).ue_radio_cap.buffer = buf2; - itti_send_msg_to_task (TASK_S1AP, ctxt_pP->instance, msg_p); } @@ -793,76 +728,64 @@ void rrc_eNB_send_S1AP_UE_CAPABILITIES_IND( */ void rrc_eNB_send_S1AP_NAS_FIRST_REQ( - const protocol_ctxt_t* const ctxt_pP, - rrc_eNB_ue_context_t* const ue_context_pP, - LTE_RRCConnectionSetupComplete_r8_IEs_t* rrcConnectionSetupComplete + const protocol_ctxt_t *const ctxt_pP, + rrc_eNB_ue_context_t *const ue_context_pP, + LTE_RRCConnectionSetupComplete_r8_IEs_t *rrcConnectionSetupComplete ) //------------------------------------------------------------------------------ { eNB_RRC_INST *rrc = RC.rrc[ctxt_pP->module_id]; - #if defined(ENABLE_ITTI) { - MessageDef* message_p = NULL; - rrc_ue_s1ap_ids_t* rrc_ue_s1ap_ids_p = NULL; + MessageDef *message_p = NULL; + rrc_ue_s1ap_ids_t *rrc_ue_s1ap_ids_p = NULL; hashtable_rc_t h_rc; - message_p = itti_alloc_new_message(TASK_RRC_ENB, S1AP_NAS_FIRST_REQ); memset(&message_p->ittiMsg.s1ap_nas_first_req, 0, sizeof(s1ap_nas_first_req_t)); - ue_context_pP->ue_context.ue_initial_id = get_next_ue_initial_id(ctxt_pP->module_id); - S1AP_NAS_FIRST_REQ(message_p).ue_initial_id = ue_context_pP->ue_context.ue_initial_id; - rrc_ue_s1ap_ids_p = malloc(sizeof(*rrc_ue_s1ap_ids_p)); rrc_ue_s1ap_ids_p->ue_initial_id = ue_context_pP->ue_context.ue_initial_id; rrc_ue_s1ap_ids_p->eNB_ue_s1ap_id = UE_INITIAL_ID_INVALID; rrc_ue_s1ap_ids_p->ue_rnti = ctxt_pP->rnti; - h_rc = hashtable_insert(RC.rrc[ctxt_pP->module_id]->initial_id2_s1ap_ids, - (hash_key_t)ue_context_pP->ue_context.ue_initial_id, - rrc_ue_s1ap_ids_p); + (hash_key_t)ue_context_pP->ue_context.ue_initial_id, + rrc_ue_s1ap_ids_p); if (h_rc != HASH_TABLE_OK) { LOG_E(S1AP, "[eNB %d] Error while hashtable_insert in initial_id2_s1ap_ids ue_initial_id %u\n", - ctxt_pP->module_id, - ue_context_pP->ue_context.ue_initial_id); + ctxt_pP->module_id, + ue_context_pP->ue_context.ue_initial_id); } /* Assume that cause is coded in the same way in RRC and S1ap, just check that the value is in S1ap range */ AssertFatal(ue_context_pP->ue_context.establishment_cause < RRC_CAUSE_LAST, - "Establishment cause invalid (%jd/%d) for eNB %d!", - ue_context_pP->ue_context.establishment_cause, - RRC_CAUSE_LAST, - ctxt_pP->module_id); - + "Establishment cause invalid (%jd/%d) for eNB %d!", + ue_context_pP->ue_context.establishment_cause, + RRC_CAUSE_LAST, + ctxt_pP->module_id); S1AP_NAS_FIRST_REQ (message_p).establishment_cause = ue_context_pP->ue_context.establishment_cause; - - /* Forward NAS message */ + /* Forward NAS message */ S1AP_NAS_FIRST_REQ (message_p).nas_pdu.buffer = rrcConnectionSetupComplete->dedicatedInfoNAS.buf; S1AP_NAS_FIRST_REQ (message_p).nas_pdu.length = rrcConnectionSetupComplete->dedicatedInfoNAS.size; - extract_imsi(S1AP_NAS_FIRST_REQ (message_p).nas_pdu.buffer, S1AP_NAS_FIRST_REQ (message_p).nas_pdu.length, ue_context_pP); - /* Fill UE identities with available information */ { S1AP_NAS_FIRST_REQ (message_p).ue_identity.presenceMask = UE_IDENTITIES_NONE; if (ue_context_pP->ue_context.Initialue_identity_s_TMSI.presence) { /* Fill s-TMSI */ - UE_S_TMSI* s_TMSI = &ue_context_pP->ue_context.Initialue_identity_s_TMSI; - + UE_S_TMSI *s_TMSI = &ue_context_pP->ue_context.Initialue_identity_s_TMSI; S1AP_NAS_FIRST_REQ (message_p).ue_identity.presenceMask |= UE_IDENTITIES_s_tmsi; S1AP_NAS_FIRST_REQ (message_p).ue_identity.s_tmsi.mme_code = s_TMSI->mme_code; S1AP_NAS_FIRST_REQ (message_p).ue_identity.s_tmsi.m_tmsi = s_TMSI->m_tmsi; - LOG_I(S1AP, "[eNB %d] Build S1AP_NAS_FIRST_REQ with s_TMSI: MME code %u M-TMSI %u ue %x\n", - ctxt_pP->module_id, - S1AP_NAS_FIRST_REQ (message_p).ue_identity.s_tmsi.mme_code, - S1AP_NAS_FIRST_REQ (message_p).ue_identity.s_tmsi.m_tmsi, - ue_context_pP->ue_context.rnti); + ctxt_pP->module_id, + S1AP_NAS_FIRST_REQ (message_p).ue_identity.s_tmsi.mme_code, + S1AP_NAS_FIRST_REQ (message_p).ue_identity.s_tmsi.m_tmsi, + ue_context_pP->ue_context.rnti); } // end if S-TMSI presence /* selected_plmn_identity: IE is 1-based, convert to 0-based (C array) */ @@ -872,30 +795,26 @@ rrc_eNB_send_S1AP_NAS_FIRST_REQ( if (rrcConnectionSetupComplete->registeredMME != NULL) { /* Fill GUMMEI */ struct LTE_RegisteredMME *r_mme = rrcConnectionSetupComplete->registeredMME; - S1AP_NAS_FIRST_REQ (message_p).ue_identity.presenceMask |= UE_IDENTITIES_gummei; if (r_mme->plmn_Identity != NULL) { if ((r_mme->plmn_Identity->mcc != NULL) && (r_mme->plmn_Identity->mcc->list.count > 0)) { /* Use first indicated PLMN MCC if it is defined */ S1AP_NAS_FIRST_REQ (message_p).ue_identity.gummei.mcc = *r_mme->plmn_Identity->mcc->list.array[selected_plmn_identity]; - LOG_I(S1AP, "[eNB %d] Build S1AP_NAS_FIRST_REQ adding in s_TMSI: GUMMEI MCC %u ue %x\n", - ctxt_pP->module_id, - S1AP_NAS_FIRST_REQ (message_p).ue_identity.gummei.mcc, - ue_context_pP->ue_context.rnti); + ctxt_pP->module_id, + S1AP_NAS_FIRST_REQ (message_p).ue_identity.gummei.mcc, + ue_context_pP->ue_context.rnti); } if (r_mme->plmn_Identity->mnc.list.count > 0) { /* Use first indicated PLMN MNC if it is defined */ S1AP_NAS_FIRST_REQ (message_p).ue_identity.gummei.mnc = *r_mme->plmn_Identity->mnc.list.array[selected_plmn_identity]; - LOG_I(S1AP, "[eNB %d] Build S1AP_NAS_FIRST_REQ adding in s_TMSI: GUMMEI MNC %u ue %x\n", - ctxt_pP->module_id, - S1AP_NAS_FIRST_REQ (message_p).ue_identity.gummei.mnc, - ue_context_pP->ue_context.rnti); + ctxt_pP->module_id, + S1AP_NAS_FIRST_REQ (message_p).ue_identity.gummei.mnc, + ue_context_pP->ue_context.rnti); } - } else { // end if plmn_Identity != NULL S1AP_NAS_FIRST_REQ(message_p).ue_identity.gummei.mcc = rrc->configuration.mcc[selected_plmn_identity]; S1AP_NAS_FIRST_REQ(message_p).ue_identity.gummei.mnc = rrc->configuration.mnc[selected_plmn_identity]; @@ -904,30 +823,24 @@ rrc_eNB_send_S1AP_NAS_FIRST_REQ( S1AP_NAS_FIRST_REQ (message_p).ue_identity.gummei.mme_code = BIT_STRING_to_uint8 (&r_mme->mmec); S1AP_NAS_FIRST_REQ (message_p).ue_identity.gummei.mme_group_id = BIT_STRING_to_uint16 (&r_mme->mmegi); - MSC_LOG_TX_MESSAGE(MSC_S1AP_ENB, - MSC_S1AP_MME, - (const char *)&message_p->ittiMsg.s1ap_nas_first_req, - sizeof(s1ap_nas_first_req_t), - MSC_AS_TIME_FMT" S1AP_NAS_FIRST_REQ eNB %u UE %x", - MSC_AS_TIME_ARGS(ctxt_pP), - ctxt_pP->module_id, - ctxt_pP->rnti); - + MSC_S1AP_MME, + (const char *)&message_p->ittiMsg.s1ap_nas_first_req, + sizeof(s1ap_nas_first_req_t), + MSC_AS_TIME_FMT" S1AP_NAS_FIRST_REQ eNB %u UE %x", + MSC_AS_TIME_ARGS(ctxt_pP), + ctxt_pP->module_id, + ctxt_pP->rnti); LOG_I(S1AP, "[eNB %d] Build S1AP_NAS_FIRST_REQ adding in s_TMSI: GUMMEI mme_code %u mme_group_id %u ue %x\n", ctxt_pP->module_id, S1AP_NAS_FIRST_REQ (message_p).ue_identity.gummei.mme_code, S1AP_NAS_FIRST_REQ (message_p).ue_identity.gummei.mme_group_id, ue_context_pP->ue_context.rnti); - } // end if MME info present } // end "Fill UE identities with available information" sub-part - itti_send_msg_to_task (TASK_S1AP, ctxt_pP->instance, message_p); } - #else - { s1ap_eNB_new_data_request ( ctxt_pP->module_id, @@ -937,7 +850,6 @@ rrc_eNB_send_S1AP_NAS_FIRST_REQ( rrcConnectionSetupComplete->dedicatedInfoNAS. size); } - #endif } @@ -945,10 +857,10 @@ rrc_eNB_send_S1AP_NAS_FIRST_REQ( //------------------------------------------------------------------------------ int rrc_eNB_process_S1AP_DOWNLINK_NAS( - MessageDef* msg_p, - const char* msg_name, + MessageDef *msg_p, + const char *msg_name, instance_t instance, - mui_t* rrc_eNB_mui + mui_t *rrc_eNB_mui ) //------------------------------------------------------------------------------ { @@ -956,14 +868,12 @@ rrc_eNB_process_S1AP_DOWNLINK_NAS( uint32_t eNB_ue_s1ap_id; uint32_t length; uint8_t *buffer; - uint8_t srb_id; - - struct rrc_eNB_ue_context_s* ue_context_p = NULL; + uint8_t srb_id; + struct rrc_eNB_ue_context_s *ue_context_p = NULL; protocol_ctxt_t ctxt; ue_initial_id = S1AP_DOWNLINK_NAS (msg_p).ue_initial_id; eNB_ue_s1ap_id = S1AP_DOWNLINK_NAS (msg_p).eNB_ue_s1ap_id; ue_context_p = rrc_eNB_get_ue_context_from_s1ap_ids(instance, ue_initial_id, eNB_ue_s1ap_id); - LOG_I(RRC, "[eNB %d] Received %s: ue_initial_id %d, eNB_ue_s1ap_id %d\n", instance, msg_name, @@ -971,7 +881,6 @@ rrc_eNB_process_S1AP_DOWNLINK_NAS( eNB_ue_s1ap_id); if (ue_context_p == NULL) { - MSC_LOG_RX_MESSAGE( MSC_RRC_ENB, MSC_S1AP_ENB, @@ -981,20 +890,14 @@ rrc_eNB_process_S1AP_DOWNLINK_NAS( 0,0,//MSC_AS_TIME_ARGS(ctxt_pP), ue_initial_id, eNB_ue_s1ap_id); - /* Can not associate this message to an UE index, send a failure to S1AP and discard it! */ MessageDef *msg_fail_p; - LOG_W(RRC, "[eNB %d] In S1AP_DOWNLINK_NAS: unknown UE from S1AP ids (%d, %d)\n", instance, ue_initial_id, eNB_ue_s1ap_id); - msg_fail_p = itti_alloc_new_message (TASK_RRC_ENB, S1AP_NAS_NON_DELIVERY_IND); S1AP_NAS_NON_DELIVERY_IND (msg_fail_p).eNB_ue_s1ap_id = eNB_ue_s1ap_id; S1AP_NAS_NON_DELIVERY_IND (msg_fail_p).nas_pdu.length = S1AP_DOWNLINK_NAS (msg_p).nas_pdu.length; S1AP_NAS_NON_DELIVERY_IND (msg_fail_p).nas_pdu.buffer = S1AP_DOWNLINK_NAS (msg_p).nas_pdu.buffer; - // TODO add failure cause when defined! - - MSC_LOG_TX_MESSAGE( MSC_RRC_ENB, MSC_S1AP_ENB, @@ -1004,14 +907,11 @@ rrc_eNB_process_S1AP_DOWNLINK_NAS( 0,0,//MSC_AS_TIME_ARGS(ctxt_pP), ue_initial_id, eNB_ue_s1ap_id); - itti_send_msg_to_task (TASK_S1AP, instance, msg_fail_p); return (-1); } else { PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt, instance, ENB_FLAG_YES, ue_context_p->ue_context.rnti, 0, 0); - srb_id = ue_context_p->ue_context.Srb2.Srb_info.Srb_id; - /* Is it the first income from S1AP ? */ if (ue_context_p->ue_context.eNB_ue_s1ap_id == 0) { @@ -1027,8 +927,6 @@ rrc_eNB_process_S1AP_DOWNLINK_NAS( 0,0,//MSC_AS_TIME_ARGS(ctxt_pP), ue_initial_id, S1AP_DOWNLINK_NAS (msg_p).eNB_ue_s1ap_id); - - /* Create message for PDCP (DLInformationTransfer_t) */ length = do_DLInformationTransfer ( instance, @@ -1036,37 +934,32 @@ rrc_eNB_process_S1AP_DOWNLINK_NAS( rrc_eNB_get_next_transaction_identifier (instance), S1AP_DOWNLINK_NAS (msg_p).nas_pdu.length, S1AP_DOWNLINK_NAS (msg_p).nas_pdu.buffer); - LOG_DUMPMSG(RRC,DEBUG_RRC,buffer,length,"[MSG] RRC DL Information Transfer\n"); - - /* - * switch UL or DL NAS message without RRC piggybacked to SRB2 if active. + /* + * switch UL or DL NAS message without RRC piggybacked to SRB2 if active. */ /* Transfer data to PDCP */ rrc_data_req ( - &ctxt, - srb_id, - *rrc_eNB_mui++, - SDU_CONFIRM_NO, - length, - buffer, - PDCP_TRANSMISSION_MODE_CONTROL); - + &ctxt, + srb_id, + *rrc_eNB_mui++, + SDU_CONFIRM_NO, + length, + buffer, + PDCP_TRANSMISSION_MODE_CONTROL); return (0); } } /*------------------------------------------------------------------------------*/ -int rrc_eNB_process_S1AP_INITIAL_CONTEXT_SETUP_REQ(MessageDef *msg_p, const char *msg_name, instance_t instance) -{ +int rrc_eNB_process_S1AP_INITIAL_CONTEXT_SETUP_REQ(MessageDef *msg_p, const char *msg_name, instance_t instance) { uint16_t ue_initial_id; uint32_t eNB_ue_s1ap_id; //MessageDef *message_gtpv1u_p = NULL; gtpv1u_enb_create_tunnel_req_t create_tunnel_req; gtpv1u_enb_create_tunnel_resp_t create_tunnel_resp; - uint8_t inde_list[NB_RB_MAX - 3]={0}; - - struct rrc_eNB_ue_context_s* ue_context_p = NULL; + uint8_t inde_list[NB_RB_MAX - 3]= {0}; + struct rrc_eNB_ue_context_s *ue_context_p = NULL; protocol_ctxt_t ctxt; ue_initial_id = S1AP_INITIAL_CONTEXT_SETUP_REQ (msg_p).ue_initial_id; eNB_ue_s1ap_id = S1AP_INITIAL_CONTEXT_SETUP_REQ (msg_p).eNB_ue_s1ap_id; @@ -1077,63 +970,49 @@ int rrc_eNB_process_S1AP_INITIAL_CONTEXT_SETUP_REQ(MessageDef *msg_p, const char if (ue_context_p == NULL) { /* Can not associate this message to an UE index, send a failure to S1AP and discard it! */ MessageDef *msg_fail_p = NULL; - LOG_W(RRC, "[eNB %d] In S1AP_INITIAL_CONTEXT_SETUP_REQ: unknown UE from S1AP ids (%d, %d)\n", instance, ue_initial_id, eNB_ue_s1ap_id); - msg_fail_p = itti_alloc_new_message (TASK_RRC_ENB, S1AP_INITIAL_CONTEXT_SETUP_FAIL); S1AP_INITIAL_CONTEXT_SETUP_FAIL (msg_fail_p).eNB_ue_s1ap_id = eNB_ue_s1ap_id; - // TODO add failure cause when defined! - itti_send_msg_to_task (TASK_S1AP, instance, msg_fail_p); return (-1); } else { - PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt, instance, ENB_FLAG_YES, ue_context_p->ue_context.rnti, 0, 0); ue_context_p->ue_context.eNB_ue_s1ap_id = S1AP_INITIAL_CONTEXT_SETUP_REQ (msg_p).eNB_ue_s1ap_id; - /* Save e RAB information for later */ { int i; - - memset(&create_tunnel_req, 0 , sizeof(create_tunnel_req)); + memset(&create_tunnel_req, 0, sizeof(create_tunnel_req)); ue_context_p->ue_context.nb_of_e_rabs = S1AP_INITIAL_CONTEXT_SETUP_REQ (msg_p).nb_of_e_rabs; - + for (i = 0; i < ue_context_p->ue_context.nb_of_e_rabs; i++) { ue_context_p->ue_context.e_rab[i].status = E_RAB_STATUS_NEW; ue_context_p->ue_context.e_rab[i].param = S1AP_INITIAL_CONTEXT_SETUP_REQ (msg_p).e_rab_param[i]; - - create_tunnel_req.eps_bearer_id[i] = S1AP_INITIAL_CONTEXT_SETUP_REQ (msg_p).e_rab_param[i].e_rab_id; create_tunnel_req.sgw_S1u_teid[i] = S1AP_INITIAL_CONTEXT_SETUP_REQ (msg_p).e_rab_param[i].gtp_teid; - memcpy(&create_tunnel_req.sgw_addr[i], &S1AP_INITIAL_CONTEXT_SETUP_REQ (msg_p).e_rab_param[i].sgw_addr, sizeof(transport_layer_addr_t)); inde_list[create_tunnel_req.num_tunnels]= i; create_tunnel_req.num_tunnels++; } - - create_tunnel_req.rnti = ue_context_p->ue_context.rnti; // warning put zero above -// create_tunnel_req.num_tunnels = i; + create_tunnel_req.rnti = ue_context_p->ue_context.rnti; // warning put zero above + // create_tunnel_req.num_tunnels = i; gtpv1u_create_s1u_tunnel( instance, &create_tunnel_req, &create_tunnel_resp); - rrc_eNB_process_GTPV1U_CREATE_TUNNEL_RESP( - &ctxt, - &create_tunnel_resp, - &inde_list[0]); + &ctxt, + &create_tunnel_resp, + &inde_list[0]); ue_context_p->ue_context.setup_e_rabs=ue_context_p->ue_context.nb_of_e_rabs; } - /* TODO parameters yet to process ... */ { // S1AP_INITIAL_CONTEXT_SETUP_REQ(msg_p).ue_ambr; } - rrc_eNB_process_security ( &ctxt, ue_context_p, @@ -1142,10 +1021,8 @@ int rrc_eNB_process_S1AP_INITIAL_CONTEXT_SETUP_REQ(MessageDef *msg_p, const char &ctxt, ue_context_p, S1AP_INITIAL_CONTEXT_SETUP_REQ(msg_p).security_key); - { uint8_t send_security_mode_command = TRUE; - #ifndef EXMIMO_IOT if ((ue_context_p->ue_context.ciphering_algorithm == SecurityAlgorithmConfig__cipheringAlgorithm_eea0) @@ -1160,7 +1037,6 @@ int rrc_eNB_process_S1AP_INITIAL_CONTEXT_SETUP_REQ(MessageDef *msg_p, const char send_security_mode_command); if (send_security_mode_command) { - rrc_eNB_generate_SecurityModeCommand ( &ctxt, ue_context_p); @@ -1179,30 +1055,23 @@ int rrc_eNB_process_S1AP_INITIAL_CONTEXT_SETUP_REQ(MessageDef *msg_p, const char } /*------------------------------------------------------------------------------*/ -int rrc_eNB_process_S1AP_UE_CTXT_MODIFICATION_REQ(MessageDef *msg_p, const char *msg_name, instance_t instance) -{ +int rrc_eNB_process_S1AP_UE_CTXT_MODIFICATION_REQ(MessageDef *msg_p, const char *msg_name, instance_t instance) { uint32_t eNB_ue_s1ap_id; - struct rrc_eNB_ue_context_s* ue_context_p = NULL; + struct rrc_eNB_ue_context_s *ue_context_p = NULL; protocol_ctxt_t ctxt; - eNB_ue_s1ap_id = S1AP_UE_CTXT_MODIFICATION_REQ (msg_p).eNB_ue_s1ap_id; ue_context_p = rrc_eNB_get_ue_context_from_s1ap_ids(instance, UE_INITIAL_ID_INVALID, eNB_ue_s1ap_id); if (ue_context_p == NULL) { /* Can not associate this message to an UE index, send a failure to S1AP and discard it! */ MessageDef *msg_fail_p; - LOG_W(RRC, "[eNB %d] In S1AP_UE_CTXT_MODIFICATION_REQ: unknown UE from eNB_ue_s1ap_id (%d)\n", instance, eNB_ue_s1ap_id); - msg_fail_p = itti_alloc_new_message (TASK_RRC_ENB, S1AP_UE_CTXT_MODIFICATION_FAIL); S1AP_UE_CTXT_MODIFICATION_FAIL (msg_fail_p).eNB_ue_s1ap_id = eNB_ue_s1ap_id; - // TODO add failure cause when defined! - itti_send_msg_to_task (TASK_S1AP, instance, msg_fail_p); return (-1); } else { - PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt, instance, ENB_FLAG_YES, ue_context_p->ue_context.rnti, 0, 0); /* TODO parameters yet to process ... */ { @@ -1228,61 +1097,47 @@ int rrc_eNB_process_S1AP_UE_CTXT_MODIFICATION_REQ(MessageDef *msg_p, const char &ctxt, ue_context_p, S1AP_UE_CTXT_MODIFICATION_REQ(msg_p).security_key); - /* TODO reconfigure lower layers... */ } /* Send the response */ { MessageDef *msg_resp_p; - msg_resp_p = itti_alloc_new_message(TASK_RRC_ENB, S1AP_UE_CTXT_MODIFICATION_RESP); S1AP_UE_CTXT_MODIFICATION_RESP(msg_resp_p).eNB_ue_s1ap_id = eNB_ue_s1ap_id; - itti_send_msg_to_task(TASK_S1AP, instance, msg_resp_p); } - return (0); } } /*------------------------------------------------------------------------------*/ -int rrc_eNB_process_S1AP_UE_CONTEXT_RELEASE_REQ (MessageDef *msg_p, const char *msg_name, instance_t instance) -{ +int rrc_eNB_process_S1AP_UE_CONTEXT_RELEASE_REQ (MessageDef *msg_p, const char *msg_name, instance_t instance) { uint32_t eNB_ue_s1ap_id; - struct rrc_eNB_ue_context_s* ue_context_p = NULL; - + struct rrc_eNB_ue_context_s *ue_context_p = NULL; eNB_ue_s1ap_id = S1AP_UE_CONTEXT_RELEASE_REQ(msg_p).eNB_ue_s1ap_id; ue_context_p = rrc_eNB_get_ue_context_from_s1ap_ids(instance, UE_INITIAL_ID_INVALID, eNB_ue_s1ap_id); if (ue_context_p == NULL) { /* Can not associate this message to an UE index, send a failure to S1AP and discard it! */ MessageDef *msg_fail_p; - LOG_W(RRC, "[eNB %d] In S1AP_UE_CONTEXT_RELEASE_REQ: unknown UE from eNB_ue_s1ap_id (%d)\n", instance, eNB_ue_s1ap_id); - msg_fail_p = itti_alloc_new_message(TASK_RRC_ENB, S1AP_UE_CONTEXT_RELEASE_RESP); /* TODO change message ID. */ S1AP_UE_CONTEXT_RELEASE_RESP(msg_fail_p).eNB_ue_s1ap_id = eNB_ue_s1ap_id; - // TODO add failure cause when defined! - itti_send_msg_to_task(TASK_S1AP, instance, msg_fail_p); return (-1); } else { /* TODO release context. */ - /* Send the response */ { MessageDef *msg_resp_p; - msg_resp_p = itti_alloc_new_message(TASK_RRC_ENB, S1AP_UE_CONTEXT_RELEASE_RESP); S1AP_UE_CONTEXT_RELEASE_RESP(msg_resp_p).eNB_ue_s1ap_id = eNB_ue_s1ap_id; - itti_send_msg_to_task(TASK_S1AP, instance, msg_resp_p); } - return (0); } } @@ -1291,7 +1146,7 @@ int rrc_eNB_process_S1AP_UE_CONTEXT_RELEASE_REQ (MessageDef *msg_p, const char * /* * Send the S1 command UE_CONTEXT_RELEASE_REQUEST to the MME. */ -void +void rrc_eNB_send_S1AP_UE_CONTEXT_RELEASE_REQ( const module_id_t enb_mod_idP, const rrc_eNB_ue_context_t *const ue_context_pP, @@ -1302,20 +1157,17 @@ rrc_eNB_send_S1AP_UE_CONTEXT_RELEASE_REQ( if (ue_context_pP == NULL) { LOG_E(RRC, "[eNB] In S1AP_UE_CONTEXT_RELEASE_REQ: invalid UE\n"); } else { - MSC_LOG_TX_MESSAGE(MSC_RRC_ENB, - MSC_S1AP_ENB, - NULL, - 0, - "0 S1AP_UE_CONTEXT_RELEASE_REQ eNB_ue_s1ap_id 0x%06"PRIX32" ", - ue_context_pP->ue_context.eNB_ue_s1ap_id); - + MSC_LOG_TX_MESSAGE(MSC_RRC_ENB, + MSC_S1AP_ENB, + NULL, + 0, + "0 S1AP_UE_CONTEXT_RELEASE_REQ eNB_ue_s1ap_id 0x%06"PRIX32" ", + ue_context_pP->ue_context.eNB_ue_s1ap_id); MessageDef *msg_context_release_req_p = NULL; msg_context_release_req_p = itti_alloc_new_message(TASK_RRC_ENB, S1AP_UE_CONTEXT_RELEASE_REQ); - S1AP_UE_CONTEXT_RELEASE_REQ(msg_context_release_req_p).eNB_ue_s1ap_id = ue_context_pP->ue_context.eNB_ue_s1ap_id; S1AP_UE_CONTEXT_RELEASE_REQ(msg_context_release_req_p).cause = causeP; S1AP_UE_CONTEXT_RELEASE_REQ(msg_context_release_req_p).cause_value = cause_valueP; - itti_send_msg_to_task(TASK_S1AP, ENB_MODULE_ID_TO_INSTANCE(enb_mod_idP), msg_context_release_req_p); } } @@ -1326,44 +1178,36 @@ rrc_eNB_send_S1AP_UE_CONTEXT_RELEASE_REQ( * Process the S1 command UE_CONTEXT_RELEASE_COMMAND, sent by MME. * The eNB should remove all e-rab, S1 context, and other context of the UE. */ -int +int rrc_eNB_process_S1AP_UE_CONTEXT_RELEASE_COMMAND( - MessageDef *msg_p, - const char *msg_name, - instance_t instance) -{ -//----------------------------------------------------------------------------- + MessageDef *msg_p, + const char *msg_name, + instance_t instance) { + //----------------------------------------------------------------------------- uint32_t eNB_ue_s1ap_id = 0; protocol_ctxt_t ctxt; struct rrc_eNB_ue_context_s *ue_context_p = NULL; struct rrc_ue_s1ap_ids_s *rrc_ue_s1ap_ids = NULL; - eNB_ue_s1ap_id = S1AP_UE_CONTEXT_RELEASE_COMMAND(msg_p).eNB_ue_s1ap_id; - ue_context_p = rrc_eNB_get_ue_context_from_s1ap_ids(instance, UE_INITIAL_ID_INVALID, eNB_ue_s1ap_id); - + if (ue_context_p == NULL) { /* Can not associate this message to an UE index */ MessageDef *msg_complete_p = NULL; - LOG_W(RRC, "[eNB %d] In S1AP_UE_CONTEXT_RELEASE_COMMAND: unknown UE from eNB_ue_s1ap_id (%d)\n", - instance, - eNB_ue_s1ap_id); - + instance, + eNB_ue_s1ap_id); MSC_LOG_EVENT(MSC_RRC_ENB, "0 S1AP_UE_CONTEXT_RELEASE_COMPLETE eNB_ue_s1ap_id 0x%06"PRIX32" context not found", - eNB_ue_s1ap_id); - + eNB_ue_s1ap_id); MSC_LOG_TX_MESSAGE(MSC_RRC_ENB, - MSC_S1AP_ENB, - NULL, - 0, - "0 S1AP_UE_CONTEXT_RELEASE_COMPLETE eNB_ue_s1ap_id 0x%06"PRIX32" ", - eNB_ue_s1ap_id); - + MSC_S1AP_ENB, + NULL, + 0, + "0 S1AP_UE_CONTEXT_RELEASE_COMPLETE eNB_ue_s1ap_id 0x%06"PRIX32" ", + eNB_ue_s1ap_id); msg_complete_p = itti_alloc_new_message(TASK_RRC_ENB, S1AP_UE_CONTEXT_RELEASE_COMPLETE); S1AP_UE_CONTEXT_RELEASE_COMPLETE(msg_complete_p).eNB_ue_s1ap_id = eNB_ue_s1ap_id; itti_send_msg_to_task(TASK_S1AP, instance, msg_complete_p); - rrc_ue_s1ap_ids = rrc_eNB_S1AP_get_ue_ids(RC.rrc[instance], UE_INITIAL_ID_INVALID, eNB_ue_s1ap_id); if (rrc_ue_s1ap_ids != NULL) { @@ -1371,30 +1215,23 @@ rrc_eNB_process_S1AP_UE_CONTEXT_RELEASE_COMMAND( } return -1; - } else { ue_context_p->ue_context.ue_release_timer_s1 = 0; - PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt, instance, ENB_FLAG_YES, ue_context_p->ue_context.rnti, 0, 0); - rrc_eNB_generate_RRCConnectionRelease(&ctxt, ue_context_p); - return 0; } } -int rrc_eNB_process_S1AP_E_RAB_SETUP_REQ(MessageDef *msg_p, const char *msg_name, instance_t instance) -{ +int rrc_eNB_process_S1AP_E_RAB_SETUP_REQ(MessageDef *msg_p, const char *msg_name, instance_t instance) { uint16_t ue_initial_id; uint32_t eNB_ue_s1ap_id; gtpv1u_enb_create_tunnel_req_t create_tunnel_req; gtpv1u_enb_create_tunnel_resp_t create_tunnel_resp; - uint8_t inde_list[NB_RB_MAX - 3]={0}; - - struct rrc_eNB_ue_context_s* ue_context_p = NULL; + uint8_t inde_list[NB_RB_MAX - 3]= {0}; + struct rrc_eNB_ue_context_s *ue_context_p = NULL; protocol_ctxt_t ctxt; uint8_t e_rab_done; - ue_initial_id = S1AP_E_RAB_SETUP_REQ (msg_p).ue_initial_id; eNB_ue_s1ap_id = S1AP_E_RAB_SETUP_REQ (msg_p).eNB_ue_s1ap_id; ue_context_p = rrc_eNB_get_ue_context_from_s1ap_ids(instance, ue_initial_id, eNB_ue_s1ap_id); @@ -1404,185 +1241,159 @@ int rrc_eNB_process_S1AP_E_RAB_SETUP_REQ(MessageDef *msg_p, const char *msg_name if (ue_context_p == NULL) { /* Can not associate this message to an UE index, send a failure to S1AP and discard it! */ MessageDef *msg_fail_p = NULL; - LOG_W(RRC, "[eNB %d] In S1AP_E_RAB_SETUP_REQ: unknown UE from S1AP ids (%d, %d)\n", instance, ue_initial_id, eNB_ue_s1ap_id); - msg_fail_p = itti_alloc_new_message (TASK_RRC_ENB, S1AP_E_RAB_SETUP_REQUEST_FAIL); S1AP_E_RAB_SETUP_REQ (msg_fail_p).eNB_ue_s1ap_id = eNB_ue_s1ap_id; - // TODO add failure cause when defined! - itti_send_msg_to_task (TASK_S1AP, instance, msg_fail_p); return (-1); } else { - PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt, instance, ENB_FLAG_YES, ue_context_p->ue_context.rnti, 0, 0); ue_context_p->ue_context.eNB_ue_s1ap_id = S1AP_E_RAB_SETUP_REQ (msg_p).eNB_ue_s1ap_id; - /* Save e RAB information for later */ { int i; - - memset(&create_tunnel_req, 0 , sizeof(create_tunnel_req)); + memset(&create_tunnel_req, 0, sizeof(create_tunnel_req)); uint8_t nb_e_rabs_tosetup = S1AP_E_RAB_SETUP_REQ (msg_p).nb_e_rabs_tosetup; e_rab_done = 0; // keep the previous bearer // the index for the rec - for (i = 0; - // i < nb_e_rabs_tosetup; - i < NB_RB_MAX - 3; // loop all e-rabs in e_rab[] - i++) { - //if (ue_context_p->ue_context.e_rab[i+ue_context_p->ue_context.setup_e_rabs].status == E_RAB_STATUS_DONE) - // LOG_W(RRC,"E-RAB already configured, reconfiguring\n"); + for (i = 0; + // i < nb_e_rabs_tosetup; + i < NB_RB_MAX - 3; // loop all e-rabs in e_rab[] + i++) { + //if (ue_context_p->ue_context.e_rab[i+ue_context_p->ue_context.setup_e_rabs].status == E_RAB_STATUS_DONE) + // LOG_W(RRC,"E-RAB already configured, reconfiguring\n"); // check e-rab status, if e rab status is greater than E_RAB_STATUS_DONE, don't not config this one if(ue_context_p->ue_context.e_rab[i].status >= E_RAB_STATUS_DONE) - continue; + continue; + //ue_context_p->ue_context.e_rab[i+ue_context_p->ue_context.setup_e_rabs].status = E_RAB_STATUS_NEW; //ue_context_p->ue_context.e_rab[i+ue_context_p->ue_context.setup_e_rabs].param = S1AP_E_RAB_SETUP_REQ (msg_p).e_rab_setup_params[i]; ue_context_p->ue_context.e_rab[i].status = E_RAB_STATUS_NEW; ue_context_p->ue_context.e_rab[i].param = S1AP_E_RAB_SETUP_REQ (msg_p).e_rab_setup_params[e_rab_done]; - create_tunnel_req.eps_bearer_id[e_rab_done] = S1AP_E_RAB_SETUP_REQ (msg_p).e_rab_setup_params[e_rab_done].e_rab_id; create_tunnel_req.sgw_S1u_teid[e_rab_done] = S1AP_E_RAB_SETUP_REQ (msg_p).e_rab_setup_params[e_rab_done].gtp_teid; - memcpy(&create_tunnel_req.sgw_addr[e_rab_done], & S1AP_E_RAB_SETUP_REQ (msg_p).e_rab_setup_params[e_rab_done].sgw_addr, sizeof(transport_layer_addr_t)); - - LOG_I(RRC,"E_RAB setup REQ: local index %d teid %u, eps id %d \n", - i, - create_tunnel_req.sgw_S1u_teid[e_rab_done], - create_tunnel_req.eps_bearer_id[i] ); + LOG_I(RRC,"E_RAB setup REQ: local index %d teid %u, eps id %d \n", + i, + create_tunnel_req.sgw_S1u_teid[e_rab_done], + create_tunnel_req.eps_bearer_id[i] ); inde_list[e_rab_done] = i; - e_rab_done++; - if(e_rab_done >= nb_e_rabs_tosetup){ - break; + e_rab_done++; + + if(e_rab_done >= nb_e_rabs_tosetup) { + break; } } + ue_context_p->ue_context.nb_of_e_rabs=nb_e_rabs_tosetup; - - create_tunnel_req.rnti = ue_context_p->ue_context.rnti; // warning put zero above create_tunnel_req.num_tunnels = e_rab_done; - // NN: not sure if we should create a new tunnel: need to check teid, etc. gtpv1u_create_s1u_tunnel( instance, &create_tunnel_req, &create_tunnel_resp); - rrc_eNB_process_GTPV1U_CREATE_TUNNEL_RESP( - &ctxt, - &create_tunnel_resp, - &inde_list[0]); - + &ctxt, + &create_tunnel_resp, + &inde_list[0]); ue_context_p->ue_context.setup_e_rabs+=nb_e_rabs_tosetup; - } - /* TODO parameters yet to process ... */ { // S1AP_INITIAL_CONTEXT_SETUP_REQ(msg_p).ue_ambr; } - rrc_eNB_generate_dedicatedRRCConnectionReconfiguration(&ctxt, ue_context_p, 0); - return (0); } } /*NN: careful about the typcast of xid (long -> uint8_t*/ -int rrc_eNB_send_S1AP_E_RAB_SETUP_RESP(const protocol_ctxt_t* const ctxt_pP, - rrc_eNB_ue_context_t* const ue_context_pP, - uint8_t xid ){ - +int rrc_eNB_send_S1AP_E_RAB_SETUP_RESP(const protocol_ctxt_t *const ctxt_pP, + rrc_eNB_ue_context_t *const ue_context_pP, + uint8_t xid ) { MessageDef *msg_p = NULL; int e_rab; int e_rabs_done = 0; int e_rabs_failed = 0; - msg_p = itti_alloc_new_message (TASK_RRC_ENB, S1AP_E_RAB_SETUP_RESP); S1AP_E_RAB_SETUP_RESP (msg_p).eNB_ue_s1ap_id = ue_context_pP->ue_context.eNB_ue_s1ap_id; - - for (e_rab = 0; e_rab < ue_context_pP->ue_context.setup_e_rabs ; e_rab++) { - /* only respond to the corresponding transaction */ + for (e_rab = 0; e_rab < ue_context_pP->ue_context.setup_e_rabs ; e_rab++) { + /* only respond to the corresponding transaction */ //if (((xid+1)%4) == ue_context_pP->ue_context.e_rab[e_rab].xid) { if (xid == ue_context_pP->ue_context.e_rab[e_rab].xid) { - if (ue_context_pP->ue_context.e_rab[e_rab].status == E_RAB_STATUS_DONE) { - - S1AP_E_RAB_SETUP_RESP (msg_p).e_rabs[e_rabs_done].e_rab_id = ue_context_pP->ue_context.e_rab[e_rab].param.e_rab_id; - // TODO add other information from S1-U when it will be integrated - S1AP_E_RAB_SETUP_RESP (msg_p).e_rabs[e_rabs_done].gtp_teid = ue_context_pP->ue_context.enb_gtp_teid[e_rab]; - S1AP_E_RAB_SETUP_RESP (msg_p).e_rabs[e_rabs_done].eNB_addr = ue_context_pP->ue_context.enb_gtp_addrs[e_rab]; - //S1AP_E_RAB_SETUP_RESP (msg_p).e_rabs[e_rab].eNB_addr.length += 4; - ue_context_pP->ue_context.e_rab[e_rab].status = E_RAB_STATUS_ESTABLISHED; - - LOG_I (RRC,"enb_gtp_addr (msg index %d, e_rab index %d, status %d, xid %d): nb_of_e_rabs %d, e_rab_id %d, teid: %u, addr: %d.%d.%d.%d \n ", - e_rabs_done, e_rab, ue_context_pP->ue_context.e_rab[e_rab].status, xid, - ue_context_pP->ue_context.nb_of_e_rabs, - S1AP_E_RAB_SETUP_RESP (msg_p).e_rabs[e_rabs_done].e_rab_id, - S1AP_E_RAB_SETUP_RESP (msg_p).e_rabs[e_rabs_done].gtp_teid, - S1AP_E_RAB_SETUP_RESP (msg_p).e_rabs[e_rabs_done].eNB_addr.buffer[0], - S1AP_E_RAB_SETUP_RESP (msg_p).e_rabs[e_rabs_done].eNB_addr.buffer[1], - S1AP_E_RAB_SETUP_RESP (msg_p).e_rabs[e_rabs_done].eNB_addr.buffer[2], - S1AP_E_RAB_SETUP_RESP (msg_p).e_rabs[e_rabs_done].eNB_addr.buffer[3]); - - e_rabs_done++; - } else if ((ue_context_pP->ue_context.e_rab[e_rab].status == E_RAB_STATUS_NEW) || - (ue_context_pP->ue_context.e_rab[e_rab].status == E_RAB_STATUS_ESTABLISHED)){ - LOG_D (RRC,"E-RAB is NEW or already ESTABLISHED\n"); - }else { /* to be improved */ - ue_context_pP->ue_context.e_rab[e_rab].status = E_RAB_STATUS_FAILED; - S1AP_E_RAB_SETUP_RESP (msg_p).e_rabs_failed[e_rabs_failed].e_rab_id = ue_context_pP->ue_context.e_rab[e_rab].param.e_rab_id; - e_rabs_failed++; - // TODO add cause when it will be integrated - } - + S1AP_E_RAB_SETUP_RESP (msg_p).e_rabs[e_rabs_done].e_rab_id = ue_context_pP->ue_context.e_rab[e_rab].param.e_rab_id; + // TODO add other information from S1-U when it will be integrated + S1AP_E_RAB_SETUP_RESP (msg_p).e_rabs[e_rabs_done].gtp_teid = ue_context_pP->ue_context.enb_gtp_teid[e_rab]; + S1AP_E_RAB_SETUP_RESP (msg_p).e_rabs[e_rabs_done].eNB_addr = ue_context_pP->ue_context.enb_gtp_addrs[e_rab]; + //S1AP_E_RAB_SETUP_RESP (msg_p).e_rabs[e_rab].eNB_addr.length += 4; + ue_context_pP->ue_context.e_rab[e_rab].status = E_RAB_STATUS_ESTABLISHED; + LOG_I (RRC,"enb_gtp_addr (msg index %d, e_rab index %d, status %d, xid %d): nb_of_e_rabs %d, e_rab_id %d, teid: %u, addr: %d.%d.%d.%d \n ", + e_rabs_done, e_rab, ue_context_pP->ue_context.e_rab[e_rab].status, xid, + ue_context_pP->ue_context.nb_of_e_rabs, + S1AP_E_RAB_SETUP_RESP (msg_p).e_rabs[e_rabs_done].e_rab_id, + S1AP_E_RAB_SETUP_RESP (msg_p).e_rabs[e_rabs_done].gtp_teid, + S1AP_E_RAB_SETUP_RESP (msg_p).e_rabs[e_rabs_done].eNB_addr.buffer[0], + S1AP_E_RAB_SETUP_RESP (msg_p).e_rabs[e_rabs_done].eNB_addr.buffer[1], + S1AP_E_RAB_SETUP_RESP (msg_p).e_rabs[e_rabs_done].eNB_addr.buffer[2], + S1AP_E_RAB_SETUP_RESP (msg_p).e_rabs[e_rabs_done].eNB_addr.buffer[3]); + e_rabs_done++; + } else if ((ue_context_pP->ue_context.e_rab[e_rab].status == E_RAB_STATUS_NEW) || + (ue_context_pP->ue_context.e_rab[e_rab].status == E_RAB_STATUS_ESTABLISHED)) { + LOG_D (RRC,"E-RAB is NEW or already ESTABLISHED\n"); + } else { /* to be improved */ + ue_context_pP->ue_context.e_rab[e_rab].status = E_RAB_STATUS_FAILED; + S1AP_E_RAB_SETUP_RESP (msg_p).e_rabs_failed[e_rabs_failed].e_rab_id = ue_context_pP->ue_context.e_rab[e_rab].param.e_rab_id; + e_rabs_failed++; + // TODO add cause when it will be integrated + } + S1AP_E_RAB_SETUP_RESP (msg_p).nb_of_e_rabs = e_rabs_done; S1AP_E_RAB_SETUP_RESP (msg_p).nb_of_e_rabs_failed = e_rabs_failed; - // NN: add conditions for e_rabs_failed + // NN: add conditions for e_rabs_failed } else { - /*debug info for the xid */ + /*debug info for the xid */ LOG_D(RRC,"xid does not corresponds (context e_rab index %d, status %d, xid %d/%d) \n ", - e_rab, ue_context_pP->ue_context.e_rab[e_rab].status, xid, ue_context_pP->ue_context.e_rab[e_rab].xid); - } + e_rab, ue_context_pP->ue_context.e_rab[e_rab].status, xid, ue_context_pP->ue_context.e_rab[e_rab].xid); + } } - if ((e_rabs_done > 0) ){ - LOG_I(RRC,"S1AP_E_RAB_SETUP_RESP: sending the message: nb_of_erabs %d, total e_rabs %d, index %d\n", - ue_context_pP->ue_context.nb_of_e_rabs, ue_context_pP->ue_context.setup_e_rabs, e_rab); - MSC_LOG_TX_MESSAGE( - MSC_RRC_ENB, - MSC_S1AP_ENB, - (const char *)&S1AP_E_RAB_SETUP_RESP (msg_p), - sizeof(s1ap_e_rab_setup_resp_t), - MSC_AS_TIME_FMT" E_RAB_SETUP_RESP UE %X eNB_ue_s1ap_id %u e_rabs:%u succ %u fail", - MSC_AS_TIME_ARGS(ctxt_pP), - ue_context_pP->ue_id_rnti, - S1AP_E_RAB_SETUP_RESP (msg_p).eNB_ue_s1ap_id, - e_rabs_done, e_rabs_failed); - - - itti_send_msg_to_task (TASK_S1AP, ctxt_pP->instance, msg_p); - } - for(int i = 0; i < NB_RB_MAX; i++) { - ue_context_pP->ue_context.e_rab[i].xid = -1; + if ((e_rabs_done > 0) ) { + LOG_I(RRC,"S1AP_E_RAB_SETUP_RESP: sending the message: nb_of_erabs %d, total e_rabs %d, index %d\n", + ue_context_pP->ue_context.nb_of_e_rabs, ue_context_pP->ue_context.setup_e_rabs, e_rab); + MSC_LOG_TX_MESSAGE( + MSC_RRC_ENB, + MSC_S1AP_ENB, + (const char *)&S1AP_E_RAB_SETUP_RESP (msg_p), + sizeof(s1ap_e_rab_setup_resp_t), + MSC_AS_TIME_FMT" E_RAB_SETUP_RESP UE %X eNB_ue_s1ap_id %u e_rabs:%u succ %u fail", + MSC_AS_TIME_ARGS(ctxt_pP), + ue_context_pP->ue_id_rnti, + S1AP_E_RAB_SETUP_RESP (msg_p).eNB_ue_s1ap_id, + e_rabs_done, e_rabs_failed); + itti_send_msg_to_task (TASK_S1AP, ctxt_pP->instance, msg_p); } - + + for(int i = 0; i < NB_RB_MAX; i++) { + ue_context_pP->ue_context.e_rab[i].xid = -1; + } + return 0; } -int rrc_eNB_process_S1AP_E_RAB_MODIFY_REQ(MessageDef *msg_p, const char *msg_name, instance_t instance) -{ +int rrc_eNB_process_S1AP_E_RAB_MODIFY_REQ(MessageDef *msg_p, const char *msg_name, instance_t instance) { int i; uint16_t ue_initial_id; uint32_t eNB_ue_s1ap_id; - struct rrc_eNB_ue_context_s* ue_context_p = NULL; + struct rrc_eNB_ue_context_s *ue_context_p = NULL; protocol_ctxt_t ctxt; - ue_initial_id = S1AP_E_RAB_MODIFY_REQ (msg_p).ue_initial_id; eNB_ue_s1ap_id = S1AP_E_RAB_MODIFY_REQ (msg_p).eNB_ue_s1ap_id; ue_context_p = rrc_eNB_get_ue_context_from_s1ap_ids(instance, ue_initial_id, eNB_ue_s1ap_id); @@ -1594,27 +1405,23 @@ int rrc_eNB_process_S1AP_E_RAB_MODIFY_REQ(MessageDef *msg_p, const char *msg_nam LOG_W(RRC, "[eNB %d] In S1AP_E_RAB_MODIFY_REQ: unknown UE from S1AP ids (%d, %d)\n", instance, ue_initial_id, eNB_ue_s1ap_id); int nb_of_e_rabs_failed = 0; MessageDef *msg_fail_p = NULL; - msg_fail_p = itti_alloc_new_message (TASK_RRC_ENB, S1AP_E_RAB_MODIFY_RESP); - S1AP_E_RAB_MODIFY_RESP (msg_fail_p).eNB_ue_s1ap_id = S1AP_E_RAB_MODIFY_REQ (msg_p).eNB_ue_s1ap_id; S1AP_E_RAB_MODIFY_RESP (msg_fail_p).nb_of_e_rabs = 0; for (nb_of_e_rabs_failed = 0; nb_of_e_rabs_failed < S1AP_E_RAB_MODIFY_REQ (msg_p).nb_e_rabs_tomodify; nb_of_e_rabs_failed++) { S1AP_E_RAB_MODIFY_RESP (msg_fail_p).e_rabs_failed[nb_of_e_rabs_failed].e_rab_id = - S1AP_E_RAB_MODIFY_REQ (msg_p).e_rab_modify_params[nb_of_e_rabs_failed].e_rab_id; + S1AP_E_RAB_MODIFY_REQ (msg_p).e_rab_modify_params[nb_of_e_rabs_failed].e_rab_id; S1AP_E_RAB_MODIFY_RESP (msg_fail_p).e_rabs_failed[nb_of_e_rabs_failed].cause = S1AP_CAUSE_RADIO_NETWORK; S1AP_E_RAB_MODIFY_RESP (msg_fail_p).e_rabs_failed[nb_of_e_rabs_failed].cause_value = 31;//S1ap_CauseRadioNetwork_multiple_E_RAB_ID_instances; } - S1AP_E_RAB_MODIFY_RESP (msg_fail_p).nb_of_e_rabs_failed = nb_of_e_rabs_failed; + S1AP_E_RAB_MODIFY_RESP (msg_fail_p).nb_of_e_rabs_failed = nb_of_e_rabs_failed; itti_send_msg_to_task(TASK_S1AP, instance, msg_fail_p); return (-1); - } else { PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt, instance, ENB_FLAG_YES, ue_context_p->ue_context.rnti, 0, 0); ue_context_p->ue_context.eNB_ue_s1ap_id = eNB_ue_s1ap_id; - /* Save e RAB information for later */ { int j; @@ -1628,9 +1435,10 @@ int rrc_eNB_process_S1AP_E_RAB_MODIFY_REQ(MessageDef *msg_p, const char *msg_nam // already treated continue; } + for (j = i+1; j < S1AP_E_RAB_MODIFY_REQ (msg_p).nb_e_rabs_tomodify; j++) { if (is_treated[j] == FALSE && - S1AP_E_RAB_MODIFY_REQ(msg_p).e_rab_modify_params[j].e_rab_id == S1AP_E_RAB_MODIFY_REQ(msg_p).e_rab_modify_params[i].e_rab_id) { + S1AP_E_RAB_MODIFY_REQ(msg_p).e_rab_modify_params[j].e_rab_id == S1AP_E_RAB_MODIFY_REQ(msg_p).e_rab_modify_params[i].e_rab_id) { // handle multiple E-RAB ID ue_context_p->ue_context.modify_e_rab[j].status = E_RAB_STATUS_NEW; ue_context_p->ue_context.modify_e_rab[j].param.e_rab_id = S1AP_E_RAB_MODIFY_REQ(msg_p).e_rab_modify_params[j].e_rab_id; @@ -1641,6 +1449,7 @@ int rrc_eNB_process_S1AP_E_RAB_MODIFY_REQ(MessageDef *msg_p, const char *msg_nam is_treated[j] = TRUE; } } + if (is_treated[i] == TRUE) { // handle multiple E-RAB ID ue_context_p->ue_context.modify_e_rab[i].status = E_RAB_STATUS_NEW; @@ -1664,9 +1473,10 @@ int rrc_eNB_process_S1AP_E_RAB_MODIFY_REQ(MessageDef *msg_p, const char *msg_nam for (j = 0; j < NB_RB_MAX-3; j++) { if (ue_context_p->ue_context.e_rab[j].param.e_rab_id == S1AP_E_RAB_MODIFY_REQ(msg_p).e_rab_modify_params[i].e_rab_id) { - if(ue_context_p->ue_context.e_rab[j].status == E_RAB_STATUS_TORELEASE || ue_context_p->ue_context.e_rab[j].status == E_RAB_STATUS_DONE){ + if(ue_context_p->ue_context.e_rab[j].status == E_RAB_STATUS_TORELEASE || ue_context_p->ue_context.e_rab[j].status == E_RAB_STATUS_DONE) { break; } + ue_context_p->ue_context.modify_e_rab[i].status = E_RAB_STATUS_NEW; ue_context_p->ue_context.modify_e_rab[i].cause = S1AP_CAUSE_NOTHING; ue_context_p->ue_context.modify_e_rab[i].param.e_rab_id = S1AP_E_RAB_MODIFY_REQ(msg_p).e_rab_modify_params[i].e_rab_id; @@ -1675,7 +1485,6 @@ int rrc_eNB_process_S1AP_E_RAB_MODIFY_REQ(MessageDef *msg_p, const char *msg_nam ue_context_p->ue_context.modify_e_rab[i].param.nas_pdu.buffer = S1AP_E_RAB_MODIFY_REQ(msg_p).e_rab_modify_params[i].nas_pdu.buffer; ue_context_p->ue_context.modify_e_rab[i].param.sgw_addr = ue_context_p->ue_context.e_rab[j].param.sgw_addr; ue_context_p->ue_context.modify_e_rab[i].param.gtp_teid = ue_context_p->ue_context.e_rab[j].param.gtp_teid; - is_treated[i] = TRUE; break; } @@ -1695,7 +1504,6 @@ int rrc_eNB_process_S1AP_E_RAB_MODIFY_REQ(MessageDef *msg_p, const char *msg_nam ue_context_p->ue_context.nb_of_modify_e_rabs = S1AP_E_RAB_MODIFY_REQ (msg_p).nb_e_rabs_tomodify; ue_context_p->ue_context.nb_of_failed_e_rabs = nb_of_failed_e_rabs; } - /* TODO parameters yet to process ... */ { // S1AP_INITIAL_CONTEXT_SETUP_REQ(msg_p).ue_ambr; @@ -1710,36 +1518,31 @@ int rrc_eNB_process_S1AP_E_RAB_MODIFY_REQ(MessageDef *msg_p, const char *msg_nam { int nb_of_e_rabs_failed = 0; MessageDef *msg_fail_p = NULL; - msg_fail_p = itti_alloc_new_message (TASK_RRC_ENB, S1AP_E_RAB_MODIFY_RESP); - S1AP_E_RAB_MODIFY_RESP (msg_fail_p).eNB_ue_s1ap_id = S1AP_E_RAB_MODIFY_REQ (msg_p).eNB_ue_s1ap_id; -// S1AP_E_RAB_MODIFY_RESP (msg_fail_p).e_rabs[S1AP_MAX_E_RAB]; + // S1AP_E_RAB_MODIFY_RESP (msg_fail_p).e_rabs[S1AP_MAX_E_RAB]; S1AP_E_RAB_MODIFY_RESP (msg_fail_p).nb_of_e_rabs = 0; for(nb_of_e_rabs_failed = 0; nb_of_e_rabs_failed < ue_context_p->ue_context.nb_of_failed_e_rabs; nb_of_e_rabs_failed++) { S1AP_E_RAB_MODIFY_RESP (msg_fail_p).e_rabs_failed[nb_of_e_rabs_failed].e_rab_id = - ue_context_p->ue_context.modify_e_rab[nb_of_e_rabs_failed].param.e_rab_id; + ue_context_p->ue_context.modify_e_rab[nb_of_e_rabs_failed].param.e_rab_id; S1AP_E_RAB_MODIFY_RESP (msg_fail_p).e_rabs_failed[nb_of_e_rabs_failed].cause = ue_context_p->ue_context.modify_e_rab[nb_of_e_rabs_failed].cause; } + S1AP_E_RAB_MODIFY_RESP (msg_fail_p).nb_of_e_rabs_failed = nb_of_e_rabs_failed; - itti_send_msg_to_task (TASK_S1AP, instance, msg_fail_p); - ue_context_p->ue_context.nb_of_modify_e_rabs = 0; ue_context_p->ue_context.nb_of_failed_e_rabs = 0; memset(ue_context_p->ue_context.modify_e_rab, 0, sizeof(ue_context_p->ue_context.modify_e_rab)); - return (0); } } // end of ue_context_p != NULL } /*NN: careful about the typcast of xid (long -> uint8_t*/ -int rrc_eNB_send_S1AP_E_RAB_MODIFY_RESP(const protocol_ctxt_t* const ctxt_pP, - rrc_eNB_ue_context_t* const ue_context_pP, - uint8_t xid ) { - +int rrc_eNB_send_S1AP_E_RAB_MODIFY_RESP(const protocol_ctxt_t *const ctxt_pP, + rrc_eNB_ue_context_t *const ue_context_pP, + uint8_t xid ) { MessageDef *msg_p = NULL; int i; int e_rab; @@ -1749,7 +1552,6 @@ int rrc_eNB_send_S1AP_E_RAB_MODIFY_RESP(const protocol_ctxt_t* const ctxt_pP, S1AP_E_RAB_MODIFY_RESP (msg_p).eNB_ue_s1ap_id = ue_context_pP->ue_context.eNB_ue_s1ap_id; for (e_rab = 0; e_rab < ue_context_pP->ue_context.nb_of_modify_e_rabs; e_rab++) { - /* only respond to the corresponding transaction */ if (xid == ue_context_pP->ue_context.modify_e_rab[e_rab].xid) { if (ue_context_pP->ue_context.modify_e_rab[e_rab].status == E_RAB_STATUS_DONE) { @@ -1762,202 +1564,200 @@ int rrc_eNB_send_S1AP_E_RAB_MODIFY_RESP(const protocol_ctxt_t* const ctxt_pP, break; } } + if (i < ue_context_pP->ue_context.setup_e_rabs) { S1AP_E_RAB_MODIFY_RESP (msg_p).e_rabs[e_rabs_done].e_rab_id = ue_context_pP->ue_context.modify_e_rab[e_rab].param.e_rab_id; - // TODO add other information from S1-U when it will be integrated - + // TODO add other information from S1-U when it will be integrated LOG_D (RRC,"enb_gtp_addr (msg index %d, e_rab index %d, status %d, xid %d): nb_of_modify_e_rabs %d, e_rab_id %d \n ", - e_rabs_done, e_rab, ue_context_pP->ue_context.modify_e_rab[e_rab].status, xid, - ue_context_pP->ue_context.nb_of_modify_e_rabs, - S1AP_E_RAB_MODIFY_RESP (msg_p).e_rabs[e_rabs_done].e_rab_id); - + e_rabs_done, e_rab, ue_context_pP->ue_context.modify_e_rab[e_rab].status, xid, + ue_context_pP->ue_context.nb_of_modify_e_rabs, + S1AP_E_RAB_MODIFY_RESP (msg_p).e_rabs[e_rabs_done].e_rab_id); e_rabs_done++; } else { // unexpected S1AP_E_RAB_MODIFY_RESP (msg_p).e_rabs_failed[e_rabs_failed].e_rab_id = ue_context_pP->ue_context.modify_e_rab[e_rab].param.e_rab_id; - S1AP_E_RAB_MODIFY_RESP (msg_p).e_rabs_failed[e_rabs_failed].cause = S1AP_CAUSE_RADIO_NETWORK; S1AP_E_RAB_MODIFY_RESP (msg_p).e_rabs_failed[e_rabs_failed].cause_value = 30;//S1ap_CauseRadioNetwork_unknown_E_RAB_ID; - e_rabs_failed++; } } else if ((ue_context_pP->ue_context.modify_e_rab[e_rab].status == E_RAB_STATUS_NEW) || - (ue_context_pP->ue_context.modify_e_rab[e_rab].status == E_RAB_STATUS_ESTABLISHED)){ + (ue_context_pP->ue_context.modify_e_rab[e_rab].status == E_RAB_STATUS_ESTABLISHED)) { LOG_D (RRC,"E-RAB is NEW or already ESTABLISHED\n"); } else { /* status == E_RAB_STATUS_FAILED; */ S1AP_E_RAB_MODIFY_RESP (msg_p).e_rabs_failed[e_rabs_failed].e_rab_id = ue_context_pP->ue_context.modify_e_rab[e_rab].param.e_rab_id; // add failure cause when defined S1AP_E_RAB_MODIFY_RESP (msg_p).e_rabs_failed[e_rabs_failed].cause = ue_context_pP->ue_context.modify_e_rab[e_rab].cause; - e_rabs_failed++; } } else { /*debug info for the xid */ LOG_D(RRC,"xid does not corresponds (context e_rab index %d, status %d, xid %d/%d) \n ", - e_rab, ue_context_pP->ue_context.modify_e_rab[e_rab].status, xid, ue_context_pP->ue_context.modify_e_rab[e_rab].xid); + e_rab, ue_context_pP->ue_context.modify_e_rab[e_rab].status, xid, ue_context_pP->ue_context.modify_e_rab[e_rab].xid); } } - S1AP_E_RAB_MODIFY_RESP (msg_p).nb_of_e_rabs = e_rabs_done; S1AP_E_RAB_MODIFY_RESP (msg_p).nb_of_e_rabs_failed = e_rabs_failed; + // NN: add conditions for e_rabs_failed if (e_rabs_done > 0 || e_rabs_failed > 0) { LOG_D(RRC,"S1AP_E_RAB_MODIFY_RESP: sending the message: nb_of_modify_e_rabs %d, total e_rabs %d, index %d\n", - ue_context_pP->ue_context.nb_of_modify_e_rabs, ue_context_pP->ue_context.setup_e_rabs, e_rab); -MSC_LOG_TX_MESSAGE( - MSC_RRC_ENB, - MSC_S1AP_ENB, - (const char *)&S1AP_E_RAB_SETUP_RESP (msg_p), - sizeof(s1ap_e_rab_setup_resp_t), - MSC_AS_TIME_FMT" E_RAB_MODIFY_RESP UE %X eNB_ue_s1ap_id %u e_rabs:%u succ %u fail", - MSC_AS_TIME_ARGS(ctxt_pP), - ue_context_pP->ue_id_rnti, - S1AP_E_RAB_MODIFY_RESP (msg_p).eNB_ue_s1ap_id, - e_rabs_done, e_rabs_failed); - + ue_context_pP->ue_context.nb_of_modify_e_rabs, ue_context_pP->ue_context.setup_e_rabs, e_rab); + MSC_LOG_TX_MESSAGE( + MSC_RRC_ENB, + MSC_S1AP_ENB, + (const char *)&S1AP_E_RAB_SETUP_RESP (msg_p), + sizeof(s1ap_e_rab_setup_resp_t), + MSC_AS_TIME_FMT" E_RAB_MODIFY_RESP UE %X eNB_ue_s1ap_id %u e_rabs:%u succ %u fail", + MSC_AS_TIME_ARGS(ctxt_pP), + ue_context_pP->ue_id_rnti, + S1AP_E_RAB_MODIFY_RESP (msg_p).eNB_ue_s1ap_id, + e_rabs_done, e_rabs_failed); itti_send_msg_to_task (TASK_S1AP, ctxt_pP->instance, msg_p); } return 0; } -int rrc_eNB_process_S1AP_E_RAB_RELEASE_COMMAND(MessageDef *msg_p, const char *msg_name, instance_t instance){ - uint32_t eNB_ue_s1ap_id; - struct rrc_eNB_ue_context_s* ue_context_p = NULL; - protocol_ctxt_t ctxt; - e_rab_release_t e_rab_release_params[S1AP_MAX_E_RAB]; - uint8_t nb_e_rabs_torelease; - int erab; - int i; - uint8_t b_existed,is_existed; - uint8_t xid; - uint8_t e_rab_release_drb; - MessageDef * msg_delete_tunnels_p = NULL; - e_rab_release_drb = 0; - memcpy(&e_rab_release_params[0], &(S1AP_E_RAB_RELEASE_COMMAND (msg_p).e_rab_release_params[0]), sizeof(e_rab_release_t)*S1AP_MAX_E_RAB); +int rrc_eNB_process_S1AP_E_RAB_RELEASE_COMMAND(MessageDef *msg_p, const char *msg_name, instance_t instance) { + uint32_t eNB_ue_s1ap_id; + struct rrc_eNB_ue_context_s *ue_context_p = NULL; + protocol_ctxt_t ctxt; + e_rab_release_t e_rab_release_params[S1AP_MAX_E_RAB]; + uint8_t nb_e_rabs_torelease; + int erab; + int i; + uint8_t b_existed,is_existed; + uint8_t xid; + uint8_t e_rab_release_drb; + MessageDef *msg_delete_tunnels_p = NULL; + e_rab_release_drb = 0; + memcpy(&e_rab_release_params[0], &(S1AP_E_RAB_RELEASE_COMMAND (msg_p).e_rab_release_params[0]), sizeof(e_rab_release_t)*S1AP_MAX_E_RAB); + eNB_ue_s1ap_id = S1AP_E_RAB_RELEASE_COMMAND (msg_p).eNB_ue_s1ap_id; + nb_e_rabs_torelease = S1AP_E_RAB_RELEASE_COMMAND (msg_p).nb_e_rabs_torelease; + ue_context_p = rrc_eNB_get_ue_context_from_s1ap_ids(instance, UE_INITIAL_ID_INVALID, eNB_ue_s1ap_id); - eNB_ue_s1ap_id = S1AP_E_RAB_RELEASE_COMMAND (msg_p).eNB_ue_s1ap_id; - nb_e_rabs_torelease = S1AP_E_RAB_RELEASE_COMMAND (msg_p).nb_e_rabs_torelease; - ue_context_p = rrc_eNB_get_ue_context_from_s1ap_ids(instance, UE_INITIAL_ID_INVALID, eNB_ue_s1ap_id); - if(ue_context_p != NULL){ - PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt, instance, ENB_FLAG_YES, ue_context_p->ue_context.rnti, 0, 0); + if(ue_context_p != NULL) { + PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt, instance, ENB_FLAG_YES, ue_context_p->ue_context.rnti, 0, 0); + xid = rrc_eNB_get_next_transaction_identifier(ctxt.module_id); + LOG_D(RRC,"S1AP-E-RAB Release Command: MME_UE_S1AP_ID %d ENB_UE_S1AP_ID %d release_e_rabs %d \n", + S1AP_E_RAB_RELEASE_COMMAND (msg_p).mme_ue_s1ap_id, eNB_ue_s1ap_id,nb_e_rabs_torelease); - xid = rrc_eNB_get_next_transaction_identifier(ctxt.module_id); + for(erab = 0; erab < nb_e_rabs_torelease; erab++) { + b_existed = 0; + is_existed = 0; - LOG_D(RRC,"S1AP-E-RAB Release Command: MME_UE_S1AP_ID %d ENB_UE_S1AP_ID %d release_e_rabs %d \n", - S1AP_E_RAB_RELEASE_COMMAND (msg_p).mme_ue_s1ap_id, eNB_ue_s1ap_id,nb_e_rabs_torelease); - for(erab = 0; erab < nb_e_rabs_torelease; erab++){ - b_existed = 0; - is_existed = 0; - for ( i = erab-1; i>= 0; i--){ - if (e_rab_release_params[erab].e_rab_id == e_rab_release_params[i].e_rab_id){ - is_existed = 1; - break; - } - } - if(is_existed == 1){ - //e_rab_id is existed - continue; - } - for ( i = 0; i < NB_RB_MAX; i++){ - if (e_rab_release_params[erab].e_rab_id == ue_context_p->ue_context.e_rab[i].param.e_rab_id){ - b_existed = 1; - break; - } - } - if(b_existed == 0) { - //no e_rab_id - ue_context_p->ue_context.e_rabs_release_failed[ue_context_p->ue_context.nb_release_of_e_rabs].e_rab_id = e_rab_release_params[erab].e_rab_id; - ue_context_p->ue_context.e_rabs_release_failed[ue_context_p->ue_context.nb_release_of_e_rabs].cause = S1AP_CAUSE_RADIO_NETWORK; - ue_context_p->ue_context.e_rabs_release_failed[ue_context_p->ue_context.nb_release_of_e_rabs].cause_value = 30; - ue_context_p->ue_context.nb_release_of_e_rabs++; - } else { - if(ue_context_p->ue_context.e_rab[i].status == E_RAB_STATUS_FAILED){ - ue_context_p->ue_context.e_rab[i].xid = xid; - continue; - } else if(ue_context_p->ue_context.e_rab[i].status == E_RAB_STATUS_ESTABLISHED){ - ue_context_p->ue_context.e_rab[i].status = E_RAB_STATUS_TORELEASE; - ue_context_p->ue_context.e_rab[i].xid = xid; - e_rab_release_drb++; - }else{ - //e_rab_id status NG - ue_context_p->ue_context.e_rabs_release_failed[ue_context_p->ue_context.nb_release_of_e_rabs].e_rab_id = e_rab_release_params[erab].e_rab_id; - ue_context_p->ue_context.e_rabs_release_failed[ue_context_p->ue_context.nb_release_of_e_rabs].cause = S1AP_CAUSE_RADIO_NETWORK; - ue_context_p->ue_context.e_rabs_release_failed[ue_context_p->ue_context.nb_release_of_e_rabs].cause_value = 0; - ue_context_p->ue_context.nb_release_of_e_rabs++; - } - } + for ( i = erab-1; i>= 0; i--) { + if (e_rab_release_params[erab].e_rab_id == e_rab_release_params[i].e_rab_id) { + is_existed = 1; + break; } - if(e_rab_release_drb > 0) { - //RRCConnectionReconfiguration To UE - rrc_eNB_generate_dedicatedRRCConnectionReconfiguration_release(&ctxt, ue_context_p, xid, S1AP_E_RAB_RELEASE_COMMAND (msg_p).nas_pdu.length, S1AP_E_RAB_RELEASE_COMMAND (msg_p).nas_pdu.buffer); + } + + if(is_existed == 1) { + //e_rab_id is existed + continue; + } + + for ( i = 0; i < NB_RB_MAX; i++) { + if (e_rab_release_params[erab].e_rab_id == ue_context_p->ue_context.e_rab[i].param.e_rab_id) { + b_existed = 1; + break; + } + } + + if(b_existed == 0) { + //no e_rab_id + ue_context_p->ue_context.e_rabs_release_failed[ue_context_p->ue_context.nb_release_of_e_rabs].e_rab_id = e_rab_release_params[erab].e_rab_id; + ue_context_p->ue_context.e_rabs_release_failed[ue_context_p->ue_context.nb_release_of_e_rabs].cause = S1AP_CAUSE_RADIO_NETWORK; + ue_context_p->ue_context.e_rabs_release_failed[ue_context_p->ue_context.nb_release_of_e_rabs].cause_value = 30; + ue_context_p->ue_context.nb_release_of_e_rabs++; + } else { + if(ue_context_p->ue_context.e_rab[i].status == E_RAB_STATUS_FAILED) { + ue_context_p->ue_context.e_rab[i].xid = xid; + continue; + } else if(ue_context_p->ue_context.e_rab[i].status == E_RAB_STATUS_ESTABLISHED) { + ue_context_p->ue_context.e_rab[i].status = E_RAB_STATUS_TORELEASE; + ue_context_p->ue_context.e_rab[i].xid = xid; + e_rab_release_drb++; } else { - //gtp tunnel delete - msg_delete_tunnels_p = itti_alloc_new_message(TASK_RRC_ENB, GTPV1U_ENB_DELETE_TUNNEL_REQ); - memset(>PV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p), 0, sizeof(GTPV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p))); - GTPV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p).rnti = ue_context_p->ue_context.rnti; - for(i = 0; i < NB_RB_MAX; i++){ - if(xid == ue_context_p->ue_context.e_rab[i].xid){ - GTPV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p).eps_bearer_id[GTPV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p).num_erab++] = ue_context_p->ue_context.enb_gtp_ebi[i]; - ue_context_p->ue_context.enb_gtp_teid[i] = 0; - memset(&ue_context_p->ue_context.enb_gtp_addrs[i], 0, sizeof(ue_context_p->ue_context.enb_gtp_addrs[i])); - ue_context_p->ue_context.enb_gtp_ebi[i] = 0; - } - } - - itti_send_msg_to_task(TASK_GTPV1_U, instance, msg_delete_tunnels_p); - - //S1AP_E_RAB_RELEASE_RESPONSE - rrc_eNB_send_S1AP_E_RAB_RELEASE_RESPONSE(&ctxt, ue_context_p, xid); + //e_rab_id status NG + ue_context_p->ue_context.e_rabs_release_failed[ue_context_p->ue_context.nb_release_of_e_rabs].e_rab_id = e_rab_release_params[erab].e_rab_id; + ue_context_p->ue_context.e_rabs_release_failed[ue_context_p->ue_context.nb_release_of_e_rabs].cause = S1AP_CAUSE_RADIO_NETWORK; + ue_context_p->ue_context.e_rabs_release_failed[ue_context_p->ue_context.nb_release_of_e_rabs].cause_value = 0; + ue_context_p->ue_context.nb_release_of_e_rabs++; } - } else { - LOG_E(RRC,"S1AP-E-RAB Release Command: MME_UE_S1AP_ID %d ENB_UE_S1AP_ID %d Error ue_context_p NULL \n", - S1AP_E_RAB_RELEASE_COMMAND (msg_p).mme_ue_s1ap_id, S1AP_E_RAB_RELEASE_COMMAND (msg_p).eNB_ue_s1ap_id); - return -1; + } } - return 0; + if(e_rab_release_drb > 0) { + //RRCConnectionReconfiguration To UE + rrc_eNB_generate_dedicatedRRCConnectionReconfiguration_release(&ctxt, ue_context_p, xid, S1AP_E_RAB_RELEASE_COMMAND (msg_p).nas_pdu.length, S1AP_E_RAB_RELEASE_COMMAND (msg_p).nas_pdu.buffer); + } else { + //gtp tunnel delete + msg_delete_tunnels_p = itti_alloc_new_message(TASK_RRC_ENB, GTPV1U_ENB_DELETE_TUNNEL_REQ); + memset(>PV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p), 0, sizeof(GTPV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p))); + GTPV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p).rnti = ue_context_p->ue_context.rnti; + + for(i = 0; i < NB_RB_MAX; i++) { + if(xid == ue_context_p->ue_context.e_rab[i].xid) { + GTPV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p).eps_bearer_id[GTPV1U_ENB_DELETE_TUNNEL_REQ(msg_delete_tunnels_p).num_erab++] = ue_context_p->ue_context.enb_gtp_ebi[i]; + ue_context_p->ue_context.enb_gtp_teid[i] = 0; + memset(&ue_context_p->ue_context.enb_gtp_addrs[i], 0, sizeof(ue_context_p->ue_context.enb_gtp_addrs[i])); + ue_context_p->ue_context.enb_gtp_ebi[i] = 0; + } + } + + itti_send_msg_to_task(TASK_GTPV1_U, instance, msg_delete_tunnels_p); + //S1AP_E_RAB_RELEASE_RESPONSE + rrc_eNB_send_S1AP_E_RAB_RELEASE_RESPONSE(&ctxt, ue_context_p, xid); + } + } else { + LOG_E(RRC,"S1AP-E-RAB Release Command: MME_UE_S1AP_ID %d ENB_UE_S1AP_ID %d Error ue_context_p NULL \n", + S1AP_E_RAB_RELEASE_COMMAND (msg_p).mme_ue_s1ap_id, S1AP_E_RAB_RELEASE_COMMAND (msg_p).eNB_ue_s1ap_id); + return -1; + } + + return 0; } -int rrc_eNB_send_S1AP_E_RAB_RELEASE_RESPONSE(const protocol_ctxt_t* const ctxt_pP, rrc_eNB_ue_context_t* const ue_context_pP, uint8_t xid){ - int e_rabs_released = 0; - MessageDef *msg_p; +int rrc_eNB_send_S1AP_E_RAB_RELEASE_RESPONSE(const protocol_ctxt_t *const ctxt_pP, rrc_eNB_ue_context_t *const ue_context_pP, uint8_t xid) { + int e_rabs_released = 0; + MessageDef *msg_p; + msg_p = itti_alloc_new_message (TASK_RRC_ENB, S1AP_E_RAB_RELEASE_RESPONSE); + S1AP_E_RAB_RELEASE_RESPONSE (msg_p).eNB_ue_s1ap_id = ue_context_pP->ue_context.eNB_ue_s1ap_id; - msg_p = itti_alloc_new_message (TASK_RRC_ENB, S1AP_E_RAB_RELEASE_RESPONSE); - S1AP_E_RAB_RELEASE_RESPONSE (msg_p).eNB_ue_s1ap_id = ue_context_pP->ue_context.eNB_ue_s1ap_id; - - for (int i = 0; i < NB_RB_MAX; i++){ - if (xid == ue_context_pP->ue_context.e_rab[i].xid){ - S1AP_E_RAB_RELEASE_RESPONSE (msg_p).e_rab_release[e_rabs_released].e_rab_id = ue_context_pP->ue_context.e_rab[i].param.e_rab_id; - e_rabs_released++; - //clear - memset(&ue_context_pP->ue_context.e_rab[i],0,sizeof(e_rab_param_t)); - } + for (int i = 0; i < NB_RB_MAX; i++) { + if (xid == ue_context_pP->ue_context.e_rab[i].xid) { + S1AP_E_RAB_RELEASE_RESPONSE (msg_p).e_rab_release[e_rabs_released].e_rab_id = ue_context_pP->ue_context.e_rab[i].param.e_rab_id; + e_rabs_released++; + //clear + memset(&ue_context_pP->ue_context.e_rab[i],0,sizeof(e_rab_param_t)); } - S1AP_E_RAB_RELEASE_RESPONSE (msg_p).nb_of_e_rabs_released = e_rabs_released; - S1AP_E_RAB_RELEASE_RESPONSE (msg_p).nb_of_e_rabs_failed = ue_context_pP->ue_context.nb_release_of_e_rabs; - memcpy(&(S1AP_E_RAB_RELEASE_RESPONSE (msg_p).e_rabs_failed[0]),&ue_context_pP->ue_context.e_rabs_release_failed[0],sizeof(e_rab_failed_t)*ue_context_pP->ue_context.nb_release_of_e_rabs); + } - ue_context_pP->ue_context.setup_e_rabs -= e_rabs_released; - LOG_I(RRC,"S1AP-E-RAB RELEASE RESPONSE: ENB_UE_S1AP_ID %d release_e_rabs %d setup_e_rabs %d \n", - S1AP_E_RAB_RELEASE_RESPONSE (msg_p).eNB_ue_s1ap_id, - e_rabs_released, ue_context_pP->ue_context.setup_e_rabs); - - itti_send_msg_to_task (TASK_S1AP, ctxt_pP->instance, msg_p); - //clear xid - for(int i = 0; i < NB_RB_MAX; i++) { - ue_context_pP->ue_context.e_rab[i].xid = -1; - } - //clear release e_rabs - ue_context_pP->ue_context.nb_release_of_e_rabs = 0; - memset(&ue_context_pP->ue_context.e_rabs_release_failed[0],0,sizeof(e_rab_failed_t)*S1AP_MAX_E_RAB); - return 0; + S1AP_E_RAB_RELEASE_RESPONSE (msg_p).nb_of_e_rabs_released = e_rabs_released; + S1AP_E_RAB_RELEASE_RESPONSE (msg_p).nb_of_e_rabs_failed = ue_context_pP->ue_context.nb_release_of_e_rabs; + memcpy(&(S1AP_E_RAB_RELEASE_RESPONSE (msg_p).e_rabs_failed[0]),&ue_context_pP->ue_context.e_rabs_release_failed[0],sizeof(e_rab_failed_t)*ue_context_pP->ue_context.nb_release_of_e_rabs); + ue_context_pP->ue_context.setup_e_rabs -= e_rabs_released; + LOG_I(RRC,"S1AP-E-RAB RELEASE RESPONSE: ENB_UE_S1AP_ID %d release_e_rabs %d setup_e_rabs %d \n", + S1AP_E_RAB_RELEASE_RESPONSE (msg_p).eNB_ue_s1ap_id, + e_rabs_released, ue_context_pP->ue_context.setup_e_rabs); + itti_send_msg_to_task (TASK_S1AP, ctxt_pP->instance, msg_p); + + //clear xid + for(int i = 0; i < NB_RB_MAX; i++) { + ue_context_pP->ue_context.e_rab[i].xid = -1; + } + + //clear release e_rabs + ue_context_pP->ue_context.nb_release_of_e_rabs = 0; + memset(&ue_context_pP->ue_context.e_rabs_release_failed[0],0,sizeof(e_rab_failed_t)*S1AP_MAX_E_RAB); + return 0; } /*------------------------------------------------------------------------------*/ -int rrc_eNB_process_PAGING_IND(MessageDef *msg_p, const char *msg_name, instance_t instance) -{ +int rrc_eNB_process_PAGING_IND(MessageDef *msg_p, const char *msg_name, instance_t instance) { const unsigned int Ttab[4] = {32,64,128,256}; uint8_t Tc,Tue; /* DRX cycle of UE */ uint32_t pcch_nB; /* 4T, 2T, T, T/2, T/4, T/8, T/16, T/32 */ @@ -1965,132 +1765,150 @@ int rrc_eNB_process_PAGING_IND(MessageDef *msg_p, const char *msg_name, instance uint32_t Ns = 0; /* Ns: max(1,nB/T) */ uint8_t i_s; /* i_s = floor(UE_ID/N) mod Ns */ uint32_t T; /* DRX cycle */ + for (uint16_t tai_size = 0; tai_size < S1AP_PAGING_IND(msg_p).tai_size; tai_size++) { - LOG_D(RRC,"[eNB %d] In S1AP_PAGING_IND: MCC %d, MNC %d, TAC %d\n", instance, S1AP_PAGING_IND(msg_p).plmn_identity[tai_size].mcc, - S1AP_PAGING_IND(msg_p).plmn_identity[tai_size].mnc, S1AP_PAGING_IND(msg_p).tac[tai_size]); - for (uint8_t j = 0; j < RC.rrc[instance]->configuration.num_plmn; j++) { - if (RC.rrc[instance]->configuration.mcc[j] == S1AP_PAGING_IND(msg_p).plmn_identity[tai_size].mcc - && RC.rrc[instance]->configuration.mnc[j] == S1AP_PAGING_IND(msg_p).plmn_identity[tai_size].mnc - && RC.rrc[instance]->configuration.tac == S1AP_PAGING_IND(msg_p).tac[tai_size]) { - for (uint8_t CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { - lte_frame_type_t frame_type = RC.eNB[instance][CC_id]->frame_parms.frame_type; - /* get nB from configuration */ - /* get default DRX cycle from configuration */ - Tc = (uint8_t)RC.rrc[instance]->configuration.pcch_defaultPagingCycle[CC_id]; - if (Tc < LTE_PCCH_Config__defaultPagingCycle_rf32 || Tc > LTE_PCCH_Config__defaultPagingCycle_rf256) { - continue; - } - Tue = (uint8_t)S1AP_PAGING_IND(msg_p).paging_drx; - /* set T = min(Tc,Tue) */ - T = Tc < Tue ? Ttab[Tc] : Ttab[Tue]; - /* set pcch_nB = PCCH-Config->nB */ - pcch_nB = (uint32_t)RC.rrc[instance]->configuration.pcch_nB[CC_id]; - switch (pcch_nB) { - case LTE_PCCH_Config__nB_fourT: - Ns = 4; - break; - case LTE_PCCH_Config__nB_twoT: - Ns = 2; - break; - default: - Ns = 1; - break; - } - /* set N = min(T,nB) */ - if (pcch_nB > LTE_PCCH_Config__nB_oneT) { - switch (pcch_nB) { - case LTE_PCCH_Config__nB_halfT: - N = T/2; - break; - case LTE_PCCH_Config__nB_quarterT: - N = T/4; - break; - case LTE_PCCH_Config__nB_oneEighthT: - N = T/8; - break; - case LTE_PCCH_Config__nB_oneSixteenthT: - N = T/16; - break; - case LTE_PCCH_Config__nB_oneThirtySecondT: - N = T/32; - break; - default: - /* pcch_nB error */ - LOG_E(RRC, "[eNB %d] In S1AP_PAGING_IND: pcch_nB error (pcch_nB %d) \n", - instance, pcch_nB); - return (-1); - } - } else { - N = T; - } + LOG_D(RRC,"[eNB %d] In S1AP_PAGING_IND: MCC %d, MNC %d, TAC %d\n", instance, S1AP_PAGING_IND(msg_p).plmn_identity[tai_size].mcc, + S1AP_PAGING_IND(msg_p).plmn_identity[tai_size].mnc, S1AP_PAGING_IND(msg_p).tac[tai_size]); - /* insert data to UE_PF_PO or update data in UE_PF_PO */ - pthread_mutex_lock(&ue_pf_po_mutex); - uint8_t i = 0; - for (i = 0; i < MAX_MOBILES_PER_ENB; i++) { - if ((UE_PF_PO[CC_id][i].enable_flag == TRUE && UE_PF_PO[CC_id][i].ue_index_value == (uint16_t)(S1AP_PAGING_IND(msg_p).ue_index_value)) - || (UE_PF_PO[CC_id][i].enable_flag != TRUE)) { - /* set T = min(Tc,Tue) */ - UE_PF_PO[CC_id][i].T = T; - /* set UE_ID */ - UE_PF_PO[CC_id][i].ue_index_value = (uint16_t)S1AP_PAGING_IND(msg_p).ue_index_value; - /* calculate PF and PO */ - /* set PF_min : SFN mod T = (T div N)*(UE_ID mod N) */ - UE_PF_PO[CC_id][i].PF_min = (T / N) * (UE_PF_PO[CC_id][i].ue_index_value % N); - /* set PO */ - /* i_s = floor(UE_ID/N) mod Ns */ - i_s = (uint8_t)((UE_PF_PO[CC_id][i].ue_index_value / N) % Ns); - if (Ns == 1) { - UE_PF_PO[CC_id][i].PO = (frame_type==FDD) ? 9 : 0; - } else if (Ns==2) { - UE_PF_PO[CC_id][i].PO = (frame_type==FDD) ? (4+(5*i_s)) : (5*i_s); - } else if (Ns==4) { - UE_PF_PO[CC_id][i].PO = (frame_type==FDD) ? (4*(i_s&1)+(5*(i_s>>1))) : ((i_s&1)+(5*(i_s>>1))); - } - if (UE_PF_PO[CC_id][i].enable_flag == TRUE) { - //paging exist UE log - LOG_D(RRC,"[eNB %d] CC_id %d In S1AP_PAGING_IND: Update exist UE %d, T %d, PF %d, PO %d\n", instance, CC_id, UE_PF_PO[CC_id][i].ue_index_value, T, UE_PF_PO[CC_id][i].PF_min, UE_PF_PO[CC_id][i].PO); - } else { - /* set enable_flag */ - UE_PF_PO[CC_id][i].enable_flag = TRUE; - //paging new UE log - LOG_D(RRC,"[eNB %d] CC_id %d In S1AP_PAGING_IND: Insert a new UE %d, T %d, PF %d, PO %d\n", instance, CC_id, UE_PF_PO[CC_id][i].ue_index_value, T, UE_PF_PO[CC_id][i].PF_min, UE_PF_PO[CC_id][i].PO); - } - break; - } - } - pthread_mutex_unlock(&ue_pf_po_mutex); + for (uint8_t j = 0; j < RC.rrc[instance]->configuration.num_plmn; j++) { + if (RC.rrc[instance]->configuration.mcc[j] == S1AP_PAGING_IND(msg_p).plmn_identity[tai_size].mcc + && RC.rrc[instance]->configuration.mnc[j] == S1AP_PAGING_IND(msg_p).plmn_identity[tai_size].mnc + && RC.rrc[instance]->configuration.tac == S1AP_PAGING_IND(msg_p).tac[tai_size]) { + for (uint8_t CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { + lte_frame_type_t frame_type = RC.eNB[instance][CC_id]->frame_parms.frame_type; + /* get nB from configuration */ + /* get default DRX cycle from configuration */ + Tc = (uint8_t)RC.rrc[instance]->configuration.pcch_defaultPagingCycle[CC_id]; - uint32_t length; - uint8_t buffer[RRC_BUF_SIZE]; - uint8_t *message_buffer; - /* Transfer data to PDCP */ - MessageDef *message_p; - message_p = itti_alloc_new_message (TASK_RRC_ENB, RRC_PCCH_DATA_REQ); - /* Create message for PDCP (DLInformationTransfer_t) */ - length = do_Paging (instance, - buffer, - S1AP_PAGING_IND(msg_p).ue_paging_identity, - S1AP_PAGING_IND(msg_p).cn_domain); - if(length == -1) - { - LOG_I(RRC, "do_Paging error"); - return -1; - } - message_buffer = itti_malloc (TASK_RRC_ENB, TASK_PDCP_ENB, length); - /* Uses a new buffer to avoid issue with PDCP buffer content that could be changed by PDCP (asynchronous message handling). */ - memcpy (message_buffer, buffer, length); - RRC_PCCH_DATA_REQ (message_p).sdu_size = length; - RRC_PCCH_DATA_REQ (message_p).sdu_p = message_buffer; - RRC_PCCH_DATA_REQ (message_p).mode = PDCP_TRANSMISSION_MODE_TRANSPARENT; /* not used */ - RRC_PCCH_DATA_REQ (message_p).rnti = P_RNTI; - RRC_PCCH_DATA_REQ (message_p).ue_index = i; - RRC_PCCH_DATA_REQ (message_p).CC_id = CC_id; - LOG_D(RRC, "[eNB %d] CC_id %d In S1AP_PAGING_IND: send encdoed buffer to PDCP buffer_size %d\n", instance, CC_id, length); - itti_send_msg_to_task (TASK_PDCP_ENB, instance, message_p); - } + if (Tc < LTE_PCCH_Config__defaultPagingCycle_rf32 || Tc > LTE_PCCH_Config__defaultPagingCycle_rf256) { + continue; } + + Tue = (uint8_t)S1AP_PAGING_IND(msg_p).paging_drx; + /* set T = min(Tc,Tue) */ + T = Tc < Tue ? Ttab[Tc] : Ttab[Tue]; + /* set pcch_nB = PCCH-Config->nB */ + pcch_nB = (uint32_t)RC.rrc[instance]->configuration.pcch_nB[CC_id]; + + switch (pcch_nB) { + case LTE_PCCH_Config__nB_fourT: + Ns = 4; + break; + + case LTE_PCCH_Config__nB_twoT: + Ns = 2; + break; + + default: + Ns = 1; + break; + } + + /* set N = min(T,nB) */ + if (pcch_nB > LTE_PCCH_Config__nB_oneT) { + switch (pcch_nB) { + case LTE_PCCH_Config__nB_halfT: + N = T/2; + break; + + case LTE_PCCH_Config__nB_quarterT: + N = T/4; + break; + + case LTE_PCCH_Config__nB_oneEighthT: + N = T/8; + break; + + case LTE_PCCH_Config__nB_oneSixteenthT: + N = T/16; + break; + + case LTE_PCCH_Config__nB_oneThirtySecondT: + N = T/32; + break; + + default: + /* pcch_nB error */ + LOG_E(RRC, "[eNB %d] In S1AP_PAGING_IND: pcch_nB error (pcch_nB %d) \n", + instance, pcch_nB); + return (-1); + } + } else { + N = T; + } + + /* insert data to UE_PF_PO or update data in UE_PF_PO */ + pthread_mutex_lock(&ue_pf_po_mutex); + uint8_t i = 0; + + for (i = 0; i < MAX_MOBILES_PER_ENB; i++) { + if ((UE_PF_PO[CC_id][i].enable_flag == TRUE && UE_PF_PO[CC_id][i].ue_index_value == (uint16_t)(S1AP_PAGING_IND(msg_p).ue_index_value)) + || (UE_PF_PO[CC_id][i].enable_flag != TRUE)) { + /* set T = min(Tc,Tue) */ + UE_PF_PO[CC_id][i].T = T; + /* set UE_ID */ + UE_PF_PO[CC_id][i].ue_index_value = (uint16_t)S1AP_PAGING_IND(msg_p).ue_index_value; + /* calculate PF and PO */ + /* set PF_min : SFN mod T = (T div N)*(UE_ID mod N) */ + UE_PF_PO[CC_id][i].PF_min = (T / N) * (UE_PF_PO[CC_id][i].ue_index_value % N); + /* set PO */ + /* i_s = floor(UE_ID/N) mod Ns */ + i_s = (uint8_t)((UE_PF_PO[CC_id][i].ue_index_value / N) % Ns); + + if (Ns == 1) { + UE_PF_PO[CC_id][i].PO = (frame_type==FDD) ? 9 : 0; + } else if (Ns==2) { + UE_PF_PO[CC_id][i].PO = (frame_type==FDD) ? (4+(5*i_s)) : (5*i_s); + } else if (Ns==4) { + UE_PF_PO[CC_id][i].PO = (frame_type==FDD) ? (4*(i_s&1)+(5*(i_s>>1))) : ((i_s&1)+(5*(i_s>>1))); + } + + if (UE_PF_PO[CC_id][i].enable_flag == TRUE) { + //paging exist UE log + LOG_D(RRC,"[eNB %d] CC_id %d In S1AP_PAGING_IND: Update exist UE %d, T %d, PF %d, PO %d\n", instance, CC_id, UE_PF_PO[CC_id][i].ue_index_value, T, UE_PF_PO[CC_id][i].PF_min, UE_PF_PO[CC_id][i].PO); + } else { + /* set enable_flag */ + UE_PF_PO[CC_id][i].enable_flag = TRUE; + //paging new UE log + LOG_D(RRC,"[eNB %d] CC_id %d In S1AP_PAGING_IND: Insert a new UE %d, T %d, PF %d, PO %d\n", instance, CC_id, UE_PF_PO[CC_id][i].ue_index_value, T, UE_PF_PO[CC_id][i].PF_min, UE_PF_PO[CC_id][i].PO); + } + + break; + } + } + + pthread_mutex_unlock(&ue_pf_po_mutex); + uint32_t length; + uint8_t buffer[RRC_BUF_SIZE]; + uint8_t *message_buffer; + /* Transfer data to PDCP */ + MessageDef *message_p; + message_p = itti_alloc_new_message (TASK_RRC_ENB, RRC_PCCH_DATA_REQ); + /* Create message for PDCP (DLInformationTransfer_t) */ + length = do_Paging (instance, + buffer, + S1AP_PAGING_IND(msg_p).ue_paging_identity, + S1AP_PAGING_IND(msg_p).cn_domain); + + if(length == -1) { + LOG_I(RRC, "do_Paging error"); + return -1; + } + + message_buffer = itti_malloc (TASK_RRC_ENB, TASK_PDCP_ENB, length); + /* Uses a new buffer to avoid issue with PDCP buffer content that could be changed by PDCP (asynchronous message handling). */ + memcpy (message_buffer, buffer, length); + RRC_PCCH_DATA_REQ (message_p).sdu_size = length; + RRC_PCCH_DATA_REQ (message_p).sdu_p = message_buffer; + RRC_PCCH_DATA_REQ (message_p).mode = PDCP_TRANSMISSION_MODE_TRANSPARENT; /* not used */ + RRC_PCCH_DATA_REQ (message_p).rnti = P_RNTI; + RRC_PCCH_DATA_REQ (message_p).ue_index = i; + RRC_PCCH_DATA_REQ (message_p).CC_id = CC_id; + LOG_D(RRC, "[eNB %d] CC_id %d In S1AP_PAGING_IND: send encdoed buffer to PDCP buffer_size %d\n", instance, CC_id, length); + itti_send_msg_to_task (TASK_PDCP_ENB, instance, message_p); + } } + } } return (0); diff --git a/openair3/S1AP/s1ap_eNB.c b/openair3/S1AP/s1ap_eNB.c index 2e89bf97f7..9eab896d83 100644 --- a/openair3/S1AP/s1ap_eNB.c +++ b/openair3/S1AP/s1ap_eNB.c @@ -61,7 +61,7 @@ #include "assertions.h" #include "conversions.h" #if defined(TEST_S1C_MME) -#include "oaisim_mme_test_s1c.h" + #include "oaisim_mme_test_s1c.h" #endif s1ap_eNB_config_t s1ap_config; @@ -74,22 +74,17 @@ void s1ap_eNB_handle_register_eNB(instance_t instance, s1ap_register_enb_req_t * void s1ap_eNB_handle_sctp_association_resp(instance_t instance, sctp_new_association_resp_t *sctp_new_association_resp); -uint32_t s1ap_generate_eNB_id(void) -{ +uint32_t s1ap_generate_eNB_id(void) { char *out; char hostname[50]; int ret; uint32_t eNB_id; - /* Retrieve the host name */ ret = gethostname(hostname, sizeof(hostname)); DevAssert(ret == 0); - out = crypt(hostname, "eurecom"); DevAssert(out != NULL); - eNB_id = ((out[0] << 24) | (out[1] << 16) | (out[2] << 8) | out[3]); - return eNB_id; } @@ -99,55 +94,42 @@ static void s1ap_eNB_register_mme(s1ap_eNB_instance_t *instance_p, uint16_t in_streams, uint16_t out_streams, uint8_t broadcast_plmn_num, - uint8_t broadcast_plmn_index[PLMN_LIST_MAX_SIZE]) -{ + uint8_t broadcast_plmn_index[PLMN_LIST_MAX_SIZE]) { MessageDef *message_p = NULL; sctp_new_association_req_t *sctp_new_association_req_p = NULL; s1ap_eNB_mme_data_t *s1ap_mme_data_p = NULL; struct s1ap_eNB_mme_data_s *mme = NULL; - DevAssert(instance_p != NULL); DevAssert(mme_ip_address != NULL); - message_p = itti_alloc_new_message(TASK_S1AP, SCTP_NEW_ASSOCIATION_REQ); - sctp_new_association_req_p = &message_p->ittiMsg.sctp_new_association_req; - sctp_new_association_req_p->port = S1AP_PORT_NUMBER; sctp_new_association_req_p->ppid = S1AP_SCTP_PPID; - sctp_new_association_req_p->in_streams = in_streams; sctp_new_association_req_p->out_streams = out_streams; - memcpy(&sctp_new_association_req_p->remote_address, mme_ip_address, sizeof(*mme_ip_address)); - memcpy(&sctp_new_association_req_p->local_address, local_ip_addr, sizeof(*local_ip_addr)); - S1AP_INFO("[eNB %d] check the mme registration state\n",instance_p->instance); - mme = NULL; if ( mme == NULL ) { - /* Create new MME descriptor */ s1ap_mme_data_p = calloc(1, sizeof(*s1ap_mme_data_p)); DevAssert(s1ap_mme_data_p != NULL); - s1ap_mme_data_p->cnx_id = s1ap_eNB_fetch_add_global_cnx_id(); sctp_new_association_req_p->ulp_cnx_id = s1ap_mme_data_p->cnx_id; - s1ap_mme_data_p->assoc_id = -1; s1ap_mme_data_p->broadcast_plmn_num = broadcast_plmn_num; + for (int i = 0; i < broadcast_plmn_num; ++i) s1ap_mme_data_p->broadcast_plmn_index[i] = broadcast_plmn_index[i]; + s1ap_mme_data_p->s1ap_eNB_instance = instance_p; - STAILQ_INIT(&s1ap_mme_data_p->served_gummei); - /* Insert the new descriptor in list of known MME * but not yet associated. */ @@ -158,12 +140,10 @@ static void s1ap_eNB_register_mme(s1ap_eNB_instance_t *instance_p, } else if (mme->state == S1AP_ENB_STATE_WAITING) { instance_p->s1ap_mme_pending_nb ++; sctp_new_association_req_p->ulp_cnx_id = mme->cnx_id; - S1AP_INFO("[eNB %d] MME already registered, retrive the data (state %d, cnx %d, mme_nb %d, mme_pending_nb %d)\n", instance_p->instance, mme->state, mme->cnx_id, instance_p->s1ap_mme_nb, instance_p->s1ap_mme_pending_nb); - /*s1ap_mme_data_p->cnx_id = mme->cnx_id; sctp_new_association_req_p->ulp_cnx_id = mme->cnx_id; @@ -181,13 +161,10 @@ static void s1ap_eNB_register_mme(s1ap_eNB_instance_t *instance_p, } -void s1ap_eNB_handle_register_eNB(instance_t instance, s1ap_register_enb_req_t *s1ap_register_eNB) -{ +void s1ap_eNB_handle_register_eNB(instance_t instance, s1ap_register_enb_req_t *s1ap_register_eNB) { s1ap_eNB_instance_t *new_instance; uint8_t index; - DevAssert(s1ap_register_eNB != NULL); - /* Look if the provided instance already exists */ new_instance = s1ap_eNB_get_instance(instance); @@ -197,38 +174,36 @@ void s1ap_eNB_handle_register_eNB(instance_t instance, s1ap_register_enb_req_t * DevCheck(new_instance->cell_type == s1ap_register_eNB->cell_type, new_instance->cell_type, s1ap_register_eNB->cell_type, 0); DevCheck(new_instance->num_plmn == s1ap_register_eNB->num_plmn, new_instance->num_plmn, s1ap_register_eNB->num_plmn, 0); DevCheck(new_instance->tac == s1ap_register_eNB->tac, new_instance->tac, s1ap_register_eNB->tac, 0); - for (int i = 0; i < new_instance->num_plmn; i++) - { + + for (int i = 0; i < new_instance->num_plmn; i++) { DevCheck(new_instance->mcc[i] == s1ap_register_eNB->mcc[i], new_instance->mcc[i], s1ap_register_eNB->mcc[i], 0); DevCheck(new_instance->mnc[i] == s1ap_register_eNB->mnc[i], new_instance->mnc[i], s1ap_register_eNB->mnc[i], 0); DevCheck(new_instance->mnc_digit_length[i] == s1ap_register_eNB->mnc_digit_length[i], new_instance->mnc_digit_length[i], s1ap_register_eNB->mnc_digit_length[i], 0); } + DevCheck(new_instance->default_drx == s1ap_register_eNB->default_drx, new_instance->default_drx, s1ap_register_eNB->default_drx, 0); } else { new_instance = calloc(1, sizeof(s1ap_eNB_instance_t)); DevAssert(new_instance != NULL); - RB_INIT(&new_instance->s1ap_ue_head); RB_INIT(&new_instance->s1ap_mme_head); - /* Copy usefull parameters */ new_instance->instance = instance; new_instance->eNB_name = s1ap_register_eNB->eNB_name; new_instance->eNB_id = s1ap_register_eNB->eNB_id; new_instance->cell_type = s1ap_register_eNB->cell_type; new_instance->tac = s1ap_register_eNB->tac; - for (int i = 0; i < s1ap_register_eNB->num_plmn; i++) - { + + for (int i = 0; i < s1ap_register_eNB->num_plmn; i++) { new_instance->mcc[i] = s1ap_register_eNB->mcc[i]; new_instance->mnc[i] = s1ap_register_eNB->mnc[i]; new_instance->mnc_digit_length[i] = s1ap_register_eNB->mnc_digit_length[i]; } + new_instance->num_plmn = s1ap_register_eNB->num_plmn; new_instance->default_drx = s1ap_register_eNB->default_drx; - /* Add the new instance to the list of eNB (meaningfull in virtual mode) */ s1ap_eNB_insert_new_instance(new_instance); - S1AP_INFO("Registered new eNB[%d] and %s eNB id %u\n", instance, s1ap_register_eNB->cell_type == CELL_MACRO_ENB ? "macro" : "home", @@ -250,16 +225,12 @@ void s1ap_eNB_handle_register_eNB(instance_t instance, s1ap_register_enb_req_t * } } -void s1ap_eNB_handle_sctp_association_resp(instance_t instance, sctp_new_association_resp_t *sctp_new_association_resp) -{ +void s1ap_eNB_handle_sctp_association_resp(instance_t instance, sctp_new_association_resp_t *sctp_new_association_resp) { s1ap_eNB_instance_t *instance_p; s1ap_eNB_mme_data_t *s1ap_mme_data_p; - DevAssert(sctp_new_association_resp != NULL); - instance_p = s1ap_eNB_get_instance(instance); DevAssert(instance_p != NULL); - s1ap_mme_data_p = s1ap_eNB_get_MME(instance_p, -1, sctp_new_association_resp->ulp_cnx_id); DevAssert(s1ap_mme_data_p != NULL); @@ -269,9 +240,7 @@ void s1ap_eNB_handle_sctp_association_resp(instance_t instance, sctp_new_associa sctp_new_association_resp->sctp_state, instance, sctp_new_association_resp->ulp_cnx_id); - s1ap_handle_s1_setup_message(s1ap_mme_data_p, sctp_new_association_resp->sctp_state == SCTP_STATE_SHUTDOWN); - return; } @@ -279,20 +248,17 @@ void s1ap_eNB_handle_sctp_association_resp(instance_t instance, sctp_new_associa s1ap_mme_data_p->assoc_id = sctp_new_association_resp->assoc_id; s1ap_mme_data_p->in_streams = sctp_new_association_resp->in_streams; s1ap_mme_data_p->out_streams = sctp_new_association_resp->out_streams; - /* Prepare new S1 Setup Request */ s1ap_eNB_generate_s1_setup_request(instance_p, s1ap_mme_data_p); } static -void s1ap_eNB_handle_sctp_data_ind(sctp_data_ind_t *sctp_data_ind) -{ +void s1ap_eNB_handle_sctp_data_ind(sctp_data_ind_t *sctp_data_ind) { int result; - DevAssert(sctp_data_ind != NULL); #if defined(TEST_S1C_MME) mme_test_s1_notify_sctp_data_ind(sctp_data_ind->assoc_id, sctp_data_ind->stream, - sctp_data_ind->buffer, sctp_data_ind->buffer_length); + sctp_data_ind->buffer, sctp_data_ind->buffer_length); #else s1ap_eNB_handle_message(sctp_data_ind->assoc_id, sctp_data_ind->stream, sctp_data_ind->buffer, sctp_data_ind->buffer_length); @@ -301,23 +267,19 @@ void s1ap_eNB_handle_sctp_data_ind(sctp_data_ind_t *sctp_data_ind) AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result); } -void s1ap_eNB_init(void) -{ +void s1ap_eNB_init(void) { S1AP_DEBUG("Starting S1AP layer\n"); - s1ap_eNB_prepare_internal_data(); - itti_mark_task_ready(TASK_S1AP); MSC_START_USE(); } -void *s1ap_eNB_process_itti_msg(void* notUsed) -{ +void *s1ap_eNB_process_itti_msg(void *notUsed) { MessageDef *received_msg = NULL; int result; - itti_receive_msg(TASK_S1AP, &received_msg); + itti_receive_msg(TASK_S1AP, &received_msg); - switch (ITTI_MSG_ID(received_msg)) { + switch (ITTI_MSG_ID(received_msg)) { case TERMINATE_MESSAGE: S1AP_WARN(" *** Exiting S1AP thread\n"); itti_exit_task(); @@ -371,16 +333,16 @@ void *s1ap_eNB_process_itti_msg(void* notUsed) case S1AP_E_RAB_SETUP_RESP: { s1ap_eNB_e_rab_setup_resp(ITTI_MESSAGE_GET_INSTANCE(received_msg), - &S1AP_E_RAB_SETUP_RESP(received_msg)); + &S1AP_E_RAB_SETUP_RESP(received_msg)); } break; case S1AP_E_RAB_MODIFY_RESP: { s1ap_eNB_e_rab_modify_resp(ITTI_MESSAGE_GET_INSTANCE(received_msg), - &S1AP_E_RAB_MODIFY_RESP(received_msg)); + &S1AP_E_RAB_MODIFY_RESP(received_msg)); } break; - + case S1AP_NAS_NON_DELIVERY_IND: { s1ap_eNB_nas_non_delivery_ind(ITTI_MESSAGE_GET_INSTANCE(received_msg), &S1AP_NAS_NON_DELIVERY_IND(received_msg)); @@ -396,11 +358,8 @@ void *s1ap_eNB_process_itti_msg(void* notUsed) case S1AP_UE_CONTEXT_RELEASE_REQ: { s1ap_eNB_instance_t *s1ap_eNB_instance_p = NULL; // test struct s1ap_eNB_ue_context_s *ue_context_p = NULL; // test - s1ap_ue_context_release_req(ITTI_MESSAGE_GET_INSTANCE(received_msg), &S1AP_UE_CONTEXT_RELEASE_REQ(received_msg)); - - s1ap_eNB_instance_p = s1ap_eNB_get_instance(ITTI_MESSAGE_GET_INSTANCE(received_msg)); // test DevAssert(s1ap_eNB_instance_p != NULL); // test @@ -413,9 +372,9 @@ void *s1ap_eNB_process_itti_msg(void* notUsed) } break; - case S1AP_E_RAB_RELEASE_RESPONSE: { - s1ap_eNB_e_rab_release_resp(ITTI_MESSAGE_GET_INSTANCE(received_msg), - &S1AP_E_RAB_RELEASE_RESPONSE(received_msg)); + case S1AP_E_RAB_RELEASE_RESPONSE: { + s1ap_eNB_e_rab_release_resp(ITTI_MESSAGE_GET_INSTANCE(received_msg), + &S1AP_E_RAB_RELEASE_RESPONSE(received_msg)); } break; @@ -423,20 +382,18 @@ void *s1ap_eNB_process_itti_msg(void* notUsed) S1AP_ERROR("Received unhandled message: %d:%s\n", ITTI_MSG_ID(received_msg), ITTI_MSG_NAME(received_msg)); break; - } + } - result = itti_free (ITTI_MSG_ORIGIN_ID(received_msg), received_msg); - AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result); - - received_msg = NULL; - return NULL; + result = itti_free (ITTI_MSG_ORIGIN_ID(received_msg), received_msg); + AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result); + received_msg = NULL; + return NULL; } -void *s1ap_eNB_task(void *arg) -{ +void *s1ap_eNB_task(void *arg) { s1ap_eNB_init(); - + while (1) { (void) s1ap_eNB_process_itti_msg(NULL); } @@ -461,12 +418,9 @@ static int s1ap_eNB_generate_s1_setup_request( uint8_t *buffer = NULL; uint32_t len = 0; int ret = 0; - DevAssert(instance_p != NULL); DevAssert(s1ap_mme_data_p != NULL); - s1ap_mme_data_p->state = S1AP_ENB_STATE_WAITING; - /* Prepare the S1AP message to encode */ memset(&pdu, 0, sizeof(pdu)); pdu.present = S1AP_S1AP_PDU_PR_initiatingMessage; @@ -474,7 +428,6 @@ static int s1ap_eNB_generate_s1_setup_request( pdu.choice.initiatingMessage.criticality = S1AP_Criticality_reject; pdu.choice.initiatingMessage.value.present = S1AP_InitiatingMessage__value_PR_S1SetupRequest; out = &pdu.choice.initiatingMessage.value.choice.S1SetupRequest; - /* mandatory */ ie = (S1AP_S1SetupRequestIEs_t *)calloc(1, sizeof(S1AP_S1SetupRequestIEs_t)); ie->id = S1AP_ProtocolIE_ID_id_Global_ENB_ID; @@ -525,7 +478,6 @@ static int s1ap_eNB_generate_s1_setup_request( ASN_SEQUENCE_ADD(&ie->value.choice.SupportedTAs.list, ta); } ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); - /* mandatory */ ie = (S1AP_S1SetupRequestIEs_t *)calloc(1, sizeof(S1AP_S1SetupRequestIEs_t)); ie->id = S1AP_ProtocolIE_ID_id_DefaultPagingDRX; @@ -546,6 +498,7 @@ static int s1ap_eNB_generate_s1_setup_request( /* optional */ #if (S1AP_VERSION >= MAKE_VERSION(13, 0, 0)) + if (0) { ie = (S1AP_S1SetupRequestIEs_t *)calloc(1, sizeof(S1AP_S1SetupRequestIEs_t)); ie->id = S1AP_ProtocolIE_ID_id_UE_RetentionInformation; @@ -564,6 +517,7 @@ static int s1ap_eNB_generate_s1_setup_request( // ie->value.choice.NB_IoT_DefaultPagingDRX = ; ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); } + #endif /* #if (S1AP_VERSION >= MAKE_VERSION(14, 0, 0)) */ if (s1ap_eNB_encode_pdu(&pdu, &buffer, &len) < 0) { @@ -573,6 +527,5 @@ static int s1ap_eNB_generate_s1_setup_request( /* Non UE-Associated signalling -> stream = 0 */ s1ap_eNB_itti_send_sctp_data_req(instance_p->instance, s1ap_mme_data_p->assoc_id, buffer, len, 0); - return ret; } diff --git a/openair3/S1AP/s1ap_eNB_handlers.c b/openair3/S1AP/s1ap_eNB_handlers.c index 4a16450206..0f7afb68f7 100644 --- a/openair3/S1AP/s1ap_eNB_handlers.c +++ b/openair3/S1AP/s1ap_eNB_handlers.c @@ -66,13 +66,13 @@ int s1ap_eNB_handle_error_indication(uint32_t assoc_id, static int s1ap_eNB_handle_initial_context_request(uint32_t assoc_id, - uint32_t stream, - S1AP_S1AP_PDU_t *pdu); + uint32_t stream, + S1AP_S1AP_PDU_t *pdu); static int s1ap_eNB_handle_ue_context_release_command(uint32_t assoc_id, - uint32_t stream, - S1AP_S1AP_PDU_t *pdu); + uint32_t stream, + S1AP_S1AP_PDU_t *pdu); static int s1ap_eNB_handle_e_rab_setup_request(uint32_t assoc_id, @@ -86,13 +86,13 @@ int s1ap_eNB_handle_paging(uint32_t assoc_id, static int s1ap_eNB_handle_e_rab_modify_request(uint32_t assoc_id, - uint32_t stream, - S1AP_S1AP_PDU_t *pdu); + uint32_t stream, + S1AP_S1AP_PDU_t *pdu); static int s1ap_eNB_handle_e_rab_release_command(uint32_t assoc_id, - uint32_t stream, - S1AP_S1AP_PDU_t *pdu); + uint32_t stream, + S1AP_S1AP_PDU_t *pdu); /* Handlers matrix. Only eNB related procedure present here */ s1ap_message_decoded_callback messages_callback[][3] = { @@ -148,16 +148,15 @@ s1ap_message_decoded_callback messages_callback[][3] = { #endif /* #if (S1AP_VERSION >= MAKE_VERSION(9, 0, 0)) */ }; char *s1ap_direction2String(int s1ap_dir) { -static char *s1ap_direction_String[] = { - "", /* Nothing */ - "Originating message", /* originating message */ - "Successfull outcome", /* successfull outcome */ - "UnSuccessfull outcome", /* successfull outcome */ -}; -return(s1ap_direction_String[s1ap_dir]); + static char *s1ap_direction_String[] = { + "", /* Nothing */ + "Originating message", /* originating message */ + "Successfull outcome", /* successfull outcome */ + "UnSuccessfull outcome", /* successfull outcome */ + }; + return(s1ap_direction_String[s1ap_dir]); } -void s1ap_handle_s1_setup_message(s1ap_eNB_mme_data_t *mme_desc_p, int sctp_shutdown) -{ +void s1ap_handle_s1_setup_message(s1ap_eNB_mme_data_t *mme_desc_p, int sctp_shutdown) { if (sctp_shutdown) { /* A previously connected MME has been shutdown */ @@ -173,7 +172,6 @@ void s1ap_handle_s1_setup_message(s1ap_eNB_mme_data_t *mme_desc_p, int sctp_shut /* If there are no more associated MME, inform eNB app */ if (mme_desc_p->s1ap_eNB_instance->s1ap_mme_associated_nb == 0) { MessageDef *message_p; - message_p = itti_alloc_new_message(TASK_S1AP, S1AP_DEREGISTERED_ENB_IND); S1AP_DEREGISTERED_ENB_IND(message_p).nb_mme = 0; itti_send_msg_to_task(TASK_ENB_APP, mme_desc_p->s1ap_eNB_instance->instance, message_p); @@ -192,7 +190,6 @@ void s1ap_handle_s1_setup_message(s1ap_eNB_mme_data_t *mme_desc_p, int sctp_shut /* If there are no more pending messages, inform eNB app */ if (mme_desc_p->s1ap_eNB_instance->s1ap_mme_pending_nb == 0) { MessageDef *message_p; - message_p = itti_alloc_new_message(TASK_S1AP, S1AP_REGISTER_ENB_CNF); S1AP_REGISTER_ENB_CNF(message_p).nb_mme = mme_desc_p->s1ap_eNB_instance->s1ap_mme_associated_nb; itti_send_msg_to_task(TASK_ENB_APP, mme_desc_p->s1ap_eNB_instance->instance, message_p); @@ -201,13 +198,10 @@ void s1ap_handle_s1_setup_message(s1ap_eNB_mme_data_t *mme_desc_p, int sctp_shut } int s1ap_eNB_handle_message(uint32_t assoc_id, int32_t stream, - const uint8_t *const data, const uint32_t data_length) -{ + const uint8_t *const data, const uint32_t data_length) { S1AP_S1AP_PDU_t pdu; int ret; - DevAssert(data != NULL); - memset(&pdu, 0, sizeof(pdu)); if (s1ap_eNB_decode_pdu(&pdu, data, data_length) < 0) { @@ -246,14 +240,11 @@ int s1ap_eNB_handle_message(uint32_t assoc_id, int32_t stream, static int s1ap_eNB_handle_s1_setup_failure(uint32_t assoc_id, uint32_t stream, - S1AP_S1AP_PDU_t *pdu) -{ + S1AP_S1AP_PDU_t *pdu) { S1AP_S1SetupFailure_t *container; S1AP_S1SetupFailureIEs_t *ie; s1ap_eNB_mme_data_t *mme_desc_p; - DevAssert(pdu != NULL); - container = &pdu->choice.unsuccessfulOutcome.value.choice.S1SetupFailure; /* S1 Setup Failure == Non UE-related procedure -> stream 0 */ @@ -280,22 +271,18 @@ int s1ap_eNB_handle_s1_setup_failure(uint32_t assoc_id, mme_desc_p->state = S1AP_ENB_STATE_WAITING; s1ap_handle_s1_setup_message(mme_desc_p, 0); - return 0; } static int s1ap_eNB_handle_s1_setup_response(uint32_t assoc_id, uint32_t stream, - S1AP_S1AP_PDU_t *pdu) -{ + S1AP_S1AP_PDU_t *pdu) { S1AP_S1SetupResponse_t *container; S1AP_S1SetupResponseIEs_t *ie; s1ap_eNB_mme_data_t *mme_desc_p; int i; - DevAssert(pdu != NULL); - container = &pdu->choice.successfulOutcome.value.choice.S1SetupResponse; /* S1 Setup Response == Non UE-related procedure -> stream 0 */ @@ -324,20 +311,16 @@ int s1ap_eNB_handle_s1_setup_response(uint32_t assoc_id, S1AP_ServedGUMMEIsItem_t *gummei_item_p; struct served_gummei_s *new_gummei_p; int j; - gummei_item_p = ie->value.choice.ServedGUMMEIs.list.array[i]; new_gummei_p = calloc(1, sizeof(struct served_gummei_s)); - STAILQ_INIT(&new_gummei_p->served_plmns); STAILQ_INIT(&new_gummei_p->served_group_ids); STAILQ_INIT(&new_gummei_p->mme_codes); - S1AP_DEBUG("servedPLMNs.list.count %d\n", gummei_item_p->servedPLMNs.list.count); for (j = 0; j < gummei_item_p->servedPLMNs.list.count; j++) { S1AP_PLMNidentity_t *plmn_identity_p; struct plmn_identity_s *new_plmn_identity_p; - plmn_identity_p = gummei_item_p->servedPLMNs.list.array[j]; new_plmn_identity_p = calloc(1, sizeof(struct plmn_identity_s)); TBCD_TO_MCC_MNC(plmn_identity_p, new_plmn_identity_p->mcc, @@ -349,7 +332,6 @@ int s1ap_eNB_handle_s1_setup_response(uint32_t assoc_id, for (j = 0; j < gummei_item_p->servedGroupIDs.list.count; j++) { S1AP_MME_Group_ID_t *mme_group_id_p; struct served_group_id_s *new_group_id_p; - mme_group_id_p = gummei_item_p->servedGroupIDs.list.array[j]; new_group_id_p = calloc(1, sizeof(struct served_group_id_s)); OCTET_STRING_TO_INT16(mme_group_id_p, new_group_id_p->mme_group_id); @@ -360,10 +342,8 @@ int s1ap_eNB_handle_s1_setup_response(uint32_t assoc_id, for (j = 0; j < gummei_item_p->servedMMECs.list.count; j++) { S1AP_MME_Code_t *mme_code_p; struct mme_code_s *new_mme_code_p; - mme_code_p = gummei_item_p->servedMMECs.list.array[j]; new_mme_code_p = calloc(1, sizeof(struct mme_code_s)); - OCTET_STRING_TO_INT8(mme_code_p, new_mme_code_p->mme_code); STAILQ_INSERT_TAIL(&new_gummei_p->mme_codes, new_mme_code_p, next); new_gummei_p->nb_mme_code++; @@ -376,10 +356,10 @@ int s1ap_eNB_handle_s1_setup_response(uint32_t assoc_id, S1AP_FIND_PROTOCOLIE_BY_ID(S1AP_S1SetupResponseIEs_t, ie, container, S1AP_ProtocolIE_ID_id_RelativeMMECapacity, true); mme_desc_p->relative_mme_capacity = ie->value.choice.RelativeMMECapacity; - /* Optionaly set the mme name */ S1AP_FIND_PROTOCOLIE_BY_ID(S1AP_S1SetupResponseIEs_t, ie, container, S1AP_ProtocolIE_ID_id_MMEname, false); + if (ie) { mme_desc_p->mme_name = calloc(ie->value.choice.MMEname.size + 1, sizeof(char)); memcpy(mme_desc_p->mme_name, ie->value.choice.MMEname.buf, @@ -394,7 +374,6 @@ int s1ap_eNB_handle_s1_setup_response(uint32_t assoc_id, mme_desc_p->state = S1AP_ENB_STATE_CONNECTED; mme_desc_p->s1ap_eNB_instance->s1ap_mme_associated_nb ++; s1ap_handle_s1_setup_message(mme_desc_p, 0); - return 0; } @@ -402,14 +381,11 @@ int s1ap_eNB_handle_s1_setup_response(uint32_t assoc_id, static int s1ap_eNB_handle_error_indication(uint32_t assoc_id, uint32_t stream, - S1AP_S1AP_PDU_t *pdu) -{ + S1AP_S1AP_PDU_t *pdu) { S1AP_ErrorIndication_t *container; S1AP_ErrorIndicationIEs_t *ie; s1ap_eNB_mme_data_t *mme_desc_p; - DevAssert(pdu != NULL); - container = &pdu->choice.initiatingMessage.value.choice.ErrorIndication; /* S1 Setup Failure == Non UE-related procedure -> stream 0 */ @@ -455,118 +431,156 @@ int s1ap_eNB_handle_error_indication(uint32_t assoc_id, case S1AP_CauseRadioNetwork_unspecified: S1AP_WARN("Received S1 Error indication S1AP_CauseRadioNetwork_unspecified\n"); break; + case S1AP_CauseRadioNetwork_tx2relocoverall_expiry: S1AP_WARN("Received S1 Error indication S1AP_CauseRadioNetwork_tx2relocoverall_expiry\n"); break; + case S1AP_CauseRadioNetwork_successful_handover: S1AP_WARN("Received S1 Error indication S1AP_CauseRadioNetwork_successful_handover\n"); break; + case S1AP_CauseRadioNetwork_release_due_to_eutran_generated_reason: S1AP_WARN("Received S1 Error indication S1AP_CauseRadioNetwork_release_due_to_eutran_generated_reason\n"); break; + case S1AP_CauseRadioNetwork_handover_cancelled: S1AP_WARN("Received S1 Error indication S1AP_CauseRadioNetwork_handover_cancelled\n"); break; + case S1AP_CauseRadioNetwork_partial_handover: S1AP_WARN("Received S1 Error indication S1AP_CauseRadioNetwork_partial_handover\n"); break; + case S1AP_CauseRadioNetwork_ho_failure_in_target_EPC_eNB_or_target_system: S1AP_WARN("Received S1 Error indication S1AP_CauseRadioNetwork_ho_failure_in_target_EPC_eNB_or_target_system\n"); break; + case S1AP_CauseRadioNetwork_ho_target_not_allowed: S1AP_WARN("Received S1 Error indication S1AP_CauseRadioNetwork_ho_target_not_allowed\n"); break; + case S1AP_CauseRadioNetwork_tS1relocoverall_expiry: S1AP_WARN("Received S1 Error indication S1AP_CauseRadioNetwork_tS1relocoverall_expiry\n"); break; + case S1AP_CauseRadioNetwork_tS1relocprep_expiry: S1AP_WARN("Received S1 Error indication S1AP_CauseRadioNetwork_tS1relocprep_expiry\n"); break; + case S1AP_CauseRadioNetwork_cell_not_available: S1AP_WARN("Received S1 Error indication S1AP_CauseRadioNetwork_cell_not_available\n"); break; + case S1AP_CauseRadioNetwork_unknown_targetID: S1AP_WARN("Received S1 Error indication S1AP_CauseRadioNetwork_unknown_targetID\n"); break; + case S1AP_CauseRadioNetwork_no_radio_resources_available_in_target_cell: S1AP_WARN("Received S1 Error indication S1AP_CauseRadioNetwork_no_radio_resources_available_in_target_cell\n"); break; + case S1AP_CauseRadioNetwork_unknown_mme_ue_s1ap_id: S1AP_WARN("Received S1 Error indication S1AP_CauseRadioNetwork_unknown_mme_ue_s1ap_id\n"); break; + case S1AP_CauseRadioNetwork_unknown_enb_ue_s1ap_id: S1AP_WARN("Received S1 Error indication S1AP_CauseRadioNetwork_unknown_enb_ue_s1ap_id\n"); break; + case S1AP_CauseRadioNetwork_unknown_pair_ue_s1ap_id: S1AP_WARN("Received S1 Error indication S1AP_CauseRadioNetwork_unknown_pair_ue_s1ap_id\n"); break; + case S1AP_CauseRadioNetwork_handover_desirable_for_radio_reason: S1AP_WARN("Received S1 Error indication S1AP_CauseRadioNetwork_handover_desirable_for_radio_reason\n"); break; + case S1AP_CauseRadioNetwork_time_critical_handover: S1AP_WARN("Received S1 Error indication S1AP_CauseRadioNetwork_time_critical_handover\n"); break; + case S1AP_CauseRadioNetwork_resource_optimisation_handover: S1AP_WARN("Received S1 Error indication S1AP_CauseRadioNetwork_resource_optimisation_handover\n"); break; + case S1AP_CauseRadioNetwork_reduce_load_in_serving_cell: S1AP_WARN("Received S1 Error indication S1AP_CauseRadioNetwork_reduce_load_in_serving_cell\n"); break; + case S1AP_CauseRadioNetwork_user_inactivity: S1AP_WARN("Received S1 Error indication S1AP_CauseRadioNetwork_user_inactivity\n"); break; + case S1AP_CauseRadioNetwork_radio_connection_with_ue_lost: S1AP_WARN("Received S1 Error indication S1AP_CauseRadioNetwork_radio_connection_with_ue_lost\n"); break; + case S1AP_CauseRadioNetwork_load_balancing_tau_required: S1AP_WARN("Received S1 Error indication S1AP_CauseRadioNetwork_load_balancing_tau_required\n"); break; + case S1AP_CauseRadioNetwork_cs_fallback_triggered: S1AP_WARN("Received S1 Error indication S1AP_CauseRadioNetwork_cs_fallback_triggered\n"); break; + case S1AP_CauseRadioNetwork_ue_not_available_for_ps_service: S1AP_WARN("Received S1 Error indication S1AP_CauseRadioNetwork_ue_not_available_for_ps_service\n"); break; + case S1AP_CauseRadioNetwork_radio_resources_not_available: S1AP_WARN("Received S1 Error indication S1AP_CauseRadioNetwork_radio_resources_not_available\n"); break; + case S1AP_CauseRadioNetwork_failure_in_radio_interface_procedure: S1AP_WARN("Received S1 Error indication S1AP_CauseRadioNetwork_failure_in_radio_interface_procedure\n"); break; + case S1AP_CauseRadioNetwork_invalid_qos_combination: S1AP_WARN("Received S1 Error indication S1AP_CauseRadioNetwork_invals1ap_id_qos_combination\n"); break; + case S1AP_CauseRadioNetwork_interrat_redirection: S1AP_WARN("Received S1 Error indication S1AP_CauseRadioNetwork_interrat_redirection\n"); break; + case S1AP_CauseRadioNetwork_interaction_with_other_procedure: S1AP_WARN("Received S1 Error indication S1AP_CauseRadioNetwork_interaction_with_other_procedure\n"); break; + case S1AP_CauseRadioNetwork_unknown_E_RAB_ID: S1AP_WARN("Received S1 Error indication S1AP_CauseRadioNetwork_unknown_E_RAB_ID\n"); break; + case S1AP_CauseRadioNetwork_multiple_E_RAB_ID_instances: S1AP_WARN("Received S1 Error indication S1AP_CauseRadioNetwork_multiple_E_RAB_ID_instances\n"); break; + case S1AP_CauseRadioNetwork_encryption_and_or_integrity_protection_algorithms_not_supported: S1AP_WARN("Received S1 Error indication S1AP_CauseRadioNetwork_encryption_and_or_integrity_protection_algorithms_not_supported\n"); break; + case S1AP_CauseRadioNetwork_s1_intra_system_handover_triggered: S1AP_WARN("Received S1 Error indication S1AP_CauseRadioNetwork_s1_intra_system_handover_triggered\n"); break; + case S1AP_CauseRadioNetwork_s1_inter_system_handover_triggered: S1AP_WARN("Received S1 Error indication S1AP_CauseRadioNetwork_s1_inter_system_handover_triggered\n"); break; + case S1AP_CauseRadioNetwork_x2_handover_triggered: S1AP_WARN("Received S1 Error indication S1AP_CauseRadioNetwork_x2_handover_triggered\n"); break; + case S1AP_CauseRadioNetwork_redirection_towards_1xRTT: S1AP_WARN("Received S1 Error indication S1AP_CauseRadioNetwork_redirection_towards_1xRTT\n"); break; + case S1AP_CauseRadioNetwork_not_supported_QCI_value: S1AP_WARN("Received S1 Error indication S1AP_CauseRadioNetwork_not_supported_QCI_value\n"); break; #if (S1AP_VERSION >= MAKE_VERSION(9, 0, 0)) + case S1AP_CauseRadioNetwork_invalid_CSG_Id: S1AP_WARN("Received S1 Error indication S1AP_CauseRadioNetwork_invals1ap_id_CSG_Id\n"); break; @@ -575,6 +589,7 @@ int s1ap_eNB_handle_error_indication(uint32_t assoc_id, default: S1AP_WARN("Received S1 Error indication cause radio network case not handled\n"); } + break; case S1AP_Cause_PR_transport: @@ -582,12 +597,15 @@ int s1ap_eNB_handle_error_indication(uint32_t assoc_id, case S1AP_CauseTransport_transport_resource_unavailable: S1AP_WARN("Received S1 Error indication S1AP_CauseTransport_transport_resource_unavailable\n"); break; + case S1AP_CauseTransport_unspecified: S1AP_WARN("Received S1 Error indication S1AP_CauseTransport_unspecified\n"); break; + default: S1AP_WARN("Received S1 Error indication cause transport case not handled\n"); } + break; case S1AP_Cause_PR_nas: @@ -595,20 +613,25 @@ int s1ap_eNB_handle_error_indication(uint32_t assoc_id, case S1AP_CauseNas_normal_release: S1AP_WARN("Received S1 Error indication S1AP_CauseNas_normal_release\n"); break; + case S1AP_CauseNas_authentication_failure: S1AP_WARN("Received S1 Error indication S1AP_CauseNas_authentication_failure\n"); break; + case S1AP_CauseNas_detach: S1AP_WARN("Received S1 Error indication S1AP_CauseNas_detach\n"); break; + case S1AP_CauseNas_unspecified: S1AP_WARN("Received S1 Error indication S1AP_CauseNas_unspecified\n"); break; #if (S1AP_VERSION >= MAKE_VERSION(9, 0, 0)) + case S1AP_CauseNas_csg_subscription_expiry: S1AP_WARN("Received S1 Error indication S1AP_CauseNas_csg_subscription_expiry\n"); break; #endif /* #if (S1AP_VERSION >= MAKE_VERSION(9, 0, 0)) */ + default: S1AP_WARN("Received S1 Error indication cause nas case not handled\n"); } @@ -620,27 +643,35 @@ int s1ap_eNB_handle_error_indication(uint32_t assoc_id, case S1AP_CauseProtocol_transfer_syntax_error: S1AP_WARN("Received S1 Error indication S1AP_CauseProtocol_transfer_syntax_error\n"); break; + case S1AP_CauseProtocol_abstract_syntax_error_reject: S1AP_WARN("Received S1 Error indication S1AP_CauseProtocol_abstract_syntax_error_reject\n"); break; + case S1AP_CauseProtocol_abstract_syntax_error_ignore_and_notify: S1AP_WARN("Received S1 Error indication S1AP_CauseProtocol_abstract_syntax_error_ignore_and_notify\n"); break; + case S1AP_CauseProtocol_message_not_compatible_with_receiver_state: S1AP_WARN("Received S1 Error indication S1AP_CauseProtocol_message_not_compatible_with_receiver_state\n"); break; + case S1AP_CauseProtocol_semantic_error: S1AP_WARN("Received S1 Error indication S1AP_CauseProtocol_semantic_error\n"); break; + case S1AP_CauseProtocol_abstract_syntax_error_falsely_constructed_message: S1AP_WARN("Received S1 Error indication S1AP_CauseProtocol_abstract_syntax_error_falsely_constructed_message\n"); break; + case S1AP_CauseProtocol_unspecified: S1AP_WARN("Received S1 Error indication S1AP_CauseProtocol_unspecified\n"); break; + default: S1AP_WARN("Received S1 Error indication cause protocol case not handled\n"); } + break; case S1AP_Cause_PR_misc: @@ -648,24 +679,31 @@ int s1ap_eNB_handle_error_indication(uint32_t assoc_id, case S1AP_CauseMisc_control_processing_overload: S1AP_WARN("Received S1 Error indication S1AP_CauseMisc_control_processing_overload\n"); break; + case S1AP_CauseMisc_not_enough_user_plane_processing_resources: S1AP_WARN("Received S1 Error indication S1AP_CauseMisc_not_enough_user_plane_processing_resources\n"); break; + case S1AP_CauseMisc_hardware_failure: S1AP_WARN("Received S1 Error indication S1AP_CauseMisc_hardware_failure\n"); break; + case S1AP_CauseMisc_om_intervention: S1AP_WARN("Received S1 Error indication S1AP_CauseMisc_om_intervention\n"); break; + case S1AP_CauseMisc_unspecified: S1AP_WARN("Received S1 Error indication S1AP_CauseMisc_unspecified\n"); break; + case S1AP_CauseMisc_unknown_PLMN: S1AP_WARN("Received S1 Error indication S1AP_CauseMisc_unknown_PLMN\n"); break; + default: S1AP_WARN("Received S1 Error indication cause misc case not handled\n"); } + break; } } @@ -676,8 +714,8 @@ int s1ap_eNB_handle_error_indication(uint32_t assoc_id, if (ie) { // TODO continue } - // TODO continue + // TODO continue return 0; } @@ -685,8 +723,7 @@ int s1ap_eNB_handle_error_indication(uint32_t assoc_id, static int s1ap_eNB_handle_initial_context_request(uint32_t assoc_id, uint32_t stream, - S1AP_S1AP_PDU_t *pdu) -{ + S1AP_S1AP_PDU_t *pdu) { int i; s1ap_eNB_mme_data_t *mme_desc_p = NULL; s1ap_eNB_ue_context_t *ue_desc_p = NULL; @@ -695,9 +732,7 @@ int s1ap_eNB_handle_initial_context_request(uint32_t assoc_id, S1AP_InitialContextSetupRequestIEs_t *ie; S1AP_ENB_UE_S1AP_ID_t enb_ue_s1ap_id; S1AP_MME_UE_S1AP_ID_t mme_ue_s1ap_id; - DevAssert(pdu != NULL); - container = &pdu->choice.initiatingMessage.value.choice.InitialContextSetupRequest; if ((mme_desc_p = s1ap_eNB_get_MME(NULL, assoc_id, 0)) == NULL) { @@ -710,14 +745,13 @@ int s1ap_eNB_handle_initial_context_request(uint32_t assoc_id, S1AP_FIND_PROTOCOLIE_BY_ID(S1AP_InitialContextSetupRequestIEs_t, ie, container, S1AP_ProtocolIE_ID_id_MME_UE_S1AP_ID, true); mme_ue_s1ap_id = ie->value.choice.MME_UE_S1AP_ID; - /* id-eNB-UE-S1AP-ID */ S1AP_FIND_PROTOCOLIE_BY_ID(S1AP_InitialContextSetupRequestIEs_t, ie, container, S1AP_ProtocolIE_ID_id_eNB_UE_S1AP_ID, true); enb_ue_s1ap_id = ie->value.choice.ENB_UE_S1AP_ID; if ((ue_desc_p = s1ap_eNB_get_ue_context(mme_desc_p->s1ap_eNB_instance, - enb_ue_s1ap_id)) == NULL) { + enb_ue_s1ap_id)) == NULL) { S1AP_ERROR("[SCTP %d] Received initial context setup request for non " "existing UE context 0x%06lx\n", assoc_id, enb_ue_s1ap_id); @@ -732,16 +766,11 @@ int s1ap_eNB_handle_initial_context_request(uint32_t assoc_id, } ue_desc_p->rx_stream = stream; - ue_desc_p->mme_ue_s1ap_id = mme_ue_s1ap_id; - message_p = itti_alloc_new_message(TASK_S1AP, S1AP_INITIAL_CONTEXT_SETUP_REQ); - S1AP_INITIAL_CONTEXT_SETUP_REQ(message_p).ue_initial_id = ue_desc_p->ue_initial_id; ue_desc_p->ue_initial_id = 0; - S1AP_INITIAL_CONTEXT_SETUP_REQ(message_p).eNB_ue_s1ap_id = ue_desc_p->eNB_ue_s1ap_id; - /* id-uEaggregateMaximumBitrate */ S1AP_FIND_PROTOCOLIE_BY_ID(S1AP_InitialContextSetupRequestIEs_t, ie, container, S1AP_ProtocolIE_ID_id_uEaggregateMaximumBitrate, true); @@ -749,11 +778,9 @@ int s1ap_eNB_handle_initial_context_request(uint32_t assoc_id, &(S1AP_INITIAL_CONTEXT_SETUP_REQ(message_p).ue_ambr.br_ul)); asn_INTEGER2ulong(&(ie->value.choice.UEAggregateMaximumBitrate.uEaggregateMaximumBitRateDL), &(S1AP_INITIAL_CONTEXT_SETUP_REQ(message_p).ue_ambr.br_dl)); - /* id-E-RABToBeSetupListCtxtSUReq */ S1AP_FIND_PROTOCOLIE_BY_ID(S1AP_InitialContextSetupRequestIEs_t, ie, container, S1AP_ProtocolIE_ID_id_E_RABToBeSetupListCtxtSUReq, true); - S1AP_INITIAL_CONTEXT_SETUP_REQ(message_p).nb_of_e_rabs = ie->value.choice.E_RABToBeSetupListCtxtSUReq.list.count; @@ -765,10 +792,8 @@ int s1ap_eNB_handle_initial_context_request(uint32_t assoc_id, if (item_p->nAS_PDU != NULL) { /* Only copy NAS pdu if present */ S1AP_INITIAL_CONTEXT_SETUP_REQ(message_p).e_rab_param[i].nas_pdu.length = item_p->nAS_PDU->size; - S1AP_INITIAL_CONTEXT_SETUP_REQ(message_p).e_rab_param[i].nas_pdu.buffer = malloc(sizeof(uint8_t) * item_p->nAS_PDU->size); - memcpy(S1AP_INITIAL_CONTEXT_SETUP_REQ(message_p).e_rab_param[i].nas_pdu.buffer, item_p->nAS_PDU->buf, item_p->nAS_PDU->size); S1AP_DEBUG("Received NAS message with the E_RAB setup procedure\n"); @@ -782,13 +807,10 @@ int s1ap_eNB_handle_initial_context_request(uint32_t assoc_id, item_p->transportLayerAddress.buf, item_p->transportLayerAddress.size); S1AP_INITIAL_CONTEXT_SETUP_REQ(message_p).e_rab_param[i].sgw_addr.length = item_p->transportLayerAddress.size * 8 - item_p->transportLayerAddress.bits_unused; - /* GTP tunnel endpoint ID */ OCTET_STRING_TO_INT32(&item_p->gTP_TEID, S1AP_INITIAL_CONTEXT_SETUP_REQ(message_p).e_rab_param[i].gtp_teid); - /* Set the QOS informations */ S1AP_INITIAL_CONTEXT_SETUP_REQ(message_p).e_rab_param[i].qos.qci = item_p->e_RABlevelQoSParameters.qCI; - S1AP_INITIAL_CONTEXT_SETUP_REQ(message_p).e_rab_param[i].qos.allocation_retention_priority.priority_level = item_p->e_RABlevelQoSParameters.allocationRetentionPriority.priorityLevel; S1AP_INITIAL_CONTEXT_SETUP_REQ(message_p).e_rab_param[i].qos.allocation_retention_priority.pre_emp_capability = @@ -804,15 +826,12 @@ int s1ap_eNB_handle_initial_context_request(uint32_t assoc_id, BIT_STRING_to_uint16(&ie->value.choice.UESecurityCapabilities.encryptionAlgorithms); S1AP_INITIAL_CONTEXT_SETUP_REQ(message_p).security_capabilities.integrity_algorithms = BIT_STRING_to_uint16(&ie->value.choice.UESecurityCapabilities.integrityProtectionAlgorithms); - /* id-SecurityKey : Copy the security key */ S1AP_FIND_PROTOCOLIE_BY_ID(S1AP_InitialContextSetupRequestIEs_t, ie, container, S1AP_ProtocolIE_ID_id_SecurityKey, true); memcpy(&S1AP_INITIAL_CONTEXT_SETUP_REQ(message_p).security_key, ie->value.choice.SecurityKey.buf, ie->value.choice.SecurityKey.size); - itti_send_msg_to_task(TASK_RRC_ENB, ue_desc_p->eNB_instance->instance, message_p); - return 0; } @@ -820,8 +839,7 @@ int s1ap_eNB_handle_initial_context_request(uint32_t assoc_id, static int s1ap_eNB_handle_ue_context_release_command(uint32_t assoc_id, uint32_t stream, - S1AP_S1AP_PDU_t *pdu) -{ + S1AP_S1AP_PDU_t *pdu) { s1ap_eNB_mme_data_t *mme_desc_p = NULL; s1ap_eNB_ue_context_t *ue_desc_p = NULL; MessageDef *message_p = NULL; @@ -829,9 +847,7 @@ int s1ap_eNB_handle_ue_context_release_command(uint32_t assoc_id, S1AP_ENB_UE_S1AP_ID_t enb_ue_s1ap_id; S1AP_UEContextReleaseCommand_t *container; S1AP_UEContextReleaseCommand_IEs_t *ie; - DevAssert(pdu != NULL); - container = &pdu->choice.initiatingMessage.value.choice.UEContextReleaseCommand; if ((mme_desc_p = s1ap_eNB_get_MME(NULL, assoc_id, 0)) == NULL) { @@ -847,7 +863,6 @@ int s1ap_eNB_handle_ue_context_release_command(uint32_t assoc_id, case S1AP_UE_S1AP_IDs_PR_uE_S1AP_ID_pair: enb_ue_s1ap_id = ie->value.choice.UE_S1AP_IDs.choice.uE_S1AP_ID_pair.eNB_UE_S1AP_ID; mme_ue_s1ap_id = ie->value.choice.UE_S1AP_IDs.choice.uE_S1AP_ID_pair.mME_UE_S1AP_ID; - MSC_LOG_RX_MESSAGE( MSC_S1AP_ENB, MSC_S1AP_MME, @@ -858,12 +873,11 @@ int s1ap_eNB_handle_ue_context_release_command(uint32_t assoc_id, mme_ue_s1ap_id); if ((ue_desc_p = s1ap_eNB_get_ue_context(mme_desc_p->s1ap_eNB_instance, - enb_ue_s1ap_id)) == NULL) { + enb_ue_s1ap_id)) == NULL) { S1AP_ERROR("[SCTP %d] Received UE context release command for non " "existing UE context 0x%06lx\n", assoc_id, enb_ue_s1ap_id); - return -1; } else { MSC_LOG_TX_MESSAGE( @@ -875,7 +889,7 @@ int s1ap_eNB_handle_ue_context_release_command(uint32_t assoc_id, message_p = itti_alloc_new_message(TASK_S1AP, S1AP_UE_CONTEXT_RELEASE_COMMAND); if (ue_desc_p->mme_ue_s1ap_id == 0) { // case of Detach Request and switch off from RRC_IDLE mode - ue_desc_p->mme_ue_s1ap_id = mme_ue_s1ap_id; + ue_desc_p->mme_ue_s1ap_id = mme_ue_s1ap_id; } S1AP_UE_CONTEXT_RELEASE_COMMAND(message_p).eNB_ue_s1ap_id = enb_ue_s1ap_id; @@ -906,8 +920,7 @@ int s1ap_eNB_handle_ue_context_release_command(uint32_t assoc_id, static int s1ap_eNB_handle_e_rab_setup_request(uint32_t assoc_id, uint32_t stream, - S1AP_S1AP_PDU_t *pdu) -{ + S1AP_S1AP_PDU_t *pdu) { int i; S1AP_MME_UE_S1AP_ID_t mme_ue_s1ap_id; S1AP_ENB_UE_S1AP_ID_t enb_ue_s1ap_id; @@ -916,9 +929,7 @@ int s1ap_eNB_handle_e_rab_setup_request(uint32_t assoc_id, MessageDef *message_p = NULL; S1AP_E_RABSetupRequest_t *container; S1AP_E_RABSetupRequestIEs_t *ie; - DevAssert(pdu != NULL); - container = &pdu->choice.initiatingMessage.value.choice.E_RABSetupRequest; if ((mme_desc_p = s1ap_eNB_get_MME(NULL, assoc_id, 0)) == NULL) { @@ -931,14 +942,13 @@ int s1ap_eNB_handle_e_rab_setup_request(uint32_t assoc_id, S1AP_FIND_PROTOCOLIE_BY_ID(S1AP_E_RABSetupRequestIEs_t, ie, container, S1AP_ProtocolIE_ID_id_MME_UE_S1AP_ID, true); mme_ue_s1ap_id = ie->value.choice.MME_UE_S1AP_ID; - /* id-eNB-UE-S1AP-ID */ S1AP_FIND_PROTOCOLIE_BY_ID(S1AP_E_RABSetupRequestIEs_t, ie, container, S1AP_ProtocolIE_ID_id_eNB_UE_S1AP_ID, true); enb_ue_s1ap_id = ie->value.choice.ENB_UE_S1AP_ID; if ((ue_desc_p = s1ap_eNB_get_ue_context(mme_desc_p->s1ap_eNB_instance, - enb_ue_s1ap_id)) == NULL) { + enb_ue_s1ap_id)) == NULL) { S1AP_ERROR("[SCTP %d] Received initial context setup request for non " "existing UE context 0x%06lx\n", assoc_id, enb_ue_s1ap_id); @@ -960,11 +970,9 @@ int s1ap_eNB_handle_e_rab_setup_request(uint32_t assoc_id, } message_p = itti_alloc_new_message(TASK_S1AP, S1AP_E_RAB_SETUP_REQ); - S1AP_E_RAB_SETUP_REQ(message_p).ue_initial_id = ue_desc_p->ue_initial_id; S1AP_E_RAB_SETUP_REQ(message_p).mme_ue_s1ap_id = mme_ue_s1ap_id; S1AP_E_RAB_SETUP_REQ(message_p).eNB_ue_s1ap_id = enb_ue_s1ap_id; - S1AP_FIND_PROTOCOLIE_BY_ID(S1AP_E_RABSetupRequestIEs_t, ie, container, S1AP_ProtocolIE_ID_id_E_RABToBeSetupListBearerSUReq, true); S1AP_E_RAB_SETUP_REQ(message_p).nb_e_rabs_tosetup = @@ -972,24 +980,19 @@ int s1ap_eNB_handle_e_rab_setup_request(uint32_t assoc_id, for (i = 0; i < ie->value.choice.E_RABToBeSetupListBearerSUReq.list.count; i++) { S1AP_E_RABToBeSetupItemBearerSUReq_t *item_p; - item_p = &(((S1AP_E_RABToBeSetupItemBearerSUReqIEs_t *)ie->value.choice.E_RABToBeSetupListBearerSUReq.list.array[i])->value.choice.E_RABToBeSetupItemBearerSUReq); - S1AP_E_RAB_SETUP_REQ(message_p).e_rab_setup_params[i].e_rab_id = item_p->e_RAB_ID; // check for the NAS PDU if (item_p->nAS_PDU.size > 0 ) { S1AP_E_RAB_SETUP_REQ(message_p).e_rab_setup_params[i].nas_pdu.length = item_p->nAS_PDU.size; - S1AP_E_RAB_SETUP_REQ(message_p).e_rab_setup_params[i].nas_pdu.buffer = malloc(sizeof(uint8_t) * item_p->nAS_PDU.size); - memcpy(S1AP_E_RAB_SETUP_REQ(message_p).e_rab_setup_params[i].nas_pdu.buffer, item_p->nAS_PDU.buf, item_p->nAS_PDU.size); // S1AP_INFO("received a NAS PDU with size %d (%02x.%02x)\n",S1AP_E_RAB_SETUP_REQ(message_p).e_rab_setup_params[i].nas_pdu.length, item_p->nAS_PDU.buf[0], item_p->nAS_PDU.buf[1]); } else { S1AP_E_RAB_SETUP_REQ(message_p).e_rab_setup_params[i].nas_pdu.length = 0; S1AP_E_RAB_SETUP_REQ(message_p).e_rab_setup_params[i].nas_pdu.buffer = NULL; - S1AP_WARN("NAS PDU is not provided, generate a E_RAB_SETUP Failure (TBD) back to MME \n"); // return -1; } @@ -999,7 +1002,6 @@ int s1ap_eNB_handle_e_rab_setup_request(uint32_t assoc_id, item_p->transportLayerAddress.buf, item_p->transportLayerAddress.size); S1AP_E_RAB_SETUP_REQ(message_p).e_rab_setup_params[i].sgw_addr.length = item_p->transportLayerAddress.size * 8 - item_p->transportLayerAddress.bits_unused; - /* S1AP_INFO("sgw addr %s len: %d (size %d, index %d)\n", S1AP_E_RAB_SETUP_REQ(message_p).e_rab_setup_params[i].sgw_addr.buffer, S1AP_E_RAB_SETUP_REQ(message_p).e_rab_setup_params[i].sgw_addr.length, @@ -1007,10 +1009,8 @@ int s1ap_eNB_handle_e_rab_setup_request(uint32_t assoc_id, */ /* GTP tunnel endpoint ID */ OCTET_STRING_TO_INT32(&item_p->gTP_TEID, S1AP_E_RAB_SETUP_REQ(message_p).e_rab_setup_params[i].gtp_teid); - /* Set the QOS informations */ S1AP_E_RAB_SETUP_REQ(message_p).e_rab_setup_params[i].qos.qci = item_p->e_RABlevelQoSParameters.qCI; - S1AP_E_RAB_SETUP_REQ(message_p).e_rab_setup_params[i].qos.allocation_retention_priority.priority_level = item_p->e_RABlevelQoSParameters.allocationRetentionPriority.priorityLevel; S1AP_E_RAB_SETUP_REQ(message_p).e_rab_setup_params[i].qos.allocation_retention_priority.pre_emp_capability = @@ -1020,32 +1020,27 @@ int s1ap_eNB_handle_e_rab_setup_request(uint32_t assoc_id, } itti_send_msg_to_task(TASK_RRC_ENB, ue_desc_p->eNB_instance->instance, message_p); - return 0; } static int s1ap_eNB_handle_paging(uint32_t assoc_id, uint32_t stream, - S1AP_S1AP_PDU_t *pdu) -{ + S1AP_S1AP_PDU_t *pdu) { s1ap_eNB_mme_data_t *mme_desc_p = NULL; s1ap_eNB_instance_t *s1ap_eNB_instance = NULL; MessageDef *message_p = NULL; S1AP_Paging_t *container; S1AP_PagingIEs_t *ie; - DevAssert(pdu != NULL); - container = &pdu->choice.initiatingMessage.value.choice.Paging; - // received Paging Message from MME S1AP_DEBUG("[SCTP %d] Received Paging Message From MME\n",assoc_id); /* Paging procedure -> stream != 0 */ if (stream == 0) { LOG_W(S1AP,"[SCTP %d] Received Paging procedure on stream (%d)\n", - assoc_id, stream); + assoc_id, stream); return -1; } @@ -1056,6 +1051,7 @@ int s1ap_eNB_handle_paging(uint32_t assoc_id, } s1ap_eNB_instance = mme_desc_p->s1ap_eNB_instance; + if (s1ap_eNB_instance == NULL) { S1AP_ERROR("[SCTP %d] Received Paging for non existing MME context : s1ap_eNB_instance is NULL\n", assoc_id); @@ -1063,7 +1059,6 @@ int s1ap_eNB_handle_paging(uint32_t assoc_id, } message_p = itti_alloc_new_message(TASK_S1AP, S1AP_PAGING_IND); - /* convert S1AP_PagingIEs_t to s1ap_paging_ind_t */ /* id-UEIdentityIndexValue : convert UE Identity Index value */ S1AP_FIND_PROTOCOLIE_BY_ID(S1AP_PagingIEs_t, ie, container, @@ -1071,13 +1066,12 @@ int s1ap_eNB_handle_paging(uint32_t assoc_id, S1AP_PAGING_IND(message_p).ue_index_value = BIT_STRING_to_uint32(&ie->value.choice.UEIdentityIndexValue); S1AP_DEBUG("[SCTP %d] Received Paging ue_index_value (%d)\n", assoc_id,(uint32_t)S1AP_PAGING_IND(message_p).ue_index_value); - S1AP_PAGING_IND(message_p).ue_paging_identity.choice.s_tmsi.mme_code = 0; S1AP_PAGING_IND(message_p).ue_paging_identity.choice.s_tmsi.m_tmsi = 0; - /* id-UEPagingID */ S1AP_FIND_PROTOCOLIE_BY_ID(S1AP_PagingIEs_t, ie, container, S1AP_ProtocolIE_ID_id_UEPagingID, true); + /* convert UE Paging Identity */ if (ie->value.choice.UEPagingID.present == S1AP_UEPagingID_PR_s_TMSI) { S1AP_PAGING_IND(message_p).ue_paging_identity.presenceMask = UE_PAGING_IDENTITY_s_tmsi; @@ -1116,7 +1110,6 @@ int s1ap_eNB_handle_paging(uint32_t assoc_id, } S1AP_PAGING_IND(message_p).paging_drx = PAGING_DRX_256; - /* id-pagingDRX */ S1AP_FIND_PROTOCOLIE_BY_ID(S1AP_PagingIEs_t, ie, container, S1AP_ProtocolIE_ID_id_pagingDRX, false); @@ -1146,7 +1139,6 @@ int s1ap_eNB_handle_paging(uint32_t assoc_id, memset (&S1AP_PAGING_IND(message_p).plmn_identity[0], 0, sizeof(plmn_identity_t)*256); memset (&S1AP_PAGING_IND(message_p).tac[0], 0, sizeof(int16_t)*256); S1AP_PAGING_IND(message_p).tai_size = 0; - /* id-TAIList */ S1AP_FIND_PROTOCOLIE_BY_ID(S1AP_PagingIEs_t, ie, container, S1AP_ProtocolIE_ID_id_TAIList, true); @@ -1166,7 +1158,6 @@ int s1ap_eNB_handle_paging(uint32_t assoc_id, S1AP_PAGING_IND(message_p).tac[i]); } - //paging parameter values S1AP_DEBUG("[SCTP %d] Received Paging parameters: ue_index_value %d cn_domain %d paging_drx %d paging_priority %d\n",assoc_id, S1AP_PAGING_IND(message_p).ue_index_value, S1AP_PAGING_IND(message_p).cn_domain, @@ -1177,18 +1168,15 @@ int s1ap_eNB_handle_paging(uint32_t assoc_id, S1AP_PAGING_IND(message_p).ue_paging_identity.choice.imsi.buffer[0], S1AP_PAGING_IND(message_p).ue_paging_identity.choice.imsi.buffer[1], S1AP_PAGING_IND(message_p).ue_paging_identity.choice.imsi.buffer[2], S1AP_PAGING_IND(message_p).ue_paging_identity.choice.imsi.buffer[3], S1AP_PAGING_IND(message_p).ue_paging_identity.choice.imsi.buffer[4], S1AP_PAGING_IND(message_p).ue_paging_identity.choice.imsi.buffer[5]); - /* send message to RRC */ itti_send_msg_to_task(TASK_RRC_ENB, s1ap_eNB_instance->instance, message_p); - return 0; } static int s1ap_eNB_handle_e_rab_modify_request(uint32_t assoc_id, - uint32_t stream, - S1AP_S1AP_PDU_t *pdu) -{ + uint32_t stream, + S1AP_S1AP_PDU_t *pdu) { int i, nb_of_e_rabs_failed; s1ap_eNB_mme_data_t *mme_desc_p = NULL; s1ap_eNB_ue_context_t *ue_desc_p = NULL; @@ -1197,9 +1185,7 @@ int s1ap_eNB_handle_e_rab_modify_request(uint32_t assoc_id, S1AP_E_RABModifyRequestIEs_t *ie; S1AP_ENB_UE_S1AP_ID_t enb_ue_s1ap_id; S1AP_MME_UE_S1AP_ID_t mme_ue_s1ap_id; - DevAssert(pdu != NULL); - container = &pdu->choice.initiatingMessage.value.choice.E_RABModifyRequest; if ((mme_desc_p = s1ap_eNB_get_MME(NULL, assoc_id, 0)) == NULL) { @@ -1212,14 +1198,13 @@ int s1ap_eNB_handle_e_rab_modify_request(uint32_t assoc_id, S1AP_FIND_PROTOCOLIE_BY_ID(S1AP_E_RABModifyRequestIEs_t, ie, container, S1AP_ProtocolIE_ID_id_MME_UE_S1AP_ID, true); mme_ue_s1ap_id = ie->value.choice.MME_UE_S1AP_ID; - /* id-eNB-UE-S1AP-ID */ S1AP_FIND_PROTOCOLIE_BY_ID(S1AP_E_RABModifyRequestIEs_t, ie, container, S1AP_ProtocolIE_ID_id_eNB_UE_S1AP_ID, true); enb_ue_s1ap_id = ie->value.choice.ENB_UE_S1AP_ID; if ((ue_desc_p = s1ap_eNB_get_ue_context(mme_desc_p->s1ap_eNB_instance, - enb_ue_s1ap_id)) == NULL) { + enb_ue_s1ap_id)) == NULL) { S1AP_ERROR("[SCTP %d] Received E-RAB modify request for non " "existing UE context 0x%06lx\n", assoc_id, enb_ue_s1ap_id); @@ -1239,9 +1224,7 @@ int s1ap_eNB_handle_e_rab_modify_request(uint32_t assoc_id, S1AP_WARN("UE context mme_ue_s1ap_id is different form that of the message (%d != %ld)", ue_desc_p->mme_ue_s1ap_id, mme_ue_s1ap_id); message_p = itti_alloc_new_message (TASK_RRC_ENB, S1AP_E_RAB_MODIFY_RESP); - S1AP_E_RAB_MODIFY_RESP (message_p).eNB_ue_s1ap_id = enb_ue_s1ap_id; - S1AP_FIND_PROTOCOLIE_BY_ID(S1AP_E_RABModifyRequestIEs_t, ie, container, S1AP_ProtocolIE_ID_id_E_RABToBeModifiedListBearerModReq, true); @@ -1253,22 +1236,18 @@ int s1ap_eNB_handle_e_rab_modify_request(uint32_t assoc_id, S1AP_E_RAB_MODIFY_RESP(message_p).e_rabs_failed[nb_of_e_rabs_failed].cause = S1AP_Cause_PR_radioNetwork; S1AP_E_RAB_MODIFY_RESP(message_p).e_rabs_failed[nb_of_e_rabs_failed].cause_value = S1AP_CauseRadioNetwork_unknown_mme_ue_s1ap_id; } - S1AP_E_RAB_MODIFY_RESP(message_p).nb_of_e_rabs_failed = nb_of_e_rabs_failed; + S1AP_E_RAB_MODIFY_RESP(message_p).nb_of_e_rabs_failed = nb_of_e_rabs_failed; s1ap_eNB_e_rab_modify_resp(mme_desc_p->s1ap_eNB_instance->instance, &S1AP_E_RAB_MODIFY_RESP(message_p)); - message_p = NULL; return -1; } message_p = itti_alloc_new_message(TASK_S1AP, S1AP_E_RAB_MODIFY_REQ); - S1AP_E_RAB_MODIFY_REQ(message_p).ue_initial_id = ue_desc_p->ue_initial_id; - S1AP_E_RAB_MODIFY_REQ(message_p).mme_ue_s1ap_id = mme_ue_s1ap_id; S1AP_E_RAB_MODIFY_REQ(message_p).eNB_ue_s1ap_id = enb_ue_s1ap_id; - /* id-E-RABToBeModifiedListBearerModReq */ S1AP_FIND_PROTOCOLIE_BY_ID(S1AP_E_RABModifyRequestIEs_t, ie, container, S1AP_ProtocolIE_ID_id_E_RABToBeModifiedListBearerModReq, true); @@ -1283,9 +1262,7 @@ int s1ap_eNB_handle_e_rab_modify_request(uint32_t assoc_id, // check for the NAS PDU if (item_p->nAS_PDU.size > 0 ) { S1AP_E_RAB_MODIFY_REQ(message_p).e_rab_modify_params[i].nas_pdu.length = item_p->nAS_PDU.size; - S1AP_E_RAB_MODIFY_REQ(message_p).e_rab_modify_params[i].nas_pdu.buffer = malloc(sizeof(uint8_t) * item_p->nAS_PDU.size); - memcpy(S1AP_E_RAB_MODIFY_REQ(message_p).e_rab_modify_params[i].nas_pdu.buffer, item_p->nAS_PDU.buf, item_p->nAS_PDU.size); } else { @@ -1296,26 +1273,22 @@ int s1ap_eNB_handle_e_rab_modify_request(uint32_t assoc_id, /* Set the QOS informations */ S1AP_E_RAB_MODIFY_REQ(message_p).e_rab_modify_params[i].qos.qci = item_p->e_RABLevelQoSParameters.qCI; - S1AP_E_RAB_MODIFY_REQ(message_p).e_rab_modify_params[i].qos.allocation_retention_priority.priority_level = item_p->e_RABLevelQoSParameters.allocationRetentionPriority.priorityLevel; S1AP_E_RAB_MODIFY_REQ(message_p).e_rab_modify_params[i].qos.allocation_retention_priority.pre_emp_capability = item_p->e_RABLevelQoSParameters.allocationRetentionPriority.pre_emptionCapability; S1AP_E_RAB_MODIFY_REQ(message_p).e_rab_modify_params[i].qos.allocation_retention_priority.pre_emp_vulnerability = item_p->e_RABLevelQoSParameters.allocationRetentionPriority.pre_emptionVulnerability; - } itti_send_msg_to_task(TASK_RRC_ENB, ue_desc_p->eNB_instance->instance, message_p); - return 0; } // handle e-rab release command and send it to rrc_end static int s1ap_eNB_handle_e_rab_release_command(uint32_t assoc_id, - uint32_t stream, - S1AP_S1AP_PDU_t *pdu) -{ + uint32_t stream, + S1AP_S1AP_PDU_t *pdu) { int i; s1ap_eNB_mme_data_t *mme_desc_p = NULL; s1ap_eNB_ue_context_t *ue_desc_p = NULL; @@ -1324,9 +1297,7 @@ int s1ap_eNB_handle_e_rab_release_command(uint32_t assoc_id, S1AP_E_RABReleaseCommandIEs_t *ie; S1AP_ENB_UE_S1AP_ID_t enb_ue_s1ap_id; S1AP_MME_UE_S1AP_ID_t mme_ue_s1ap_id; - DevAssert(pdu != NULL); - container = &pdu->choice.initiatingMessage.value.choice.E_RABReleaseCommand; if ((mme_desc_p = s1ap_eNB_get_MME(NULL, assoc_id, 0)) == NULL) { @@ -1338,14 +1309,13 @@ int s1ap_eNB_handle_e_rab_release_command(uint32_t assoc_id, S1AP_FIND_PROTOCOLIE_BY_ID(S1AP_E_RABReleaseCommandIEs_t, ie, container, S1AP_ProtocolIE_ID_id_MME_UE_S1AP_ID, true); mme_ue_s1ap_id = ie->value.choice.MME_UE_S1AP_ID; - /* id-eNB-UE-S1AP-ID */ S1AP_FIND_PROTOCOLIE_BY_ID(S1AP_E_RABReleaseCommandIEs_t, ie, container, S1AP_ProtocolIE_ID_id_eNB_UE_S1AP_ID, true); enb_ue_s1ap_id = ie->value.choice.ENB_UE_S1AP_ID; if ((ue_desc_p = s1ap_eNB_get_ue_context(mme_desc_p->s1ap_eNB_instance, - enb_ue_s1ap_id)) == NULL) { + enb_ue_s1ap_id)) == NULL) { S1AP_ERROR("[SCTP %d] Received E-RAB release command for non existing UE context 0x%06lx\n", assoc_id, ie->value.choice.ENB_UE_S1AP_ID); return -1; @@ -1367,14 +1337,13 @@ int s1ap_eNB_handle_e_rab_release_command(uint32_t assoc_id, S1AP_DEBUG("[SCTP %d] Received E-RAB release command for eNB_UE_S1AP_ID %ld mme_ue_s1ap_id %ld\n", assoc_id, enb_ue_s1ap_id, mme_ue_s1ap_id); - message_p = itti_alloc_new_message(TASK_S1AP, S1AP_E_RAB_RELEASE_COMMAND); S1AP_E_RAB_RELEASE_COMMAND(message_p).eNB_ue_s1ap_id = enb_ue_s1ap_id; S1AP_E_RAB_RELEASE_COMMAND(message_p).mme_ue_s1ap_id = mme_ue_s1ap_id; - /* id-NAS-PDU */ S1AP_FIND_PROTOCOLIE_BY_ID(S1AP_E_RABReleaseCommandIEs_t, ie, container, S1AP_ProtocolIE_ID_id_NAS_PDU, false); + if(ie && ie->value.choice.NAS_PDU.size > 0) { S1AP_E_RAB_RELEASE_COMMAND(message_p).nas_pdu.length = ie->value.choice.NAS_PDU.size; S1AP_E_RAB_RELEASE_COMMAND(message_p).nas_pdu.buffer = @@ -1400,6 +1369,5 @@ int s1ap_eNB_handle_e_rab_release_command(uint32_t assoc_id, } itti_send_msg_to_task(TASK_RRC_ENB, ue_desc_p->eNB_instance->instance, message_p); - return 0; } diff --git a/openair3/S1AP/s1ap_eNB_nas_procedures.c b/openair3/S1AP/s1ap_eNB_nas_procedures.c index 0e2b809189..2189140dad 100644 --- a/openair3/S1AP/s1ap_eNB_nas_procedures.c +++ b/openair3/S1AP/s1ap_eNB_nas_procedures.c @@ -61,13 +61,10 @@ int s1ap_eNB_handle_nas_first_req( S1AP_InitialUEMessage_IEs_t *ie; uint8_t *buffer = NULL; uint32_t length = 0; - DevAssert(s1ap_nas_first_req_p != NULL); - /* Retrieve the S1AP eNB instance associated with Mod_id */ instance_p = s1ap_eNB_get_instance(instance); DevAssert(instance_p != NULL); - memset(&pdu, 0, sizeof(pdu)); pdu.present = S1AP_S1AP_PDU_PR_initiatingMessage; pdu.choice.initiatingMessage.procedureCode = S1AP_ProcedureCode_id_initialUEMessage; @@ -81,6 +78,7 @@ int s1ap_eNB_handle_nas_first_req( instance_p, s1ap_nas_first_req_p->establishment_cause, s1ap_nas_first_req_p->ue_identity.gummei); + if (mme_desc_p) { S1AP_INFO("[eNB %d] Chose MME '%s' (assoc_id %d) through GUMMEI MCC %d MNC %d MMEGI %d MMEC %d\n", instance, @@ -101,6 +99,7 @@ int s1ap_eNB_handle_nas_first_req( s1ap_nas_first_req_p->establishment_cause, s1ap_nas_first_req_p->selected_plmn_identity, s1ap_nas_first_req_p->ue_identity.s_tmsi.mme_code); + if (mme_desc_p) { S1AP_INFO("[eNB %d] Chose MME '%s' (assoc_id %d) through S-TMSI MMEC %d and selected PLMN Identity index %d MCC %d MNC %d\n", instance, @@ -121,6 +120,7 @@ int s1ap_eNB_handle_nas_first_req( instance_p, s1ap_nas_first_req_p->establishment_cause, s1ap_nas_first_req_p->selected_plmn_identity); + if (mme_desc_p) { S1AP_INFO("[eNB %d] Chose MME '%s' (assoc_id %d) through selected PLMN Identity index %d MCC %d MNC %d\n", instance, @@ -140,6 +140,7 @@ int s1ap_eNB_handle_nas_first_req( mme_desc_p = s1ap_eNB_nnsf_select_mme( instance_p, s1ap_nas_first_req_p->establishment_cause); + if (mme_desc_p) { S1AP_INFO("[eNB %d] Chose MME '%s' (assoc_id %d) through highest relative capacity\n", instance, @@ -153,7 +154,6 @@ int s1ap_eNB_handle_nas_first_req( * In case eNB has no MME associated, the eNB should inform RRC and discard * this request. */ - S1AP_WARN("No MME is associated to the eNB\n"); // TODO: Inform RRC return -1; @@ -164,7 +164,6 @@ int s1ap_eNB_handle_nas_first_req( */ ue_desc_p = s1ap_eNB_allocate_new_UE_context(); DevAssert(ue_desc_p != NULL); - /* Keep a reference to the selected MME */ ue_desc_p->mme_ref = mme_desc_p; ue_desc_p->ue_initial_id = s1ap_nas_first_req_p->ue_initial_id; @@ -173,7 +172,6 @@ int s1ap_eNB_handle_nas_first_req( do { struct s1ap_eNB_ue_context_s *collision_p; - /* Peek a random value for the eNB_ue_s1ap_id */ ue_desc_p->eNB_ue_s1ap_id = (random() + random()) & 0x00ffffff; @@ -194,7 +192,6 @@ int s1ap_eNB_handle_nas_first_req( ie->value.present = S1AP_InitialUEMessage_IEs__value_PR_ENB_UE_S1AP_ID; ie->value.choice.ENB_UE_S1AP_ID = ue_desc_p->eNB_ue_s1ap_id; ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); - /* mandatory */ ie = (S1AP_InitialUEMessage_IEs_t *)calloc(1, sizeof(S1AP_InitialUEMessage_IEs_t)); ie->id = S1AP_ProtocolIE_ID_id_NAS_PDU; @@ -210,7 +207,6 @@ int s1ap_eNB_handle_nas_first_req( #endif ie->value.choice.NAS_PDU.size = s1ap_nas_first_req_p->nas_pdu.length; ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); - /* mandatory */ ie = (S1AP_InitialUEMessage_IEs_t *)calloc(1, sizeof(S1AP_InitialUEMessage_IEs_t)); ie->id = S1AP_ProtocolIE_ID_id_TAI; @@ -223,7 +219,6 @@ int s1ap_eNB_handle_nas_first_req( instance_p->mnc_digit_length[ue_desc_p->selected_plmn_identity], &ie->value.choice.TAI.pLMNidentity); ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); - /* mandatory */ ie = (S1AP_InitialUEMessage_IEs_t *)calloc(1, sizeof(S1AP_InitialUEMessage_IEs_t)); ie->id = S1AP_ProtocolIE_ID_id_EUTRAN_CGI; @@ -242,11 +237,9 @@ int s1ap_eNB_handle_nas_first_req( instance_p->mnc_digit_length[ue_desc_p->selected_plmn_identity], &ie->value.choice.EUTRAN_CGI.pLMNidentity); ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); - /* Set the establishment cause according to those provided by RRC */ DevCheck(s1ap_nas_first_req_p->establishment_cause < RRC_CAUSE_LAST, s1ap_nas_first_req_p->establishment_cause, RRC_CAUSE_LAST, 0); - /* mandatory */ ie = (S1AP_InitialUEMessage_IEs_t *)calloc(1, sizeof(S1AP_InitialUEMessage_IEs_t)); ie->id = S1AP_ProtocolIE_ID_id_RRC_Establishment_Cause; @@ -300,6 +293,7 @@ int s1ap_eNB_handle_nas_first_req( /* optional */ #if (S1AP_VERSION >= MAKE_VERSION(9, 0, 0)) + if (0) { ie = (S1AP_InitialUEMessage_IEs_t *)calloc(1, sizeof(S1AP_InitialUEMessage_IEs_t)); ie->id = S1AP_ProtocolIE_ID_id_CellAccessMode; @@ -311,6 +305,7 @@ int s1ap_eNB_handle_nas_first_req( /* optional */ #if (S1AP_VERSION >= MAKE_VERSION(10, 0, 0)) + if (0) { ie = (S1AP_InitialUEMessage_IEs_t *)calloc(1, sizeof(S1AP_InitialUEMessage_IEs_t)); ie->id = S1AP_ProtocolIE_ID_id_GW_TransportLayerAddress; @@ -331,6 +326,7 @@ int s1ap_eNB_handle_nas_first_req( } #if (S1AP_VERSION >= MAKE_VERSION(11, 0, 0)) + /* optional */ if (0) { ie = (S1AP_InitialUEMessage_IEs_t *)calloc(1, sizeof(S1AP_InitialUEMessage_IEs_t)); @@ -372,6 +368,7 @@ int s1ap_eNB_handle_nas_first_req( } #if (S1AP_VERSION >= MAKE_VERSION(13, 0, 0)) + /* optional */ if (0) { ie = (S1AP_InitialUEMessage_IEs_t *)calloc(1, sizeof(S1AP_InitialUEMessage_IEs_t)); @@ -403,6 +400,7 @@ int s1ap_eNB_handle_nas_first_req( } #if (S1AP_VERSION >= MAKE_VERSION(14, 0, 0)) + /* optional */ if (0) { ie = (S1AP_InitialUEMessage_IEs_t *)calloc(1, sizeof(S1AP_InitialUEMessage_IEs_t)); @@ -422,6 +420,7 @@ int s1ap_eNB_handle_nas_first_req( // ie->value.choice.Coverage_Level = ue_release_req_p->eNB_ue_s1ap_id; ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); } + #endif /* #if (S1AP_VERSION >= MAKE_VERSION(14, 0, 0)) */ #endif /* #if (S1AP_VERSION >= MAKE_VERSION(13, 0, 0)) */ #endif /* #if (S1AP_VERSION >= MAKE_VERSION(11, 0, 0)) */ @@ -435,7 +434,6 @@ int s1ap_eNB_handle_nas_first_req( /* Update the current S1AP UE state */ ue_desc_p->ue_state = S1AP_UE_WAITING_CSR; - /* Assign a stream for this UE : * From 3GPP 36.412 7)Transport layers: * Within the SCTP association established between one MME and eNB pair: @@ -455,7 +453,6 @@ int s1ap_eNB_handle_nas_first_req( } ue_desc_p->tx_stream = mme_desc_p->nextstream; - MSC_LOG_TX_MESSAGE( MSC_S1AP_ENB, MSC_S1AP_MME, @@ -464,11 +461,9 @@ int s1ap_eNB_handle_nas_first_req( MSC_AS_TIME_FMT" initialUEMessage initiatingMessage eNB_ue_s1ap_id %u", 0,0,//MSC_AS_TIME_ARGS(ctxt_pP), ue_desc_p->eNB_ue_s1ap_id); - /* Send encoded message over sctp */ s1ap_eNB_itti_send_sctp_data_req(instance_p->instance, mme_desc_p->assoc_id, buffer, length, ue_desc_p->tx_stream); - return 0; } @@ -502,20 +497,17 @@ int s1ap_eNB_handle_nas_downlink(uint32_t assoc_id, } s1ap_eNB_instance = mme_desc_p->s1ap_eNB_instance; - /* Prepare the S1AP message to encode */ container = &pdu->choice.initiatingMessage.value.choice.DownlinkNASTransport; - S1AP_FIND_PROTOCOLIE_BY_ID(S1AP_DownlinkNASTransport_IEs_t, ie, container, S1AP_ProtocolIE_ID_id_MME_UE_S1AP_ID, true); mme_ue_s1ap_id = ie->value.choice.MME_UE_S1AP_ID; - S1AP_FIND_PROTOCOLIE_BY_ID(S1AP_DownlinkNASTransport_IEs_t, ie, container, S1AP_ProtocolIE_ID_id_eNB_UE_S1AP_ID, true); enb_ue_s1ap_id = ie->value.choice.ENB_UE_S1AP_ID; if ((ue_desc_p = s1ap_eNB_get_ue_context(s1ap_eNB_instance, - enb_ue_s1ap_id)) == NULL) { + enb_ue_s1ap_id)) == NULL) { MSC_LOG_RX_DISCARDED_MESSAGE( MSC_S1AP_ENB, MSC_S1AP_MME, @@ -563,7 +555,6 @@ int s1ap_eNB_handle_nas_downlink(uint32_t assoc_id, MSC_AS_TIME_FMT" downlinkNASTransport eNB_ue_s1ap_id %u mme_ue_s1ap_id %u", assoc_id, mme_ue_s1ap_id); - S1AP_FIND_PROTOCOLIE_BY_ID(S1AP_DownlinkNASTransport_IEs_t, ie, container, S1AP_ProtocolIE_ID_id_NAS_PDU, true); /* Forward the NAS PDU to RRC */ @@ -572,7 +563,6 @@ int s1ap_eNB_handle_nas_downlink(uint32_t assoc_id, ue_desc_p->eNB_ue_s1ap_id, ie->value.choice.NAS_PDU.buf, ie->value.choice.NAS_PDU.size); - return 0; } @@ -587,9 +577,7 @@ int s1ap_eNB_nas_uplink(instance_t instance, s1ap_uplink_nas_t *s1ap_uplink_nas_ S1AP_UplinkNASTransport_IEs_t *ie; uint8_t *buffer; uint32_t length; - DevAssert(s1ap_uplink_nas_p != NULL); - /* Retrieve the S1AP eNB instance associated with Mod_id */ s1ap_eNB_instance_p = s1ap_eNB_get_instance(instance); DevAssert(s1ap_eNB_instance_p != NULL); @@ -619,7 +607,6 @@ int s1ap_eNB_nas_uplink(instance_t instance, s1ap_uplink_nas_t *s1ap_uplink_nas_ pdu.choice.initiatingMessage.criticality = S1AP_Criticality_ignore; pdu.choice.initiatingMessage.value.present = S1AP_InitiatingMessage__value_PR_UplinkNASTransport; out = &pdu.choice.initiatingMessage.value.choice.UplinkNASTransport; - /* mandatory */ ie = (S1AP_UplinkNASTransport_IEs_t *)calloc(1, sizeof(S1AP_UplinkNASTransport_IEs_t)); ie->id = S1AP_ProtocolIE_ID_id_MME_UE_S1AP_ID; @@ -627,7 +614,6 @@ int s1ap_eNB_nas_uplink(instance_t instance, s1ap_uplink_nas_t *s1ap_uplink_nas_ ie->value.present = S1AP_UplinkNASTransport_IEs__value_PR_MME_UE_S1AP_ID; ie->value.choice.MME_UE_S1AP_ID = ue_context_p->mme_ue_s1ap_id; ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); - /* mandatory */ ie = (S1AP_UplinkNASTransport_IEs_t *)calloc(1, sizeof(S1AP_UplinkNASTransport_IEs_t)); ie->id = S1AP_ProtocolIE_ID_id_eNB_UE_S1AP_ID; @@ -635,7 +621,6 @@ int s1ap_eNB_nas_uplink(instance_t instance, s1ap_uplink_nas_t *s1ap_uplink_nas_ ie->value.present = S1AP_UplinkNASTransport_IEs__value_PR_ENB_UE_S1AP_ID; ie->value.choice.ENB_UE_S1AP_ID = ue_context_p->eNB_ue_s1ap_id; ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); - /* mandatory */ ie = (S1AP_UplinkNASTransport_IEs_t *)calloc(1, sizeof(S1AP_UplinkNASTransport_IEs_t)); ie->id = S1AP_ProtocolIE_ID_id_NAS_PDU; @@ -644,7 +629,6 @@ int s1ap_eNB_nas_uplink(instance_t instance, s1ap_uplink_nas_t *s1ap_uplink_nas_ ie->value.choice.NAS_PDU.buf = s1ap_uplink_nas_p->nas_pdu.buffer; ie->value.choice.NAS_PDU.size = s1ap_uplink_nas_p->nas_pdu.length; ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); - /* mandatory */ ie = (S1AP_UplinkNASTransport_IEs_t *)calloc(1, sizeof(S1AP_UplinkNASTransport_IEs_t)); ie->id = S1AP_ProtocolIE_ID_id_EUTRAN_CGI; @@ -660,7 +644,6 @@ int s1ap_eNB_nas_uplink(instance_t instance, s1ap_uplink_nas_t *s1ap_uplink_nas_ 0, &ie->value.choice.EUTRAN_CGI.cell_ID); ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); - /* mandatory */ ie = (S1AP_UplinkNASTransport_IEs_t *)calloc(1, sizeof(S1AP_UplinkNASTransport_IEs_t)); ie->id = S1AP_ProtocolIE_ID_id_TAI; @@ -673,9 +656,9 @@ int s1ap_eNB_nas_uplink(instance_t instance, s1ap_uplink_nas_t *s1ap_uplink_nas_ &ie->value.choice.TAI.pLMNidentity); TAC_TO_ASN1(s1ap_eNB_instance_p->tac, &ie->value.choice.TAI.tAC); ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); - /* optional */ #if (S1AP_VERSION >= MAKE_VERSION(10, 0, 0)) + if (0) { ie = (S1AP_UplinkNASTransport_IEs_t *)calloc(1, sizeof(S1AP_UplinkNASTransport_IEs_t)); ie->id = S1AP_ProtocolIE_ID_id_GW_TransportLayerAddress; @@ -687,6 +670,7 @@ int s1ap_eNB_nas_uplink(instance_t instance, s1ap_uplink_nas_t *s1ap_uplink_nas_ /* optional */ #if (S1AP_VERSION >= MAKE_VERSION(14, 0, 0)) + if (0) { ie = (S1AP_UplinkNASTransport_IEs_t *)calloc(1, sizeof(S1AP_UplinkNASTransport_IEs_t)); ie->id = S1AP_ProtocolIE_ID_id_SIPTO_L_GW_TransportLayerAddress; @@ -705,6 +689,7 @@ int s1ap_eNB_nas_uplink(instance_t instance, s1ap_uplink_nas_t *s1ap_uplink_nas_ // ie->value.choice.LHN_ID =; ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); } + #endif /* #if (S1AP_VERSION >= MAKE_VERSION(14, 0, 0)) */ #endif /* #if (S1AP_VERSION >= MAKE_VERSION(10, 0, 0)) */ @@ -723,12 +708,10 @@ int s1ap_eNB_nas_uplink(instance_t instance, s1ap_uplink_nas_t *s1ap_uplink_nas_ 0,0,//MSC_AS_TIME_ARGS(ctxt_pP), ue_context_p->eNB_ue_s1ap_id, ue_context_p->mme_ue_s1ap_id); - /* UE associated signalling -> use the allocated stream */ s1ap_eNB_itti_send_sctp_data_req(s1ap_eNB_instance_p->instance, ue_context_p->mme_ref->assoc_id, buffer, length, ue_context_p->tx_stream); - return 0; } @@ -745,9 +728,7 @@ int s1ap_eNB_nas_non_delivery_ind(instance_t instance, S1AP_NASNonDeliveryIndication_IEs_t *ie; uint8_t *buffer; uint32_t length; - DevAssert(s1ap_nas_non_delivery_ind != NULL); - /* Retrieve the S1AP eNB instance associated with Mod_id */ s1ap_eNB_instance_p = s1ap_eNB_get_instance(instance); DevAssert(s1ap_eNB_instance_p != NULL); @@ -770,7 +751,6 @@ int s1ap_eNB_nas_non_delivery_ind(instance_t instance, pdu.choice.initiatingMessage.criticality = S1AP_Criticality_ignore; pdu.choice.initiatingMessage.value.present = S1AP_InitiatingMessage__value_PR_NASNonDeliveryIndication; out = &pdu.choice.initiatingMessage.value.choice.NASNonDeliveryIndication; - /* mandatory */ ie = (S1AP_NASNonDeliveryIndication_IEs_t *)calloc(1, sizeof(S1AP_NASNonDeliveryIndication_IEs_t)); ie->id = S1AP_ProtocolIE_ID_id_MME_UE_S1AP_ID; @@ -778,7 +758,6 @@ int s1ap_eNB_nas_non_delivery_ind(instance_t instance, ie->value.present = S1AP_NASNonDeliveryIndication_IEs__value_PR_MME_UE_S1AP_ID; ie->value.choice.MME_UE_S1AP_ID = ue_context_p->mme_ue_s1ap_id; ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); - /* mandatory */ ie = (S1AP_NASNonDeliveryIndication_IEs_t *)calloc(1, sizeof(S1AP_NASNonDeliveryIndication_IEs_t)); ie->id = S1AP_ProtocolIE_ID_id_eNB_UE_S1AP_ID; @@ -786,7 +765,6 @@ int s1ap_eNB_nas_non_delivery_ind(instance_t instance, ie->value.present = S1AP_NASNonDeliveryIndication_IEs__value_PR_ENB_UE_S1AP_ID; ie->value.choice.ENB_UE_S1AP_ID = ue_context_p->eNB_ue_s1ap_id; ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); - /* mandatory */ ie = (S1AP_NASNonDeliveryIndication_IEs_t *)calloc(1, sizeof(S1AP_NASNonDeliveryIndication_IEs_t)); ie->id = S1AP_ProtocolIE_ID_id_NAS_PDU; @@ -794,9 +772,7 @@ int s1ap_eNB_nas_non_delivery_ind(instance_t instance, ie->value.present = S1AP_NASNonDeliveryIndication_IEs__value_PR_NAS_PDU; ie->value.choice.NAS_PDU.buf = s1ap_nas_non_delivery_ind->nas_pdu.buffer; ie->value.choice.NAS_PDU.size = s1ap_nas_non_delivery_ind->nas_pdu.length; - ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); - /* mandatory */ ie = (S1AP_NASNonDeliveryIndication_IEs_t *)calloc(1, sizeof(S1AP_NASNonDeliveryIndication_IEs_t)); ie->id = S1AP_ProtocolIE_ID_id_Cause; @@ -825,7 +801,6 @@ int s1ap_eNB_nas_non_delivery_ind(instance_t instance, 0,0,//MSC_AS_TIME_ARGS(ctxt_pP), ue_context_p->eNB_ue_s1ap_id, ue_context_p->mme_ue_s1ap_id); - /* UE associated signalling -> use the allocated stream */ s1ap_eNB_itti_send_sctp_data_req(s1ap_eNB_instance_p->instance, ue_context_p->mme_ref->assoc_id, buffer, @@ -846,10 +821,8 @@ int s1ap_eNB_initial_ctxt_resp( uint8_t *buffer = NULL; uint32_t length; int i; - /* Retrieve the S1AP eNB instance associated with Mod_id */ s1ap_eNB_instance_p = s1ap_eNB_get_instance(instance); - DevAssert(initial_ctxt_resp_p != NULL); DevAssert(s1ap_eNB_instance_p != NULL); @@ -879,7 +852,6 @@ int s1ap_eNB_initial_ctxt_resp( pdu.choice.successfulOutcome.criticality = S1AP_Criticality_reject; pdu.choice.successfulOutcome.value.present = S1AP_SuccessfulOutcome__value_PR_InitialContextSetupResponse; out = &pdu.choice.successfulOutcome.value.choice.InitialContextSetupResponse; - /* mandatory */ ie = (S1AP_InitialContextSetupResponseIEs_t *)calloc(1, sizeof(S1AP_InitialContextSetupResponseIEs_t)); ie->id = S1AP_ProtocolIE_ID_id_MME_UE_S1AP_ID; @@ -887,7 +859,6 @@ int s1ap_eNB_initial_ctxt_resp( ie->value.present = S1AP_InitialContextSetupResponseIEs__value_PR_MME_UE_S1AP_ID; ie->value.choice.MME_UE_S1AP_ID = ue_context_p->mme_ue_s1ap_id; ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); - /* mandatory */ ie = (S1AP_InitialContextSetupResponseIEs_t *)calloc(1, sizeof(S1AP_InitialContextSetupResponseIEs_t)); ie->id = S1AP_ProtocolIE_ID_id_eNB_UE_S1AP_ID; @@ -895,7 +866,6 @@ int s1ap_eNB_initial_ctxt_resp( ie->value.present = S1AP_InitialContextSetupResponseIEs__value_PR_ENB_UE_S1AP_ID; ie->value.choice.ENB_UE_S1AP_ID = initial_ctxt_resp_p->eNB_ue_s1ap_id; ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); - /* mandatory */ ie = (S1AP_InitialContextSetupResponseIEs_t *)calloc(1, sizeof(S1AP_InitialContextSetupResponseIEs_t)); ie->id = S1AP_ProtocolIE_ID_id_E_RABSetupListCtxtSURes; @@ -912,7 +882,7 @@ int s1ap_eNB_initial_ctxt_resp( item->value.choice.E_RABSetupItemCtxtSURes.e_RAB_ID = initial_ctxt_resp_p->e_rabs[i].e_rab_id; GTP_TEID_TO_ASN1(initial_ctxt_resp_p->e_rabs[i].gtp_teid, &item->value.choice.E_RABSetupItemCtxtSURes.gTP_TEID); item->value.choice.E_RABSetupItemCtxtSURes.transportLayerAddress.buf = malloc(initial_ctxt_resp_p->e_rabs[i].eNB_addr.length); - memcpy(item->value.choice.E_RABSetupItemCtxtSURes.transportLayerAddress.buf, + memcpy(item->value.choice.E_RABSetupItemCtxtSURes.transportLayerAddress.buf, initial_ctxt_resp_p->e_rabs[i].eNB_addr.buffer, initial_ctxt_resp_p->e_rabs[i].eNB_addr.length); item->value.choice.E_RABSetupItemCtxtSURes.transportLayerAddress.size = initial_ctxt_resp_p->e_rabs[i].eNB_addr.length; @@ -946,23 +916,27 @@ int s1ap_eNB_initial_ctxt_resp( item->value.choice.E_RABItem.e_RAB_ID = initial_ctxt_resp_p->e_rabs_failed[i].e_rab_id; item->value.choice.E_RABItem.cause.present = initial_ctxt_resp_p->e_rabs_failed[i].cause; - switch(item->value.choice.E_RABItem.cause.present) - { + switch(item->value.choice.E_RABItem.cause.present) { case S1AP_Cause_PR_radioNetwork: item->value.choice.E_RABItem.cause.choice.radioNetwork = initial_ctxt_resp_p->e_rabs_failed[i].cause_value; break; + case S1AP_Cause_PR_transport: item->value.choice.E_RABItem.cause.choice.transport = initial_ctxt_resp_p->e_rabs_failed[i].cause_value; break; + case S1AP_Cause_PR_nas: item->value.choice.E_RABItem.cause.choice.nas = initial_ctxt_resp_p->e_rabs_failed[i].cause_value; break; + case S1AP_Cause_PR_protocol: item->value.choice.E_RABItem.cause.choice.protocol = initial_ctxt_resp_p->e_rabs_failed[i].cause_value; break; + case S1AP_Cause_PR_misc: item->value.choice.E_RABItem.cause.choice.misc = initial_ctxt_resp_p->e_rabs_failed[i].cause_value; break; + case S1AP_Cause_PR_NOTHING: default: break; @@ -1000,12 +974,10 @@ int s1ap_eNB_initial_ctxt_resp( 0,0,//MSC_AS_TIME_ARGS(ctxt_pP), initial_ctxt_resp_p->eNB_ue_s1ap_id, ue_context_p->mme_ue_s1ap_id); - /* UE associated signalling -> use the allocated stream */ s1ap_eNB_itti_send_sctp_data_req(s1ap_eNB_instance_p->instance, ue_context_p->mme_ref->assoc_id, buffer, length, ue_context_p->tx_stream); - return 0; } @@ -1021,10 +993,8 @@ int s1ap_eNB_ue_capabilities(instance_t instance, S1AP_UECapabilityInfoIndicationIEs_t *ie; uint8_t *buffer; uint32_t length; - /* Retrieve the S1AP eNB instance associated with Mod_id */ s1ap_eNB_instance_p = s1ap_eNB_get_instance(instance); - DevAssert(ue_cap_info_ind_p != NULL); DevAssert(s1ap_eNB_instance_p != NULL); @@ -1054,7 +1024,6 @@ int s1ap_eNB_ue_capabilities(instance_t instance, pdu.choice.initiatingMessage.criticality = S1AP_Criticality_ignore; pdu.choice.initiatingMessage.value.present = S1AP_InitiatingMessage__value_PR_UECapabilityInfoIndication; out = &pdu.choice.initiatingMessage.value.choice.UECapabilityInfoIndication; - /* mandatory */ ie = (S1AP_UECapabilityInfoIndicationIEs_t *)calloc(1, sizeof(S1AP_UECapabilityInfoIndicationIEs_t)); ie->id = S1AP_ProtocolIE_ID_id_MME_UE_S1AP_ID; @@ -1062,7 +1031,6 @@ int s1ap_eNB_ue_capabilities(instance_t instance, ie->value.present = S1AP_UECapabilityInfoIndicationIEs__value_PR_MME_UE_S1AP_ID; ie->value.choice.MME_UE_S1AP_ID = ue_context_p->mme_ue_s1ap_id; ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); - /* mandatory */ ie = (S1AP_UECapabilityInfoIndicationIEs_t *)calloc(1, sizeof(S1AP_UECapabilityInfoIndicationIEs_t)); ie->id = S1AP_ProtocolIE_ID_id_eNB_UE_S1AP_ID; @@ -1070,7 +1038,6 @@ int s1ap_eNB_ue_capabilities(instance_t instance, ie->value.present = S1AP_UECapabilityInfoIndicationIEs__value_PR_ENB_UE_S1AP_ID; ie->value.choice.ENB_UE_S1AP_ID = ue_cap_info_ind_p->eNB_ue_s1ap_id; ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); - /* mandatory */ ie = (S1AP_UECapabilityInfoIndicationIEs_t *)calloc(1, sizeof(S1AP_UECapabilityInfoIndicationIEs_t)); ie->id = S1AP_ProtocolIE_ID_id_UERadioCapability; @@ -1079,9 +1046,9 @@ int s1ap_eNB_ue_capabilities(instance_t instance, ie->value.choice.UERadioCapability.buf = ue_cap_info_ind_p->ue_radio_cap.buffer; ie->value.choice.UERadioCapability.size = ue_cap_info_ind_p->ue_radio_cap.length; ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); - /* optional */ #if (S1AP_VERSION >= MAKE_VERSION(12, 0, 0)) + if (0) { ie = (S1AP_UECapabilityInfoIndicationIEs_t *)calloc(1, sizeof(S1AP_UECapabilityInfoIndicationIEs_t)); ie->id = S1AP_ProtocolIE_ID_id_UERadioCapabilityForPaging; @@ -1090,6 +1057,7 @@ int s1ap_eNB_ue_capabilities(instance_t instance, // ie->value.choice.UERadioCapabilityForPaging = ; ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); } + #endif /* #if (S1AP_VERSION >= MAKE_VERSION(14, 0, 0)) */ if (s1ap_eNB_encode_pdu(&pdu, &buffer, &length) < 0) { @@ -1107,12 +1075,10 @@ int s1ap_eNB_ue_capabilities(instance_t instance, 0,0,//MSC_AS_TIME_ARGS(ctxt_pP), ue_cap_info_ind_p->eNB_ue_s1ap_id, ue_context_p->mme_ue_s1ap_id); - /* UE associated signalling -> use the allocated stream */ s1ap_eNB_itti_send_sctp_data_req(s1ap_eNB_instance_p->instance, ue_context_p->mme_ref->assoc_id, buffer, length, ue_context_p->tx_stream); - return 0; } @@ -1129,15 +1095,13 @@ int s1ap_eNB_e_rab_setup_resp(instance_t instance, uint8_t *buffer = NULL; uint32_t length; int i; - /* Retrieve the S1AP eNB instance associated with Mod_id */ s1ap_eNB_instance_p = s1ap_eNB_get_instance(instance); - DevAssert(e_rab_setup_resp_p != NULL); DevAssert(s1ap_eNB_instance_p != NULL); if ((ue_context_p = s1ap_eNB_get_ue_context(s1ap_eNB_instance_p, - e_rab_setup_resp_p->eNB_ue_s1ap_id)) == NULL) { + e_rab_setup_resp_p->eNB_ue_s1ap_id)) == NULL) { /* The context for this eNB ue s1ap id doesn't exist in the map of eNB UEs */ S1AP_WARN("Failed to find ue context associated with eNB ue s1ap id: 0x%06x\n", e_rab_setup_resp_p->eNB_ue_s1ap_id); @@ -1162,7 +1126,6 @@ int s1ap_eNB_e_rab_setup_resp(instance_t instance, pdu.choice.successfulOutcome.criticality = S1AP_Criticality_reject; pdu.choice.successfulOutcome.value.present = S1AP_SuccessfulOutcome__value_PR_E_RABSetupResponse; out = &pdu.choice.successfulOutcome.value.choice.E_RABSetupResponse; - /* mandatory */ ie = (S1AP_E_RABSetupResponseIEs_t *)calloc(1, sizeof(S1AP_E_RABSetupResponseIEs_t)); ie->id = S1AP_ProtocolIE_ID_id_MME_UE_S1AP_ID; @@ -1170,7 +1133,6 @@ int s1ap_eNB_e_rab_setup_resp(instance_t instance, ie->value.present = S1AP_E_RABSetupResponseIEs__value_PR_MME_UE_S1AP_ID; ie->value.choice.MME_UE_S1AP_ID = ue_context_p->mme_ue_s1ap_id; ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); - /* mandatory */ ie = (S1AP_E_RABSetupResponseIEs_t *)calloc(1, sizeof(S1AP_E_RABSetupResponseIEs_t)); ie->id = S1AP_ProtocolIE_ID_id_eNB_UE_S1AP_ID; @@ -1231,23 +1193,27 @@ int s1ap_eNB_e_rab_setup_resp(instance_t instance, item->value.choice.E_RABItem.e_RAB_ID = e_rab_setup_resp_p->e_rabs_failed[i].e_rab_id; item->value.choice.E_RABItem.cause.present = e_rab_setup_resp_p->e_rabs_failed[i].cause; - switch(item->value.choice.E_RABItem.cause.present) - { + switch(item->value.choice.E_RABItem.cause.present) { case S1AP_Cause_PR_radioNetwork: item->value.choice.E_RABItem.cause.choice.radioNetwork = e_rab_setup_resp_p->e_rabs_failed[i].cause_value; break; + case S1AP_Cause_PR_transport: item->value.choice.E_RABItem.cause.choice.transport = e_rab_setup_resp_p->e_rabs_failed[i].cause_value; break; + case S1AP_Cause_PR_nas: item->value.choice.E_RABItem.cause.choice.nas = e_rab_setup_resp_p->e_rabs_failed[i].cause_value; break; + case S1AP_Cause_PR_protocol: item->value.choice.E_RABItem.cause.choice.protocol = e_rab_setup_resp_p->e_rabs_failed[i].cause_value; break; + case S1AP_Cause_PR_misc: item->value.choice.E_RABItem.cause.choice.misc = e_rab_setup_resp_p->e_rabs_failed[i].cause_value; break; + case S1AP_Cause_PR_NOTHING: default: break; @@ -1277,6 +1243,7 @@ int s1ap_eNB_e_rab_setup_resp(instance_t instance, ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_S1AP_E_RABSetupListBearerSURes, &e_RABSetupListBearerSURes); */ fprintf(stderr, "start encode\n"); + if (s1ap_eNB_encode_pdu(&pdu, &buffer, &length) < 0) { S1AP_ERROR("Failed to encode uplink transport\n"); /* Encode procedure has failed... */ @@ -1292,12 +1259,10 @@ int s1ap_eNB_e_rab_setup_resp(instance_t instance, 0,0,//MSC_AS_TIME_ARGS(ctxt_pP), e_rab_setup_resp_p->eNB_ue_s1ap_id, ue_context_p->mme_ue_s1ap_id); - /* UE associated signalling -> use the allocated stream */ s1ap_eNB_itti_send_sctp_data_req(s1ap_eNB_instance_p->instance, ue_context_p->mme_ref->assoc_id, buffer, length, ue_context_p->tx_stream); - return 0; } @@ -1311,19 +1276,16 @@ int s1ap_eNB_e_rab_modify_resp(instance_t instance, S1AP_S1AP_PDU_t pdu; S1AP_E_RABModifyResponse_t *out; S1AP_E_RABModifyResponseIEs_t *ie; - uint8_t *buffer = NULL; uint32_t length; int i; - /* Retrieve the S1AP eNB instance associated with Mod_id */ s1ap_eNB_instance_p = s1ap_eNB_get_instance(instance); - DevAssert(e_rab_modify_resp_p != NULL); DevAssert(s1ap_eNB_instance_p != NULL); if ((ue_context_p = s1ap_eNB_get_ue_context(s1ap_eNB_instance_p, - e_rab_modify_resp_p->eNB_ue_s1ap_id)) == NULL) { + e_rab_modify_resp_p->eNB_ue_s1ap_id)) == NULL) { /* The context for this eNB ue s1ap id doesn't exist in the map of eNB UEs */ S1AP_WARN("Failed to find ue context associated with eNB ue s1ap id: 0x%06x\n", e_rab_modify_resp_p->eNB_ue_s1ap_id); @@ -1348,7 +1310,6 @@ int s1ap_eNB_e_rab_modify_resp(instance_t instance, pdu.choice.successfulOutcome.criticality = S1AP_Criticality_reject; pdu.choice.successfulOutcome.value.present = S1AP_SuccessfulOutcome__value_PR_E_RABModifyResponse; out = &pdu.choice.successfulOutcome.value.choice.E_RABModifyResponse; - /* mandatory */ ie = (S1AP_E_RABModifyResponseIEs_t *)calloc(1, sizeof(S1AP_E_RABModifyResponseIEs_t)); ie->id = S1AP_ProtocolIE_ID_id_MME_UE_S1AP_ID; @@ -1356,7 +1317,6 @@ int s1ap_eNB_e_rab_modify_resp(instance_t instance, ie->value.present = S1AP_E_RABModifyResponseIEs__value_PR_MME_UE_S1AP_ID; ie->value.choice.MME_UE_S1AP_ID = ue_context_p->mme_ue_s1ap_id; ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); - /* mandatory */ ie = (S1AP_E_RABModifyResponseIEs_t *)calloc(1, sizeof(S1AP_E_RABModifyResponseIEs_t)); ie->id = S1AP_ProtocolIE_ID_id_eNB_UE_S1AP_ID; @@ -1402,23 +1362,27 @@ int s1ap_eNB_e_rab_modify_resp(instance_t instance, item->value.choice.E_RABItem.e_RAB_ID = e_rab_modify_resp_p->e_rabs_failed[i].e_rab_id; item->value.choice.E_RABItem.cause.present = e_rab_modify_resp_p->e_rabs_failed[i].cause; - switch(item->value.choice.E_RABItem.cause.present) - { + switch(item->value.choice.E_RABItem.cause.present) { case S1AP_Cause_PR_radioNetwork: item->value.choice.E_RABItem.cause.choice.radioNetwork = e_rab_modify_resp_p->e_rabs_failed[i].cause_value; break; + case S1AP_Cause_PR_transport: item->value.choice.E_RABItem.cause.choice.transport = e_rab_modify_resp_p->e_rabs_failed[i].cause_value; break; + case S1AP_Cause_PR_nas: item->value.choice.E_RABItem.cause.choice.nas = e_rab_modify_resp_p->e_rabs_failed[i].cause_value; break; + case S1AP_Cause_PR_protocol: item->value.choice.E_RABItem.cause.choice.protocol = e_rab_modify_resp_p->e_rabs_failed[i].cause_value; break; + case S1AP_Cause_PR_misc: item->value.choice.E_RABItem.cause.choice.misc = e_rab_modify_resp_p->e_rabs_failed[i].cause_value; break; + case S1AP_Cause_PR_NOTHING: default: break; @@ -1442,6 +1406,7 @@ int s1ap_eNB_e_rab_modify_resp(instance_t instance, } fprintf(stderr, "start encode\n"); + if (s1ap_eNB_encode_pdu(&pdu, &buffer, &length) < 0) { S1AP_ERROR("Failed to encode uplink transport\n"); /* Encode procedure has failed... */ @@ -1457,7 +1422,6 @@ int s1ap_eNB_e_rab_modify_resp(instance_t instance, 0,0,//MSC_AS_TIME_ARGS(ctxt_pP), e_rab_modify_resp_p->eNB_ue_s1ap_id, ue_context_p->mme_ue_s1ap_id); - /* UE associated signalling -> use the allocated stream */ s1ap_eNB_itti_send_sctp_data_req(s1ap_eNB_instance_p->instance, ue_context_p->mme_ref->assoc_id, buffer, @@ -1477,14 +1441,13 @@ int s1ap_eNB_e_rab_release_resp(instance_t instance, uint8_t *buffer = NULL; uint32_t length; int i; - /* Retrieve the S1AP eNB instance associated with Mod_id */ s1ap_eNB_instance_p = s1ap_eNB_get_instance(instance); DevAssert(e_rab_release_resp_p != NULL); DevAssert(s1ap_eNB_instance_p != NULL); if ((ue_context_p = s1ap_eNB_get_ue_context(s1ap_eNB_instance_p, - e_rab_release_resp_p->eNB_ue_s1ap_id)) == NULL) { + e_rab_release_resp_p->eNB_ue_s1ap_id)) == NULL) { /* The context for this eNB ue s1ap id doesn't exist in the map of eNB UEs */ S1AP_WARN("Failed to find ue context associated with eNB ue s1ap id: %u\n", e_rab_release_resp_p->eNB_ue_s1ap_id); @@ -1498,7 +1461,6 @@ int s1ap_eNB_e_rab_release_resp(instance_t instance, pdu.choice.successfulOutcome.criticality = S1AP_Criticality_reject; pdu.choice.successfulOutcome.value.present = S1AP_SuccessfulOutcome__value_PR_E_RABReleaseResponse; out = &pdu.choice.successfulOutcome.value.choice.E_RABReleaseResponse; - /* mandatory */ ie = (S1AP_E_RABReleaseResponseIEs_t *)calloc(1, sizeof(S1AP_E_RABReleaseResponseIEs_t)); ie->id = S1AP_ProtocolIE_ID_id_MME_UE_S1AP_ID; @@ -1506,7 +1468,6 @@ int s1ap_eNB_e_rab_release_resp(instance_t instance, ie->value.present = S1AP_E_RABReleaseResponseIEs__value_PR_MME_UE_S1AP_ID; ie->value.choice.MME_UE_S1AP_ID = ue_context_p->mme_ue_s1ap_id; ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); - /* mandatory */ ie = (S1AP_E_RABReleaseResponseIEs_t *)calloc(1, sizeof(S1AP_E_RABReleaseResponseIEs_t)); ie->id = S1AP_ProtocolIE_ID_id_eNB_UE_S1AP_ID; @@ -1552,23 +1513,27 @@ int s1ap_eNB_e_rab_release_resp(instance_t instance, item->value.choice.E_RABItem.e_RAB_ID = e_rab_release_resp_p->e_rabs_failed[i].e_rab_id; item->value.choice.E_RABItem.cause.present = e_rab_release_resp_p->e_rabs_failed[i].cause; - switch(item->value.choice.E_RABItem.cause.present) - { + switch(item->value.choice.E_RABItem.cause.present) { case S1AP_Cause_PR_radioNetwork: item->value.choice.E_RABItem.cause.choice.radioNetwork = e_rab_release_resp_p->e_rabs_failed[i].cause_value; break; + case S1AP_Cause_PR_transport: item->value.choice.E_RABItem.cause.choice.transport = e_rab_release_resp_p->e_rabs_failed[i].cause_value; break; + case S1AP_Cause_PR_nas: item->value.choice.E_RABItem.cause.choice.nas = e_rab_release_resp_p->e_rabs_failed[i].cause_value; break; + case S1AP_Cause_PR_protocol: item->value.choice.E_RABItem.cause.choice.protocol = e_rab_release_resp_p->e_rabs_failed[i].cause_value; break; + case S1AP_Cause_PR_misc: item->value.choice.E_RABItem.cause.choice.misc = e_rab_release_resp_p->e_rabs_failed[i].cause_value; break; + case S1AP_Cause_PR_NOTHING: default: break; @@ -1592,6 +1557,7 @@ int s1ap_eNB_e_rab_release_resp(instance_t instance, /* optional */ #if (S1AP_VERSION >= MAKE_VERSION(12, 0, 0)) + if(0) { ie = (S1AP_E_RABReleaseResponseIEs_t *)calloc(1, sizeof(S1AP_E_RABReleaseResponseIEs_t)); ie->id = S1AP_ProtocolIE_ID_id_UserLocationInformation; @@ -1600,9 +1566,10 @@ int s1ap_eNB_e_rab_release_resp(instance_t instance, // ie->value.choice.UserLocationInformation = ; ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); } -#endif /* #if (S1AP_VERSION >= MAKE_VERSION(14, 0, 0)) */ +#endif /* #if (S1AP_VERSION >= MAKE_VERSION(14, 0, 0)) */ fprintf(stderr, "start encode\n"); + if (s1ap_eNB_encode_pdu(&pdu, &buffer, &length) < 0) { S1AP_ERROR("Failed to encode release response\n"); /* Encode procedure has failed... */ @@ -1618,14 +1585,11 @@ int s1ap_eNB_e_rab_release_resp(instance_t instance, 0,0,//MSC_AS_TIME_ARGS(ctxt_pP), e_rab_release_resp_p->eNB_ue_s1ap_id, ue_context_p->mme_ue_s1ap_id); - /* UE associated signalling -> use the allocated stream */ s1ap_eNB_itti_send_sctp_data_req(s1ap_eNB_instance_p->instance, ue_context_p->mme_ref->assoc_id, buffer, length, ue_context_p->tx_stream); - S1AP_INFO("e_rab_release_response sended eNB_UE_S1AP_ID %d mme_ue_s1ap_id %d nb_of_e_rabs_released %d nb_of_e_rabs_failed %d\n", e_rab_release_resp_p->eNB_ue_s1ap_id, ue_context_p->mme_ue_s1ap_id,e_rab_release_resp_p->nb_of_e_rabs_released,e_rab_release_resp_p->nb_of_e_rabs_failed); - return 0; } diff --git a/targets/RT/USER/lte-enb.c b/targets/RT/USER/lte-enb.c index d194ea42ae..cef0232932 100644 --- a/targets/RT/USER/lte-enb.c +++ b/targets/RT/USER/lte-enb.c @@ -77,16 +77,16 @@ #ifndef OPENAIR2 -#include "UTIL/OTG/otg_extern.h" + #include "UTIL/OTG/otg_extern.h" #endif #if defined(ENABLE_ITTI) -# if defined(ENABLE_USE_MME) -# include "s1ap_eNB.h" -#ifdef PDCP_USE_NETLINK -# include "SIMULATION/ETH_TRANSPORT/proto.h" -#endif -# endif + #if defined(ENABLE_USE_MME) + #include "s1ap_eNB.h" + #ifdef PDCP_USE_NETLINK + #include "SIMULATION/ETH_TRANSPORT/proto.h" + #endif + #endif #endif #include "T.h" @@ -106,8 +106,8 @@ struct timing_info_t { #if defined(ENABLE_ITTI) -extern volatile int start_eNB; -extern volatile int start_UE; + extern volatile int start_eNB; + extern volatile int start_UE; #endif extern volatile int oai_exit; @@ -147,7 +147,7 @@ int wakeup_tx(PHY_VARS_eNB *eNB,RU_proc_t *ru_proc); int wakeup_txfh(eNB_rxtx_proc_t *proc,RU_proc_t *ru_proc); void wakeup_prach_eNB(PHY_VARS_eNB *eNB,RU_t *ru,int frame,int subframe); #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) -void wakeup_prach_eNB_br(PHY_VARS_eNB *eNB,RU_t *ru,int frame,int subframe); + void wakeup_prach_eNB_br(PHY_VARS_eNB *eNB,RU_t *ru,int frame,int subframe); #endif extern PARALLEL_CONF_t get_thread_parallel_conf(void); extern WORKER_CONF_t get_thread_worker_conf(void); @@ -166,13 +166,10 @@ static inline int rxtx(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc, char *thread_nam // ******************************************************************* if (nfapi_mode == 1) { - // I am a PNF and I need to let nFAPI know that we have a (sub)frame tick uint16_t frame = proc->frame_rx; uint16_t subframe = proc->subframe_rx; - //add_subframe(&frame, &subframe, 4); - //oai_subframe_ind(proc->frame_tx, proc->subframe_tx); //LOG_D(PHY, "oai_subframe_ind(frame:%u, subframe:%d) - NOT CALLED ********\n", frame, subframe); start_meas(&nfapi_meas); @@ -185,14 +182,14 @@ static inline int rxtx(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc, char *thread_nam eNB->UL_INFO.rach_ind.rach_indication_body.number_of_preambles || eNB->UL_INFO.cqi_ind.number_of_cqis ) { - LOG_D(PHY, "UL_info[rx_ind:%05d:%d harqs:%05d:%d crcs:%05d:%d preambles:%05d:%d cqis:%d] RX:%04d%d TX:%04d%d num_pdcch_symbols:%d\n", - NFAPI_SFNSF2DEC(eNB->UL_INFO.rx_ind.sfn_sf), eNB->UL_INFO.rx_ind.rx_indication_body.number_of_pdus, - NFAPI_SFNSF2DEC(eNB->UL_INFO.harq_ind.sfn_sf), eNB->UL_INFO.harq_ind.harq_indication_body.number_of_harqs, - NFAPI_SFNSF2DEC(eNB->UL_INFO.crc_ind.sfn_sf), eNB->UL_INFO.crc_ind.crc_indication_body.number_of_crcs, - NFAPI_SFNSF2DEC(eNB->UL_INFO.rach_ind.sfn_sf), eNB->UL_INFO.rach_ind.rach_indication_body.number_of_preambles, - eNB->UL_INFO.cqi_ind.number_of_cqis, - proc->frame_rx, proc->subframe_rx, - proc->frame_tx, proc->subframe_tx, eNB->pdcch_vars[proc->subframe_tx&1].num_pdcch_symbols); + LOG_D(PHY, "UL_info[rx_ind:%05d:%d harqs:%05d:%d crcs:%05d:%d preambles:%05d:%d cqis:%d] RX:%04d%d TX:%04d%d num_pdcch_symbols:%d\n", + NFAPI_SFNSF2DEC(eNB->UL_INFO.rx_ind.sfn_sf), eNB->UL_INFO.rx_ind.rx_indication_body.number_of_pdus, + NFAPI_SFNSF2DEC(eNB->UL_INFO.harq_ind.sfn_sf), eNB->UL_INFO.harq_ind.harq_indication_body.number_of_harqs, + NFAPI_SFNSF2DEC(eNB->UL_INFO.crc_ind.sfn_sf), eNB->UL_INFO.crc_ind.crc_indication_body.number_of_crcs, + NFAPI_SFNSF2DEC(eNB->UL_INFO.rach_ind.sfn_sf), eNB->UL_INFO.rach_ind.rach_indication_body.number_of_preambles, + eNB->UL_INFO.cqi_ind.number_of_cqis, + proc->frame_rx, proc->subframe_rx, + proc->frame_tx, proc->subframe_tx, eNB->pdcch_vars[proc->subframe_tx&1].num_pdcch_symbols); } } @@ -203,7 +200,6 @@ static inline int rxtx(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc, char *thread_nam // **************************************** // Common RX procedures subframe n - T(T_ENB_PHY_DL_TICK, T_INT(eNB->Mod_id), T_INT(proc->frame_tx), T_INT(proc->subframe_tx)); // if this is IF5 or 3GPP_eNB @@ -220,103 +216,97 @@ static inline int rxtx(PHY_VARS_eNB *eNB,eNB_rxtx_proc_t *proc, char *thread_nam if (nfapi_mode == 0 || nfapi_mode == 1) { phy_procedures_eNB_uespec_RX(eNB, proc); } - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ULSCH_SCHEDULER , 1 ); - if(get_thread_parallel_conf() == PARALLEL_RU_L1_TRX_SPLIT){ + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ULSCH_SCHEDULER, 1 ); + + if(get_thread_parallel_conf() == PARALLEL_RU_L1_TRX_SPLIT) { if(wait_on_condition(&proc[1].mutex_rxtx,&proc[1].cond_rxtx,&proc[1].pipe_ready,"wakeup_tx")<0) { LOG_E(PHY,"Frame %d, subframe %d: TX1 not ready\n",proc[1].frame_rx,proc[1].subframe_rx); return(-1); } + if (release_thread(&proc[1].mutex_rxtx,&proc[1].pipe_ready,"wakeup_tx")<0) return(-1); } pthread_mutex_lock(&eNB->UL_INFO_mutex); - eNB->UL_INFO.frame = proc->frame_rx; eNB->UL_INFO.subframe = proc->subframe_rx; eNB->UL_INFO.module_id = eNB->Mod_id; eNB->UL_INFO.CC_id = eNB->CC_id; - eNB->if_inst->UL_indication(&eNB->UL_INFO); - pthread_mutex_unlock(&eNB->UL_INFO_mutex); /* this conflict resolution may be totally wrong, to be tested */ /* CONFLICT RESOLUTION: BEGIN */ - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ULSCH_SCHEDULER , 0 ); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ULSCH_SCHEDULER, 0 ); + if(oai_exit) return(-1); - if(get_thread_parallel_conf() == PARALLEL_SINGLE_THREAD){ + + if(get_thread_parallel_conf() == PARALLEL_SINGLE_THREAD) { #ifndef PHY_TX_THREAD phy_procedures_eNB_TX(eNB, proc, 1); #endif } + /* CONFLICT RESOLUTION: what about this release_thread call, has it to be done? if yes, where? */ //if (release_thread(&proc->mutex_rxtx,&proc->instance_cnt_rxtx,thread_name)<0) return(-1); /* CONFLICT RESOLUTION: END */ - stop_meas( &softmodem_stats_rxtx_sf ); - LOG_D(PHY,"%s() Exit proc[rx:%d%d tx:%d%d]\n", __FUNCTION__, proc->frame_rx, proc->subframe_rx, proc->frame_tx, proc->subframe_tx); - LOG_D(PHY, "rxtx:%lld nfapi:%lld tx:%lld rx:%lld prach:%lld ofdm:%lld ", - softmodem_stats_rxtx_sf.p_time, nfapi_meas.p_time, - TICK_TO_US(eNB->phy_proc_tx), - TICK_TO_US(eNB->phy_proc_rx), - TICK_TO_US(eNB->rx_prach), - TICK_TO_US(eNB->ofdm_mod_stats) - ); + softmodem_stats_rxtx_sf.p_time, nfapi_meas.p_time, + TICK_TO_US(eNB->phy_proc_tx), + TICK_TO_US(eNB->phy_proc_rx), + TICK_TO_US(eNB->rx_prach), + TICK_TO_US(eNB->ofdm_mod_stats) + ); LOG_D(PHY, - "dlsch[enc:%lld mod:%lld scr:%lld rm:%lld t:%lld i:%lld] rx_dft:%lld ", - TICK_TO_US(eNB->dlsch_encoding_stats), - TICK_TO_US(eNB->dlsch_modulation_stats), - TICK_TO_US(eNB->dlsch_scrambling_stats), - TICK_TO_US(eNB->dlsch_rate_matching_stats), - TICK_TO_US(eNB->dlsch_turbo_encoding_stats), - TICK_TO_US(eNB->dlsch_interleaving_stats), - TICK_TO_US(eNB->rx_dft_stats)); - + "dlsch[enc:%lld mod:%lld scr:%lld rm:%lld t:%lld i:%lld] rx_dft:%lld ", + TICK_TO_US(eNB->dlsch_encoding_stats), + TICK_TO_US(eNB->dlsch_modulation_stats), + TICK_TO_US(eNB->dlsch_scrambling_stats), + TICK_TO_US(eNB->dlsch_rate_matching_stats), + TICK_TO_US(eNB->dlsch_turbo_encoding_stats), + TICK_TO_US(eNB->dlsch_interleaving_stats), + TICK_TO_US(eNB->rx_dft_stats)); LOG_D(PHY," ulsch[ch:%lld freq:%lld dec:%lld demod:%lld ru:%lld ", - TICK_TO_US(eNB->ulsch_channel_estimation_stats), - TICK_TO_US(eNB->ulsch_freq_offset_estimation_stats), - TICK_TO_US(eNB->ulsch_decoding_stats), - TICK_TO_US(eNB->ulsch_demodulation_stats), - TICK_TO_US(eNB->ulsch_rate_unmatching_stats)); - + TICK_TO_US(eNB->ulsch_channel_estimation_stats), + TICK_TO_US(eNB->ulsch_freq_offset_estimation_stats), + TICK_TO_US(eNB->ulsch_decoding_stats), + TICK_TO_US(eNB->ulsch_demodulation_stats), + TICK_TO_US(eNB->ulsch_rate_unmatching_stats)); LOG_D(PHY, "td:%lld dei:%lld dem:%lld llr:%lld tci:%lld ", - TICK_TO_US(eNB->ulsch_turbo_decoding_stats), - TICK_TO_US(eNB->ulsch_deinterleaving_stats), - TICK_TO_US(eNB->ulsch_demultiplexing_stats), - TICK_TO_US(eNB->ulsch_llr_stats), - TICK_TO_US(eNB->ulsch_tc_init_stats)); - LOG_D(PHY, "tca:%lld tcb:%lld tcg:%lld tce:%lld l1:%lld l2:%lld]\n\n", - TICK_TO_US(eNB->ulsch_tc_alpha_stats), - TICK_TO_US(eNB->ulsch_tc_beta_stats), - TICK_TO_US(eNB->ulsch_tc_gamma_stats), - TICK_TO_US(eNB->ulsch_tc_ext_stats), - TICK_TO_US(eNB->ulsch_tc_intl1_stats), - TICK_TO_US(eNB->ulsch_tc_intl2_stats) - ); - + TICK_TO_US(eNB->ulsch_turbo_decoding_stats), + TICK_TO_US(eNB->ulsch_deinterleaving_stats), + TICK_TO_US(eNB->ulsch_demultiplexing_stats), + TICK_TO_US(eNB->ulsch_llr_stats), + TICK_TO_US(eNB->ulsch_tc_init_stats)); + LOG_D(PHY, "tca:%lld tcb:%lld tcg:%lld tce:%lld l1:%lld l2:%lld]\n\n", + TICK_TO_US(eNB->ulsch_tc_alpha_stats), + TICK_TO_US(eNB->ulsch_tc_beta_stats), + TICK_TO_US(eNB->ulsch_tc_gamma_stats), + TICK_TO_US(eNB->ulsch_tc_ext_stats), + TICK_TO_US(eNB->ulsch_tc_intl1_stats), + TICK_TO_US(eNB->ulsch_tc_intl2_stats) + ); return(0); } -static void* tx_thread(void* param) { - - eNB_proc_t *eNB_proc = (eNB_proc_t*)param; +static void *tx_thread(void *param) { + eNB_proc_t *eNB_proc = (eNB_proc_t *)param; eNB_rxtx_proc_t *proc = &eNB_proc->proc_rxtx[1]; PHY_VARS_eNB *eNB = RC.eNB[0][proc->CC_id]; - char thread_name[100]; sprintf(thread_name,"TXnp4_%d\n",&eNB->proc.proc_rxtx[0] == proc ? 0 : 1); thread_top_init(thread_name,1,470000,500000,500000); - - //wait_sync("tx_thread"); - - while (!oai_exit) { - + //wait_sync("tx_thread"); + + while (!oai_exit) { if (wait_on_condition(&proc->mutex_rxtx,&proc->cond_rxtx,&proc->instance_cnt_rxtx,thread_name)<0) break; - if (oai_exit) break; + + if (oai_exit) break; + // ***************************************** // TX processing for subframe n+4 // run PHY TX procedures the one after the other for all CCs to avoid race conditions @@ -326,17 +316,19 @@ static void* tx_thread(void* param) { VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_SUBFRAME_NUMBER_RX1_ENB,proc->subframe_rx); VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX1_ENB,proc->frame_tx); VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_RX1_ENB,proc->frame_rx); - phy_procedures_eNB_TX(eNB, proc, 1); + if (release_thread(&proc->mutex_rxtx,&proc->instance_cnt_rxtx,thread_name)<0) break; - + pthread_mutex_lock( &proc->mutex_rxtx ); proc->pipe_ready++; + // the thread can now be woken up if (pthread_cond_signal(&proc->cond_rxtx) != 0) { LOG_E( PHY, "[eNB] ERROR pthread_cond_signal for eNB TXnp4 thread\n"); exit_fun( "ERROR pthread_cond_signal" ); } + pthread_mutex_unlock( &proc->mutex_rxtx ); wakeup_txfh(proc,eNB_proc->ru_proc); } @@ -350,44 +342,32 @@ static void* tx_thread(void* param) { * \returns a pointer to an int. The storage is not on the heap and must not be freed. */ -static void* eNB_thread_rxtx( void* param ) { - +static void *eNB_thread_rxtx( void *param ) { static int eNB_thread_rxtx_status; //eNB_proc_t *eNB_proc = (eNB_proc_t*)param; eNB_rxtx_proc_t *proc; // Working - if(nfapi_mode ==2){ - proc = (eNB_rxtx_proc_t*)param; + if(nfapi_mode ==2) { + proc = (eNB_rxtx_proc_t *)param; + } else { + eNB_proc_t *eNB_proc = (eNB_proc_t *)param; + proc = &eNB_proc->proc_rxtx[0]; } - else{ - eNB_proc_t *eNB_proc = (eNB_proc_t*)param; - proc = &eNB_proc->proc_rxtx[0]; - } - PHY_VARS_eNB *eNB = RC.eNB[0][proc->CC_id]; //RU_proc_t *ru_proc = NULL; - char thread_name[100]; - cpu_set_t cpuset; CPU_ZERO(&cpuset); - // set default return value eNB_thread_rxtx_status = 0; - - sprintf(thread_name,"RXn_TXnp4_%d\n",&eNB->proc.proc_rxtx[0] == proc ? 0 : 1); thread_top_init(thread_name,1,470000,500000,500000); pthread_setname_np( pthread_self(),"rxtx processing"); LOG_I(PHY,"thread rxtx created id=%ld\n", syscall(__NR_gettid)); - - while (!oai_exit) { - - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_eNB_PROC_RXTX0+(proc->subframe_rx&1), 0 ); T(T_ENB_MASTER_TICK, T_INT(0), T_INT(proc->frame_rx), T_INT(proc->subframe_rx)); @@ -395,61 +375,55 @@ static void* eNB_thread_rxtx( void* param ) { VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_CPUID_ENB_THREAD_RXTX,sched_getcpu()); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_eNB_PROC_RXTX0+(proc->subframe_rx&1), 1 ); - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_SUBFRAME_NUMBER_TX0_ENB,proc->subframe_tx); VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_SUBFRAME_NUMBER_RX0_ENB,proc->subframe_rx); VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX0_ENB,proc->frame_tx); VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_RX0_ENB,proc->frame_rx); - if (oai_exit) break; - if (eNB->CC_id==0) - { + if (eNB->CC_id==0) { if (rxtx(eNB,proc,thread_name) < 0) break; } if (release_thread(&proc->mutex_rxtx,&proc->instance_cnt_rxtx,thread_name)<0) break; + pthread_mutex_lock( &proc->mutex_rxtx ); proc->pipe_ready++; + // the thread can now be woken up if (pthread_cond_signal(&proc->cond_rxtx) != 0) { LOG_E( PHY, "[eNB] ERROR pthread_cond_signal for eNB TXnp4 thread\n"); exit_fun( "ERROR pthread_cond_signal" ); } - pthread_mutex_unlock( &proc->mutex_rxtx ); - if (nfapi_mode!=2){ - if(get_thread_parallel_conf() == PARALLEL_RU_L1_TRX_SPLIT) wakeup_tx(eNB,eNB->proc.ru_proc); - else if(get_thread_parallel_conf() == PARALLEL_RU_L1_SPLIT) - { - phy_procedures_eNB_TX(eNB, proc, 1); - wakeup_txfh(proc,eNB->proc.ru_proc); - } - } + pthread_mutex_unlock( &proc->mutex_rxtx ); + + if (nfapi_mode!=2) { + if(get_thread_parallel_conf() == PARALLEL_RU_L1_TRX_SPLIT) wakeup_tx(eNB,eNB->proc.ru_proc); + else if(get_thread_parallel_conf() == PARALLEL_RU_L1_SPLIT) { + phy_procedures_eNB_TX(eNB, proc, 1); + wakeup_txfh(proc,eNB->proc.ru_proc); + } + } } // while !oai_exit VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_eNB_PROC_RXTX0+(proc->subframe_rx&1), 0 ); - LOG_D(PHY, " *** Exiting eNB thread RXn_TXnp4\n"); - eNB_thread_rxtx_status = 0; return &eNB_thread_rxtx_status; } -void eNB_top(PHY_VARS_eNB *eNB, int frame_rx, int subframe_rx, char *string,RU_t *ru) -{ +void eNB_top(PHY_VARS_eNB *eNB, int frame_rx, int subframe_rx, char *string,RU_t *ru) { eNB_proc_t *proc = &eNB->proc; eNB_rxtx_proc_t *proc_rxtx = &proc->proc_rxtx[0]; LTE_DL_FRAME_PARMS *fp = &ru->frame_parms; RU_proc_t *ru_proc=&ru->proc; - proc->frame_rx = frame_rx; proc->subframe_rx = subframe_rx; if (!oai_exit) { T(T_ENB_MASTER_TICK, T_INT(0), T_INT(proc->frame_rx), T_INT(proc->subframe_rx)); - proc_rxtx->timestamp_tx = ru_proc->timestamp_rx + (sf_ahead*fp->samples_per_tti); proc_rxtx->frame_rx = ru_proc->frame_rx; proc_rxtx->subframe_rx = ru_proc->subframe_rx; @@ -457,6 +431,7 @@ void eNB_top(PHY_VARS_eNB *eNB, int frame_rx, int subframe_rx, char *string,RU_t proc_rxtx->subframe_tx = (proc_rxtx->subframe_rx + sf_ahead)%10; if (rxtx(eNB,proc_rxtx,string) < 0) LOG_E(PHY,"eNB %d CC_id %d failed during execution\n",eNB->Mod_id,eNB->CC_id); + ru_proc->timestamp_tx = proc_rxtx->timestamp_tx; ru_proc->subframe_tx = proc_rxtx->subframe_tx; ru_proc->frame_tx = proc_rxtx->frame_tx; @@ -464,66 +439,60 @@ void eNB_top(PHY_VARS_eNB *eNB, int frame_rx, int subframe_rx, char *string,RU_t } int wakeup_txfh(eNB_rxtx_proc_t *proc,RU_proc_t *ru_proc) { - - if(ru_proc == NULL) - return(0); + if(ru_proc == NULL) + return(0); + struct timespec wait; wait.tv_sec=0; wait.tv_nsec=5000000L; - if(wait_on_condition(&ru_proc->mutex_eNBs,&ru_proc->cond_eNBs,&ru_proc->ru_tx_ready,"wakeup_txfh")<0) { LOG_E(PHY,"Frame %d, subframe %d: TX FH not ready\n", ru_proc->frame_tx, ru_proc->subframe_tx); return(-1); } + if (release_thread(&ru_proc->mutex_eNBs,&ru_proc->ru_tx_ready,"wakeup_txfh")<0) return(-1); - + if (ru_proc->instance_cnt_eNBs == 0) { LOG_E(PHY,"Frame %d, subframe %d: TX FH thread busy, dropping Frame %d, subframe %d\n", ru_proc->frame_tx, ru_proc->subframe_tx, proc->frame_rx, proc->subframe_rx); return(-1); } + if (pthread_mutex_timedlock(&ru_proc->mutex_eNBs,&wait) != 0) { LOG_E( PHY, "[eNB] ERROR pthread_mutex_lock for eNB TX1 thread %d (IC %d)\n", ru_proc->subframe_rx&1,ru_proc->instance_cnt_eNBs ); exit_fun( "error locking mutex_eNB" ); return(-1); } - ++ru_proc->instance_cnt_eNBs; - ru_proc->timestamp_tx = proc->timestamp_tx; - ru_proc->subframe_tx = proc->subframe_tx; - ru_proc->frame_tx = proc->frame_tx; - + ++ru_proc->instance_cnt_eNBs; + ru_proc->timestamp_tx = proc->timestamp_tx; + ru_proc->subframe_tx = proc->subframe_tx; + ru_proc->frame_tx = proc->frame_tx; + // the thread can now be woken up if (pthread_cond_signal(&ru_proc->cond_eNBs) != 0) { LOG_E( PHY, "[eNB] ERROR pthread_cond_signal for eNB TXnp4 thread\n"); exit_fun( "ERROR pthread_cond_signal" ); return(-1); } - - pthread_mutex_unlock( &ru_proc->mutex_eNBs ); + pthread_mutex_unlock( &ru_proc->mutex_eNBs ); return(0); } int wakeup_tx(PHY_VARS_eNB *eNB,RU_proc_t *ru_proc) { - eNB_proc_t *proc=&eNB->proc; - eNB_rxtx_proc_t *proc_rxtx1=&proc->proc_rxtx[1];//*proc_rxtx=&proc->proc_rxtx[proc->frame_rx&1]; eNB_rxtx_proc_t *proc_rxtx0=&proc->proc_rxtx[0]; - - struct timespec wait; wait.tv_sec=0; wait.tv_nsec=5000000L; - - - + if (proc_rxtx1->instance_cnt_rxtx == 0) { LOG_E(PHY,"Frame %d, subframe %d: TX1 thread busy, dropping\n",proc_rxtx1->frame_rx,proc_rxtx1->subframe_rx); return(-1); } - + if (pthread_mutex_timedlock(&proc_rxtx1->mutex_rxtx,&wait) != 0) { LOG_E( PHY, "[eNB] ERROR pthread_mutex_lock for eNB TX1 thread %d (IC %d)\n", proc_rxtx1->subframe_rx&1,proc_rxtx1->instance_cnt_rxtx ); exit_fun( "error locking mutex_tx" ); @@ -531,72 +500,62 @@ int wakeup_tx(PHY_VARS_eNB *eNB,RU_proc_t *ru_proc) { } ++proc_rxtx1->instance_cnt_rxtx; - - proc_rxtx1->subframe_rx = proc_rxtx0->subframe_rx; proc_rxtx1->frame_rx = proc_rxtx0->frame_rx; proc_rxtx1->subframe_tx = proc_rxtx0->subframe_tx; proc_rxtx1->frame_tx = proc_rxtx0->frame_tx; proc_rxtx1->timestamp_tx = proc_rxtx0->timestamp_tx; - + // the thread can now be woken up if (pthread_cond_signal(&proc_rxtx1->cond_rxtx) != 0) { LOG_E( PHY, "[eNB] ERROR pthread_cond_signal for eNB TXnp4 thread\n"); exit_fun( "ERROR pthread_cond_signal" ); return(-1); } - - pthread_mutex_unlock( &proc_rxtx1->mutex_rxtx ); + pthread_mutex_unlock( &proc_rxtx1->mutex_rxtx ); return(0); } int wakeup_rxtx(PHY_VARS_eNB *eNB,RU_t *ru) { - eNB_proc_t *proc=&eNB->proc; RU_proc_t *ru_proc=&ru->proc; - eNB_rxtx_proc_t *proc_rxtx0=&proc->proc_rxtx[0]; //eNB_rxtx_proc_t *proc_rxtx1=&proc->proc_rxtx[1]; - - LTE_DL_FRAME_PARMS *fp = &eNB->frame_parms; - int i; struct timespec wait; - pthread_mutex_lock(&proc->mutex_RU); - for (i=0;inum_RU;i++) { + + for (i=0; inum_RU; i++) { if (ru == eNB->RU_list[i]) { if ((proc->RU_mask&(1< 0) - LOG_E(PHY,"eNB %d frame %d, subframe %d : previous information from RU %d (num_RU %d,mask %x) has not been served yet!\n", - eNB->Mod_id,proc->frame_rx,proc->subframe_rx,ru->idx,eNB->num_RU,proc->RU_mask); + LOG_E(PHY,"eNB %d frame %d, subframe %d : previous information from RU %d (num_RU %d,mask %x) has not been served yet!\n", + eNB->Mod_id,proc->frame_rx,proc->subframe_rx,ru->idx,eNB->num_RU,proc->RU_mask); + proc->RU_mask |= (1<RU_mask != (1<num_RU)-1) { // not all RUs have provided their information so return LOG_E(PHY,"Not all RUs have provided their info\n"); pthread_mutex_unlock(&proc->mutex_RU); return(0); - } - else { // all RUs have provided their information so continue on and wakeup eNB processing + } else { // all RUs have provided their information so continue on and wakeup eNB processing proc->RU_mask = 0; pthread_mutex_unlock(&proc->mutex_RU); } - - - wait.tv_sec=0; wait.tv_nsec=5000000L; - if(wait_on_condition(&proc_rxtx0->mutex_rxtx,&proc_rxtx0->cond_rxtx,&proc_rxtx0->pipe_ready,"wakeup_rxtx")<0) { LOG_E(PHY,"Frame %d, subframe %d: RXTX0 not ready\n",proc_rxtx0->frame_rx,proc_rxtx0->subframe_rx); return(-1); } + if (release_thread(&proc_rxtx0->mutex_rxtx,&proc_rxtx0->pipe_ready,"wakeup_rxtx")<0) return(-1); - + if (proc_rxtx0->instance_cnt_rxtx == 0) { LOG_E(PHY,"Frame %d, subframe %d: RXTX0 thread busy, dropping\n",proc_rxtx0->frame_rx,proc_rxtx0->subframe_rx); return(-1); @@ -609,14 +568,12 @@ int wakeup_rxtx(PHY_VARS_eNB *eNB,RU_t *ru) { exit_fun( "error locking mutex_rxtx" ); return(-1); } - ++proc_rxtx0->instance_cnt_rxtx; - - // We have just received and processed the common part of a subframe, say n. - // TS_rx is the last received timestamp (start of 1st slot), TS_tx is the desired + // We have just received and processed the common part of a subframe, say n. + // TS_rx is the last received timestamp (start of 1st slot), TS_tx is the desired // transmitted timestamp of the next TX slot (first). - // The last (TS_rx mod samples_per_frame) was n*samples_per_tti, + // The last (TS_rx mod samples_per_frame) was n*samples_per_tti, // we want to generate subframe (n+sf_ahead), so TS_tx = TX_rx+sf_ahead*samples_per_tti, // and proc->subframe_tx = proc->subframe_rx+sf_ahead proc_rxtx0->timestamp_tx = ru_proc->timestamp_rx + (sf_ahead*fp->samples_per_tti); @@ -631,414 +588,381 @@ int wakeup_rxtx(PHY_VARS_eNB *eNB,RU_t *ru) { exit_fun( "ERROR pthread_cond_signal" ); return(-1); } - - pthread_mutex_unlock( &proc_rxtx0->mutex_rxtx ); + pthread_mutex_unlock( &proc_rxtx0->mutex_rxtx ); return(0); } void wakeup_prach_eNB(PHY_VARS_eNB *eNB,RU_t *ru,int frame,int subframe) { - eNB_proc_t *proc = &eNB->proc; LTE_DL_FRAME_PARMS *fp=&eNB->frame_parms; int i; if (ru!=NULL) { pthread_mutex_lock(&proc->mutex_RU_PRACH); - for (i=0;inum_RU;i++) { + + for (i=0; inum_RU; i++) { if (ru == eNB->RU_list[i]) { - LOG_D(PHY,"frame %d, subframe %d: RU %d for eNB %d signals PRACH (mask %x, num_RU %d)\n",frame,subframe,i,eNB->Mod_id,proc->RU_mask_prach,eNB->num_RU); - if ((proc->RU_mask_prach&(1< 0) - LOG_E(PHY,"eNB %d frame %d, subframe %d : previous information (PRACH) from RU %d (num_RU %d, mask %x) has not been served yet!\n", - eNB->Mod_id,frame,subframe,ru->idx,eNB->num_RU,proc->RU_mask_prach); - proc->RU_mask_prach |= (1<Mod_id,proc->RU_mask_prach,eNB->num_RU); + + if ((proc->RU_mask_prach&(1< 0) + LOG_E(PHY,"eNB %d frame %d, subframe %d : previous information (PRACH) from RU %d (num_RU %d, mask %x) has not been served yet!\n", + eNB->Mod_id,frame,subframe,ru->idx,eNB->num_RU,proc->RU_mask_prach); + + proc->RU_mask_prach |= (1<RU_mask_prach != (1<num_RU)-1) { // not all RUs have provided their information so return pthread_mutex_unlock(&proc->mutex_RU_PRACH); return; - } - else { // all RUs have provided their information so continue on and wakeup eNB processing + } else { // all RUs have provided their information so continue on and wakeup eNB processing proc->RU_mask_prach = 0; pthread_mutex_unlock(&proc->mutex_RU_PRACH); } } - + // check if we have to detect PRACH first - if (is_prach_subframe(fp,frame,subframe)>0) { + if (is_prach_subframe(fp,frame,subframe)>0) { LOG_D(PHY,"Triggering prach processing, frame %d, subframe %d\n",frame,subframe); + if (proc->instance_cnt_prach == 0) { LOG_W(PHY,"[eNB] Frame %d Subframe %d, dropping PRACH\n", frame,subframe); return; } - + // wake up thread for PRACH RX if (pthread_mutex_lock(&proc->mutex_prach) != 0) { LOG_E( PHY, "[eNB] ERROR pthread_mutex_lock for eNB PRACH thread %d (IC %d)\n", proc->thread_index, proc->instance_cnt_prach); exit_fun( "error locking mutex_prach" ); return; } - + ++proc->instance_cnt_prach; // set timing for prach thread proc->frame_prach = frame; proc->subframe_prach = subframe; - + // the thread can now be woken up if (pthread_cond_signal(&proc->cond_prach) != 0) { LOG_E( PHY, "[eNB] ERROR pthread_cond_signal for eNB PRACH thread %d\n", proc->thread_index); exit_fun( "ERROR pthread_cond_signal" ); return; } - + pthread_mutex_unlock( &proc->mutex_prach ); } - } #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) void wakeup_prach_eNB_br(PHY_VARS_eNB *eNB,RU_t *ru,int frame,int subframe) { - eNB_proc_t *proc = &eNB->proc; LTE_DL_FRAME_PARMS *fp=&eNB->frame_parms; int i; if (ru!=NULL) { pthread_mutex_lock(&proc->mutex_RU_PRACH_br); - for (i=0;inum_RU;i++) { + + for (i=0; inum_RU; i++) { if (ru == eNB->RU_list[i]) { - LOG_D(PHY,"frame %d, subframe %d: RU %d for eNB %d signals PRACH BR (mask %x, num_RU %d)\n",frame,subframe,i,eNB->Mod_id,proc->RU_mask_prach_br,eNB->num_RU); - if ((proc->RU_mask_prach_br&(1< 0) - LOG_E(PHY,"eNB %d frame %d, subframe %d : previous information (PRACH BR) from RU %d (num_RU %d, mask %x) has not been served yet!\n", - eNB->Mod_id,frame,subframe,ru->idx,eNB->num_RU,proc->RU_mask_prach_br); - proc->RU_mask_prach_br |= (1<Mod_id,proc->RU_mask_prach_br,eNB->num_RU); + + if ((proc->RU_mask_prach_br&(1< 0) + LOG_E(PHY,"eNB %d frame %d, subframe %d : previous information (PRACH BR) from RU %d (num_RU %d, mask %x) has not been served yet!\n", + eNB->Mod_id,frame,subframe,ru->idx,eNB->num_RU,proc->RU_mask_prach_br); + + proc->RU_mask_prach_br |= (1<RU_mask_prach_br != (1<num_RU)-1) { // not all RUs have provided their information so return pthread_mutex_unlock(&proc->mutex_RU_PRACH_br); return; - } - else { // all RUs have provided their information so continue on and wakeup eNB processing + } else { // all RUs have provided their information so continue on and wakeup eNB processing proc->RU_mask_prach_br = 0; pthread_mutex_unlock(&proc->mutex_RU_PRACH_br); } } - -<<<<<<< HEAD + + <<<<<<< HEAD + // check if we have to detect PRACH first - if (is_prach_subframe(fp,frame,subframe)>0) { + if (is_prach_subframe(fp,frame,subframe)>0) { LOG_D(PHY,"Triggering prach br processing, frame %d, subframe %d\n",frame,subframe); + if (proc->instance_cnt_prach_br == 0) { LOG_W(PHY,"[eNB] Frame %d Subframe %d, dropping PRACH BR\n", frame,subframe); return; -======= + ======= + } + + eNB_thread_asynch_rxtx_status=0; + return(&eNB_thread_asynch_rxtx_status); } - eNB_thread_asynch_rxtx_status=0; - return(&eNB_thread_asynch_rxtx_status); -} + void rx_rf(PHY_VARS_eNB *eNB,int *frame,int *subframe) { + eNB_proc_t *proc = &eNB->proc; + LTE_DL_FRAME_PARMS *fp = &eNB->frame_parms; + void *rxp[fp->nb_antennas_rx],*txp[fp->nb_antennas_tx]; + unsigned int rxs,txs; + int i; + int tx_sfoffset = (eNB->single_thread_flag == 1) ? 3 : 2; + openair0_timestamp ts,old_ts; - - - - -void rx_rf(PHY_VARS_eNB *eNB,int *frame,int *subframe) { - - eNB_proc_t *proc = &eNB->proc; - LTE_DL_FRAME_PARMS *fp = &eNB->frame_parms; - void *rxp[fp->nb_antennas_rx],*txp[fp->nb_antennas_tx]; - unsigned int rxs,txs; - int i; - int tx_sfoffset = (eNB->single_thread_flag == 1) ? 3 : 2; - openair0_timestamp ts,old_ts; - - if (proc->first_rx==0) { - - // Transmit TX buffer based on timestamp from RX - // printf("trx_write -> USRP TS %llu (sf %d)\n", (proc->timestamp_rx+(3*fp->samples_per_tti)),(proc->subframe_rx+2)%10); - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TST, (proc->timestamp_rx+(tx_sfoffset*fp->samples_per_tti)-openair0_cfg[0].tx_sample_advance)&0xffffffff ); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE, 1 ); - // prepare tx buffer pointers - - lte_subframe_t SF_type = subframe_select(fp,(proc->subframe_rx+tx_sfoffset)%10); - lte_subframe_t prevSF_type = subframe_select(fp,(proc->subframe_rx+tx_sfoffset+9)%10); - lte_subframe_t nextSF_type = subframe_select(fp,(proc->subframe_rx+tx_sfoffset+1)%10); - int sf_extension = 0; - - if ((SF_type == SF_DL) || - (SF_type == SF_S)) { - - int siglen=fp->samples_per_tti,flags=1; - - if (SF_type == SF_S) { - siglen = (fp->dl_symbols_in_S_subframe+1)*(fp->ofdm_symbol_size+fp->nb_prefix_samples0); - flags=3; // end of burst - } - if ((fp->frame_type == TDD) && - (SF_type == SF_DL)&& - (prevSF_type == SF_UL) && - (nextSF_type == SF_DL)) { - flags = 2; // start of burst - sf_extension = eNB->N_TA_offset<<1; - } - if ((fp->frame_type == TDD) && - (SF_type == SF_DL)&& - (prevSF_type == SF_UL) && - (nextSF_type == SF_UL)) { - flags = 4; // start of burst and end of burst (only one DL SF between two UL) - sf_extension = eNB->N_TA_offset<<1; - } - + if (proc->first_rx==0) { + // Transmit TX buffer based on timestamp from RX + // printf("trx_write -> USRP TS %llu (sf %d)\n", (proc->timestamp_rx+(3*fp->samples_per_tti)),(proc->subframe_rx+2)%10); + VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TST, (proc->timestamp_rx+(tx_sfoffset*fp->samples_per_tti)-openair0_cfg[0].tx_sample_advance)&0xffffffff ); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE, 1 ); - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_WRITE_FLAGS,flags); + // prepare tx buffer pointers + lte_subframe_t SF_type = subframe_select(fp,(proc->subframe_rx+tx_sfoffset)%10); + lte_subframe_t prevSF_type = subframe_select(fp,(proc->subframe_rx+tx_sfoffset+9)%10); + lte_subframe_t nextSF_type = subframe_select(fp,(proc->subframe_rx+tx_sfoffset+1)%10); + int sf_extension = 0; - for (i=0; inb_antennas_tx; i++) - txp[i] = (void*)&eNB->common_vars.txdata[0][i][((proc->subframe_rx+tx_sfoffset)%10)*fp->samples_per_tti-sf_extension]; + if ((SF_type == SF_DL) || + (SF_type == SF_S)) { + int siglen=fp->samples_per_tti,flags=1; - txs = eNB->rfdevice.trx_write_func(&eNB->rfdevice, - proc->timestamp_rx+eNB->ts_offset+(tx_sfoffset*fp->samples_per_tti)-openair0_cfg[0].tx_sample_advance-sf_extension, - txp, - siglen+sf_extension, - fp->nb_antennas_tx, - flags); - clock_gettime( CLOCK_MONOTONIC, &end_rf); - end_rf_ts = proc->timestamp_rx+eNB->ts_offset+(tx_sfoffset*fp->samples_per_tti)-openair0_cfg[0].tx_sample_advance; - if (recv_if_count != 0 ) { - recv_if_count = recv_if_count-1; - LOG_D(HW,"[From Timestamp %"PRId64" to Timestamp %"PRId64"] RTT_RF: %"PRId64"; RTT_RF\n", start_rf_prev_ts, end_rf_ts, clock_difftime_ns(start_rf_prev, end_rf)); - LOG_D(HW,"[From Timestamp %"PRId64" to Timestamp %"PRId64"] RTT_RF: %"PRId64"; RTT_RF\n",start_rf_prev2_ts, end_rf_ts, clock_difftime_ns(start_rf_prev2, end_rf)); + if (SF_type == SF_S) { + siglen = (fp->dl_symbols_in_S_subframe+1)*(fp->ofdm_symbol_size+fp->nb_prefix_samples0); + flags=3; // end of burst + } + + if ((fp->frame_type == TDD) && + (SF_type == SF_DL)&& + (prevSF_type == SF_UL) && + (nextSF_type == SF_DL)) { + flags = 2; // start of burst + sf_extension = eNB->N_TA_offset<<1; + } + + if ((fp->frame_type == TDD) && + (SF_type == SF_DL)&& + (prevSF_type == SF_UL) && + (nextSF_type == SF_UL)) { + flags = 4; // start of burst and end of burst (only one DL SF between two UL) + sf_extension = eNB->N_TA_offset<<1; + } + + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE, 1 ); + VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_WRITE_FLAGS,flags); + + for (i=0; inb_antennas_tx; i++) + txp[i] = (void *)&eNB->common_vars.txdata[0][i][((proc->subframe_rx+tx_sfoffset)%10)*fp->samples_per_tti-sf_extension]; + + txs = eNB->rfdevice.trx_write_func(&eNB->rfdevice, + proc->timestamp_rx+eNB->ts_offset+(tx_sfoffset*fp->samples_per_tti)-openair0_cfg[0].tx_sample_advance-sf_extension, + txp, + siglen+sf_extension, + fp->nb_antennas_tx, + flags); + clock_gettime( CLOCK_MONOTONIC, &end_rf); + end_rf_ts = proc->timestamp_rx+eNB->ts_offset+(tx_sfoffset*fp->samples_per_tti)-openair0_cfg[0].tx_sample_advance; + + if (recv_if_count != 0 ) { + recv_if_count = recv_if_count-1; + LOG_D(HW,"[From Timestamp %"PRId64" to Timestamp %"PRId64"] RTT_RF: %"PRId64"; RTT_RF\n", start_rf_prev_ts, end_rf_ts, clock_difftime_ns(start_rf_prev, end_rf)); + LOG_D(HW,"[From Timestamp %"PRId64" to Timestamp %"PRId64"] RTT_RF: %"PRId64"; RTT_RF\n",start_rf_prev2_ts, end_rf_ts, clock_difftime_ns(start_rf_prev2, end_rf)); + } + + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE, 0 ); + + if (txs != siglen+sf_extension) { + LOG_E(PHY,"TX : Timeout (sent %d/%d)\n",txs, fp->samples_per_tti); + exit_fun( "problem transmitting samples" ); + } } - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE, 0 ); - - - - if (txs != siglen+sf_extension) { - LOG_E(PHY,"TX : Timeout (sent %d/%d)\n",txs, fp->samples_per_tti); - exit_fun( "problem transmitting samples" ); - } + } + + for (i=0; inb_antennas_rx; i++) + rxp[i] = (void *)&eNB->common_vars.rxdata[0][i][*subframe*fp->samples_per_tti]; + + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ, 1 ); + old_ts = proc->timestamp_rx; + rxs = eNB->rfdevice.trx_read_func(&eNB->rfdevice, + &ts, + rxp, + fp->samples_per_tti, + fp->nb_antennas_rx); + start_rf_prev2= start_rf_prev; + start_rf_prev2_ts= start_rf_prev_ts; + start_rf_prev = start_rf_new; + start_rf_prev_ts = start_rf_new_ts; + clock_gettime( CLOCK_MONOTONIC, &start_rf_new); + start_rf_new_ts = ts; + LOG_D(PHY,"rx_rf: first_rx %d received ts %"PRId64" (sptti %d)\n",proc->first_rx,ts,fp->samples_per_tti); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ, 0 ); + proc->timestamp_rx = ts-eNB->ts_offset; + + if (rxs != fp->samples_per_tti) + LOG_E(PHY,"rx_rf: Asked for %d samples, got %d from USRP\n",fp->samples_per_tti,rxs); + + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ, 0 ); + + if (proc->first_rx == 1) { + eNB->ts_offset = proc->timestamp_rx; + proc->timestamp_rx=0; + } else { + if (proc->timestamp_rx - old_ts != fp->samples_per_tti) { + LOG_I(PHY,"rx_rf: rfdevice timing drift of %"PRId64" samples (ts_off %"PRId64")\n",proc->timestamp_rx - old_ts - fp->samples_per_tti,eNB->ts_offset); + eNB->ts_offset += (proc->timestamp_rx - old_ts - fp->samples_per_tti); + proc->timestamp_rx = ts-eNB->ts_offset; + } + } + + proc->frame_rx = (proc->timestamp_rx / (fp->samples_per_tti*10))&1023; + proc->subframe_rx = (proc->timestamp_rx / fp->samples_per_tti)%10; + proc->frame_rx = (proc->frame_rx+proc->frame_offset)&1023; + proc->frame_tx = proc->frame_rx; + + if (proc->subframe_rx > 5) proc->frame_tx=(proc->frame_tx+1)&1023; + + // synchronize first reception to frame 0 subframe 0 + proc->timestamp_tx = proc->timestamp_rx+(4*fp->samples_per_tti); + // printf("trx_read <- USRP TS %lu (offset %d sf %d, f %d, first_rx %d)\n", proc->timestamp_rx,eNB->ts_offset,proc->subframe_rx,proc->frame_rx,proc->first_rx); + + if (proc->first_rx == 0) { + if (proc->subframe_rx != *subframe) { + LOG_E(PHY,"rx_rf: Received Timestamp (%"PRId64") doesn't correspond to the time we think it is (proc->subframe_rx %d, subframe %d)\n",proc->timestamp_rx,proc->subframe_rx,*subframe); + exit_fun("Exiting"); + } + + int f2 = (*frame+proc->frame_offset)&1023; + + if (proc->frame_rx != f2) { + LOG_E(PHY,"rx_rf: Received Timestamp (%"PRId64") doesn't correspond to the time we think it is (proc->frame_rx %d frame %d, frame_offset %d, f2 %d)\n",proc->timestamp_rx,proc->frame_rx,*frame, + proc->frame_offset,f2); + exit_fun("Exiting"); + } + } else { + proc->first_rx--; + *frame = proc->frame_rx; + *subframe = proc->subframe_rx; + } + + //printf("timestamp_rx %lu, frame %d(%d), subframe %d(%d)\n",proc->timestamp_rx,proc->frame_rx,frame,proc->subframe_rx,subframe); + VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TS, proc->timestamp_rx&0xffffffff ); + + if (rxs != fp->samples_per_tti) + exit_fun( "problem receiving samples" ); + } + void rx_fh_if5(PHY_VARS_eNB *eNB,int *frame, int *subframe) { + LTE_DL_FRAME_PARMS *fp = &eNB->frame_parms; + eNB_proc_t *proc = &eNB->proc; + recv_IF5(eNB, &proc->timestamp_rx, *subframe, IF5_RRH_GW_UL); + proc->frame_rx = (proc->timestamp_rx / (fp->samples_per_tti*10))&1023; + proc->subframe_rx = (proc->timestamp_rx / fp->samples_per_tti)%10; + + if (proc->first_rx == 0) { + if (proc->subframe_rx != *subframe) { + LOG_E(PHY,"rx_fh_if5: Received Timestamp doesn't correspond to the time we think it is (proc->subframe_rx %d, subframe %d)\n",proc->subframe_rx,*subframe); + exit_fun("Exiting"); + >>>>>>> ae0494b0bc431bf664e300b0b5a10f348d6b6757 + } + + // wake up thread for PRACH RX + if (pthread_mutex_lock(&proc->mutex_prach_br) != 0) { + LOG_E( PHY, "[eNB] ERROR pthread_mutex_lock for eNB PRACH thread %d (IC %d)\n", proc->thread_index, proc->instance_cnt_prach_br); + exit_fun( "error locking mutex_prach" ); + return; + } + + ++proc->instance_cnt_prach_br; + // set timing for prach thread + proc->frame_prach_br = frame; + proc->subframe_prach_br = subframe; + + // the thread can now be woken up + if (pthread_cond_signal(&proc->cond_prach_br) != 0) { + LOG_E( PHY, "[eNB] ERROR pthread_cond_signal for eNB PRACH BR thread %d\n", proc->thread_index); + exit_fun( "ERROR pthread_cond_signal" ); + return; + } + + pthread_mutex_unlock( &proc->mutex_prach_br ); } } - - for (i=0; inb_antennas_rx; i++) - rxp[i] = (void*)&eNB->common_vars.rxdata[0][i][*subframe*fp->samples_per_tti]; - - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ, 1 ); - - old_ts = proc->timestamp_rx; - - rxs = eNB->rfdevice.trx_read_func(&eNB->rfdevice, - &ts, - rxp, - fp->samples_per_tti, - fp->nb_antennas_rx); - start_rf_prev2= start_rf_prev; - start_rf_prev2_ts= start_rf_prev_ts; - start_rf_prev = start_rf_new; - start_rf_prev_ts = start_rf_new_ts; - clock_gettime( CLOCK_MONOTONIC, &start_rf_new); - start_rf_new_ts = ts; - LOG_D(PHY,"rx_rf: first_rx %d received ts %"PRId64" (sptti %d)\n",proc->first_rx,ts,fp->samples_per_tti); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ, 0 ); - - proc->timestamp_rx = ts-eNB->ts_offset; - - if (rxs != fp->samples_per_tti) - LOG_E(PHY,"rx_rf: Asked for %d samples, got %d from USRP\n",fp->samples_per_tti,rxs); - - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ, 0 ); - - if (proc->first_rx == 1) { - eNB->ts_offset = proc->timestamp_rx; - proc->timestamp_rx=0; - } - else { - - if (proc->timestamp_rx - old_ts != fp->samples_per_tti) { - LOG_I(PHY,"rx_rf: rfdevice timing drift of %"PRId64" samples (ts_off %"PRId64")\n",proc->timestamp_rx - old_ts - fp->samples_per_tti,eNB->ts_offset); - eNB->ts_offset += (proc->timestamp_rx - old_ts - fp->samples_per_tti); - proc->timestamp_rx = ts-eNB->ts_offset; - } - } - proc->frame_rx = (proc->timestamp_rx / (fp->samples_per_tti*10))&1023; - proc->subframe_rx = (proc->timestamp_rx / fp->samples_per_tti)%10; - proc->frame_rx = (proc->frame_rx+proc->frame_offset)&1023; - proc->frame_tx = proc->frame_rx; - if (proc->subframe_rx > 5) proc->frame_tx=(proc->frame_tx+1)&1023; - // synchronize first reception to frame 0 subframe 0 - - proc->timestamp_tx = proc->timestamp_rx+(4*fp->samples_per_tti); - // printf("trx_read <- USRP TS %lu (offset %d sf %d, f %d, first_rx %d)\n", proc->timestamp_rx,eNB->ts_offset,proc->subframe_rx,proc->frame_rx,proc->first_rx); - - if (proc->first_rx == 0) { - if (proc->subframe_rx != *subframe){ - LOG_E(PHY,"rx_rf: Received Timestamp (%"PRId64") doesn't correspond to the time we think it is (proc->subframe_rx %d, subframe %d)\n",proc->timestamp_rx,proc->subframe_rx,*subframe); - exit_fun("Exiting"); - } - int f2 = (*frame+proc->frame_offset)&1023; - if (proc->frame_rx != f2) { - LOG_E(PHY,"rx_rf: Received Timestamp (%"PRId64") doesn't correspond to the time we think it is (proc->frame_rx %d frame %d, frame_offset %d, f2 %d)\n",proc->timestamp_rx,proc->frame_rx,*frame,proc->frame_offset,f2); - exit_fun("Exiting"); - } - } else { - proc->first_rx--; - *frame = proc->frame_rx; - *subframe = proc->subframe_rx; - } - - //printf("timestamp_rx %lu, frame %d(%d), subframe %d(%d)\n",proc->timestamp_rx,proc->frame_rx,frame,proc->subframe_rx,subframe); - - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TS, proc->timestamp_rx&0xffffffff ); - - if (rxs != fp->samples_per_tti) - exit_fun( "problem receiving samples" ); - - - -} - -void rx_fh_if5(PHY_VARS_eNB *eNB,int *frame, int *subframe) { - - LTE_DL_FRAME_PARMS *fp = &eNB->frame_parms; - eNB_proc_t *proc = &eNB->proc; - - recv_IF5(eNB, &proc->timestamp_rx, *subframe, IF5_RRH_GW_UL); - - proc->frame_rx = (proc->timestamp_rx / (fp->samples_per_tti*10))&1023; - proc->subframe_rx = (proc->timestamp_rx / fp->samples_per_tti)%10; - - if (proc->first_rx == 0) { - if (proc->subframe_rx != *subframe){ - LOG_E(PHY,"rx_fh_if5: Received Timestamp doesn't correspond to the time we think it is (proc->subframe_rx %d, subframe %d)\n",proc->subframe_rx,*subframe); - exit_fun("Exiting"); ->>>>>>> ae0494b0bc431bf664e300b0b5a10f348d6b6757 - } - - // wake up thread for PRACH RX - if (pthread_mutex_lock(&proc->mutex_prach_br) != 0) { - LOG_E( PHY, "[eNB] ERROR pthread_mutex_lock for eNB PRACH thread %d (IC %d)\n", proc->thread_index, proc->instance_cnt_prach_br); - exit_fun( "error locking mutex_prach" ); - return; - } - - ++proc->instance_cnt_prach_br; - // set timing for prach thread - proc->frame_prach_br = frame; - proc->subframe_prach_br = subframe; - - // the thread can now be woken up - if (pthread_cond_signal(&proc->cond_prach_br) != 0) { - LOG_E( PHY, "[eNB] ERROR pthread_cond_signal for eNB PRACH BR thread %d\n", proc->thread_index); - exit_fun( "ERROR pthread_cond_signal" ); - return; - } - - pthread_mutex_unlock( &proc->mutex_prach_br ); - } - -} #endif + /*! + * \brief The prach receive thread of eNB. + * \param param is a \ref eNB_proc_t structure which contains the info what to process. + * \returns a pointer to an int. The storage is not on the heap and must not be freed. + */ + static void *eNB_thread_prach( void *param ) { + static int eNB_thread_prach_status; + PHY_VARS_eNB *eNB= (PHY_VARS_eNB *)param; + eNB_proc_t *proc = &eNB->proc; + // set default return value + eNB_thread_prach_status = 0; + thread_top_init("eNB_thread_prach",1,500000,1000000,20000000); + //wait_sync("eNB_thread_prach"); -/*! - * \brief The prach receive thread of eNB. - * \param param is a \ref eNB_proc_t structure which contains the info what to process. - * \returns a pointer to an int. The storage is not on the heap and must not be freed. - */ -static void* eNB_thread_prach( void* param ) { - static int eNB_thread_prach_status; + while (!oai_exit) { + if (wait_on_condition(&proc->mutex_prach,&proc->cond_prach,&proc->instance_cnt_prach,"eNB_prach_thread") < 0) break; + if (oai_exit) break; - PHY_VARS_eNB *eNB= (PHY_VARS_eNB *)param; - eNB_proc_t *proc = &eNB->proc; - - // set default return value - eNB_thread_prach_status = 0; - - thread_top_init("eNB_thread_prach",1,500000,1000000,20000000); - - //wait_sync("eNB_thread_prach"); - - while (!oai_exit) { - - - - if (wait_on_condition(&proc->mutex_prach,&proc->cond_prach,&proc->instance_cnt_prach,"eNB_prach_thread") < 0) break; - if (oai_exit) break; - - LOG_D(PHY,"Running eNB prach procedures\n"); - prach_procedures(eNB + LOG_D(PHY,"Running eNB prach procedures\n"); + prach_procedures(eNB #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - ,0 + ,0 #endif - ); - - if (release_thread(&proc->mutex_prach,&proc->instance_cnt_prach,"eNB_prach_thread") < 0) break; + ); + + if (release_thread(&proc->mutex_prach,&proc->instance_cnt_prach,"eNB_prach_thread") < 0) break; + } + + LOG_I(PHY, "Exiting eNB thread PRACH\n"); + eNB_thread_prach_status = 0; + return &eNB_thread_prach_status; } - - LOG_I(PHY, "Exiting eNB thread PRACH\n"); - - eNB_thread_prach_status = 0; - return &eNB_thread_prach_status; -} - #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) -/*! - * \brief The prach receive thread of eNB for BL/CE UEs. - * \param param is a \ref eNB_proc_t structure which contains the info what to process. - * \returns a pointer to an int. The storage is not on the heap and must not be freed. - */ -static void* eNB_thread_prach_br( void* param ) { - static int eNB_thread_prach_status; + /*! + * \brief The prach receive thread of eNB for BL/CE UEs. + * \param param is a \ref eNB_proc_t structure which contains the info what to process. + * \returns a pointer to an int. The storage is not on the heap and must not be freed. + */ + static void *eNB_thread_prach_br( void *param ) { + static int eNB_thread_prach_status; + PHY_VARS_eNB *eNB= (PHY_VARS_eNB *)param; + eNB_proc_t *proc = &eNB->proc; + // set default return value + eNB_thread_prach_status = 0; + thread_top_init("eNB_thread_prach_br",1,500000,1000000,20000000); + while (!oai_exit) { + if (wait_on_condition(&proc->mutex_prach_br,&proc->cond_prach_br,&proc->instance_cnt_prach_br,"eNB_prach_thread_br") < 0) break; - PHY_VARS_eNB *eNB= (PHY_VARS_eNB *)param; - eNB_proc_t *proc = &eNB->proc; + if (oai_exit) break; - // set default return value - eNB_thread_prach_status = 0; + LOG_D(PHY,"Running eNB prach procedures for BL/CE UEs\n"); + prach_procedures(eNB,1); - thread_top_init("eNB_thread_prach_br",1,500000,1000000,20000000); + if (release_thread(&proc->mutex_prach_br,&proc->instance_cnt_prach_br,"eNB_prach_thread_br") < 0) break; + } - while (!oai_exit) { - - - - if (wait_on_condition(&proc->mutex_prach_br,&proc->cond_prach_br,&proc->instance_cnt_prach_br,"eNB_prach_thread_br") < 0) break; - if (oai_exit) break; - - LOG_D(PHY,"Running eNB prach procedures for BL/CE UEs\n"); - prach_procedures(eNB,1); - - if (release_thread(&proc->mutex_prach_br,&proc->instance_cnt_prach_br,"eNB_prach_thread_br") < 0) break; + LOG_I(PHY, "Exiting eNB thread PRACH BR\n"); + eNB_thread_prach_status = 0; + return &eNB_thread_prach_status; } - - LOG_I(PHY, "Exiting eNB thread PRACH BR\n"); - - eNB_thread_prach_status = 0; - return &eNB_thread_prach_status; -} - #endif + extern void init_td_thread(PHY_VARS_eNB *); + extern void init_te_thread(PHY_VARS_eNB *); + extern void kill_td_thread(PHY_VARS_eNB *); + extern void kill_te_thread(PHY_VARS_eNB *); + static void *process_stats_thread(void *param) { + PHY_VARS_eNB *eNB = (PHY_VARS_eNB *)param; + wait_sync("process_stats_thread"); + while (!oai_exit) { + sleep(1); - -extern void init_td_thread(PHY_VARS_eNB *); -extern void init_te_thread(PHY_VARS_eNB *); -extern void kill_td_thread(PHY_VARS_eNB *); -extern void kill_te_thread(PHY_VARS_eNB *); - -static void* process_stats_thread(void* param) { - - PHY_VARS_eNB *eNB = (PHY_VARS_eNB*)param; - - wait_sync("process_stats_thread"); - - while (!oai_exit) { - sleep(1); if (opp_enabled == 1) { if (eNB->td) print_meas(&eNB->ulsch_decoding_stats,"ulsch_decoding",NULL,NULL); - if (eNB->te) - { + + if (eNB->te) { print_meas(&eNB->dlsch_turbo_encoding_preperation_stats,"dlsch_coding_crc",NULL,NULL); print_meas(&eNB->dlsch_turbo_encoding_segmentation_stats,"dlsch_segmentation",NULL,NULL); print_meas(&eNB->dlsch_encoding_stats,"dlsch_encoding",NULL,NULL); @@ -1050,488 +974,428 @@ static void* process_stats_thread(void* param) { print_meas(&eNB->dlsch_turbo_encoding_waiting_stats,"coding_wait",NULL,NULL); print_meas(&eNB->dlsch_turbo_encoding_wakeup_stats0,"coding_worker_0",NULL,NULL); print_meas(&eNB->dlsch_turbo_encoding_wakeup_stats1,"coding_worker_1",NULL,NULL); - } - print_meas(&eNB->dlsch_modulation_stats,"dlsch_modulation",NULL,NULL); - } - } - return(NULL); -} + } - -void init_eNB_proc(int inst) { - - /*int i=0;*/ - int CC_id; - PHY_VARS_eNB *eNB; - eNB_proc_t *proc; - eNB_rxtx_proc_t *proc_rxtx; - pthread_attr_t *attr0=NULL,*attr1=NULL,*attr_prach=NULL; -#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - pthread_attr_t *attr_prach_br=NULL; -#endif - - LOG_I(PHY,"%s(inst:%d) RC.nb_CC[inst]:%d \n",__FUNCTION__,inst,RC.nb_CC[inst]); - - for (CC_id=0; CC_idproc; - - proc_rxtx = proc->proc_rxtx; - proc_rxtx[0].instance_cnt_rxtx = -1; - proc_rxtx[1].instance_cnt_rxtx = -1; - proc_rxtx[0].pipe_ready = 0; - proc_rxtx[1].pipe_ready = 0; - proc->instance_cnt_prach = -1; - proc->instance_cnt_asynch_rxtx = -1; - proc->instance_cnt_synch = -1; - proc->CC_id = CC_id; - - proc->first_rx=1; - proc->first_tx=1; - proc->RU_mask=0; - proc->RU_mask_prach=0; - - pthread_mutex_init( &eNB->UL_INFO_mutex, NULL); - pthread_mutex_init( &proc_rxtx[0].mutex_rxtx, NULL); - pthread_mutex_init( &proc_rxtx[1].mutex_rxtx, NULL); - pthread_cond_init( &proc_rxtx[0].cond_rxtx, NULL); - pthread_cond_init( &proc_rxtx[1].cond_rxtx, NULL); - - pthread_mutex_init( &proc->mutex_prach, NULL); - pthread_mutex_init( &proc->mutex_asynch_rxtx, NULL); - pthread_mutex_init( &proc->mutex_RU,NULL); - pthread_mutex_init( &proc->mutex_RU_PRACH,NULL); - - pthread_cond_init( &proc->cond_prach, NULL); - pthread_cond_init( &proc->cond_asynch_rxtx, NULL); - - pthread_attr_init( &proc->attr_prach); - pthread_attr_init( &proc->attr_asynch_rxtx); - pthread_attr_init( &proc_rxtx[0].attr_rxtx); - pthread_attr_init( &proc_rxtx[1].attr_rxtx); -#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - proc->instance_cnt_prach_br = -1; - proc->RU_mask_prach_br=0; - pthread_mutex_init( &proc->mutex_prach_br, NULL); - pthread_mutex_init( &proc->mutex_RU_PRACH_br,NULL); - pthread_cond_init( &proc->cond_prach_br, NULL); - pthread_attr_init( &proc->attr_prach_br); -#endif -#ifndef DEADLINE_SCHEDULER - attr0 = &proc_rxtx[0].attr_rxtx; - attr1 = &proc_rxtx[1].attr_rxtx; - attr_prach = &proc->attr_prach; -#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - attr_prach_br = &proc->attr_prach_br; -#endif - - // attr_td = &proc->attr_td; - // attr_te = &proc->attr_te; -#endif - - if(get_thread_worker_conf() == WORKER_ENABLE) - { - init_te_thread(eNB); - init_td_thread(eNB); - } - - - LOG_I(PHY,"eNB->single_thread_flag:%d\n", eNB->single_thread_flag); - - if ((get_thread_parallel_conf() == PARALLEL_RU_L1_SPLIT || get_thread_parallel_conf() == PARALLEL_RU_L1_TRX_SPLIT) && nfapi_mode!=2) { - pthread_create( &proc_rxtx[0].pthread_rxtx, attr0, eNB_thread_rxtx, proc ); - pthread_create( &proc_rxtx[1].pthread_rxtx, attr1, tx_thread, proc); - } - pthread_create( &proc->pthread_prach, attr_prach, eNB_thread_prach, eNB ); -#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - pthread_create( &proc->pthread_prach_br, attr_prach_br, eNB_thread_prach_br, eNB ); -#endif - /*char name[16]; - if (eNB->single_thread_flag==0) { - snprintf( name, sizeof(name), "RXTX0 %d", i ); - pthread_setname_np( proc_rxtx[0].pthread_rxtx, name ); - snprintf( name, sizeof(name), "RXTX1 %d", i ); - pthread_setname_np( proc_rxtx[1].pthread_rxtx, name ); - }*/ - - AssertFatal(proc->instance_cnt_prach == -1,"instance_cnt_prach = %d\n",proc->instance_cnt_prach); - - - if (opp_enabled == 1) pthread_create(&proc->process_stats_thread,NULL,process_stats_thread,(void*)eNB); - - - } - - //for multiple CCs: setup master and slaves - /* - for (CC_id=0; CC_idnode_timing == synch_to_ext_device) { //master - eNB->proc.num_slaves = MAX_NUM_CCs-1; - eNB->proc.slave_proc = (eNB_proc_t**)malloc(eNB->proc.num_slaves*sizeof(eNB_proc_t*)); - - for (i=0; i< eNB->proc.num_slaves; i++) { - if (i < CC_id) eNB->proc.slave_proc[i] = &(PHY_vars_eNB_g[inst][i]->proc); - if (i >= CC_id) eNB->proc.slave_proc[i] = &(PHY_vars_eNB_g[inst][i+1]->proc); - } - } - } - */ - - /* setup PHY proc TX sync mechanism */ - pthread_mutex_init(&sync_phy_proc.mutex_phy_proc_tx, NULL); - pthread_cond_init(&sync_phy_proc.cond_phy_proc_tx, NULL); - sync_phy_proc.phy_proc_CC_id = 0; - - -} - - - -/*! - * \brief Terminate eNB TX and RX threads. - */ -void kill_eNB_proc(int inst) { - - int *status; - PHY_VARS_eNB *eNB; - eNB_proc_t *proc; - eNB_rxtx_proc_t *proc_rxtx; - int i; - for (int CC_id=0; CC_idproc; - proc_rxtx = &proc->proc_rxtx[0]; - - if(get_thread_worker_conf() == WORKER_ENABLE) { - kill_td_thread(eNB); - kill_te_thread(eNB); - } - LOG_I(PHY, "Killing TX CC_id %d inst %d\n", CC_id, inst ); - for (i=0; i<2; i++) { - pthread_mutex_lock(&proc_rxtx[i].mutex_rxtx); - proc_rxtx[i].instance_cnt_rxtx = 0; - proc_rxtx[i].pipe_ready = 0; - pthread_cond_signal(&proc_rxtx[i].cond_rxtx); - pthread_mutex_unlock(&proc_rxtx[i].mutex_rxtx); - } - pthread_mutex_lock(&proc->mutex_prach); - proc->instance_cnt_prach = 0; - pthread_cond_signal( &proc->cond_prach ); - pthread_mutex_unlock(&proc->mutex_prach); - - pthread_cond_signal( &proc->cond_asynch_rxtx ); - pthread_cond_broadcast(&sync_phy_proc.cond_phy_proc_tx); - - LOG_D(PHY, "joining pthread_prach\n"); - pthread_join( proc->pthread_prach, (void**)&status ); - - LOG_I(PHY, "Destroying prach mutex/cond\n"); - pthread_mutex_destroy( &proc->mutex_prach ); - pthread_cond_destroy( &proc->cond_prach ); -#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - proc->instance_cnt_prach_br = 0; - pthread_cond_signal( &proc->cond_prach_br ); - pthread_join( proc->pthread_prach_br, (void**)&status ); - pthread_mutex_destroy( &proc->mutex_prach_br ); - pthread_cond_destroy( &proc->cond_prach_br ); -#endif - LOG_I(PHY, "Destroying UL_INFO mutex\n"); - pthread_mutex_destroy(&eNB->UL_INFO_mutex); - for (i=0;i<2;i++) { - LOG_I(PHY, "Joining rxtx[%d] mutex/cond\n",i); - pthread_join( proc_rxtx[i].pthread_rxtx, (void**)&status ); - LOG_I(PHY, "Destroying rxtx[%d] mutex/cond\n",i); - pthread_mutex_destroy( &proc_rxtx[i].mutex_rxtx ); - pthread_cond_destroy( &proc_rxtx[i].cond_rxtx ); - } - - pthread_attr_destroy(&proc->attr_prach); - pthread_attr_destroy(&proc->attr_asynch_rxtx); - pthread_attr_destroy(&proc_rxtx[0].attr_rxtx); - pthread_attr_destroy(&proc_rxtx[1].attr_rxtx); -#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - pthread_mutex_destroy(&proc->mutex_RU_PRACH_br); - pthread_attr_destroy(&proc->attr_prach_br); -#endif - - } -} - - - - -void reset_opp_meas(void) { - - int sfn; - reset_meas(&softmodem_stats_mt); - reset_meas(&softmodem_stats_hw); - - for (sfn=0; sfn < 10; sfn++) { - reset_meas(&softmodem_stats_rxtx_sf); - reset_meas(&softmodem_stats_rx_sf); - } -} - - -void print_opp_meas(void) { - - int sfn=0; - print_meas(&softmodem_stats_mt, "Main ENB Thread", NULL, NULL); - print_meas(&softmodem_stats_hw, "HW Acquisation", NULL, NULL); - - for (sfn=0; sfn < 10; sfn++) { - print_meas(&softmodem_stats_rxtx_sf,"[eNB][total_phy_proc_rxtx]",NULL, NULL); - print_meas(&softmodem_stats_rx_sf,"[eNB][total_phy_proc_rx]",NULL,NULL); - } -} - -void free_transport(PHY_VARS_eNB *eNB) -{ - int i; - int j; - - for (i=0; idlsch[i][j]); - - LOG_D(PHY, "Freeing Transport Channel Buffer for ULSCH, UE %d\n",i); - free_eNB_ulsch(eNB->ulsch[1+i]); - } - free_eNB_ulsch(eNB->ulsch[0]); -} - -void init_transport(PHY_VARS_eNB *eNB) { - - int i; - int j; - LTE_DL_FRAME_PARMS *fp = &eNB->frame_parms; - - LOG_I(PHY, "Initialise transport\n"); - - for (i=0; idlsch[i][j] = new_eNB_dlsch(1,8,NSOFT,fp->N_RB_DL,0,fp); - if (!eNB->dlsch[i][j]) { - LOG_E(PHY,"Can't get eNB dlsch structures for UE %d \n", i); - exit(-1); - } else { - eNB->dlsch[i][j]->rnti=0; - LOG_D(PHY,"dlsch[%d][%d] => %p rnti:%d\n",i,j,eNB->dlsch[i][j], eNB->dlsch[i][j]->rnti); + print_meas(&eNB->dlsch_modulation_stats,"dlsch_modulation",NULL,NULL); } } - - LOG_D(PHY,"Allocating Transport Channel Buffer for ULSCH, UE %d\n",i); - eNB->ulsch[1+i] = new_eNB_ulsch(MAX_TURBO_ITERATIONS,fp->N_RB_UL, 0); - - if (!eNB->ulsch[1+i]) { + + return(NULL); + } + void init_eNB_proc(int inst) { + /*int i=0;*/ + int CC_id; + PHY_VARS_eNB *eNB; + eNB_proc_t *proc; + eNB_rxtx_proc_t *proc_rxtx; + pthread_attr_t *attr0=NULL,*attr1=NULL,*attr_prach=NULL; +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + pthread_attr_t *attr_prach_br=NULL; +#endif + LOG_I(PHY,"%s(inst:%d) RC.nb_CC[inst]:%d \n",__FUNCTION__,inst,RC.nb_CC[inst]); + + for (CC_id=0; CC_idproc; + proc_rxtx = proc->proc_rxtx; + proc_rxtx[0].instance_cnt_rxtx = -1; + proc_rxtx[1].instance_cnt_rxtx = -1; + proc_rxtx[0].pipe_ready = 0; + proc_rxtx[1].pipe_ready = 0; + proc->instance_cnt_prach = -1; + proc->instance_cnt_asynch_rxtx = -1; + proc->instance_cnt_synch = -1; + proc->CC_id = CC_id; + proc->first_rx=1; + proc->first_tx=1; + proc->RU_mask=0; + proc->RU_mask_prach=0; + pthread_mutex_init( &eNB->UL_INFO_mutex, NULL); + pthread_mutex_init( &proc_rxtx[0].mutex_rxtx, NULL); + pthread_mutex_init( &proc_rxtx[1].mutex_rxtx, NULL); + pthread_cond_init( &proc_rxtx[0].cond_rxtx, NULL); + pthread_cond_init( &proc_rxtx[1].cond_rxtx, NULL); + pthread_mutex_init( &proc->mutex_prach, NULL); + pthread_mutex_init( &proc->mutex_asynch_rxtx, NULL); + pthread_mutex_init( &proc->mutex_RU,NULL); + pthread_mutex_init( &proc->mutex_RU_PRACH,NULL); + pthread_cond_init( &proc->cond_prach, NULL); + pthread_cond_init( &proc->cond_asynch_rxtx, NULL); + pthread_attr_init( &proc->attr_prach); + pthread_attr_init( &proc->attr_asynch_rxtx); + pthread_attr_init( &proc_rxtx[0].attr_rxtx); + pthread_attr_init( &proc_rxtx[1].attr_rxtx); +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + proc->instance_cnt_prach_br = -1; + proc->RU_mask_prach_br=0; + pthread_mutex_init( &proc->mutex_prach_br, NULL); + pthread_mutex_init( &proc->mutex_RU_PRACH_br,NULL); + pthread_cond_init( &proc->cond_prach_br, NULL); + pthread_attr_init( &proc->attr_prach_br); +#endif +#ifndef DEADLINE_SCHEDULER + attr0 = &proc_rxtx[0].attr_rxtx; + attr1 = &proc_rxtx[1].attr_rxtx; + attr_prach = &proc->attr_prach; +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + attr_prach_br = &proc->attr_prach_br; +#endif + // attr_td = &proc->attr_td; + // attr_te = &proc->attr_te; +#endif + + if(get_thread_worker_conf() == WORKER_ENABLE) { + init_te_thread(eNB); + init_td_thread(eNB); + } + + LOG_I(PHY,"eNB->single_thread_flag:%d\n", eNB->single_thread_flag); + + if ((get_thread_parallel_conf() == PARALLEL_RU_L1_SPLIT || get_thread_parallel_conf() == PARALLEL_RU_L1_TRX_SPLIT) && nfapi_mode!=2) { + pthread_create( &proc_rxtx[0].pthread_rxtx, attr0, eNB_thread_rxtx, proc ); + pthread_create( &proc_rxtx[1].pthread_rxtx, attr1, tx_thread, proc); + } + + pthread_create( &proc->pthread_prach, attr_prach, eNB_thread_prach, eNB ); +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + pthread_create( &proc->pthread_prach_br, attr_prach_br, eNB_thread_prach_br, eNB ); +#endif + /*char name[16]; + if (eNB->single_thread_flag==0) { + snprintf( name, sizeof(name), "RXTX0 %d", i ); + pthread_setname_np( proc_rxtx[0].pthread_rxtx, name ); + snprintf( name, sizeof(name), "RXTX1 %d", i ); + pthread_setname_np( proc_rxtx[1].pthread_rxtx, name ); + }*/ + AssertFatal(proc->instance_cnt_prach == -1,"instance_cnt_prach = %d\n",proc->instance_cnt_prach); + + if (opp_enabled == 1) pthread_create(&proc->process_stats_thread,NULL,process_stats_thread,(void *)eNB); + } + + //for multiple CCs: setup master and slaves + /* + for (CC_id=0; CC_idnode_timing == synch_to_ext_device) { //master + eNB->proc.num_slaves = MAX_NUM_CCs-1; + eNB->proc.slave_proc = (eNB_proc_t**)malloc(eNB->proc.num_slaves*sizeof(eNB_proc_t*)); + + for (i=0; i< eNB->proc.num_slaves; i++) { + if (i < CC_id) eNB->proc.slave_proc[i] = &(PHY_vars_eNB_g[inst][i]->proc); + if (i >= CC_id) eNB->proc.slave_proc[i] = &(PHY_vars_eNB_g[inst][i+1]->proc); + } + } + } + */ + /* setup PHY proc TX sync mechanism */ + pthread_mutex_init(&sync_phy_proc.mutex_phy_proc_tx, NULL); + pthread_cond_init(&sync_phy_proc.cond_phy_proc_tx, NULL); + sync_phy_proc.phy_proc_CC_id = 0; + } + /*! + * \brief Terminate eNB TX and RX threads. + */ + void kill_eNB_proc(int inst) { + int *status; + PHY_VARS_eNB *eNB; + eNB_proc_t *proc; + eNB_rxtx_proc_t *proc_rxtx; + int i; + + for (int CC_id=0; CC_idproc; + proc_rxtx = &proc->proc_rxtx[0]; + + if(get_thread_worker_conf() == WORKER_ENABLE) { + kill_td_thread(eNB); + kill_te_thread(eNB); + } + + LOG_I(PHY, "Killing TX CC_id %d inst %d\n", CC_id, inst ); + + for (i=0; i<2; i++) { + pthread_mutex_lock(&proc_rxtx[i].mutex_rxtx); + proc_rxtx[i].instance_cnt_rxtx = 0; + proc_rxtx[i].pipe_ready = 0; + pthread_cond_signal(&proc_rxtx[i].cond_rxtx); + pthread_mutex_unlock(&proc_rxtx[i].mutex_rxtx); + } + + pthread_mutex_lock(&proc->mutex_prach); + proc->instance_cnt_prach = 0; + pthread_cond_signal( &proc->cond_prach ); + pthread_mutex_unlock(&proc->mutex_prach); + pthread_cond_signal( &proc->cond_asynch_rxtx ); + pthread_cond_broadcast(&sync_phy_proc.cond_phy_proc_tx); + LOG_D(PHY, "joining pthread_prach\n"); + pthread_join( proc->pthread_prach, (void **)&status ); + LOG_I(PHY, "Destroying prach mutex/cond\n"); + pthread_mutex_destroy( &proc->mutex_prach ); + pthread_cond_destroy( &proc->cond_prach ); +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + proc->instance_cnt_prach_br = 0; + pthread_cond_signal( &proc->cond_prach_br ); + pthread_join( proc->pthread_prach_br, (void **)&status ); + pthread_mutex_destroy( &proc->mutex_prach_br ); + pthread_cond_destroy( &proc->cond_prach_br ); +#endif + LOG_I(PHY, "Destroying UL_INFO mutex\n"); + pthread_mutex_destroy(&eNB->UL_INFO_mutex); + + for (i=0; i<2; i++) { + LOG_I(PHY, "Joining rxtx[%d] mutex/cond\n",i); + pthread_join( proc_rxtx[i].pthread_rxtx, (void **)&status ); + LOG_I(PHY, "Destroying rxtx[%d] mutex/cond\n",i); + pthread_mutex_destroy( &proc_rxtx[i].mutex_rxtx ); + pthread_cond_destroy( &proc_rxtx[i].cond_rxtx ); + } + + pthread_attr_destroy(&proc->attr_prach); + pthread_attr_destroy(&proc->attr_asynch_rxtx); + pthread_attr_destroy(&proc_rxtx[0].attr_rxtx); + pthread_attr_destroy(&proc_rxtx[1].attr_rxtx); +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + pthread_mutex_destroy(&proc->mutex_RU_PRACH_br); + pthread_attr_destroy(&proc->attr_prach_br); +#endif + } + } + void reset_opp_meas(void) { + int sfn; + reset_meas(&softmodem_stats_mt); + reset_meas(&softmodem_stats_hw); + + for (sfn=0; sfn < 10; sfn++) { + reset_meas(&softmodem_stats_rxtx_sf); + reset_meas(&softmodem_stats_rx_sf); + } + } + void print_opp_meas(void) { + int sfn=0; + print_meas(&softmodem_stats_mt, "Main ENB Thread", NULL, NULL); + print_meas(&softmodem_stats_hw, "HW Acquisation", NULL, NULL); + + for (sfn=0; sfn < 10; sfn++) { + print_meas(&softmodem_stats_rxtx_sf,"[eNB][total_phy_proc_rxtx]",NULL, NULL); + print_meas(&softmodem_stats_rx_sf,"[eNB][total_phy_proc_rx]",NULL,NULL); + } + } + void free_transport(PHY_VARS_eNB *eNB) { + int i; + int j; + + for (i=0; idlsch[i][j]); + + LOG_D(PHY, "Freeing Transport Channel Buffer for ULSCH, UE %d\n",i); + free_eNB_ulsch(eNB->ulsch[1+i]); + } + + free_eNB_ulsch(eNB->ulsch[0]); + } + void init_transport(PHY_VARS_eNB *eNB) { + int i; + int j; + LTE_DL_FRAME_PARMS *fp = &eNB->frame_parms; + LOG_I(PHY, "Initialise transport\n"); + + for (i=0; idlsch[i][j] = new_eNB_dlsch(1,8,NSOFT,fp->N_RB_DL,0,fp); + + if (!eNB->dlsch[i][j]) { + LOG_E(PHY,"Can't get eNB dlsch structures for UE %d \n", i); + exit(-1); + } else { + eNB->dlsch[i][j]->rnti=0; + LOG_D(PHY,"dlsch[%d][%d] => %p rnti:%d\n",i,j,eNB->dlsch[i][j], eNB->dlsch[i][j]->rnti); + } + } + + LOG_D(PHY,"Allocating Transport Channel Buffer for ULSCH, UE %d\n",i); + eNB->ulsch[1+i] = new_eNB_ulsch(MAX_TURBO_ITERATIONS,fp->N_RB_UL, 0); + + if (!eNB->ulsch[1+i]) { + LOG_E(PHY,"Can't get eNB ulsch structures\n"); + exit(-1); + } + + // this is the transmission mode for the signalling channels + // this will be overwritten with the real transmission mode by the RRC once the UE is connected + eNB->transmission_mode[i] = fp->nb_antenna_ports_eNB==1 ? 1 : 2; + } + + // ULSCH for RA + eNB->ulsch[0] = new_eNB_ulsch(MAX_TURBO_ITERATIONS, fp->N_RB_UL, 0); + + if (!eNB->ulsch[0]) { LOG_E(PHY,"Can't get eNB ulsch structures\n"); exit(-1); } - - // this is the transmission mode for the signalling channels - // this will be overwritten with the real transmission mode by the RRC once the UE is connected - eNB->transmission_mode[i] = fp->nb_antenna_ports_eNB==1 ? 1 : 2; + + eNB->dlsch_SI = new_eNB_dlsch(1,8,NSOFT,fp->N_RB_DL, 0, fp); + LOG_D(PHY,"eNB %d.%d : SI %p\n",eNB->Mod_id,eNB->CC_id,eNB->dlsch_SI); + eNB->dlsch_ra = new_eNB_dlsch(1,8,NSOFT,fp->N_RB_DL, 0, fp); + LOG_D(PHY,"eNB %d.%d : RA %p\n",eNB->Mod_id,eNB->CC_id,eNB->dlsch_ra); + eNB->dlsch_MCH = new_eNB_dlsch(1,8,NSOFT,fp->N_RB_DL, 0, fp); + LOG_D(PHY,"eNB %d.%d : MCH %p\n",eNB->Mod_id,eNB->CC_id,eNB->dlsch_MCH); + eNB->rx_total_gain_dB=130; + + for(i=0; imu_mimo_mode[i].dl_pow_off = 2; + + eNB->check_for_total_transmissions = 0; + eNB->check_for_MUMIMO_transmissions = 0; + eNB->FULL_MUMIMO_transmissions = 0; + eNB->check_for_SUMIMO_transmissions = 0; + fp->pucch_config_common.deltaPUCCH_Shift = 1; } - // ULSCH for RA - eNB->ulsch[0] = new_eNB_ulsch(MAX_TURBO_ITERATIONS, fp->N_RB_UL, 0); - - if (!eNB->ulsch[0]) { - LOG_E(PHY,"Can't get eNB ulsch structures\n"); - exit(-1); - } - eNB->dlsch_SI = new_eNB_dlsch(1,8,NSOFT,fp->N_RB_DL, 0, fp); - LOG_D(PHY,"eNB %d.%d : SI %p\n",eNB->Mod_id,eNB->CC_id,eNB->dlsch_SI); - eNB->dlsch_ra = new_eNB_dlsch(1,8,NSOFT,fp->N_RB_DL, 0, fp); - LOG_D(PHY,"eNB %d.%d : RA %p\n",eNB->Mod_id,eNB->CC_id,eNB->dlsch_ra); - eNB->dlsch_MCH = new_eNB_dlsch(1,8,NSOFT,fp->N_RB_DL, 0, fp); - LOG_D(PHY,"eNB %d.%d : MCH %p\n",eNB->Mod_id,eNB->CC_id,eNB->dlsch_MCH); - - - eNB->rx_total_gain_dB=130; - - for(i=0; imu_mimo_mode[i].dl_pow_off = 2; - - eNB->check_for_total_transmissions = 0; - - eNB->check_for_MUMIMO_transmissions = 0; - - eNB->FULL_MUMIMO_transmissions = 0; - - eNB->check_for_SUMIMO_transmissions = 0; - - fp->pucch_config_common.deltaPUCCH_Shift = 1; - -} + void init_eNB_afterRU(void) { + int inst,CC_id,ru_id,i,aa; + PHY_VARS_eNB *eNB; + LOG_I(PHY,"%s() RC.nb_inst:%d\n", __FUNCTION__, RC.nb_inst); -void init_eNB_afterRU(void) { + for (inst=0; instnum_RU>0,"Number of RU attached to eNB %d is zero\n",eNB->Mod_id); - for (inst=0;instnum_RU>0,"Number of RU attached to eNB %d is zero\n",eNB->Mod_id); - LOG_I(PHY,"Mapping RX ports from %d RUs to eNB %d\n",eNB->num_RU,eNB->Mod_id); - eNB->frame_parms.nb_antennas_rx = 0; - - LOG_I(PHY,"Overwriting eNB->prach_vars.rxsigF[0]:%p\n", eNB->prach_vars.rxsigF[0]); - - eNB->prach_vars.rxsigF[0] = (int16_t**)malloc16(64*sizeof(int16_t*)); + LOG_I(PHY,"Mapping RX ports from %d RUs to eNB %d\n",eNB->num_RU,eNB->Mod_id); + eNB->frame_parms.nb_antennas_rx = 0; + LOG_I(PHY,"Overwriting eNB->prach_vars.rxsigF[0]:%p\n", eNB->prach_vars.rxsigF[0]); + eNB->prach_vars.rxsigF[0] = (int16_t **)malloc16(64*sizeof(int16_t *)); #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - for (int ce_level=0;ce_level<4;ce_level++) { - LOG_I(PHY,"Overwriting eNB->prach_vars_br.rxsigF.rxsigF[0]:%p\n", eNB->prach_vars_br.rxsigF[ce_level]); - eNB->prach_vars_br.rxsigF[ce_level] = (int16_t**)malloc16(64*sizeof(int16_t*)); - } + + for (int ce_level=0; ce_level<4; ce_level++) { + LOG_I(PHY,"Overwriting eNB->prach_vars_br.rxsigF.rxsigF[0]:%p\n", eNB->prach_vars_br.rxsigF[ce_level]); + eNB->prach_vars_br.rxsigF[ce_level] = (int16_t **)malloc16(64*sizeof(int16_t *)); + } + #endif + LOG_I(PHY,"eNB->num_RU:%d\n", eNB->num_RU); - LOG_I(PHY,"eNB->num_RU:%d\n", eNB->num_RU); + for (ru_id=0,aa=0; ru_idnum_RU; ru_id++) { + eNB->frame_parms.nb_antennas_rx += eNB->RU_list[ru_id]->nb_rx; + AssertFatal(eNB->RU_list[ru_id]->common.rxdataF!=NULL, + "RU %d : common.rxdataF is NULL\n", + eNB->RU_list[ru_id]->idx); + AssertFatal(eNB->RU_list[ru_id]->prach_rxsigF!=NULL, + "RU %d : prach_rxsigF is NULL\n", + eNB->RU_list[ru_id]->idx); - for (ru_id=0,aa=0;ru_idnum_RU;ru_id++) { - eNB->frame_parms.nb_antennas_rx += eNB->RU_list[ru_id]->nb_rx; - - AssertFatal(eNB->RU_list[ru_id]->common.rxdataF!=NULL, - "RU %d : common.rxdataF is NULL\n", - eNB->RU_list[ru_id]->idx); - - AssertFatal(eNB->RU_list[ru_id]->prach_rxsigF!=NULL, - "RU %d : prach_rxsigF is NULL\n", - eNB->RU_list[ru_id]->idx); - - for (i=0;iRU_list[ru_id]->nb_rx;aa++,i++) { - LOG_I(PHY,"Attaching RU %d antenna %d to eNB antenna %d\n",eNB->RU_list[ru_id]->idx,i,aa); - eNB->prach_vars.rxsigF[0][aa] = eNB->RU_list[ru_id]->prach_rxsigF[i]; + for (i=0; iRU_list[ru_id]->nb_rx; aa++,i++) { + LOG_I(PHY,"Attaching RU %d antenna %d to eNB antenna %d\n",eNB->RU_list[ru_id]->idx,i,aa); + eNB->prach_vars.rxsigF[0][aa] = eNB->RU_list[ru_id]->prach_rxsigF[i]; #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - for (int ce_level=0;ce_level<4;ce_level++) - eNB->prach_vars_br.rxsigF[ce_level][aa] = eNB->RU_list[ru_id]->prach_rxsigF_br[ce_level][i]; + + for (int ce_level=0; ce_level<4; ce_level++) + eNB->prach_vars_br.rxsigF[ce_level][aa] = eNB->RU_list[ru_id]->prach_rxsigF_br[ce_level][i]; + #endif - eNB->common_vars.rxdataF[aa] = eNB->RU_list[ru_id]->common.rxdataF[i]; - } + eNB->common_vars.rxdataF[aa] = eNB->RU_list[ru_id]->common.rxdataF[i]; + } + } + + /* TODO: review this code, there is something wrong. + * In monolithic mode, we come here with nb_antennas_rx == 0 + * (not tested in other modes). + */ + if (eNB->frame_parms.nb_antennas_rx < 1) { + LOG_I(PHY, "%s() ************* DJP ***** eNB->frame_parms.nb_antennas_rx:%d - GOING TO HARD CODE TO 1", __FUNCTION__, eNB->frame_parms.nb_antennas_rx); + eNB->frame_parms.nb_antennas_rx = 1; + } else { + //LOG_I(PHY," Delete code\n"); + } + + if (eNB->frame_parms.nb_antennas_tx < 1) { + LOG_I(PHY, "%s() ************* DJP ***** eNB->frame_parms.nb_antennas_tx:%d - GOING TO HARD CODE TO 1", __FUNCTION__, eNB->frame_parms.nb_antennas_tx); + eNB->frame_parms.nb_antennas_tx = 1; + } else { + //LOG_I(PHY," Delete code\n"); + } + + AssertFatal(eNB->frame_parms.nb_antennas_rx >0, + "inst %d, CC_id %d : nb_antennas_rx %d\n",inst,CC_id,eNB->frame_parms.nb_antennas_rx); + LOG_I(PHY,"inst %d, CC_id %d : nb_antennas_rx %d\n",inst,CC_id,eNB->frame_parms.nb_antennas_rx); + init_transport(eNB); + //init_precoding_weights(RC.eNB[inst][CC_id]); } - - - /* TODO: review this code, there is something wrong. - * In monolithic mode, we come here with nb_antennas_rx == 0 - * (not tested in other modes). - */ - if (eNB->frame_parms.nb_antennas_rx < 1) - { - LOG_I(PHY, "%s() ************* DJP ***** eNB->frame_parms.nb_antennas_rx:%d - GOING TO HARD CODE TO 1", __FUNCTION__, eNB->frame_parms.nb_antennas_rx); - eNB->frame_parms.nb_antennas_rx = 1; - } - else - { - //LOG_I(PHY," Delete code\n"); - } - - if (eNB->frame_parms.nb_antennas_tx < 1) - { - LOG_I(PHY, "%s() ************* DJP ***** eNB->frame_parms.nb_antennas_tx:%d - GOING TO HARD CODE TO 1", __FUNCTION__, eNB->frame_parms.nb_antennas_tx); - eNB->frame_parms.nb_antennas_tx = 1; - } - else - { - //LOG_I(PHY," Delete code\n"); - } - - - - - AssertFatal(eNB->frame_parms.nb_antennas_rx >0, - "inst %d, CC_id %d : nb_antennas_rx %d\n",inst,CC_id,eNB->frame_parms.nb_antennas_rx); - LOG_I(PHY,"inst %d, CC_id %d : nb_antennas_rx %d\n",inst,CC_id,eNB->frame_parms.nb_antennas_rx); - - init_transport(eNB); - //init_precoding_weights(RC.eNB[inst][CC_id]); + init_eNB_proc(inst); } - init_eNB_proc(inst); - } - for (ru_id=0;ru_idwakeup_rxtx = wakeup_rxtx; - RC.ru[ru_id]->wakeup_prach_eNB = wakeup_prach_eNB; + for (ru_id=0; ru_idwakeup_rxtx = wakeup_rxtx; + RC.ru[ru_id]->wakeup_prach_eNB = wakeup_prach_eNB; #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - RC.ru[ru_id]->wakeup_prach_eNB_br = wakeup_prach_eNB_br; + RC.ru[ru_id]->wakeup_prach_eNB_br = wakeup_prach_eNB_br; #endif - RC.ru[ru_id]->eNB_top = eNB_top; + RC.ru[ru_id]->eNB_top = eNB_top; + } } -} + void init_eNB(int single_thread_flag,int wait_for_sync) { + int CC_id; + int inst; + PHY_VARS_eNB *eNB; + LOG_I(PHY,"[lte-softmodem.c] eNB structure about to allocated RC.nb_L1_inst:%d RC.nb_L1_CC[0]:%d\n",RC.nb_L1_inst,RC.nb_L1_CC[0]); -void init_eNB(int single_thread_flag,int wait_for_sync) { - - int CC_id; - int inst; - PHY_VARS_eNB *eNB; + if (RC.eNB == NULL) RC.eNB = (PHY_VARS_eNB ***) malloc(RC.nb_L1_inst*sizeof(PHY_VARS_eNB **)); - LOG_I(PHY,"[lte-softmodem.c] eNB structure about to allocated RC.nb_L1_inst:%d RC.nb_L1_CC[0]:%d\n",RC.nb_L1_inst,RC.nb_L1_CC[0]); + LOG_I(PHY,"[lte-softmodem.c] eNB structure RC.eNB allocated\n"); - if (RC.eNB == NULL) RC.eNB = (PHY_VARS_eNB***) malloc(RC.nb_L1_inst*sizeof(PHY_VARS_eNB **)); - LOG_I(PHY,"[lte-softmodem.c] eNB structure RC.eNB allocated\n"); - for (inst=0;instabstraction_flag = 0; - eNB->single_thread_flag = single_thread_flag; + for (inst=0; instabstraction_flag = 0; + eNB->single_thread_flag = single_thread_flag; + LOG_I(PHY,"Initializing eNB %d CC_id %d single_thread_flag:%d\n",inst,CC_id,single_thread_flag); #ifndef OCP_FRAMEWORK - LOG_I(PHY,"Initializing eNB %d CC_id %d\n",inst,CC_id); + LOG_I(PHY,"Initializing eNB %d CC_id %d\n",inst,CC_id); #endif - - - eNB->td = ulsch_decoding_data_all; - eNB->te = dlsch_encoding_all; - - - LOG_I(PHY,"Registering with MAC interface module\n"); - AssertFatal((eNB->if_inst = IF_Module_init(inst))!=NULL,"Cannot register interface"); - eNB->if_inst->schedule_response = schedule_response; - eNB->if_inst->PHY_config_req = phy_config_request; - memset((void*)&eNB->UL_INFO,0,sizeof(eNB->UL_INFO)); - memset((void*)&eNB->Sched_INFO,0,sizeof(eNB->Sched_INFO)); - LOG_I(PHY,"Setting indication lists\n"); - eNB->UL_INFO.rx_ind.rx_indication_body.rx_pdu_list = eNB->rx_pdu_list; - eNB->UL_INFO.crc_ind.crc_indication_body.crc_pdu_list = eNB->crc_pdu_list; - eNB->UL_INFO.sr_ind.sr_indication_body.sr_pdu_list = eNB->sr_pdu_list; - eNB->UL_INFO.harq_ind.harq_indication_body.harq_pdu_list = eNB->harq_pdu_list; - eNB->UL_INFO.cqi_ind.cqi_pdu_list = eNB->cqi_pdu_list; - eNB->UL_INFO.cqi_ind.cqi_raw_pdu_list = eNB->cqi_raw_pdu_list; - eNB->prach_energy_counter = 0; + eNB->td = ulsch_decoding_data_all; + eNB->te = dlsch_encoding_all; + LOG_I(PHY,"Registering with MAC interface module\n"); + AssertFatal((eNB->if_inst = IF_Module_init(inst))!=NULL,"Cannot register interface"); + eNB->if_inst->schedule_response = schedule_response; + eNB->if_inst->PHY_config_req = phy_config_request; + memset((void *)&eNB->UL_INFO,0,sizeof(eNB->UL_INFO)); + memset((void *)&eNB->Sched_INFO,0,sizeof(eNB->Sched_INFO)); + LOG_I(PHY,"Setting indication lists\n"); + eNB->UL_INFO.rx_ind.rx_indication_body.rx_pdu_list = eNB->rx_pdu_list; + eNB->UL_INFO.crc_ind.crc_indication_body.crc_pdu_list = eNB->crc_pdu_list; + eNB->UL_INFO.sr_ind.sr_indication_body.sr_pdu_list = eNB->sr_pdu_list; + eNB->UL_INFO.harq_ind.harq_indication_body.harq_pdu_list = eNB->harq_pdu_list; + eNB->UL_INFO.cqi_ind.cqi_pdu_list = eNB->cqi_pdu_list; + eNB->UL_INFO.cqi_ind.cqi_raw_pdu_list = eNB->cqi_raw_pdu_list; + eNB->prach_energy_counter = 0; + } } + LOG_I(PHY,"[lte-softmodem.c] eNB structure allocated\n"); } - - LOG_I(PHY,"[lte-softmodem.c] eNB structure allocated\n"); -} - - -void stop_eNB(int nb_inst) { - - for (int inst=0;inst Date: Fri, 16 Nov 2018 10:15:30 +0100 Subject: [PATCH 148/233] astyle applied --- openair1/PHY/phy_vars_ue.h | 20 +- openair1/SCHED_UE/phy_procedures_lte_ue.c | 5897 ++++++++++----------- 2 files changed, 2792 insertions(+), 3125 deletions(-) diff --git a/openair1/PHY/phy_vars_ue.h b/openair1/PHY/phy_vars_ue.h index 0d29b03f63..33f93fc78d 100644 --- a/openair1/PHY/phy_vars_ue.h +++ b/openair1/PHY/phy_vars_ue.h @@ -28,9 +28,9 @@ #include "common/ran_context.h" -char* namepointer_chMag ; +char *namepointer_chMag ; char fmageren_name2[512]; -char* namepointer_log2; +char *namepointer_log2; #include "PHY/LTE_REFSIG/primary_synch.h" @@ -45,7 +45,7 @@ int16_t *primary_synch2_time; PHY_VARS_UE ***PHY_vars_UE_g; LTE_DL_FRAME_PARMS *lte_frame_parms_g; #else -PHY_VARS_UE * PHY_vars_UE_g[MAX_UE][MAX_NUM_CCs]={NULL}; +PHY_VARS_UE *PHY_vars_UE_g[MAX_UE][MAX_NUM_CCs]= {NULL}; #endif @@ -62,10 +62,10 @@ char mode_string[4][20] = {"NOT SYNCHED","PRACH","RAR","PUSCH"}; #ifndef OPENAIR2 -unsigned char NB_eNB_INST=0; -unsigned char NB_UE_INST=0; -unsigned char NB_RN_INST=0; -unsigned char NB_INST=0; + unsigned char NB_eNB_INST=0; + unsigned char NB_UE_INST=0; + unsigned char NB_RN_INST=0; + unsigned char NB_INST=0; #endif unsigned int ULSCH_max_consecutive_errors = 20; @@ -134,9 +134,9 @@ double beta2_dlsch[6][MCS_COUNT] = { {2.52163, 0.83231, 0.77472, 1.36536, 1.1682 #ifdef OCP_FRAMEWORK #include #else -char eNB_functions[6][20]={"eNodeB_3GPP","eNodeB_3GPP_BBU","NGFI_RAU_IF4p5","NGFI_RRU_IF5","NGFI_RRU_IF4p5",}; -char eNB_timing[2][20]={"synch_to_ext_device","synch_to_other"}; -char ru_if_types[MAX_RU_IF_TYPES][20]={"local RF","IF5 RRU","IF5 Mobipass","IF4p5 RRU","IF1pp RRU"}; +char eNB_functions[6][20]= {"eNodeB_3GPP","eNodeB_3GPP_BBU","NGFI_RAU_IF4p5","NGFI_RRU_IF5","NGFI_RRU_IF4p5",}; +char eNB_timing[2][20]= {"synch_to_ext_device","synch_to_other"}; +char ru_if_types[MAX_RU_IF_TYPES][20]= {"local RF","IF5 RRU","IF5 Mobipass","IF4p5 RRU","IF1pp RRU"}; #endif /// lookup table for unscrambling in RX diff --git a/openair1/SCHED_UE/phy_procedures_lte_ue.c b/openair1/SCHED_UE/phy_procedures_lte_ue.c index f8fc0369bd..2af47fb2c0 100644 --- a/openair1/SCHED_UE/phy_procedures_lte_ue.c +++ b/openair1/SCHED_UE/phy_procedures_lte_ue.c @@ -45,7 +45,7 @@ #ifndef PUCCH -#define PUCCH + #define PUCCH #endif #include "LAYER2/MAC/mac.h" @@ -55,7 +55,7 @@ #include "UTIL/OPT/opt.h" #if defined(ENABLE_ITTI) -# include "intertask_interface.h" + #include "intertask_interface.h" #endif #include "PHY/defs_UE.h" @@ -77,41 +77,36 @@ void Msg1_transmitted(module_id_t module_idP,uint8_t CC_id,frame_t frameP, uint8 void Msg3_transmitted(module_id_t module_idP,uint8_t CC_id,frame_t frameP, uint8_t eNB_id); #if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR) -extern uint32_t downlink_frequency[MAX_NUM_CCs][4]; + extern uint32_t downlink_frequency[MAX_NUM_CCs][4]; #endif void get_dumpparam(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id, uint8_t nb_rb, uint32_t *alloc_even, uint8_t subframe,uint32_t Qm, uint32_t Nl, uint32_t tm, uint8_t *nsymb, uint32_t *coded_bits_per_codeword) { - *nsymb = (ue->frame_parms.Ncp == 0) ? 14 : 12; - *coded_bits_per_codeword = get_G(&ue->frame_parms, - nb_rb, - alloc_even, - Qm, - Nl, - ue->pdcch_vars[0%RX_NB_TH][eNB_id]->num_pdcch_symbols, - proc->frame_rx, - subframe, - tm); + nb_rb, + alloc_even, + Qm, + Nl, + ue->pdcch_vars[0%RX_NB_TH][eNB_id]->num_pdcch_symbols, + proc->frame_rx, + subframe, + tm); } -void dump_dlsch(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t subframe,uint8_t harq_pid) -{ - if (LOG_DUMPFLAG(DEBUG_UE_PHYPROC)) { +void dump_dlsch(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t subframe,uint8_t harq_pid) { + if (LOG_DUMPFLAG(DEBUG_UE_PHYPROC)) { unsigned int coded_bits_per_codeword; uint8_t nsymb ; - - get_dumpparam(ue, proc, eNB_id, - ue->dlsch[ue->current_thread_id[subframe]][eNB_id][0]->harq_processes[harq_pid]->nb_rb , - ue->dlsch[ue->current_thread_id[subframe]][eNB_id][0]->harq_processes[harq_pid]->rb_alloc_even, - subframe, - ue->dlsch[ue->current_thread_id[subframe]][eNB_id][0]->harq_processes[harq_pid]->Qm, - ue->dlsch[ue->current_thread_id[subframe]][eNB_id][0]->harq_processes[harq_pid]->Nl, - ue->transmission_mode[eNB_id]<7?0:ue->transmission_mode[eNB_id], - &nsymb, &coded_bits_per_codeword); - + get_dumpparam(ue, proc, eNB_id, + ue->dlsch[ue->current_thread_id[subframe]][eNB_id][0]->harq_processes[harq_pid]->nb_rb, + ue->dlsch[ue->current_thread_id[subframe]][eNB_id][0]->harq_processes[harq_pid]->rb_alloc_even, + subframe, + ue->dlsch[ue->current_thread_id[subframe]][eNB_id][0]->harq_processes[harq_pid]->Qm, + ue->dlsch[ue->current_thread_id[subframe]][eNB_id][0]->harq_processes[harq_pid]->Nl, + ue->transmission_mode[eNB_id]<7?0:ue->transmission_mode[eNB_id], + &nsymb, &coded_bits_per_codeword); LOG_M("rxsigF0.m","rxsF0", ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].rxdataF[0],2*nsymb*ue->frame_parms.ofdm_symbol_size,2,1); LOG_M("rxsigF0_ext.m","rxsF0_ext", ue->pdsch_vars[ue->current_thread_id[subframe]][0]->rxdataF_ext[0],2*nsymb*ue->frame_parms.ofdm_symbol_size,1,1); LOG_M("dlsch00_ch0_ext.m","dl00_ch0_ext", ue->pdsch_vars[ue->current_thread_id[subframe]][0]->dl_ch_estimates_ext[0],300*nsymb,1,1); @@ -123,36 +118,30 @@ void dump_dlsch(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t subf */ LOG_M("dlsch_rxF_comp0.m","dlsch0_rxF_comp0", ue->pdsch_vars[ue->current_thread_id[subframe]][0]->rxdataF_comp0[0],300*12,1,1); LOG_M("dlsch_rxF_llr.m","dlsch_llr", ue->pdsch_vars[ue->current_thread_id[subframe]][0]->llr[0],coded_bits_per_codeword,1,0); - LOG_M("dlsch_mag1.m","dlschmag1",ue->pdsch_vars[ue->current_thread_id[subframe]][0]->dl_ch_mag0,300*12,1,1); LOG_M("dlsch_mag2.m","dlschmag2",ue->pdsch_vars[ue->current_thread_id[subframe]][0]->dl_ch_magb0,300*12,1,1); - } + } } -void dump_dlsch_SI(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t subframe) -{ - if (LOG_DUMPFLAG(DEBUG_UE_PHYPROC)){ +void dump_dlsch_SI(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t subframe) { + if (LOG_DUMPFLAG(DEBUG_UE_PHYPROC)) { unsigned int coded_bits_per_codeword; uint8_t nsymb; - get_dumpparam(ue, proc, eNB_id, - ue->dlsch_SI[eNB_id]->harq_processes[0]->nb_rb, - ue->dlsch_SI[eNB_id]->harq_processes[0]->rb_alloc_even, - subframe,2,1,0, - &nsymb, &coded_bits_per_codeword); - + ue->dlsch_SI[eNB_id]->harq_processes[0]->nb_rb, + ue->dlsch_SI[eNB_id]->harq_processes[0]->rb_alloc_even, + subframe,2,1,0, + &nsymb, &coded_bits_per_codeword); LOG_D(PHY,"[UE %d] Dumping dlsch_SI : ofdm_symbol_size %d, nsymb %d, nb_rb %d, mcs %d, nb_rb %d, num_pdcch_symbols %d,G %d\n", - ue->Mod_id, - ue->frame_parms.ofdm_symbol_size, - nsymb, - ue->dlsch_SI[eNB_id]->harq_processes[0]->nb_rb, - ue->dlsch_SI[eNB_id]->harq_processes[0]->mcs, - ue->dlsch_SI[eNB_id]->harq_processes[0]->nb_rb, - ue->pdcch_vars[0%RX_NB_TH][eNB_id]->num_pdcch_symbols, - coded_bits_per_codeword); - + ue->Mod_id, + ue->frame_parms.ofdm_symbol_size, + nsymb, + ue->dlsch_SI[eNB_id]->harq_processes[0]->nb_rb, + ue->dlsch_SI[eNB_id]->harq_processes[0]->mcs, + ue->dlsch_SI[eNB_id]->harq_processes[0]->nb_rb, + ue->pdcch_vars[0%RX_NB_TH][eNB_id]->num_pdcch_symbols, + coded_bits_per_codeword); LOG_M("rxsig0.m","rxs0", &ue->common_vars.rxdata[0][subframe*ue->frame_parms.samples_per_tti],ue->frame_parms.samples_per_tti,1,1); - LOG_M("rxsigF0.m","rxsF0", ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].rxdataF[0],nsymb*ue->frame_parms.ofdm_symbol_size,1,1); LOG_M("rxsigF0_ext.m","rxsF0_ext", ue->pdsch_vars_SI[0]->rxdataF_ext[0],2*nsymb*ue->frame_parms.ofdm_symbol_size,1,1); LOG_M("dlsch00_ch0_ext.m","dl00_ch0_ext", ue->pdsch_vars_SI[0]->dl_ch_estimates_ext[0],ue->frame_parms.N_RB_DL*12*nsymb,1,1); @@ -164,7 +153,6 @@ void dump_dlsch_SI(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t s */ LOG_M("dlsch_rxF_comp0.m","dlsch0_rxF_comp0", ue->pdsch_vars_SI[0]->rxdataF_comp0[0],ue->frame_parms.N_RB_DL*12*nsymb,1,1); LOG_M("dlsch_rxF_llr.m","dlsch_llr", ue->pdsch_vars_SI[0]->llr[0],coded_bits_per_codeword,1,0); - LOG_M("dlsch_mag1.m","dlschmag1",ue->pdsch_vars_SI[0]->dl_ch_mag0,300*nsymb,1,1); LOG_M("dlsch_mag2.m","dlschmag2",ue->pdsch_vars_SI[0]->dl_ch_magb0,300*nsymb,1,1); sleep(1); @@ -214,9 +202,7 @@ void dump_dlsch_SI(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t s } */ -unsigned int get_tx_amp(int power_dBm, int power_max_dBm, int N_RB_UL, int nb_rb) -{ - +unsigned int get_tx_amp(int power_dBm, int power_max_dBm, int N_RB_UL, int nb_rb) { int gain_dB; double gain_lin; @@ -232,27 +218,22 @@ unsigned int get_tx_amp(int power_dBm, int power_max_dBm, int N_RB_UL, int nb_rb #endif -void dump_dlsch_ra(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t subframe) -{ - if (LOG_DUMPFLAG(DEBUG_UE_PHYPROC)){ +void dump_dlsch_ra(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t subframe) { + if (LOG_DUMPFLAG(DEBUG_UE_PHYPROC)) { unsigned int coded_bits_per_codeword; uint8_t nsymb ; - - get_dumpparam(ue, proc, eNB_id, - ue->dlsch_SI[eNB_id]->harq_processes[0]->nb_rb, - ue->dlsch_SI[eNB_id]->harq_processes[0]->rb_alloc_even, - subframe,2,1,0, - &nsymb, &coded_bits_per_codeword); - + ue->dlsch_SI[eNB_id]->harq_processes[0]->nb_rb, + ue->dlsch_SI[eNB_id]->harq_processes[0]->rb_alloc_even, + subframe,2,1,0, + &nsymb, &coded_bits_per_codeword); LOG_D(PHY,"[UE %d] Dumping dlsch_ra : nb_rb %d, mcs %d, nb_rb %d, num_pdcch_symbols %d,G %d\n", - ue->Mod_id, - ue->dlsch_ra[eNB_id]->harq_processes[0]->nb_rb, - ue->dlsch_ra[eNB_id]->harq_processes[0]->mcs, - ue->dlsch_ra[eNB_id]->harq_processes[0]->nb_rb, - ue->pdcch_vars[0%RX_NB_TH][eNB_id]->num_pdcch_symbols, - coded_bits_per_codeword); - + ue->Mod_id, + ue->dlsch_ra[eNB_id]->harq_processes[0]->nb_rb, + ue->dlsch_ra[eNB_id]->harq_processes[0]->mcs, + ue->dlsch_ra[eNB_id]->harq_processes[0]->nb_rb, + ue->pdcch_vars[0%RX_NB_TH][eNB_id]->num_pdcch_symbols, + coded_bits_per_codeword); LOG_M("rxsigF0.m","rxsF0", ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].rxdataF[0],2*12*ue->frame_parms.ofdm_symbol_size,2,1); LOG_M("rxsigF0_ext.m","rxsF0_ext", ue->pdsch_vars_ra[0]->rxdataF_ext[0],2*12*ue->frame_parms.ofdm_symbol_size,1,1); LOG_M("dlsch00_ch0_ext.m","dl00_ch0_ext", ue->pdsch_vars_ra[0]->dl_ch_estimates_ext[0],300*nsymb,1,1); @@ -264,60 +245,53 @@ void dump_dlsch_ra(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t s */ LOG_M("dlsch_rxF_comp0.m","dlsch0_rxF_comp0", ue->pdsch_vars_ra[0]->rxdataF_comp0[0],300*nsymb,1,1); LOG_M("dlsch_rxF_llr.m","dlsch_llr", ue->pdsch_vars_ra[0]->llr[0],coded_bits_per_codeword,1,0); - LOG_M("dlsch_mag1.m","dlschmag1",ue->pdsch_vars_ra[0]->dl_ch_mag0,300*nsymb,1,1); LOG_M("dlsch_mag2.m","dlschmag2",ue->pdsch_vars_ra[0]->dl_ch_magb0,300*nsymb,1,1); } } -void phy_reset_ue(module_id_t Mod_id,uint8_t CC_id,uint8_t eNB_index) -{ - +void phy_reset_ue(module_id_t Mod_id,uint8_t CC_id,uint8_t eNB_index) { // This flushes ALL DLSCH and ULSCH harq buffers of ALL connected eNBs...add the eNB_index later // for more flexibility - uint8_t i,j,k,s; PHY_VARS_UE *ue = PHY_vars_UE_g[Mod_id][CC_id]; //[NUMBER_OF_RX_THREAD=2][NUMBER_OF_CONNECTED_eNB_MAX][2]; for(int l=0; ldlsch[l][i][j]) { - for(k=0; kdlsch[l][i][j]->harq_processes[k]; k++) { - ue->dlsch[l][i][j]->harq_processes[k]->status = SCH_IDLE; - for (s=0; s<10; s++) { - // reset ACK/NACK bit to DTX for all subframes s = 0..9 - ue->dlsch[l][i][j]->harq_ack[s].ack = 2; - ue->dlsch[l][i][j]->harq_ack[s].send_harq_status = 0; - ue->dlsch[l][i][j]->harq_ack[s].vDAI_UL = 0xff; - ue->dlsch[l][i][j]->harq_ack[s].vDAI_DL = 0xff; - } - } - } + for(i=0; idlsch[l][i][j]) { + for(k=0; kdlsch[l][i][j]->harq_processes[k]; k++) { + ue->dlsch[l][i][j]->harq_processes[k]->status = SCH_IDLE; + + for (s=0; s<10; s++) { + // reset ACK/NACK bit to DTX for all subframes s = 0..9 + ue->dlsch[l][i][j]->harq_ack[s].ack = 2; + ue->dlsch[l][i][j]->harq_ack[s].send_harq_status = 0; + ue->dlsch[l][i][j]->harq_ack[s].vDAI_UL = 0xff; + ue->dlsch[l][i][j]->harq_ack[s].vDAI_DL = 0xff; + } } - - //UL HARQ - if(ue->ulsch[i]) { - for(k=0; kulsch[i]->harq_processes[k]; k++) { - ue->ulsch[i]->harq_processes[k]->status = SCH_IDLE; - //Set NDIs for all UL HARQs to 0 - // ue->ulsch[i]->harq_processes[k]->Ndi = 0; - - } - } - - // flush Msg3 buffer - ue->ulsch_Msg3_active[i] = 0; - + } } + + //UL HARQ + if(ue->ulsch[i]) { + for(k=0; kulsch[i]->harq_processes[k]; k++) { + ue->ulsch[i]->harq_processes[k]->status = SCH_IDLE; + //Set NDIs for all UL HARQs to 0 + // ue->ulsch[i]->harq_processes[k]->Ndi = 0; + } + } + + // flush Msg3 buffer + ue->ulsch_Msg3_active[i] = 0; + } } } -void ra_failed(uint8_t Mod_id,uint8_t CC_id,uint8_t eNB_index) -{ - +void ra_failed(uint8_t Mod_id,uint8_t CC_id,uint8_t eNB_index) { // if contention resolution fails, go back to PRACH PHY_vars_UE_g[Mod_id][CC_id]->UE_mode[eNB_index] = PRACH; PHY_vars_UE_g[Mod_id][CC_id]->pdcch_vars[0][eNB_index]->crnti_is_temporary = 0; @@ -327,13 +301,9 @@ void ra_failed(uint8_t Mod_id,uint8_t CC_id,uint8_t eNB_index) LOG_E(PHY,"[UE %d] Random-access procedure fails, going back to PRACH, setting SIStatus = 0, discard temporary C-RNTI and State RRC_IDLE\n",Mod_id); } -void ra_succeeded(uint8_t Mod_id,uint8_t CC_id,uint8_t eNB_index) -{ - +void ra_succeeded(uint8_t Mod_id,uint8_t CC_id,uint8_t eNB_index) { int i; - LOG_I(PHY,"[UE %d][RAPROC] Random-access procedure succeeded. Set C-RNTI = Temporary C-RNTI\n",Mod_id); - PHY_vars_UE_g[Mod_id][CC_id]->pdcch_vars[0][eNB_index]->crnti_is_temporary = 0; PHY_vars_UE_g[Mod_id][CC_id]->pdcch_vars[1][eNB_index]->crnti_is_temporary = 0; PHY_vars_UE_g[Mod_id][CC_id]->ulsch_Msg3_active[eNB_index] = 0; @@ -347,50 +317,31 @@ void ra_succeeded(uint8_t Mod_id,uint8_t CC_id,uint8_t eNB_index) PHY_vars_UE_g[Mod_id][CC_id]->ulsch[eNB_index]->harq_processes[i]->subframe_scheduling_flag=0; } } - - } -UE_MODE_t get_ue_mode(uint8_t Mod_id,uint8_t CC_id,uint8_t eNB_index) -{ - +UE_MODE_t get_ue_mode(uint8_t Mod_id,uint8_t CC_id,uint8_t eNB_index) { return(PHY_vars_UE_g[Mod_id][CC_id]->UE_mode[eNB_index]); - } void process_timing_advance_rar(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint16_t timing_advance) { - ue->timing_advance = timing_advance*4; - if (LOG_DEBUGFLAG(DEBUG_UE_PHYPROC)) { - /* TODO: fix this log, what is 'HW timing advance'? */ - /*LOG_I(PHY,"[UE %d] AbsoluteSubFrame %d.%d, received (rar) timing_advance %d, HW timing advance %d\n",ue->Mod_id,proc->frame_rx, proc->subframe_rx, ue->timing_advance);*/ + /* TODO: fix this log, what is 'HW timing advance'? */ + /*LOG_I(PHY,"[UE %d] AbsoluteSubFrame %d.%d, received (rar) timing_advance %d, HW timing advance %d\n",ue->Mod_id,proc->frame_rx, proc->subframe_rx, ue->timing_advance);*/ LOG_UI(PHY,"[UE %d] AbsoluteSubFrame %d.%d, received (rar) timing_advance %d\n",ue->Mod_id,proc->frame_rx, proc->subframe_rx, ue->timing_advance); } - } -void process_timing_advance(module_id_t Mod_id,uint8_t CC_id,int16_t timing_advance) -{ - +void process_timing_advance(module_id_t Mod_id,uint8_t CC_id,int16_t timing_advance) { // uint32_t frame = PHY_vars_UE_g[Mod_id]->frame; - // timing advance has Q1.5 format timing_advance = timing_advance - 31; - PHY_vars_UE_g[Mod_id][CC_id]->timing_advance = PHY_vars_UE_g[Mod_id][CC_id]->timing_advance+timing_advance*4; //this is for 25RB only!!! - - LOG_D(PHY,"[UE %d] Got timing advance %d from MAC, new value %d\n",Mod_id, timing_advance, PHY_vars_UE_g[Mod_id][CC_id]->timing_advance); - - } -uint8_t is_SR_TXOp(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id) -{ - +uint8_t is_SR_TXOp(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id) { int subframe=proc->subframe_tx; - LOG_D(PHY,"[UE %d][SR %x] Frame %d subframe %d Checking for SR TXOp (sr_ConfigIndex %d)\n", ue->Mod_id,ue->pdcch_vars[ue->current_thread_id[proc->subframe_rx]][eNB_id]->crnti,proc->frame_tx,subframe, ue->scheduling_request_config[eNB_id].sr_ConfigIndex); @@ -415,8 +366,7 @@ uint8_t is_SR_TXOp(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id) return(0); } -uint8_t is_cqi_TXOp(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id) -{ +uint8_t is_cqi_TXOp(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id) { int subframe = proc->subframe_tx; int frame = proc->frame_tx; CQI_REPORTPERIODIC *cqirep = &ue->cqi_report_config[eNB_id].CQI_ReportPeriodic; @@ -433,10 +383,7 @@ uint8_t is_cqi_TXOp(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id) else return(0); } -uint8_t is_ri_TXOp(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id) -{ - - +uint8_t is_ri_TXOp(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id) { int subframe = proc->subframe_tx; int frame = proc->frame_tx; CQI_REPORTPERIODIC *cqirep = &ue->cqi_report_config[eNB_id].CQI_ReportPeriodic; @@ -462,22 +409,17 @@ void compute_cqi_ri_resources(PHY_VARS_UE *ue, uint16_t p_rnti, uint16_t cba_rnti, uint8_t cqi_status, - uint8_t ri_status) -{ - //PHY_MEASUREMENTS *meas = &ue->measurements; - //uint8_t transmission_mode = ue->transmission_mode[eNB_id]; + uint8_t ri_status) { + //PHY_MEASUREMENTS *meas = &ue->measurements; + //uint8_t transmission_mode = ue->transmission_mode[eNB_id]; - - //LOG_I(PHY,"compute_cqi_ri_resources O_RI %d O %d uci format %d \n",ulsch->O_RI,ulsch->O,ulsch->uci_format); - if (cqi_status == 1 || ri_status == 1) - { - ulsch->O = 4; - } + //LOG_I(PHY,"compute_cqi_ri_resources O_RI %d O %d uci format %d \n",ulsch->O_RI,ulsch->O,ulsch->uci_format); + if (cqi_status == 1 || ri_status == 1) { + ulsch->O = 4; + } } -void ue_compute_srs_occasion(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t isSubframeSRS) -{ - +void ue_compute_srs_occasion(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t isSubframeSRS) { LTE_DL_FRAME_PARMS *frame_parms = &ue->frame_parms; int frame_tx = proc->frame_tx; int subframe_tx = proc->subframe_tx; @@ -486,91 +428,81 @@ void ue_compute_srs_occasion(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id uint16_t srsOffset; uint8_t is_pucch2_subframe = 0; uint8_t is_sr_an_subframe = 0; - // check for SRS opportunity pSoundingrs_ul_config_dedicated->srsUeSubframe = 0; pSoundingrs_ul_config_dedicated->srsCellSubframe = isSubframeSRS; if (isSubframeSRS) { LOG_D(PHY," SrsDedicatedSetup: %d \n",pSoundingrs_ul_config_dedicated->srsConfigDedicatedSetup); - if(pSoundingrs_ul_config_dedicated->srsConfigDedicatedSetup) - { - compute_srs_pos(frame_parms->frame_type, pSoundingrs_ul_config_dedicated->srs_ConfigIndex, &srsPeriodicity, &srsOffset); - LOG_D(PHY," srsPeriodicity: %d srsOffset: %d isSubframeSRS %d \n",srsPeriodicity,srsOffset,isSubframeSRS); + if(pSoundingrs_ul_config_dedicated->srsConfigDedicatedSetup) { + compute_srs_pos(frame_parms->frame_type, pSoundingrs_ul_config_dedicated->srs_ConfigIndex, &srsPeriodicity, &srsOffset); + LOG_D(PHY," srsPeriodicity: %d srsOffset: %d isSubframeSRS %d \n",srsPeriodicity,srsOffset,isSubframeSRS); + // transmit SRS if the four following constraints are respected: + // - UE is configured to transmit SRS + // - SRS are configured in current subframe + // - UE is configured to send SRS in this subframe + // 36.213 8.2 + // 1- A UE shall not transmit SRS whenever SRS and PUCCH format 2/2a/2b transmissions happen to coincide in the same subframe + // 2- A UE shall not transmit SRS whenever SRS transmit + // on and PUCCH transmission carrying ACK/NACK and/or + // positive SR happen to coincide in the same subframe if the parameter + // Simultaneous-AN-and-SRS is FALSE + // check PUCCH format 2/2a/2b transmissions + is_pucch2_subframe = is_cqi_TXOp(ue,proc,eNB_id) && (ue->cqi_report_config[eNB_id].CQI_ReportPeriodic.cqi_PMI_ConfigIndex>0); + is_pucch2_subframe = (is_ri_TXOp(ue,proc,eNB_id) && (ue->cqi_report_config[eNB_id].CQI_ReportPeriodic.ri_ConfigIndex>0)) || is_pucch2_subframe; - // transmit SRS if the four following constraints are respected: - // - UE is configured to transmit SRS - // - SRS are configured in current subframe - // - UE is configured to send SRS in this subframe + // check ACK/SR transmission + if(frame_parms->soundingrs_ul_config_common.ackNackSRS_SimultaneousTransmission == FALSE) { + if(is_SR_TXOp(ue,proc,eNB_id)) { + uint32_t SR_payload = 0; - // 36.213 8.2 - // 1- A UE shall not transmit SRS whenever SRS and PUCCH format 2/2a/2b transmissions happen to coincide in the same subframe - // 2- A UE shall not transmit SRS whenever SRS transmit - // on and PUCCH transmission carrying ACK/NACK and/or - // positive SR happen to coincide in the same subframe if the parameter - // Simultaneous-AN-and-SRS is FALSE + if (ue->mac_enabled==1) { + int Mod_id = ue->Mod_id; + int CC_id = ue->CC_id; + SR_payload = ue_get_SR(Mod_id, + CC_id, + frame_tx, + eNB_id, + ue->pdcch_vars[ue->current_thread_id[proc->subframe_rx]][eNB_id]->crnti, + subframe_tx); // subframe used for meas gap - // check PUCCH format 2/2a/2b transmissions - is_pucch2_subframe = is_cqi_TXOp(ue,proc,eNB_id) && (ue->cqi_report_config[eNB_id].CQI_ReportPeriodic.cqi_PMI_ConfigIndex>0); - is_pucch2_subframe = (is_ri_TXOp(ue,proc,eNB_id) && (ue->cqi_report_config[eNB_id].CQI_ReportPeriodic.ri_ConfigIndex>0)) || is_pucch2_subframe; - - // check ACK/SR transmission - if(frame_parms->soundingrs_ul_config_common.ackNackSRS_SimultaneousTransmission == FALSE) - { - if(is_SR_TXOp(ue,proc,eNB_id)) - { - uint32_t SR_payload = 0; - if (ue->mac_enabled==1) - { - int Mod_id = ue->Mod_id; - int CC_id = ue->CC_id; - SR_payload = ue_get_SR(Mod_id, - CC_id, - frame_tx, - eNB_id, - ue->pdcch_vars[ue->current_thread_id[proc->subframe_rx]][eNB_id]->crnti, - subframe_tx); // subframe used for meas gap - - if (SR_payload > 0) - is_sr_an_subframe = 1; - } - } - - uint8_t pucch_ack_payload[2]; - if (get_ack(&ue->frame_parms, - ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->harq_ack, - subframe_tx,proc->subframe_rx,pucch_ack_payload,0) > 0) - { - is_sr_an_subframe = 1; - } + if (SR_payload > 0) + is_sr_an_subframe = 1; } + } - // check SRS UE opportunity - if( isSubframeSRS && - (((10*frame_tx+subframe_tx) % srsPeriodicity) == srsOffset) - ) - { - if ((is_pucch2_subframe == 0) && (is_sr_an_subframe == 0)) - { - pSoundingrs_ul_config_dedicated->srsUeSubframe = 1; - ue->ulsch[eNB_id]->srs_active = 1; - ue->ulsch[eNB_id]->Nsymb_pusch = 12-(frame_parms->Ncp<<1)- ue->ulsch[eNB_id]->srs_active; - } - else - { - LOG_I(PHY,"DROP UE-SRS-TX for this subframe %d.%d: collision with PUCCH2 or SR/AN: PUCCH2-occasion: %d, SR-AN-occasion[simSRS-SR-AN %d]: %d \n", frame_tx, subframe_tx, is_pucch2_subframe, frame_parms->soundingrs_ul_config_common.ackNackSRS_SimultaneousTransmission, is_sr_an_subframe); - } - } + uint8_t pucch_ack_payload[2]; + + if (get_ack(&ue->frame_parms, + ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->harq_ack, + subframe_tx,proc->subframe_rx,pucch_ack_payload,0) > 0) { + is_sr_an_subframe = 1; + } } - LOG_D(PHY," srsCellSubframe: %d, srsUeSubframe: %d, Nsymb-pusch: %d \n", pSoundingrs_ul_config_dedicated->srsCellSubframe, pSoundingrs_ul_config_dedicated->srsUeSubframe, ue->ulsch[eNB_id]->Nsymb_pusch); + + // check SRS UE opportunity + if( isSubframeSRS && + (((10*frame_tx+subframe_tx) % srsPeriodicity) == srsOffset) + ) { + if ((is_pucch2_subframe == 0) && (is_sr_an_subframe == 0)) { + pSoundingrs_ul_config_dedicated->srsUeSubframe = 1; + ue->ulsch[eNB_id]->srs_active = 1; + ue->ulsch[eNB_id]->Nsymb_pusch = 12-(frame_parms->Ncp<<1)- ue->ulsch[eNB_id]->srs_active; + } else { + LOG_I(PHY,"DROP UE-SRS-TX for this subframe %d.%d: collision with PUCCH2 or SR/AN: PUCCH2-occasion: %d, SR-AN-occasion[simSRS-SR-AN %d]: %d \n", frame_tx, subframe_tx, is_pucch2_subframe, + frame_parms->soundingrs_ul_config_common.ackNackSRS_SimultaneousTransmission, is_sr_an_subframe); + } + } + } + + LOG_D(PHY," srsCellSubframe: %d, srsUeSubframe: %d, Nsymb-pusch: %d \n", pSoundingrs_ul_config_dedicated->srsCellSubframe, pSoundingrs_ul_config_dedicated->srsUeSubframe, + ue->ulsch[eNB_id]->Nsymb_pusch); } } -void get_cqipmiri_params(PHY_VARS_UE *ue,uint8_t eNB_id) -{ - +void get_cqipmiri_params(PHY_VARS_UE *ue,uint8_t eNB_id) { CQI_REPORTPERIODIC *cqirep = &ue->cqi_report_config[eNB_id].CQI_ReportPeriodic; int cqi_PMI_ConfigIndex = cqirep->cqi_PMI_ConfigIndex; @@ -596,46 +528,41 @@ void get_cqipmiri_params(PHY_VARS_UE *ue,uint8_t eNB_id) } else if (cqi_PMI_ConfigIndex <= 316) { // 160 ms CQI_PMI period cqirep->Npd = 160; cqirep->N_OFFSET_CQI = cqi_PMI_ConfigIndex-157; - } - else if (cqi_PMI_ConfigIndex > 317) { - + } else if (cqi_PMI_ConfigIndex > 317) { if (cqi_PMI_ConfigIndex <= 349) { // 32 ms CQI_PMI period - cqirep->Npd = 32; - cqirep->N_OFFSET_CQI = cqi_PMI_ConfigIndex-318; - } - else if (cqi_PMI_ConfigIndex <= 413) { // 64 ms CQI_PMI period - cqirep->Npd = 64; - cqirep->N_OFFSET_CQI = cqi_PMI_ConfigIndex-350; - } - else if (cqi_PMI_ConfigIndex <= 541) { // 128 ms CQI_PMI period - cqirep->Npd = 128; - cqirep->N_OFFSET_CQI = cqi_PMI_ConfigIndex-414; + cqirep->Npd = 32; + cqirep->N_OFFSET_CQI = cqi_PMI_ConfigIndex-318; + } else if (cqi_PMI_ConfigIndex <= 413) { // 64 ms CQI_PMI period + cqirep->Npd = 64; + cqirep->N_OFFSET_CQI = cqi_PMI_ConfigIndex-350; + } else if (cqi_PMI_ConfigIndex <= 541) { // 128 ms CQI_PMI period + cqirep->Npd = 128; + cqirep->N_OFFSET_CQI = cqi_PMI_ConfigIndex-414; } } - } - else { // TDD - if (cqi_PMI_ConfigIndex == 0) { // all UL subframes - cqirep->Npd = 1; - cqirep->N_OFFSET_CQI = 0; - } else if (cqi_PMI_ConfigIndex <= 6) { // 5 ms CQI_PMI period - cqirep->Npd = 5; - cqirep->N_OFFSET_CQI = cqi_PMI_ConfigIndex-1; - } else if (cqi_PMI_ConfigIndex <=16) { // 10ms CQI_PMI period - cqirep->Npd = 10; - cqirep->N_OFFSET_CQI = cqi_PMI_ConfigIndex-6; - } else if (cqi_PMI_ConfigIndex <= 36) { // 20 ms CQI_PMI period - cqirep->Npd = 20; - cqirep->N_OFFSET_CQI = cqi_PMI_ConfigIndex-16; - } else if (cqi_PMI_ConfigIndex <= 76) { // 40 ms CQI_PMI period - cqirep->Npd = 40; - cqirep->N_OFFSET_CQI = cqi_PMI_ConfigIndex-36; - } else if (cqi_PMI_ConfigIndex <= 156) { // 80 ms CQI_PMI period - cqirep->Npd = 80; - cqirep->N_OFFSET_CQI = cqi_PMI_ConfigIndex-76; - } else if (cqi_PMI_ConfigIndex <= 316) { // 160 ms CQI_PMI period - cqirep->Npd = 160; - cqirep->N_OFFSET_CQI = cqi_PMI_ConfigIndex-156; - } + } else { // TDD + if (cqi_PMI_ConfigIndex == 0) { // all UL subframes + cqirep->Npd = 1; + cqirep->N_OFFSET_CQI = 0; + } else if (cqi_PMI_ConfigIndex <= 6) { // 5 ms CQI_PMI period + cqirep->Npd = 5; + cqirep->N_OFFSET_CQI = cqi_PMI_ConfigIndex-1; + } else if (cqi_PMI_ConfigIndex <=16) { // 10ms CQI_PMI period + cqirep->Npd = 10; + cqirep->N_OFFSET_CQI = cqi_PMI_ConfigIndex-6; + } else if (cqi_PMI_ConfigIndex <= 36) { // 20 ms CQI_PMI period + cqirep->Npd = 20; + cqirep->N_OFFSET_CQI = cqi_PMI_ConfigIndex-16; + } else if (cqi_PMI_ConfigIndex <= 76) { // 40 ms CQI_PMI period + cqirep->Npd = 40; + cqirep->N_OFFSET_CQI = cqi_PMI_ConfigIndex-36; + } else if (cqi_PMI_ConfigIndex <= 156) { // 80 ms CQI_PMI period + cqirep->Npd = 80; + cqirep->N_OFFSET_CQI = cqi_PMI_ConfigIndex-76; + } else if (cqi_PMI_ConfigIndex <= 316) { // 160 ms CQI_PMI period + cqirep->Npd = 160; + cqirep->N_OFFSET_CQI = cqi_PMI_ConfigIndex-156; + } } } @@ -645,76 +572,66 @@ PUCCH_FMT_t get_pucch_format(lte_frame_type_t frame_type, uint8_t nb_cw, uint8_t cqi_status, uint8_t ri_status, - uint8_t bundling_flag) -{ - if((cqi_status == 0) && (ri_status==0)) - { - // PUCCH Format 1 1a 1b - // 1- SR only ==> PUCCH format 1 - // 2- 1bit Ack/Nack with/without SR ==> PUCCH format 1a - // 3- 2bits Ack/Nack with/without SR ==> PUCCH format 1b - if((nb_cw == 1)&&(bundling_flag==bundling)) - { - return pucch_format1a; - } - if((nb_cw == 1)&&(bundling_flag==multiplexing)) - { - return pucch_format1b; - } - if(nb_cw == 2) - { - return pucch_format1b; - } - if(SR_payload == 1) - { + uint8_t bundling_flag) { + if((cqi_status == 0) && (ri_status==0)) { + // PUCCH Format 1 1a 1b + // 1- SR only ==> PUCCH format 1 + // 2- 1bit Ack/Nack with/without SR ==> PUCCH format 1a + // 3- 2bits Ack/Nack with/without SR ==> PUCCH format 1b + if((nb_cw == 1)&&(bundling_flag==bundling)) { + return pucch_format1a; + } + + if((nb_cw == 1)&&(bundling_flag==multiplexing)) { + return pucch_format1b; + } + + if(nb_cw == 2) { + return pucch_format1b; + } + + if(SR_payload == 1) { + return pucch_format1; + /* + if (frame_type == FDD) { return pucch_format1; - /* - if (frame_type == FDD) { - return pucch_format1; - } else if (frame_type == TDD) { - return pucch_format1b; - } else { - AssertFatal(1==0,"Unknown frame_type"); - }*/ - } - } - else - { - // PUCCH Format 2 2a 2b - // 1- CQI only or RI only ==> PUCCH format 2 - // 2- CQI or RI + 1bit Ack/Nack for normal CP ==> PUCCH format 2a - // 3- CQI or RI + 2bits Ack/Nack for normal CP ==> PUCCH format 2b - // 4- CQI or RI + Ack/Nack for extended CP ==> PUCCH format 2 - if(nb_cw == 0) - { - return pucch_format2; - } - if(cyclic_prefix_type == NORMAL) - { - if(nb_cw == 1) - { - return pucch_format2a; - } - if(nb_cw == 2) - { - return pucch_format2b; - } - } - else - { - return pucch_format2; + } else if (frame_type == TDD) { + return pucch_format1b; + } else { + AssertFatal(1==0,"Unknown frame_type"); + }*/ + } + } else { + // PUCCH Format 2 2a 2b + // 1- CQI only or RI only ==> PUCCH format 2 + // 2- CQI or RI + 1bit Ack/Nack for normal CP ==> PUCCH format 2a + // 3- CQI or RI + 2bits Ack/Nack for normal CP ==> PUCCH format 2b + // 4- CQI or RI + Ack/Nack for extended CP ==> PUCCH format 2 + if(nb_cw == 0) { + return pucch_format2; + } + + if(cyclic_prefix_type == NORMAL) { + if(nb_cw == 1) { + return pucch_format2a; } + + if(nb_cw == 2) { + return pucch_format2b; + } + } else { + return pucch_format2; + } } + return pucch_format1a; } uint16_t get_n1_pucch(PHY_VARS_UE *ue, - UE_rxtx_proc_t *proc, + UE_rxtx_proc_t *proc, harq_status_t *harq_ack, uint8_t eNB_id, uint8_t *b, - uint8_t SR) -{ - + uint8_t SR) { LTE_DL_FRAME_PARMS *frame_parms=&ue->frame_parms; uint8_t nCCE0,nCCE1,nCCE2,nCCE3,harq_ack1,harq_ack0,harq_ack3,harq_ack2; ANFBmode_t bundling_flag; @@ -726,7 +643,6 @@ uint16_t get_n1_pucch(PHY_VARS_UE *ue, uint8_t ack_counter=0; // clear this, important for case where n1_pucch selection is not used int subframe=proc->subframe_tx; - ue->pucch_sel[subframe] = 0; if (frame_parms->frame_type == FDD ) { // FDD @@ -738,10 +654,9 @@ uint16_t get_n1_pucch(PHY_VARS_UE *ue, else return(ue->scheduling_request_config[eNB_id].sr_PUCCH_ResourceIndex); } else { - bundling_flag = ue->pucch_config_dedicated[eNB_id].tdd_AckNackFeedbackMode; - if (LOG_DEBUGFLAG(DEBUG_UE_PHYPROC)) { + if (LOG_DEBUGFLAG(DEBUG_UE_PHYPROC)) { if (bundling_flag==bundling) { LOG_D(PHY,"[UE%d] Frame %d subframe %d : get_n1_pucch, bundling, SR %d/%d\n",ue->Mod_id,proc->frame_tx,subframe,SR, ue->scheduling_request_config[eNB_id].sr_PUCCH_ResourceIndex); @@ -751,179 +666,175 @@ uint16_t get_n1_pucch(PHY_VARS_UE *ue, } } - switch (frame_parms->tdd_config) { - case 1: // DL:S:UL:UL:DL:DL:S:UL:UL:DL + case 1: // DL:S:UL:UL:DL:DL:S:UL:UL:DL + harq_ack0 = 2; // DTX + M=1; - harq_ack0 = 2; // DTX - M=1; - - // This is the offset for a particular subframe (2,3,4) => (0,2,4) - if (subframe == 2) { // ACK subframes 5,6 - candidate_dl[0] = 6; - candidate_dl[1] = 5; - M=2; - } else if (subframe == 3) { // ACK subframe 9 - candidate_dl[0] = 9; - } else if (subframe == 7) { // ACK subframes 0,1 - candidate_dl[0] = 1; - candidate_dl[1] = 0; - M=2; - } else if (subframe == 8) { // ACK subframes 4 - candidate_dl[0] = 4; - } else { - LOG_E(PHY,"[UE%d] : Frame %d phy_procedures_lte.c: get_n1pucch, illegal tx-subframe %d for tdd_config %d\n", - ue->Mod_id,proc->frame_tx,subframe,frame_parms->tdd_config); - return(0); - } - - // checking which downlink candidate is the last downlink with valid DL-DCI - int k; - for (k=0;k0) { - last_dl = candidate_dl[k]; - break; - } - } - if (last_dl >= 10) { - LOG_E(PHY,"[UE%d] : Frame %d phy_procedures_lte.c: get_n1pucch, illegal rx-subframe %d (tx-subframe %d) for tdd_config %d\n", - ue->Mod_id,proc->frame_tx,last_dl,subframe,frame_parms->tdd_config); - return (0); - } - - LOG_D(PHY,"SFN/SF %d/%d calculating n1_pucch0 from last_dl=%d\n", - proc->frame_tx%1024, - proc->subframe_tx, - last_dl); - - // i=0 - nCCE0 = ue->pdcch_vars[ue->current_thread_id[proc->subframe_rx]][eNB_id]->nCCE[last_dl]; - n1_pucch0 = get_Np(frame_parms->N_RB_DL,nCCE0,0) + nCCE0+ frame_parms->pucch_config_common.n1PUCCH_AN; - - harq_ack0 = b[0]; - - if (harq_ack0!=2) { // DTX - if (frame_parms->frame_type == FDD ) { - if (SR == 0) { // last paragraph pg 68 from 36.213 (v8.6), m=0 - b[0]=(M==2) ? 1-harq_ack0 : harq_ack0; - b[1]=harq_ack0; // in case we use pucch format 1b (subframes 2,7) - ue->pucch_sel[subframe] = 0; - return(n1_pucch0); - } else { // SR and only 0 or 1 ACKs (first 2 entries in Table 7.3-1 of 36.213) - b[0]=harq_ack0; - return(ue->scheduling_request_config[eNB_id].sr_PUCCH_ResourceIndex); - } + // This is the offset for a particular subframe (2,3,4) => (0,2,4) + if (subframe == 2) { // ACK subframes 5,6 + candidate_dl[0] = 6; + candidate_dl[1] = 5; + M=2; + } else if (subframe == 3) { // ACK subframe 9 + candidate_dl[0] = 9; + } else if (subframe == 7) { // ACK subframes 0,1 + candidate_dl[0] = 1; + candidate_dl[1] = 0; + M=2; + } else if (subframe == 8) { // ACK subframes 4 + candidate_dl[0] = 4; } else { - if (SR == 0) { - b[0] = harq_ack0; + LOG_E(PHY,"[UE%d] : Frame %d phy_procedures_lte.c: get_n1pucch, illegal tx-subframe %d for tdd_config %d\n", + ue->Mod_id,proc->frame_tx,subframe,frame_parms->tdd_config); + return(0); + } + + // checking which downlink candidate is the last downlink with valid DL-DCI + int k; + + for (k=0; k0) { + last_dl = candidate_dl[k]; + break; + } + } + + if (last_dl >= 10) { + LOG_E(PHY,"[UE%d] : Frame %d phy_procedures_lte.c: get_n1pucch, illegal rx-subframe %d (tx-subframe %d) for tdd_config %d\n", + ue->Mod_id,proc->frame_tx,last_dl,subframe,frame_parms->tdd_config); + return (0); + } + + LOG_D(PHY,"SFN/SF %d/%d calculating n1_pucch0 from last_dl=%d\n", + proc->frame_tx%1024, + proc->subframe_tx, + last_dl); + // i=0 + nCCE0 = ue->pdcch_vars[ue->current_thread_id[proc->subframe_rx]][eNB_id]->nCCE[last_dl]; + n1_pucch0 = get_Np(frame_parms->N_RB_DL,nCCE0,0) + nCCE0+ frame_parms->pucch_config_common.n1PUCCH_AN; + harq_ack0 = b[0]; + + if (harq_ack0!=2) { // DTX + if (frame_parms->frame_type == FDD ) { + if (SR == 0) { // last paragraph pg 68 from 36.213 (v8.6), m=0 + b[0]=(M==2) ? 1-harq_ack0 : harq_ack0; + b[1]=harq_ack0; // in case we use pucch format 1b (subframes 2,7) + ue->pucch_sel[subframe] = 0; + return(n1_pucch0); + } else { // SR and only 0 or 1 ACKs (first 2 entries in Table 7.3-1 of 36.213) + b[0]=harq_ack0; + return(ue->scheduling_request_config[eNB_id].sr_PUCCH_ResourceIndex); + } + } else { + if (SR == 0) { + b[0] = harq_ack0; + b[1] = harq_ack0; + ue->pucch_sel[subframe] = 0; + return(n1_pucch0); + } else { + b[0] = harq_ack0; + b[1] = harq_ack0; + return(ue->scheduling_request_config[eNB_id].sr_PUCCH_ResourceIndex); + } + } + } + + break; + + case 3: // DL:S:UL:UL:UL:DL:DL:DL:DL:DL + // in this configuration we have M=2 from pg 68 of 36.213 (v8.6) + // Note: this doesn't allow using subframe 1 for PDSCH transmission!!! (i.e. SF 1 cannot be acked in SF 2) + // set ACK/NAKs to DTX + harq_ack1 = 2; // DTX + harq_ack0 = 2; // DTX + // This is the offset for a particular subframe (2,3,4) => (0,2,4) + last_dl = (subframe-2)<<1; + // i=0 + nCCE0 = ue->pdcch_vars[ue->current_thread_id[proc->subframe_rx]][eNB_id]->nCCE[5+last_dl]; + n1_pucch0 = get_Np(frame_parms->N_RB_DL,nCCE0,0) + nCCE0+ frame_parms->pucch_config_common.n1PUCCH_AN; + // i=1 + nCCE1 = ue->pdcch_vars[ue->current_thread_id[proc->subframe_rx]][eNB_id]->nCCE[(6+last_dl)%10]; + n1_pucch1 = get_Np(frame_parms->N_RB_DL,nCCE1,1) + nCCE1 + frame_parms->pucch_config_common.n1PUCCH_AN; + + // set ACK/NAK to values if not DTX + if (ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->harq_ack[(6+last_dl)%10].send_harq_status>0) // n-6 // subframe 6 is to be ACK/NAKed + harq_ack1 = ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->harq_ack[(6+last_dl)%10].ack; + + if (ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->harq_ack[5+last_dl].send_harq_status>0) // n-6 // subframe 5 is to be ACK/NAKed + harq_ack0 = ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->harq_ack[5+last_dl].ack; + + LOG_D(PHY,"SFN/SF %d/%d calculating n1_pucch cce0=%d n1_pucch0=%d cce1=%d n1_pucch1=%d\n", + proc->frame_tx%1024, + proc->subframe_tx, + nCCE0,n1_pucch0, + nCCE1,n1_pucch1); + + if (harq_ack1!=2) { // n-6 // subframe 6,8,0 and maybe 5,7,9 is to be ACK/NAKed + if ((bundling_flag==bundling)&&(SR == 0)) { // This is for bundling without SR, + // n1_pucch index takes value of smallest element in set {0,1} + // i.e. 0 if harq_ack0 is not DTX, otherwise 1 + b[0] = harq_ack1; + + if (harq_ack0!=2) + b[0]=b[0]&harq_ack0; + + ue->pucch_sel[subframe] = 1; + return(n1_pucch1); + } else if ((bundling_flag==multiplexing)&&(SR==0)) { // Table 10.1 + if (harq_ack0 == 2) + harq_ack0 = 0; + b[1] = harq_ack0; + b[0] = (harq_ack0!=harq_ack1)?0:1; + + if ((harq_ack0 == 1) && (harq_ack1 == 0)) { + ue->pucch_sel[subframe] = 0; + return(n1_pucch0); + } else { + ue->pucch_sel[subframe] = 1; + return(n1_pucch1); + } + } else if (SR==1) { // SR and 0,1,or 2 ACKS, (first 3 entries in Table 7.3-1 of 36.213) + // this should be number of ACKs (including + if (harq_ack0 == 2) + harq_ack0 = 0; + + b[0]= harq_ack1 | harq_ack0; + b[1]= harq_ack1 ^ harq_ack0; + return(ue->scheduling_request_config[eNB_id].sr_PUCCH_ResourceIndex); + } + } else if (harq_ack0!=2) { // n-7 // subframe 5,7,9 only is to be ACK/NAKed + if ((bundling_flag==bundling)&&(SR == 0)) { // last paragraph pg 68 from 36.213 (v8.6), m=0 + b[0]=harq_ack0; ue->pucch_sel[subframe] = 0; return(n1_pucch0); - } else { + } else if ((bundling_flag==multiplexing)&&(SR==0)) { // Table 10.1 with i=1 set to DTX b[0] = harq_ack0; - b[1] = harq_ack0; + b[1] = 1-b[0]; + ue->pucch_sel[subframe] = 0; + return(n1_pucch0); + } else if (SR==1) { // SR and only 0 or 1 ACKs (first 2 entries in Table 7.3-1 of 36.213) + b[0]=harq_ack0; + b[1]=b[0]; return(ue->scheduling_request_config[eNB_id].sr_PUCCH_ResourceIndex); } } - } + break; - break; + case 4: // DL:S:UL:UL:DL:DL:DL:DL:DL:DL + // in this configuration we have M=4 from pg 68 of 36.213 (v8.6) + // Note: this doesn't allow using subframe 1 for PDSCH transmission!!! (i.e. SF 1 cannot be acked in SF 2) + // set ACK/NAKs to DTX + harq_ack3 = 2; // DTX + harq_ack2 = 2; // DTX + harq_ack1 = 2; // DTX + harq_ack0 = 2; // DTX - case 3: // DL:S:UL:UL:UL:DL:DL:DL:DL:DL - // in this configuration we have M=2 from pg 68 of 36.213 (v8.6) - // Note: this doesn't allow using subframe 1 for PDSCH transmission!!! (i.e. SF 1 cannot be acked in SF 2) - // set ACK/NAKs to DTX - harq_ack1 = 2; // DTX - harq_ack0 = 2; // DTX - // This is the offset for a particular subframe (2,3,4) => (0,2,4) - last_dl = (subframe-2)<<1; - // i=0 - nCCE0 = ue->pdcch_vars[ue->current_thread_id[proc->subframe_rx]][eNB_id]->nCCE[5+last_dl]; - n1_pucch0 = get_Np(frame_parms->N_RB_DL,nCCE0,0) + nCCE0+ frame_parms->pucch_config_common.n1PUCCH_AN; - // i=1 - nCCE1 = ue->pdcch_vars[ue->current_thread_id[proc->subframe_rx]][eNB_id]->nCCE[(6+last_dl)%10]; - n1_pucch1 = get_Np(frame_parms->N_RB_DL,nCCE1,1) + nCCE1 + frame_parms->pucch_config_common.n1PUCCH_AN; - - // set ACK/NAK to values if not DTX - if (ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->harq_ack[(6+last_dl)%10].send_harq_status>0) // n-6 // subframe 6 is to be ACK/NAKed - harq_ack1 = ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->harq_ack[(6+last_dl)%10].ack; - - if (ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->harq_ack[5+last_dl].send_harq_status>0) // n-6 // subframe 5 is to be ACK/NAKed - harq_ack0 = ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->harq_ack[5+last_dl].ack; - - LOG_D(PHY,"SFN/SF %d/%d calculating n1_pucch cce0=%d n1_pucch0=%d cce1=%d n1_pucch1=%d\n", - proc->frame_tx%1024, - proc->subframe_tx, - nCCE0,n1_pucch0, - nCCE1,n1_pucch1); - - if (harq_ack1!=2) { // n-6 // subframe 6,8,0 and maybe 5,7,9 is to be ACK/NAKed - - if ((bundling_flag==bundling)&&(SR == 0)) { // This is for bundling without SR, - // n1_pucch index takes value of smallest element in set {0,1} - // i.e. 0 if harq_ack0 is not DTX, otherwise 1 - b[0] = harq_ack1; - - if (harq_ack0!=2) - b[0]=b[0]&harq_ack0; - - ue->pucch_sel[subframe] = 1; - return(n1_pucch1); - - } else if ((bundling_flag==multiplexing)&&(SR==0)) { // Table 10.1 - if (harq_ack0 == 2) - harq_ack0 = 0; - - b[1] = harq_ack0; - b[0] = (harq_ack0!=harq_ack1)?0:1; - - if ((harq_ack0 == 1) && (harq_ack1 == 0)) { - ue->pucch_sel[subframe] = 0; - return(n1_pucch0); - } else { - ue->pucch_sel[subframe] = 1; - return(n1_pucch1); - } - } else if (SR==1) { // SR and 0,1,or 2 ACKS, (first 3 entries in Table 7.3-1 of 36.213) - // this should be number of ACKs (including - if (harq_ack0 == 2) - harq_ack0 = 0; - - b[0]= harq_ack1 | harq_ack0; - b[1]= harq_ack1 ^ harq_ack0; - return(ue->scheduling_request_config[eNB_id].sr_PUCCH_ResourceIndex); - } - } else if (harq_ack0!=2) { // n-7 // subframe 5,7,9 only is to be ACK/NAKed - if ((bundling_flag==bundling)&&(SR == 0)) { // last paragraph pg 68 from 36.213 (v8.6), m=0 - b[0]=harq_ack0; - ue->pucch_sel[subframe] = 0; - return(n1_pucch0); - } else if ((bundling_flag==multiplexing)&&(SR==0)) { // Table 10.1 with i=1 set to DTX - b[0] = harq_ack0; - b[1] = 1-b[0]; - ue->pucch_sel[subframe] = 0; - return(n1_pucch0); - } else if (SR==1) { // SR and only 0 or 1 ACKs (first 2 entries in Table 7.3-1 of 36.213) - b[0]=harq_ack0; - b[1]=b[0]; - return(ue->scheduling_request_config[eNB_id].sr_PUCCH_ResourceIndex); - } - } - - break; - - case 4: // DL:S:UL:UL:DL:DL:DL:DL:DL:DL - // in this configuration we have M=4 from pg 68 of 36.213 (v8.6) - // Note: this doesn't allow using subframe 1 for PDSCH transmission!!! (i.e. SF 1 cannot be acked in SF 2) - // set ACK/NAKs to DTX - harq_ack3 = 2; // DTX - harq_ack2 = 2; // DTX - harq_ack1 = 2; // DTX - harq_ack0 = 2; // DTX - // This is the offset for a particular subframe (2,3,4) => (0,2,4) - //last_dl = (subframe-2)<<1; - if (subframe == 2) { + // This is the offset for a particular subframe (2,3,4) => (0,2,4) + //last_dl = (subframe-2)<<1; + if (subframe == 2) { // i=0 //nCCE0 = ue->pdcch_vars[ue->current_thread_id[proc->subframe_rx]][eNB_id]->nCCE[2+subframe]; nCCE0 = ue->pdcch_vars[ue->current_thread_id[proc->subframe_rx]][eNB_id]->nCCE[(8+subframe)%10]; @@ -933,8 +844,8 @@ uint16_t get_n1_pucch(PHY_VARS_UE *ue, n1_pucch1 = get_Np(frame_parms->N_RB_DL,nCCE1,0) + get_Np(frame_parms->N_RB_DL,nCCE1,1) + nCCE1 + frame_parms->pucch_config_common.n1PUCCH_AN; // i=2 nCCE2 = ue->pdcch_vars[ue->current_thread_id[proc->subframe_rx]][eNB_id]->nCCE[(8+subframe)%10]; - n1_pucch2 = 2*get_Np(frame_parms->N_RB_DL,nCCE2,1) + nCCE2+ frame_parms->pucch_config_common.n1PUCCH_AN; + // i=3 //nCCE3 = ue->pdcch_vars[ue->current_thread_id[proc->subframe_rx]][eNB_id]->nCCE[(9+subframe)%10]; //n1_pucch3 = get_Np(frame_parms->N_RB_DL,nCCE3,1) + nCCE3 + frame_parms->pucch_config_common.n1PUCCH_AN; @@ -950,15 +861,14 @@ uint16_t get_n1_pucch(PHY_VARS_UE *ue, harq_ack2 = ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->harq_ack[3+subframe].ack; //if (ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->harq_ack[(9+subframe)%10].send_harq_status>0) // n-6 // subframe 5 is to be ACK/NAKed - //harq_ack3 = ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->harq_ack[(9+subframe)%10].ack; + //harq_ack3 = ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->harq_ack[(9+subframe)%10].ack; //LOG_I(PHY,"SFN/SF %d/%d calculating n1_pucch cce0=%d n1_pucch0=%d cce1=%d n1_pucch1=%d cce2=%d n1_pucch2=%d\n", // proc->frame_tx%1024, // proc->subframe_tx, // nCCE0,n1_pucch0, // nCCE1,n1_pucch1, nCCE2, n1_pucch2); - }else if (subframe == 3) { + } else if (subframe == 3) { // i=0 - nCCE0 = ue->pdcch_vars[ue->current_thread_id[proc->subframe_rx]][eNB_id]->nCCE[4+subframe]; n1_pucch0 = 3*get_Np(frame_parms->N_RB_DL,nCCE0,0) + nCCE0+ frame_parms->pucch_config_common.n1PUCCH_AN; // i=1 @@ -973,236 +883,238 @@ uint16_t get_n1_pucch(PHY_VARS_UE *ue, // set ACK/NAK to values if not DTX if (ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->harq_ack[4+subframe].send_harq_status>0) // n-6 // subframe 6 is to be ACK/NAKed - harq_ack0 = ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->harq_ack[4+subframe].ack; + harq_ack0 = ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->harq_ack[4+subframe].ack; if (ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->harq_ack[5+subframe].send_harq_status>0) // n-6 // subframe 5 is to be ACK/NAKed - harq_ack1 = ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->harq_ack[5+subframe].ack; + harq_ack1 = ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->harq_ack[5+subframe].ack; if (ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->harq_ack[(6+subframe)].send_harq_status>0) // n-6 // subframe 6 is to be ACK/NAKed - harq_ack2 = ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->harq_ack[(6+subframe)].ack; + harq_ack2 = ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->harq_ack[(6+subframe)].ack; if (ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->harq_ack[(3+subframe)].send_harq_status>0) // n-6 // subframe 5 is to be ACK/NAKed - harq_ack3 = ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->harq_ack[(3+subframe)].ack; + harq_ack3 = ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->harq_ack[(3+subframe)].ack; + } + + //LOG_I(PHY,"SFN/SF %d/%d calculating n1_pucch cce0=%d n1_pucch0=%d harq_ack0=%d cce1=%d n1_pucch1=%d harq_ack1=%d cce2=%d n1_pucch2=%d harq_ack2=%d cce3=%d n1_pucch3=%d harq_ack3=%d bundling_flag=%d\n", + // proc->frame_tx%1024, + // proc->subframe_tx, + // nCCE0,n1_pucch0,harq_ack0, + // nCCE1,n1_pucch1,harq_ack1, nCCE2, n1_pucch2, harq_ack2, + // nCCE3, n1_pucch3, harq_ack3, bundling_flag); + + if ((bundling_flag==bundling)&&(SR == 0)) { // This is for bundling without SR, + b[0] = 1; + ack_counter = 0; + + if ((harq_ack3!=2) ) { + b[0] = b[0]&harq_ack3; + n1_pucch_inter = n1_pucch3; + ack_counter ++; } - //LOG_I(PHY,"SFN/SF %d/%d calculating n1_pucch cce0=%d n1_pucch0=%d harq_ack0=%d cce1=%d n1_pucch1=%d harq_ack1=%d cce2=%d n1_pucch2=%d harq_ack2=%d cce3=%d n1_pucch3=%d harq_ack3=%d bundling_flag=%d\n", - // proc->frame_tx%1024, - // proc->subframe_tx, - // nCCE0,n1_pucch0,harq_ack0, - // nCCE1,n1_pucch1,harq_ack1, nCCE2, n1_pucch2, harq_ack2, - // nCCE3, n1_pucch3, harq_ack3, bundling_flag); + if ((harq_ack0!=2) ) { + b[0] = b[0]&harq_ack0; + n1_pucch_inter = n1_pucch0; + ack_counter ++; + } - if ((bundling_flag==bundling)&&(SR == 0)) { // This is for bundling without SR, - b[0] = 1; - ack_counter = 0; + if ((harq_ack1!=2) ) { + b[0] = b[0]&harq_ack1; + n1_pucch_inter = n1_pucch1; + ack_counter ++; + } - if ((harq_ack3!=2) ) { - b[0] = b[0]&harq_ack3; - n1_pucch_inter = n1_pucch3; - ack_counter ++; - } - if ((harq_ack0!=2) ) { - b[0] = b[0]&harq_ack0; - n1_pucch_inter = n1_pucch0; - ack_counter ++; - } - if ((harq_ack1!=2) ) { - b[0] = b[0]&harq_ack1; - n1_pucch_inter = n1_pucch1; - ack_counter ++; - } - if ((harq_ack2!=2) ) { - b[0] = b[0]&harq_ack2; - n1_pucch_inter = n1_pucch2; - ack_counter ++; - } + if ((harq_ack2!=2) ) { + b[0] = b[0]&harq_ack2; + n1_pucch_inter = n1_pucch2; + ack_counter ++; + } - if (ack_counter == 0) - b[0] = 0; + if (ack_counter == 0) + b[0] = 0; - /*if (subframe == 3) { - n1_pucch_inter = n1_pucch2; - } else if (subframe == 2) { - n1_pucch_inter = n1_pucch1; - }*/ + /*if (subframe == 3) { + n1_pucch_inter = n1_pucch2; + } else if (subframe == 2) { + n1_pucch_inter = n1_pucch1; + }*/ + //LOG_I(PHY,"SFN/SF %d/%d calculating n1_pucch n1_pucch_inter=%d b[0]=%d b[1]=%d \n", + // proc->frame_tx%1024, + // proc->subframe_tx,n1_pucch_inter, + // b[0],b[1]); + return(n1_pucch_inter); + } else if ((bundling_flag==multiplexing)&&(SR==0)) { // Table 10.1 + if (subframe == 3) { + LOG_I(PHY, "sbuframe=%d \n",subframe); - //LOG_I(PHY,"SFN/SF %d/%d calculating n1_pucch n1_pucch_inter=%d b[0]=%d b[1]=%d \n", - // proc->frame_tx%1024, - // proc->subframe_tx,n1_pucch_inter, - // b[0],b[1]); - - return(n1_pucch_inter); - - } else if ((bundling_flag==multiplexing)&&(SR==0)) { // Table 10.1 - - if (subframe == 3) { - LOG_I(PHY, "sbuframe=%d \n",subframe); - if ((harq_ack0 == 1) && (harq_ack1 == 1) && (harq_ack2 == 1) && (harq_ack3 == 1)) { - b[0] = 1; - b[1] = 1; - return(n1_pucch1); - } else if ((harq_ack0 == 1) && (harq_ack1 == 1) && (harq_ack2 == 1) && ((harq_ack3 == 2) || (harq_ack3 == 0))) { - b[0] = 1; - b[1] = 0; - return(n1_pucch1); - } else if (((harq_ack0 == 0) || (harq_ack0 == 2)) && ((harq_ack1 == 2) || (harq_ack1 == 0)) && (harq_ack2 == 0) && (harq_ack3 == 2)) { - b[0] = 1; - b[1] = 1; - return(n1_pucch2); - } else if ((harq_ack0 == 1) && (harq_ack1 == 1) && ((harq_ack2 == 2) || (harq_ack2 == 0)) && (harq_ack3 == 1)) { - b[0] = 1; - b[1] = 0; - return(n1_pucch1); - } else if ((harq_ack0 == 0) && (harq_ack1 == 2) && (harq_ack2 == 2) && (harq_ack3 == 2)) { - b[0] = 1; - b[1] = 0; - return(n1_pucch0); - } else if ((harq_ack0 == 1) && (harq_ack1 == 1) && ((harq_ack2 == 2) || (harq_ack2 == 0)) && ((harq_ack3 == 2) || (harq_ack3 == 0))) { - b[0] = 1; - b[1] = 0; - return(n1_pucch1); - } else if ((harq_ack0 == 1) && ((harq_ack1 == 2) || (harq_ack1 == 0)) && (harq_ack2 == 1) && (harq_ack3 == 1)) { - b[0] = 0; - b[1] = 1; - return(n1_pucch3); - } else if (((harq_ack0 == 0) || (harq_ack0 == 2)) && ((harq_ack1 == 2) || (harq_ack1 == 0)) && ((harq_ack2 == 2) || (harq_ack2 == 0)) && (harq_ack3 == 0)) { - b[0] = 1; - b[1] = 1; - return(n1_pucch3); - } else if ((harq_ack0 == 1) && ((harq_ack1 == 2) || (harq_ack1 == 0)) && (harq_ack2 == 1) && ((harq_ack3 == 2) || (harq_ack3 == 0))) { - b[0] = 0; - b[1] = 1; - return(n1_pucch2); - } else if ((harq_ack0 == 1) && ((harq_ack1 == 2) || (harq_ack1 == 0)) && ((harq_ack2 == 2) || (harq_ack2 == 0)) && (harq_ack3 == 1)) { - b[0] = 0; - b[1] = 1; - return(n1_pucch0); - } else if ((harq_ack0 == 1) && ((harq_ack1 == 2) || (harq_ack1 == 0)) && ((harq_ack2 == 2) || (harq_ack2 == 0)) && ((harq_ack3 == 2) || (harq_ack3 == 0))) { - b[0] = 0; - b[1] = 1; - return(n1_pucch0); - } else if (((harq_ack0 == 2) || (harq_ack0 == 0)) && (harq_ack1 == 1) && (harq_ack2 == 1) && (harq_ack3 == 1)) { - b[0] = 0; - b[1] = 1; - return(n1_pucch3); - } else if (((harq_ack0 == 2) || (harq_ack0 == 0)) && (harq_ack1 == 0) && (harq_ack2 == 2) && (harq_ack3 == 2)) { - b[0] = 0; - b[1] = 0; - return(n1_pucch1); - } else if (((harq_ack0 == 2) || (harq_ack0 == 0)) && (harq_ack1 == 1) && (harq_ack2 == 1) && ((harq_ack3 == 2) || (harq_ack3 == 0))) { - b[0] = 1; - b[1] = 0; - return(n1_pucch2); - } else if (((harq_ack0 == 2) || (harq_ack0 == 0)) && (harq_ack1 == 1) && ((harq_ack2 == 2) || (harq_ack2 == 0)) && (harq_ack3 == 1)) { - b[0] = 1; - b[1] = 0; - return(n1_pucch3); - } else if (((harq_ack0 == 2) || (harq_ack0 == 0)) && (harq_ack1 == 1) && ((harq_ack2 == 2) || (harq_ack2 == 0)) && ((harq_ack3 == 2) || (harq_ack3 == 0))) { - b[0] = 0; - b[1] = 1; - return(n1_pucch1); - } else if (((harq_ack0 == 2) || (harq_ack0 == 0)) && ((harq_ack1 == 2) || (harq_ack1 == 0)) && (harq_ack2 == 1) && (harq_ack3 == 1)) { - b[0] = 0; - b[1] = 1; - return(n1_pucch3); - } else if (((harq_ack0 == 2) || (harq_ack0 == 0)) && ((harq_ack1 == 2) || (harq_ack1 == 0)) && (harq_ack2 == 1) && ((harq_ack3 == 2) || (harq_ack3 == 0))) { - b[0] = 0; - b[1] = 0; - return(n1_pucch2); - } else if (((harq_ack0 == 2) || (harq_ack0 == 0)) && ((harq_ack1 == 2) || (harq_ack1 == 0)) && (harq_ack3 == 1) && ((harq_ack2 == 2) || (harq_ack2 == 0))) { - b[0] = 0; - b[1] = 0; - return(n1_pucch3); - } - } else if (subframe == 2) { - if ((harq_ack0 == 1) && (harq_ack1 == 1) && (harq_ack2 == 1)) { - b[0] = 1; - b[1] = 1; - return(n1_pucch2); - } else if ((harq_ack0 == 1) && (harq_ack1 == 1) && ((harq_ack2 == 2) || (harq_ack2 == 0))) { - b[0] = 1; - b[1] = 1; - return(n1_pucch1); - } else if ((harq_ack0 == 1) && ((harq_ack1 == 2) || (harq_ack1 == 0)) && (harq_ack2 == 1)) { - b[0] = 1; - b[1] = 1; - return(n1_pucch0); - } else if ((harq_ack0 == 1) && ((harq_ack1 == 2) || (harq_ack1 == 0)) && ((harq_ack2 == 2) || (harq_ack2 == 0))) { - b[0] = 0; - b[1] = 1; - return(n1_pucch0); - } else if (((harq_ack0 == 2) || (harq_ack0 == 0)) && (harq_ack1 == 1) && (harq_ack2 == 1)) { - b[0] = 1; - b[1] = 0; - return(n1_pucch2); - } else if (((harq_ack0 == 2) || (harq_ack0 == 0)) && (harq_ack1 == 1) && ((harq_ack2 == 2) || (harq_ack2 == 0))) { - b[1] = 0; - b[0] = 0; - return(n1_pucch1); - } else if (((harq_ack0 == 2) || (harq_ack0 == 0)) && ((harq_ack1 == 2) || (harq_ack1 == 0)) && (harq_ack2 == 1)) { - b[0] = 0; - b[1] = 0; - return(n1_pucch2); - } else if ((harq_ack0 == 2) && (harq_ack1 == 2) && (harq_ack2 == 0)) { - b[0] = 0; - b[1] = 1; - return(n1_pucch2); - } else if ((harq_ack0 == 2) && (harq_ack1 == 0) && ((harq_ack2 == 2) || (harq_ack2 == 0))) { - b[0] = 1; - b[1] = 0; - return(n1_pucch1); - } else if ((harq_ack0 == 0) && ((harq_ack1 == 2) || (harq_ack1 == 0)) && ((harq_ack2 == 2) || (harq_ack2 == 0))) { - b[0] = 1; - b[1] = 0; - return(n1_pucch0); - } - - } - } else if (SR==1) { // SR and 0,1,or 2 ACKS, (first 3 entries in Table 7.3-1 of 36.213) - // this should be number of ACKs (including - ack_counter = 0; - if (harq_ack0==1) - ack_counter ++; - if (harq_ack1==1) - ack_counter ++; - if (harq_ack2==1) - ack_counter ++; - if (harq_ack3==1) - ack_counter ++; - - switch (ack_counter) { - case 0: - b[0] = 0; - b[1] = 0; - break; - - case 1: - b[0] = 1; - b[1] = 1; - break; - - case 2: - b[0] = 1; - b[1] = 0; - break; - - case 3: - b[0] = 0; - b[1] = 1; - break; - - case 4: - b[0] = 1; - b[1] = 1; - break; + if ((harq_ack0 == 1) && (harq_ack1 == 1) && (harq_ack2 == 1) && (harq_ack3 == 1)) { + b[0] = 1; + b[1] = 1; + return(n1_pucch1); + } else if ((harq_ack0 == 1) && (harq_ack1 == 1) && (harq_ack2 == 1) && ((harq_ack3 == 2) || (harq_ack3 == 0))) { + b[0] = 1; + b[1] = 0; + return(n1_pucch1); + } else if (((harq_ack0 == 0) || (harq_ack0 == 2)) && ((harq_ack1 == 2) || (harq_ack1 == 0)) && (harq_ack2 == 0) && (harq_ack3 == 2)) { + b[0] = 1; + b[1] = 1; + return(n1_pucch2); + } else if ((harq_ack0 == 1) && (harq_ack1 == 1) && ((harq_ack2 == 2) || (harq_ack2 == 0)) && (harq_ack3 == 1)) { + b[0] = 1; + b[1] = 0; + return(n1_pucch1); + } else if ((harq_ack0 == 0) && (harq_ack1 == 2) && (harq_ack2 == 2) && (harq_ack3 == 2)) { + b[0] = 1; + b[1] = 0; + return(n1_pucch0); + } else if ((harq_ack0 == 1) && (harq_ack1 == 1) && ((harq_ack2 == 2) || (harq_ack2 == 0)) && ((harq_ack3 == 2) || (harq_ack3 == 0))) { + b[0] = 1; + b[1] = 0; + return(n1_pucch1); + } else if ((harq_ack0 == 1) && ((harq_ack1 == 2) || (harq_ack1 == 0)) && (harq_ack2 == 1) && (harq_ack3 == 1)) { + b[0] = 0; + b[1] = 1; + return(n1_pucch3); + } else if (((harq_ack0 == 0) || (harq_ack0 == 2)) && ((harq_ack1 == 2) || (harq_ack1 == 0)) && ((harq_ack2 == 2) || (harq_ack2 == 0)) && (harq_ack3 == 0)) { + b[0] = 1; + b[1] = 1; + return(n1_pucch3); + } else if ((harq_ack0 == 1) && ((harq_ack1 == 2) || (harq_ack1 == 0)) && (harq_ack2 == 1) && ((harq_ack3 == 2) || (harq_ack3 == 0))) { + b[0] = 0; + b[1] = 1; + return(n1_pucch2); + } else if ((harq_ack0 == 1) && ((harq_ack1 == 2) || (harq_ack1 == 0)) && ((harq_ack2 == 2) || (harq_ack2 == 0)) && (harq_ack3 == 1)) { + b[0] = 0; + b[1] = 1; + return(n1_pucch0); + } else if ((harq_ack0 == 1) && ((harq_ack1 == 2) || (harq_ack1 == 0)) && ((harq_ack2 == 2) || (harq_ack2 == 0)) && ((harq_ack3 == 2) || (harq_ack3 == 0))) { + b[0] = 0; + b[1] = 1; + return(n1_pucch0); + } else if (((harq_ack0 == 2) || (harq_ack0 == 0)) && (harq_ack1 == 1) && (harq_ack2 == 1) && (harq_ack3 == 1)) { + b[0] = 0; + b[1] = 1; + return(n1_pucch3); + } else if (((harq_ack0 == 2) || (harq_ack0 == 0)) && (harq_ack1 == 0) && (harq_ack2 == 2) && (harq_ack3 == 2)) { + b[0] = 0; + b[1] = 0; + return(n1_pucch1); + } else if (((harq_ack0 == 2) || (harq_ack0 == 0)) && (harq_ack1 == 1) && (harq_ack2 == 1) && ((harq_ack3 == 2) || (harq_ack3 == 0))) { + b[0] = 1; + b[1] = 0; + return(n1_pucch2); + } else if (((harq_ack0 == 2) || (harq_ack0 == 0)) && (harq_ack1 == 1) && ((harq_ack2 == 2) || (harq_ack2 == 0)) && (harq_ack3 == 1)) { + b[0] = 1; + b[1] = 0; + return(n1_pucch3); + } else if (((harq_ack0 == 2) || (harq_ack0 == 0)) && (harq_ack1 == 1) && ((harq_ack2 == 2) || (harq_ack2 == 0)) && ((harq_ack3 == 2) || (harq_ack3 == 0))) { + b[0] = 0; + b[1] = 1; + return(n1_pucch1); + } else if (((harq_ack0 == 2) || (harq_ack0 == 0)) && ((harq_ack1 == 2) || (harq_ack1 == 0)) && (harq_ack2 == 1) && (harq_ack3 == 1)) { + b[0] = 0; + b[1] = 1; + return(n1_pucch3); + } else if (((harq_ack0 == 2) || (harq_ack0 == 0)) && ((harq_ack1 == 2) || (harq_ack1 == 0)) && (harq_ack2 == 1) && ((harq_ack3 == 2) || (harq_ack3 == 0))) { + b[0] = 0; + b[1] = 0; + return(n1_pucch2); + } else if (((harq_ack0 == 2) || (harq_ack0 == 0)) && ((harq_ack1 == 2) || (harq_ack1 == 0)) && (harq_ack3 == 1) && ((harq_ack2 == 2) || (harq_ack2 == 0))) { + b[0] = 0; + b[1] = 0; + return(n1_pucch3); } + } else if (subframe == 2) { + if ((harq_ack0 == 1) && (harq_ack1 == 1) && (harq_ack2 == 1)) { + b[0] = 1; + b[1] = 1; + return(n1_pucch2); + } else if ((harq_ack0 == 1) && (harq_ack1 == 1) && ((harq_ack2 == 2) || (harq_ack2 == 0))) { + b[0] = 1; + b[1] = 1; + return(n1_pucch1); + } else if ((harq_ack0 == 1) && ((harq_ack1 == 2) || (harq_ack1 == 0)) && (harq_ack2 == 1)) { + b[0] = 1; + b[1] = 1; + return(n1_pucch0); + } else if ((harq_ack0 == 1) && ((harq_ack1 == 2) || (harq_ack1 == 0)) && ((harq_ack2 == 2) || (harq_ack2 == 0))) { + b[0] = 0; + b[1] = 1; + return(n1_pucch0); + } else if (((harq_ack0 == 2) || (harq_ack0 == 0)) && (harq_ack1 == 1) && (harq_ack2 == 1)) { + b[0] = 1; + b[1] = 0; + return(n1_pucch2); + } else if (((harq_ack0 == 2) || (harq_ack0 == 0)) && (harq_ack1 == 1) && ((harq_ack2 == 2) || (harq_ack2 == 0))) { + b[1] = 0; + b[0] = 0; + return(n1_pucch1); + } else if (((harq_ack0 == 2) || (harq_ack0 == 0)) && ((harq_ack1 == 2) || (harq_ack1 == 0)) && (harq_ack2 == 1)) { + b[0] = 0; + b[1] = 0; + return(n1_pucch2); + } else if ((harq_ack0 == 2) && (harq_ack1 == 2) && (harq_ack2 == 0)) { + b[0] = 0; + b[1] = 1; + return(n1_pucch2); + } else if ((harq_ack0 == 2) && (harq_ack1 == 0) && ((harq_ack2 == 2) || (harq_ack2 == 0))) { + b[0] = 1; + b[1] = 0; + return(n1_pucch1); + } else if ((harq_ack0 == 0) && ((harq_ack1 == 2) || (harq_ack1 == 0)) && ((harq_ack2 == 2) || (harq_ack2 == 0))) { + b[0] = 1; + b[1] = 0; + return(n1_pucch0); + } + } + } else if (SR==1) { // SR and 0,1,or 2 ACKS, (first 3 entries in Table 7.3-1 of 36.213) + // this should be number of ACKs (including + ack_counter = 0; - ack_counter = 0; - return(ue->scheduling_request_config[eNB_id].sr_PUCCH_ResourceIndex); + if (harq_ack0==1) + ack_counter ++; + + if (harq_ack1==1) + ack_counter ++; + + if (harq_ack2==1) + ack_counter ++; + + if (harq_ack3==1) + ack_counter ++; + + switch (ack_counter) { + case 0: + b[0] = 0; + b[1] = 0; + break; + + case 1: + b[0] = 1; + b[1] = 1; + break; + + case 2: + b[0] = 1; + b[1] = 0; + break; + + case 3: + b[0] = 0; + b[1] = 1; + break; + + case 4: + b[0] = 1; + b[1] = 1; + break; } - break; + ack_counter = 0; + return(ue->scheduling_request_config[eNB_id].sr_PUCCH_ResourceIndex); + } + break; } // switch tdd_config } @@ -1212,10 +1124,8 @@ uint16_t get_n1_pucch(PHY_VARS_UE *ue, void ulsch_common_procedures(PHY_VARS_UE *ue, UE_rxtx_proc_t *proc, uint8_t empty_subframe) { - int aa; LTE_DL_FRAME_PARMS *frame_parms=&ue->frame_parms; - int nsymb; int subframe_tx = proc->subframe_tx; int ulsch_start; @@ -1224,46 +1134,43 @@ void ulsch_common_procedures(PHY_VARS_UE *ue, UE_rxtx_proc_t *proc, uint8_t empt int k,l; int dummy_tx_buffer[frame_parms->samples_per_tti] __attribute__((aligned(16))); #endif - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX_ULSCH_COMMON,VCD_FUNCTION_IN); + if ( LOG_DEBUGFLAG(UE_TIMING)) { start_meas(&ue->ofdm_mod_stats); } - nsymb = (frame_parms->Ncp == 0) ? 14 : 12; + nsymb = (frame_parms->Ncp == 0) ? 14 : 12; #if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR)//this is the EXPRESS MIMO case ulsch_start = (ue->rx_offset+subframe_tx*frame_parms->samples_per_tti- - ue->hw_timing_advance- - ue->timing_advance- - ue->N_TA_offset+5); + ue->hw_timing_advance- + ue->timing_advance- + ue->N_TA_offset+5); //LOG_E(PHY,"ul-signal [subframe: %d, ulsch_start %d]\n",subframe_tx, ulsch_start); if(ulsch_start < 0) - ulsch_start = ulsch_start + (LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*frame_parms->samples_per_tti); + ulsch_start = ulsch_start + (LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*frame_parms->samples_per_tti); if (ulsch_start > (LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*frame_parms->samples_per_tti)) - ulsch_start = ulsch_start % (LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*frame_parms->samples_per_tti); + ulsch_start = ulsch_start % (LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*frame_parms->samples_per_tti); //LOG_E(PHY,"ul-signal [subframe: %d, ulsch_start %d]\n",subframe_tx, ulsch_start); #else //this is the normal case ulsch_start = (frame_parms->samples_per_tti*subframe_tx)-ue->N_TA_offset; //-ue->timing_advance; #endif //else EXMIMO - if (empty_subframe) - { + if (empty_subframe) { overflow = ulsch_start - 9*frame_parms->samples_per_tti; + for (aa=0; aanb_antennas_tx; aa++) { - - if (overflow > 0) - { - memset(&ue->common_vars.txdata[aa][ulsch_start],0,4*(frame_parms->samples_per_tti-overflow)); - memset(&ue->common_vars.txdata[aa][0],0,4*overflow); - } - else - { - memset(&ue->common_vars.txdata[aa][ulsch_start],0,4*frame_parms->samples_per_tti); - } + if (overflow > 0) { + memset(&ue->common_vars.txdata[aa][ulsch_start],0,4*(frame_parms->samples_per_tti-overflow)); + memset(&ue->common_vars.txdata[aa][0],0,4*overflow); + } else { + memset(&ue->common_vars.txdata[aa][ulsch_start],0,4*frame_parms->samples_per_tti); + } } + return; } @@ -1271,32 +1178,31 @@ void ulsch_common_procedures(PHY_VARS_UE *ue, UE_rxtx_proc_t *proc, uint8_t empt if (frame_parms->Ncp == 1) PHY_ofdm_mod(&ue->common_vars.txdataF[aa][subframe_tx*nsymb*frame_parms->ofdm_symbol_size], #if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR) - dummy_tx_buffer, + dummy_tx_buffer, #else - &ue->common_vars.txdata[aa][ulsch_start], + &ue->common_vars.txdata[aa][ulsch_start], #endif - frame_parms->ofdm_symbol_size, - nsymb, - frame_parms->nb_prefix_samples, - CYCLIC_PREFIX); + frame_parms->ofdm_symbol_size, + nsymb, + frame_parms->nb_prefix_samples, + CYCLIC_PREFIX); else { normal_prefix_mod(&ue->common_vars.txdataF[aa][subframe_tx*nsymb*frame_parms->ofdm_symbol_size], #if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR) - dummy_tx_buffer, + dummy_tx_buffer, #else - &ue->common_vars.txdata[aa][ulsch_start], + &ue->common_vars.txdata[aa][ulsch_start], #endif - nsymb>>1, - &ue->frame_parms); - + nsymb>>1, + &ue->frame_parms); normal_prefix_mod(&ue->common_vars.txdataF[aa][((subframe_tx*nsymb)+(nsymb>>1))*frame_parms->ofdm_symbol_size], #if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR) - dummy_tx_buffer+(frame_parms->samples_per_tti>>1), + dummy_tx_buffer+(frame_parms->samples_per_tti>>1), #else - &ue->common_vars.txdata[aa][ulsch_start+(frame_parms->samples_per_tti>>1)], + &ue->common_vars.txdata[aa][ulsch_start+(frame_parms->samples_per_tti>>1)], #endif - nsymb>>1, - &ue->frame_parms); + nsymb>>1, + &ue->frame_parms); } #if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR) @@ -1306,31 +1212,31 @@ void ulsch_common_procedures(PHY_VARS_UE *ue, UE_rxtx_proc_t *proc, uint8_t empt apply_7_5_kHz(ue,&ue->common_vars.txdata[aa][ulsch_start],0); apply_7_5_kHz(ue,&ue->common_vars.txdata[aa][ulsch_start],1); #endif - - #if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR) overflow = ulsch_start - 9*frame_parms->samples_per_tti; - for (k=ulsch_start,l=0; ksamples_per_tti*LTE_NUMBER_OF_SUBFRAMES_PER_FRAME,ulsch_start+frame_parms->samples_per_tti); k++,l++) { - ((short*)ue->common_vars.txdata[aa])[2*k] = ((short*)dummy_tx_buffer)[2*l]; - ((short*)ue->common_vars.txdata[aa])[2*k+1] = ((short*)dummy_tx_buffer)[2*l+1]; + ((short *)ue->common_vars.txdata[aa])[2*k] = ((short *)dummy_tx_buffer)[2*l]; + ((short *)ue->common_vars.txdata[aa])[2*k+1] = ((short *)dummy_tx_buffer)[2*l+1]; } for (k=0; kcommon_vars.txdata[aa])[2*k] = ((short*)dummy_tx_buffer)[2*l]; - ((short*)ue->common_vars.txdata[aa])[2*k+1] = ((short*)dummy_tx_buffer)[2*l+1]; + ((short *)ue->common_vars.txdata[aa])[2*k] = ((short *)dummy_tx_buffer)[2*l]; + ((short *)ue->common_vars.txdata[aa])[2*k+1] = ((short *)dummy_tx_buffer)[2*l+1]; } + #if defined(EXMIMO) + // handle switch before 1st TX subframe, guarantee that the slot prior to transmission is switch on for (k=ulsch_start - (frame_parms->samples_per_tti>>1) ; kcommon_vars.txdata[aa][k+frame_parms->samples_per_tti*LTE_NUMBER_OF_SUBFRAMES_PER_FRAME] &= 0xFFFEFFFE; + ue->common_vars.txdata[aa][k+frame_parms->samples_per_tti*LTE_NUMBER_OF_SUBFRAMES_PER_FRAME] &= 0xFFFEFFFE; else if (k>(frame_parms->samples_per_tti*LTE_NUMBER_OF_SUBFRAMES_PER_FRAME)) - ue->common_vars.txdata[aa][k-frame_parms->samples_per_tti*LTE_NUMBER_OF_SUBFRAMES_PER_FRAME] &= 0xFFFEFFFE; + ue->common_vars.txdata[aa][k-frame_parms->samples_per_tti*LTE_NUMBER_OF_SUBFRAMES_PER_FRAME] &= 0xFFFEFFFE; else - ue->common_vars.txdata[aa][k] &= 0xFFFEFFFE; + ue->common_vars.txdata[aa][k] &= 0xFFFEFFFE; } + #endif #endif /* @@ -1342,7 +1248,6 @@ void ulsch_common_procedures(PHY_VARS_UE *ue, UE_rxtx_proc_t *proc, uint8_t empt LOG_M("txBuff.m","txSignal",&ue->common_vars.txdata[aa][ulsch_start],frame_parms->samples_per_tti,1,1); } */ - } //nb_antennas_tx if ( LOG_DEBUGFLAG(UE_TIMING)) { @@ -1350,133 +1255,119 @@ void ulsch_common_procedures(PHY_VARS_UE *ue, UE_rxtx_proc_t *proc, uint8_t empt } VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX_ULSCH_COMMON,VCD_FUNCTION_OUT); - } void ue_prach_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t abstraction_flag,runmode_t mode) { - int frame_tx = proc->frame_tx; int subframe_tx = proc->subframe_tx; LOG_USEDINLOG_VAR(int, prach_power); PRACH_RESOURCES_t prach_resources_local; - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX_PRACH, VCD_FUNCTION_IN); - ue->generate_prach=0; - if (ue->mac_enabled==0){ + if (ue->mac_enabled==0) { ue->prach_resources[eNB_id] = &prach_resources_local; prach_resources_local.ra_RNTI = 0xbeef; prach_resources_local.ra_PreambleIndex = 0; } - if (ue->mac_enabled==1){ + if (ue->mac_enabled==1) { // ask L2 for RACH transport if ((mode != rx_calib_ue) && (mode != rx_calib_ue_med) && (mode != rx_calib_ue_byp) && (mode != no_L2_connect) ) { //LOG_D(PHY,"Getting PRACH resources\n"); - ue->prach_resources[eNB_id] = ue_get_rach(ue->Mod_id, - ue->CC_id, - frame_tx, - eNB_id, - subframe_tx); + ue->CC_id, + frame_tx, + eNB_id, + subframe_tx); LOG_D(PHY,"Prach resources %p\n",ue->prach_resources[eNB_id]); } } if (ue->prach_resources[eNB_id]!=NULL) { - ue->generate_prach=1; ue->prach_cnt=0; #ifdef SMBV ue->prach_resources[eNB_id]->ra_PreambleIndex = 19; #endif LOG_I(PHY,"mode %d\n",mode); - + if ((ue->mac_enabled==1) && (mode != calib_prach_tx)) { ue->tx_power_dBm[subframe_tx] = ue->prach_resources[eNB_id]->ra_PREAMBLE_RECEIVED_TARGET_POWER+get_PL(ue->Mod_id,ue->CC_id,eNB_id); - } - else { + } else { ue->tx_power_dBm[subframe_tx] = ue->tx_power_max_dBm; ue->prach_resources[eNB_id]->ra_PreambleIndex = 19; } - + LOG_D(PHY,"[UE %d][RAPROC] Frame %d, Subframe %d : Generating PRACH, preamble %d,PL %d, P0_PRACH %d, TARGET_RECEIVED_POWER %d dBm, PRACH TDD Resource index %d, RA-RNTI %d\n", - ue->Mod_id, - frame_tx, - subframe_tx, - ue->prach_resources[eNB_id]->ra_PreambleIndex, - get_PL(ue->Mod_id,ue->CC_id,eNB_id), - ue->tx_power_dBm[subframe_tx], - ue->prach_resources[eNB_id]->ra_PREAMBLE_RECEIVED_TARGET_POWER, - ue->prach_resources[eNB_id]->ra_TDD_map_index, - ue->prach_resources[eNB_id]->ra_RNTI); - + ue->Mod_id, + frame_tx, + subframe_tx, + ue->prach_resources[eNB_id]->ra_PreambleIndex, + get_PL(ue->Mod_id,ue->CC_id,eNB_id), + ue->tx_power_dBm[subframe_tx], + ue->prach_resources[eNB_id]->ra_PREAMBLE_RECEIVED_TARGET_POWER, + ue->prach_resources[eNB_id]->ra_TDD_map_index, + ue->prach_resources[eNB_id]->ra_RNTI); ue->tx_total_RE[subframe_tx] = 96; - #if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR) ue->prach_vars[eNB_id]->amp = get_tx_amp(ue->tx_power_dBm[subframe_tx], - ue->tx_power_max_dBm, - ue->frame_parms.N_RB_UL, - 6); - + ue->tx_power_max_dBm, + ue->frame_parms.N_RB_UL, + 6); #else ue->prach_vars[eNB_id]->amp = AMP; #endif if ((mode == calib_prach_tx) && (((proc->frame_tx&0xfffe)%100)==0)) LOG_D(PHY,"[UE %d][RAPROC] Frame %d, Subframe %d : PRACH TX power %d dBm, amp %d\n", - ue->Mod_id, - proc->frame_rx, - proc->subframe_tx, - ue->tx_power_dBm[subframe_tx], - ue->prach_vars[eNB_id]->amp); - - + ue->Mod_id, + proc->frame_rx, + proc->subframe_tx, + ue->tx_power_dBm[subframe_tx], + ue->prach_vars[eNB_id]->amp); + // start_meas(&ue->tx_prach); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_GENERATE_PRACH, VCD_FUNCTION_IN); prach_power = generate_prach(ue,eNB_id,subframe_tx,frame_tx); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_GENERATE_PRACH, VCD_FUNCTION_OUT); // stop_meas(&ue->tx_prach); LOG_D(PHY,"[UE %d][RAPROC] PRACH PL %d dB, power %d dBm, digital power %d dB (amp %d)\n", - ue->Mod_id, - get_PL(ue->Mod_id,ue->CC_id,eNB_id), - ue->tx_power_dBm[subframe_tx], - dB_fixed(prach_power), - ue->prach_vars[eNB_id]->amp); + ue->Mod_id, + get_PL(ue->Mod_id,ue->CC_id,eNB_id), + ue->tx_power_dBm[subframe_tx], + dB_fixed(prach_power), + ue->prach_vars[eNB_id]->amp); - if (ue->mac_enabled==1){ + if (ue->mac_enabled==1) { Msg1_transmitted(ue->Mod_id, - ue->CC_id, - frame_tx, - eNB_id); + ue->CC_id, + frame_tx, + eNB_id); } - + LOG_I(PHY,"[UE %d][RAPROC] Frame %d, subframe %d: Generating PRACH (eNB %d) preamble index %d for UL, TX power %d dBm (PL %d dB), l3msg \n", - ue->Mod_id,frame_tx,subframe_tx,eNB_id, - ue->prach_resources[eNB_id]->ra_PreambleIndex, - ue->prach_resources[eNB_id]->ra_PREAMBLE_RECEIVED_TARGET_POWER+get_PL(ue->Mod_id,ue->CC_id,eNB_id), - get_PL(ue->Mod_id,ue->CC_id,eNB_id)); - - - + ue->Mod_id,frame_tx,subframe_tx,eNB_id, + ue->prach_resources[eNB_id]->ra_PreambleIndex, + ue->prach_resources[eNB_id]->ra_PREAMBLE_RECEIVED_TARGET_POWER+get_PL(ue->Mod_id,ue->CC_id,eNB_id), + get_PL(ue->Mod_id,ue->CC_id,eNB_id)); + // if we're calibrating the PRACH kill the pointer to its resources so that the RA protocol doesn't continue if (mode == calib_prach_tx) ue->prach_resources[eNB_id]=NULL; LOG_D(PHY,"[UE %d] frame %d subframe %d : generate_prach %d, prach_cnt %d\n", - ue->Mod_id,frame_tx,subframe_tx,ue->generate_prach,ue->prach_cnt); - + ue->Mod_id,frame_tx,subframe_tx,ue->generate_prach,ue->prach_cnt); ue->prach_cnt++; if (ue->prach_cnt==3) ue->generate_prach=0; } + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX_PRACH, VCD_FUNCTION_OUT); } void ue_ulsch_uespec_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t abstraction_flag) { - int harq_pid; int frame_tx=proc->frame_tx; int subframe_tx=proc->subframe_tx; @@ -1497,76 +1388,76 @@ void ue_ulsch_uespec_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB uint8_t cqi_status = 0; uint8_t ri_status = 0; VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX_ULSCH_UESPEC,VCD_FUNCTION_IN); - // get harq_pid from subframe relationship harq_pid = subframe2harq_pid(&ue->frame_parms, - frame_tx, - subframe_tx); - + frame_tx, + subframe_tx); LOG_D(PHY,"Frame %d, Subframe %d : ue_uespec_procedures, harq_pid %d => subframe_scheduling %d\n", - frame_tx,subframe_tx,harq_pid, - ue->ulsch[eNB_id]->harq_processes[harq_pid]->subframe_scheduling_flag); + frame_tx,subframe_tx,harq_pid, + ue->ulsch[eNB_id]->harq_processes[harq_pid]->subframe_scheduling_flag); if (ue->mac_enabled == 1) { if ((ue->ulsch_Msg3_active[eNB_id] == 1) && - (ue->ulsch_Msg3_frame[eNB_id] == frame_tx) && - (ue->ulsch_Msg3_subframe[eNB_id] == subframe_tx)) { // Initial Transmission of Msg3 - + (ue->ulsch_Msg3_frame[eNB_id] == frame_tx) && + (ue->ulsch_Msg3_subframe[eNB_id] == subframe_tx)) { // Initial Transmission of Msg3 ue->ulsch[eNB_id]->harq_processes[harq_pid]->subframe_scheduling_flag = 1; if (ue->ulsch[eNB_id]->harq_processes[harq_pid]->round==0) - generate_ue_ulsch_params_from_rar(ue, - proc, - eNB_id); + generate_ue_ulsch_params_from_rar(ue, + proc, + eNB_id); ue->ulsch[eNB_id]->power_offset = 14; LOG_D(PHY,"[UE %d][RAPROC] Frame %d: Setting Msg3_flag in subframe %d, for harq_pid %d\n", - Mod_id, - frame_tx, - subframe_tx, - harq_pid); + Mod_id, + frame_tx, + subframe_tx, + harq_pid); Msg3_flag = 1; } else { - - AssertFatal(harq_pid!=255,"[UE%d] Frame %d subframe %d ulsch_decoding.c: FATAL ERROR: illegal harq_pid, exiting\n", - Mod_id,frame_tx, subframe_tx); + Mod_id,frame_tx, subframe_tx); Msg3_flag=0; } } if (ue->ulsch[eNB_id]->harq_processes[harq_pid]->subframe_scheduling_flag == 1) { - uint8_t isBad = 0; + if (ue->frame_parms.N_RB_UL <= ue->ulsch[eNB_id]->harq_processes[harq_pid]->first_rb) { LOG_D(PHY,"Invalid PUSCH first_RB=%d for N_RB_UL=%d\n", - ue->ulsch[eNB_id]->harq_processes[harq_pid]->first_rb, - ue->frame_parms.N_RB_UL); + ue->ulsch[eNB_id]->harq_processes[harq_pid]->first_rb, + ue->frame_parms.N_RB_UL); isBad = 1; } + if (ue->frame_parms.N_RB_UL < ue->ulsch[eNB_id]->harq_processes[harq_pid]->nb_rb) { LOG_D(PHY,"Invalid PUSCH num_RB=%d for N_RB_UL=%d\n", - ue->ulsch[eNB_id]->harq_processes[harq_pid]->nb_rb, - ue->frame_parms.N_RB_UL); + ue->ulsch[eNB_id]->harq_processes[harq_pid]->nb_rb, + ue->frame_parms.N_RB_UL); isBad = 1; } + if (0 > ue->ulsch[eNB_id]->harq_processes[harq_pid]->first_rb) { LOG_D(PHY,"Invalid PUSCH first_RB=%d\n", - ue->ulsch[eNB_id]->harq_processes[harq_pid]->first_rb); + ue->ulsch[eNB_id]->harq_processes[harq_pid]->first_rb); isBad = 1; } + if (0 >= ue->ulsch[eNB_id]->harq_processes[harq_pid]->nb_rb) { LOG_D(PHY,"Invalid PUSCH num_RB=%d\n", - ue->ulsch[eNB_id]->harq_processes[harq_pid]->nb_rb); + ue->ulsch[eNB_id]->harq_processes[harq_pid]->nb_rb); isBad = 1; } + if (ue->frame_parms.N_RB_UL < (ue->ulsch[eNB_id]->harq_processes[harq_pid]->nb_rb + ue->ulsch[eNB_id]->harq_processes[harq_pid]->first_rb)) { LOG_D(PHY,"Invalid PUSCH num_RB=%d + first_RB=%d for N_RB_UL=%d\n", - ue->ulsch[eNB_id]->harq_processes[harq_pid]->nb_rb, - ue->ulsch[eNB_id]->harq_processes[harq_pid]->first_rb, - ue->frame_parms.N_RB_UL); + ue->ulsch[eNB_id]->harq_processes[harq_pid]->nb_rb, + ue->ulsch[eNB_id]->harq_processes[harq_pid]->first_rb, + ue->frame_parms.N_RB_UL); isBad = 1; } + if ((0 > ue->ulsch[eNB_id]->harq_processes[harq_pid]->rvidx) || (3 < ue->ulsch[eNB_id]->harq_processes[harq_pid]->rvidx)) { LOG_D(PHY,"Invalid PUSCH RV index=%d\n", ue->ulsch[eNB_id]->harq_processes[harq_pid]->rvidx); @@ -1578,273 +1469,254 @@ void ue_ulsch_uespec_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB ue->ulsch[eNB_id]->harq_processes[harq_pid]->subframe_scheduling_flag = 0; } } + if (ue->ulsch[eNB_id]->harq_processes[harq_pid]->subframe_scheduling_flag == 1) { - ue->generate_ul_signal[eNB_id] = 1; - // deactivate service request // ue->ulsch[eNB_id]->harq_processes[harq_pid]->subframe_scheduling_flag = 0; - LOG_D(PHY,"Generating PUSCH (Abssubframe: %d.%d): harq-Id: %d, round: %d, MaxReTrans: %d \n",frame_tx,subframe_tx,harq_pid,ue->ulsch[eNB_id]->harq_processes[harq_pid]->round,ue->ulsch[eNB_id]->Mlimit); - if (ue->ulsch[eNB_id]->harq_processes[harq_pid]->round >= (ue->ulsch[eNB_id]->Mlimit - 1)) - { + LOG_D(PHY,"Generating PUSCH (Abssubframe: %d.%d): harq-Id: %d, round: %d, MaxReTrans: %d \n",frame_tx,subframe_tx,harq_pid,ue->ulsch[eNB_id]->harq_processes[harq_pid]->round, + ue->ulsch[eNB_id]->Mlimit); + + if (ue->ulsch[eNB_id]->harq_processes[harq_pid]->round >= (ue->ulsch[eNB_id]->Mlimit - 1)) { // LOG_D(PHY,"PUSCH MAX Retransmission achieved ==> send last pusch\n"); - ue->ulsch[eNB_id]->harq_processes[harq_pid]->subframe_scheduling_flag = 0; - ue->ulsch[eNB_id]->harq_processes[harq_pid]->round = 0; + ue->ulsch[eNB_id]->harq_processes[harq_pid]->subframe_scheduling_flag = 0; + ue->ulsch[eNB_id]->harq_processes[harq_pid]->round = 0; } ack_status_cw0 = reset_ack(&ue->frame_parms, - ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->harq_ack, - subframe_tx, - proc->subframe_rx, - ue->ulsch[eNB_id]->o_ACK, - &Nbundled, - 0); + ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->harq_ack, + subframe_tx, + proc->subframe_rx, + ue->ulsch[eNB_id]->o_ACK, + &Nbundled, + 0); ack_status_cw1 = reset_ack(&ue->frame_parms, - ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][1]->harq_ack, - subframe_tx, - proc->subframe_rx, - ue->ulsch[eNB_id]->o_ACK, - &NbundledCw1, - 1); - + ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][1]->harq_ack, + subframe_tx, + proc->subframe_rx, + ue->ulsch[eNB_id]->o_ACK, + &NbundledCw1, + 1); //Nbundled = ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->harq_ack; //ue->ulsch[eNB_id]->bundling = Nbundled; - first_rb = ue->ulsch[eNB_id]->harq_processes[harq_pid]->first_rb; nb_rb = ue->ulsch[eNB_id]->harq_processes[harq_pid]->nb_rb; - - // check Periodic CQI/RI reporting cqi_status = ((ue->cqi_report_config[eNB_id].CQI_ReportPeriodic.cqi_PMI_ConfigIndex>0)&& - (is_cqi_TXOp(ue,proc,eNB_id)==1)); - + (is_cqi_TXOp(ue,proc,eNB_id)==1)); ri_status = ((ue->cqi_report_config[eNB_id].CQI_ReportPeriodic.ri_ConfigIndex>0) && - (is_ri_TXOp(ue,proc,eNB_id)==1)); - + (is_ri_TXOp(ue,proc,eNB_id)==1)); // compute CQI/RI resources compute_cqi_ri_resources(ue, ue->ulsch[eNB_id], eNB_id, ue->ulsch[eNB_id]->rnti, P_RNTI, CBA_RNTI, cqi_status, ri_status); if (ack_status_cw0 > 0) { - // check if we received a PDSCH at subframe_tx - 4 // ==> send ACK/NACK on PUSCH - if (ue->frame_parms.frame_type == FDD) - { + if (ue->frame_parms.frame_type == FDD) { ue->ulsch[eNB_id]->harq_processes[harq_pid]->O_ACK = ack_status_cw0 + ack_status_cw1; } + if ( LOG_DEBUGFLAG(DEBUG_UE_PHYPROC)) { + if(ue->ulsch[eNB_id]->o_ACK[0]) { + LOG_I(PHY,"PUSCH ACK\n"); + T(T_UE_PHY_DLSCH_UE_ACK, T_INT(eNB_id), T_INT(frame_tx%1024), T_INT(subframe_tx), T_INT(ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->rnti), + T_INT(ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->current_harq_pid)); + } else { + LOG_I(PHY,"PUSCH NACK\n"); + T(T_UE_PHY_DLSCH_UE_NACK, T_INT(eNB_id), T_INT(frame_tx%1024), T_INT(subframe_tx), T_INT(ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->rnti), + T_INT(ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->current_harq_pid)); + } + + LOG_I(PHY,"[UE %d][PDSCH %x] AbsSubFrame %d.%d Generating ACK (%d,%d) for %d bits on PUSCH\n", + Mod_id, + ue->ulsch[eNB_id]->rnti, + frame_tx%1024,subframe_tx, + ue->ulsch[eNB_id]->o_ACK[0],ue->ulsch[eNB_id]->o_ACK[1], + ue->ulsch[eNB_id]->harq_processes[harq_pid]->O_ACK); + } + } if ( LOG_DEBUGFLAG(DEBUG_UE_PHYPROC)) { - if(ue->ulsch[eNB_id]->o_ACK[0]) - { - LOG_I(PHY,"PUSCH ACK\n"); - T(T_UE_PHY_DLSCH_UE_ACK, T_INT(eNB_id), T_INT(frame_tx%1024), T_INT(subframe_tx), T_INT(ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->rnti), - T_INT(ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->current_harq_pid)); - } - else - { - LOG_I(PHY,"PUSCH NACK\n"); - T(T_UE_PHY_DLSCH_UE_NACK, T_INT(eNB_id), T_INT(frame_tx%1024), T_INT(subframe_tx), T_INT(ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->rnti), - T_INT(ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->current_harq_pid)); - } - LOG_I(PHY,"[UE %d][PDSCH %x] AbsSubFrame %d.%d Generating ACK (%d,%d) for %d bits on PUSCH\n", - Mod_id, - ue->ulsch[eNB_id]->rnti, - frame_tx%1024,subframe_tx, - ue->ulsch[eNB_id]->o_ACK[0],ue->ulsch[eNB_id]->o_ACK[1], - ue->ulsch[eNB_id]->harq_processes[harq_pid]->O_ACK); + LOG_D(PHY, + "[UE %d][PUSCH %d] AbsSubframe %d.%d Generating PUSCH : first_rb %d, nb_rb %d, round %d, mcs %d, rv %d, " + "cyclic_shift %d (cyclic_shift_common %d,n_DMRS2 %d,n_PRS %d), ACK (%d,%d), O_ACK %d, ack_status_cw0 %d ack_status_cw1 %d bundling %d, Nbundled %d, CQI %d, RI %d\n", + Mod_id,harq_pid,frame_tx%1024,subframe_tx, + first_rb,nb_rb, + ue->ulsch[eNB_id]->harq_processes[harq_pid]->round, + ue->ulsch[eNB_id]->harq_processes[harq_pid]->mcs, + ue->ulsch[eNB_id]->harq_processes[harq_pid]->rvidx, + (ue->frame_parms.pusch_config_common.ul_ReferenceSignalsPUSCH.cyclicShift+ + ue->ulsch[eNB_id]->harq_processes[harq_pid]->n_DMRS2+ + ue->frame_parms.pusch_config_common.ul_ReferenceSignalsPUSCH.nPRS[subframe_tx<<1])%12, + ue->frame_parms.pusch_config_common.ul_ReferenceSignalsPUSCH.cyclicShift, + ue->ulsch[eNB_id]->harq_processes[harq_pid]->n_DMRS2, + ue->frame_parms.pusch_config_common.ul_ReferenceSignalsPUSCH.nPRS[subframe_tx<<1], + ue->ulsch[eNB_id]->o_ACK[0],ue->ulsch[eNB_id]->o_ACK[1], + ue->ulsch[eNB_id]->harq_processes[harq_pid]->O_ACK, + ack_status_cw0, + ack_status_cw1, + ue->ulsch[eNB_id]->bundling, Nbundled, + cqi_status, + ri_status); } - } - - - if ( LOG_DEBUGFLAG(DEBUG_UE_PHYPROC)){ - LOG_D(PHY, - "[UE %d][PUSCH %d] AbsSubframe %d.%d Generating PUSCH : first_rb %d, nb_rb %d, round %d, mcs %d, rv %d, " - "cyclic_shift %d (cyclic_shift_common %d,n_DMRS2 %d,n_PRS %d), ACK (%d,%d), O_ACK %d, ack_status_cw0 %d ack_status_cw1 %d bundling %d, Nbundled %d, CQI %d, RI %d\n", - Mod_id,harq_pid,frame_tx%1024,subframe_tx, - first_rb,nb_rb, - ue->ulsch[eNB_id]->harq_processes[harq_pid]->round, - ue->ulsch[eNB_id]->harq_processes[harq_pid]->mcs, - ue->ulsch[eNB_id]->harq_processes[harq_pid]->rvidx, - (ue->frame_parms.pusch_config_common.ul_ReferenceSignalsPUSCH.cyclicShift+ - ue->ulsch[eNB_id]->harq_processes[harq_pid]->n_DMRS2+ - ue->frame_parms.pusch_config_common.ul_ReferenceSignalsPUSCH.nPRS[subframe_tx<<1])%12, - ue->frame_parms.pusch_config_common.ul_ReferenceSignalsPUSCH.cyclicShift, - ue->ulsch[eNB_id]->harq_processes[harq_pid]->n_DMRS2, - ue->frame_parms.pusch_config_common.ul_ReferenceSignalsPUSCH.nPRS[subframe_tx<<1], - ue->ulsch[eNB_id]->o_ACK[0],ue->ulsch[eNB_id]->o_ACK[1], - ue->ulsch[eNB_id]->harq_processes[harq_pid]->O_ACK, - ack_status_cw0, - ack_status_cw1, - ue->ulsch[eNB_id]->bundling, Nbundled, - cqi_status, - ri_status); - } - - - - if (Msg3_flag == 1) { LOG_I(PHY,"[UE %d][RAPROC] Frame %d, Subframe %d Generating (RRCConnectionRequest) Msg3 (nb_rb %d, first_rb %d, round %d, rvidx %d) Msg3: %x.%x.%x|%x.%x.%x.%x.%x.%x\n",Mod_id,frame_tx, - subframe_tx, - ue->ulsch[eNB_id]->harq_processes[harq_pid]->nb_rb, - ue->ulsch[eNB_id]->harq_processes[harq_pid]->first_rb, - ue->ulsch[eNB_id]->harq_processes[harq_pid]->round, - ue->ulsch[eNB_id]->harq_processes[harq_pid]->rvidx, - ue->prach_resources[eNB_id]->Msg3[0], - ue->prach_resources[eNB_id]->Msg3[1], - ue->prach_resources[eNB_id]->Msg3[2], - ue->prach_resources[eNB_id]->Msg3[3], - ue->prach_resources[eNB_id]->Msg3[4], - ue->prach_resources[eNB_id]->Msg3[5], - ue->prach_resources[eNB_id]->Msg3[6], - ue->prach_resources[eNB_id]->Msg3[7], - ue->prach_resources[eNB_id]->Msg3[8]); - if ( LOG_DEBUGFLAG(UE_TIMING)) { - start_meas(&ue->ulsch_encoding_stats); - } - + subframe_tx, + ue->ulsch[eNB_id]->harq_processes[harq_pid]->nb_rb, + ue->ulsch[eNB_id]->harq_processes[harq_pid]->first_rb, + ue->ulsch[eNB_id]->harq_processes[harq_pid]->round, + ue->ulsch[eNB_id]->harq_processes[harq_pid]->rvidx, + ue->prach_resources[eNB_id]->Msg3[0], + ue->prach_resources[eNB_id]->Msg3[1], + ue->prach_resources[eNB_id]->Msg3[2], + ue->prach_resources[eNB_id]->Msg3[3], + ue->prach_resources[eNB_id]->Msg3[4], + ue->prach_resources[eNB_id]->Msg3[5], + ue->prach_resources[eNB_id]->Msg3[6], + ue->prach_resources[eNB_id]->Msg3[7], + ue->prach_resources[eNB_id]->Msg3[8]); + + if ( LOG_DEBUGFLAG(UE_TIMING)) { + start_meas(&ue->ulsch_encoding_stats); + } + AssertFatal(ulsch_encoding(ue->prach_resources[eNB_id]->Msg3, - ue, - harq_pid, - eNB_id, - proc->subframe_rx, - ue->transmission_mode[eNB_id],0,0)==0, - "ulsch_coding.c: FATAL ERROR: returning\n"); - - if ( LOG_DEBUGFLAG(UE_TIMING)) { - stop_meas(&ue->phy_proc_tx); - LOG_I(PHY,"------FULL TX PROC : %5.2f ------\n",ue->phy_proc_tx.p_time/(cpuf*1000.0)); - stop_meas(&ue->ulsch_encoding_stats); - } + ue, + harq_pid, + eNB_id, + proc->subframe_rx, + ue->transmission_mode[eNB_id],0,0)==0, + "ulsch_coding.c: FATAL ERROR: returning\n"); + + if ( LOG_DEBUGFLAG(UE_TIMING)) { + stop_meas(&ue->phy_proc_tx); + LOG_I(PHY,"------FULL TX PROC : %5.2f ------\n",ue->phy_proc_tx.p_time/(cpuf*1000.0)); + stop_meas(&ue->ulsch_encoding_stats); + } if (ue->mac_enabled == 1) { - - // signal MAC that Msg3 was sent - Msg3_transmitted(Mod_id, - CC_id, - frame_tx, - eNB_id); + // signal MAC that Msg3 was sent + Msg3_transmitted(Mod_id, + CC_id, + frame_tx, + eNB_id); } + LOG_I(PHY,"Done Msg3 encoding\n"); } // Msg3_flag==1 else {// Msg3_flag==0 input_buffer_length = ue->ulsch[eNB_id]->harq_processes[harq_pid]->TBS/8; if (ue->mac_enabled==1) { + // LOG_D(PHY,"[UE %d] ULSCH : Searching for MAC SDUs\n",Mod_id); + if (ue->ulsch[eNB_id]->harq_processes[harq_pid]->round==0) { + //if (ue->ulsch[eNB_id]->harq_processes[harq_pid]->calibration_flag == 0) { + access_mode=SCHEDULED_ACCESS; + ue_get_sdu(Mod_id, + CC_id, + frame_tx, + subframe_tx, + eNB_id, + ulsch_input_buffer, + input_buffer_length, + &access_mode); + } - // LOG_D(PHY,"[UE %d] ULSCH : Searching for MAC SDUs\n",Mod_id); - if (ue->ulsch[eNB_id]->harq_processes[harq_pid]->round==0) { - //if (ue->ulsch[eNB_id]->harq_processes[harq_pid]->calibration_flag == 0) { - access_mode=SCHEDULED_ACCESS; + if (LOG_DEBUGFLAG(DEBUG_UE_PHYPROC)) { + LOG_D(PHY,"[UE] Frame %d, subframe %d : ULSCH SDU (TX harq_pid %d) (%d bytes) : \n",frame_tx,subframe_tx,harq_pid, ue->ulsch[eNB_id]->harq_processes[harq_pid]->TBS>>3); - ue_get_sdu(Mod_id, - CC_id, - frame_tx, - subframe_tx, - eNB_id, - ulsch_input_buffer, - input_buffer_length, - &access_mode); - } - - + for (i=0; iulsch[eNB_id]->harq_processes[harq_pid]->TBS>>3; i++) + LOG_T(PHY,"%x.",ulsch_input_buffer[i]); - - if (LOG_DEBUGFLAG(DEBUG_UE_PHYPROC)) { - LOG_D(PHY,"[UE] Frame %d, subframe %d : ULSCH SDU (TX harq_pid %d) (%d bytes) : \n",frame_tx,subframe_tx,harq_pid, ue->ulsch[eNB_id]->harq_processes[harq_pid]->TBS>>3); - - for (i=0; iulsch[eNB_id]->harq_processes[harq_pid]->TBS>>3; i++) - LOG_T(PHY,"%x.",ulsch_input_buffer[i]); - - LOG_T(PHY,"\n"); + LOG_T(PHY,"\n"); + } + } else { + unsigned int taus(void); + + for (i=0; iulsch_encoding_stats); - } + + if ( LOG_DEBUGFLAG(UE_TIMING)) { + start_meas(&ue->ulsch_encoding_stats); + } + if (abstraction_flag==0) { - - if (ulsch_encoding(ulsch_input_buffer, - ue, - harq_pid, - eNB_id, - proc->subframe_rx, - ue->transmission_mode[eNB_id],0, - Nbundled)!=0) { - LOG_E(PHY,"ulsch_coding.c: FATAL ERROR: returning\n"); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX, VCD_FUNCTION_OUT); + if (ulsch_encoding(ulsch_input_buffer, + ue, + harq_pid, + eNB_id, + proc->subframe_rx, + ue->transmission_mode[eNB_id],0, + Nbundled)!=0) { + LOG_E(PHY,"ulsch_coding.c: FATAL ERROR: returning\n"); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX, VCD_FUNCTION_OUT); + if (LOG_DEBUGFLAG(UE_TIMING)) { - stop_meas(&ue->phy_proc_tx); + stop_meas(&ue->phy_proc_tx); } - return; - } + + return; + } } - + if(LOG_DEBUGFLAG(UE_TIMING)) { stop_meas(&ue->ulsch_encoding_stats); } } - + if (abstraction_flag == 0) { if (ue->mac_enabled==1) { - pusch_power_cntl(ue,proc,eNB_id,1, abstraction_flag); - ue->tx_power_dBm[subframe_tx] = ue->ulsch[eNB_id]->Po_PUSCH; - } - else { - ue->tx_power_dBm[subframe_tx] = ue->tx_power_max_dBm; + pusch_power_cntl(ue,proc,eNB_id,1, abstraction_flag); + ue->tx_power_dBm[subframe_tx] = ue->ulsch[eNB_id]->Po_PUSCH; + } else { + ue->tx_power_dBm[subframe_tx] = ue->tx_power_max_dBm; } + ue->tx_total_RE[subframe_tx] = nb_rb*12; - #if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR) tx_amp = get_tx_amp(ue->tx_power_dBm[subframe_tx], - ue->tx_power_max_dBm, - ue->frame_parms.N_RB_UL, - nb_rb); + ue->tx_power_max_dBm, + ue->frame_parms.N_RB_UL, + nb_rb); #else - tx_amp = AMP; + tx_amp = AMP; #endif + T(T_UE_PHY_PUSCH_TX_POWER, T_INT(eNB_id), T_INT(frame_tx%1024), T_INT(subframe_tx),T_INT(ue->tx_power_dBm[subframe_tx]), + T_INT(tx_amp),T_INT(ue->ulsch[eNB_id]->f_pusch),T_INT(get_PL(Mod_id,0,eNB_id)),T_INT(nb_rb)); - T(T_UE_PHY_PUSCH_TX_POWER, T_INT(eNB_id), T_INT(frame_tx%1024), T_INT(subframe_tx),T_INT(ue->tx_power_dBm[subframe_tx]), - T_INT(tx_amp),T_INT(ue->ulsch[eNB_id]->f_pusch),T_INT(get_PL(Mod_id,0,eNB_id)),T_INT(nb_rb)); + if (LOG_DEBUGFLAG(DEBUG_UE_PHYPROC)) { + LOG_D(PHY,"[UE %d][PUSCH %d] AbsSubFrame %d.%d, generating PUSCH, Po_PUSCH: %d dBm (max %d dBm), amp %d\n", + Mod_id,harq_pid,frame_tx%1024,subframe_tx,ue->tx_power_dBm[subframe_tx],ue->tx_power_max_dBm, tx_amp); + } - if (LOG_DEBUGFLAG(DEBUG_UE_PHYPROC)) { - LOG_D(PHY,"[UE %d][PUSCH %d] AbsSubFrame %d.%d, generating PUSCH, Po_PUSCH: %d dBm (max %d dBm), amp %d\n", - Mod_id,harq_pid,frame_tx%1024,subframe_tx,ue->tx_power_dBm[subframe_tx],ue->tx_power_max_dBm, tx_amp); - } - if (LOG_DEBUGFLAG(UE_TIMING)) { - start_meas(&ue->ulsch_modulation_stats); - } - ulsch_modulation(ue->common_vars.txdataF, - tx_amp, - frame_tx, - subframe_tx, - &ue->frame_parms, - ue->ulsch[eNB_id]); - for (aa=0; aa<1/*frame_parms->nb_antennas_tx*/; aa++) - generate_drs_pusch(ue, - proc, - eNB_id, - tx_amp, - subframe_tx, - first_rb, - nb_rb, - aa); + if (LOG_DEBUGFLAG(UE_TIMING)) { + start_meas(&ue->ulsch_modulation_stats); + } - if (LOG_DEBUGFLAG(UE_TIMING)) { - stop_meas(&ue->ulsch_modulation_stats); + ulsch_modulation(ue->common_vars.txdataF, + tx_amp, + frame_tx, + subframe_tx, + &ue->frame_parms, + ue->ulsch[eNB_id]); + + for (aa=0; aa<1/*frame_parms->nb_antennas_tx*/; aa++) + generate_drs_pusch(ue, + proc, + eNB_id, + tx_amp, + subframe_tx, + first_rb, + nb_rb, + aa); + + if (LOG_DEBUGFLAG(UE_TIMING)) { + stop_meas(&ue->ulsch_modulation_stats); + } } - } - if (abstraction_flag==1) { // clear SR ue->sr[subframe_tx]=0; @@ -1852,84 +1724,72 @@ void ue_ulsch_uespec_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB } // subframe_scheduling_flag==1 VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX_ULSCH_UESPEC,VCD_FUNCTION_OUT); - } -void ue_srs_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t abstraction_flag) -{ - +void ue_srs_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t abstraction_flag) { //LTE_DL_FRAME_PARMS *frame_parms = &ue->frame_parms; //int8_t frame_tx = proc->frame_tx; int8_t subframe_tx = proc->subframe_tx; int16_t tx_amp; int16_t Po_SRS; uint8_t nb_rb_srs; - SOUNDINGRS_UL_CONFIG_DEDICATED *pSoundingrs_ul_config_dedicated=&ue->soundingrs_ul_config_dedicated[eNB_id]; uint8_t isSrsTxOccasion = pSoundingrs_ul_config_dedicated->srsUeSubframe; - if(isSrsTxOccasion) - { + if(isSrsTxOccasion) { ue->generate_ul_signal[eNB_id] = 1; - if (ue->mac_enabled==1) - { - srs_power_cntl(ue,proc,eNB_id, (uint8_t*)(&nb_rb_srs), abstraction_flag); + + if (ue->mac_enabled==1) { + srs_power_cntl(ue,proc,eNB_id, (uint8_t *)(&nb_rb_srs), abstraction_flag); Po_SRS = ue->ulsch[eNB_id]->Po_SRS; - } - else - { + } else { Po_SRS = ue->tx_power_max_dBm; } #if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR) - if (ue->mac_enabled==1) - { - tx_amp = get_tx_amp(Po_SRS, - ue->tx_power_max_dBm, - ue->frame_parms.N_RB_UL, - nb_rb_srs); - } - else - { - tx_amp = AMP; - } -#else + + if (ue->mac_enabled==1) { + tx_amp = get_tx_amp(Po_SRS, + ue->tx_power_max_dBm, + ue->frame_parms.N_RB_UL, + nb_rb_srs); + } else { tx_amp = AMP; + } + +#else + tx_amp = AMP; #endif LOG_D(PHY,"SRS PROC; TX_MAX_POWER %d, Po_SRS %d, NB_RB_UL %d, NB_RB_SRS %d TX_AMPL %d\n",ue->tx_power_max_dBm, - Po_SRS, - ue->frame_parms.N_RB_UL, - nb_rb_srs, - tx_amp); - + Po_SRS, + ue->frame_parms.N_RB_UL, + nb_rb_srs, + tx_amp); uint16_t nsymb = (ue->frame_parms.Ncp==0) ? 14:12; uint16_t symbol_offset = (int)ue->frame_parms.ofdm_symbol_size*((subframe_tx*nsymb)+(nsymb-1)); generate_srs(&ue->frame_parms, - &ue->soundingrs_ul_config_dedicated[eNB_id], - &ue->common_vars.txdataF[eNB_id][symbol_offset], - tx_amp, - subframe_tx); + &ue->soundingrs_ul_config_dedicated[eNB_id], + &ue->common_vars.txdataF[eNB_id][symbol_offset], + tx_amp, + subframe_tx); } } int16_t get_pucch2_cqi(PHY_VARS_UE *ue,int eNB_id,int *len) { - if ((ue->transmission_mode[eNB_id]<4)|| (ue->transmission_mode[eNB_id]==7)) { // Mode 1-0 feedback // 4-bit CQI message - /*LOG_I(PHY,"compute CQI value, TM %d, length 4, Cqi Avg %d, value %d \n", ue->transmission_mode[eNB_id], - ue->measurements.wideband_cqi_avg[eNB_id], - sinr2cqi((double)ue->measurements.wideband_cqi_avg[eNB_id], - ue->transmission_mode[eNB_id]));*/ + /*LOG_I(PHY,"compute CQI value, TM %d, length 4, Cqi Avg %d, value %d \n", ue->transmission_mode[eNB_id], + ue->measurements.wideband_cqi_avg[eNB_id], + sinr2cqi((double)ue->measurements.wideband_cqi_avg[eNB_id], + ue->transmission_mode[eNB_id]));*/ *len=4; return(sinr2cqi((double)ue->measurements.wideband_cqi_avg[eNB_id], - ue->transmission_mode[eNB_id])); - } - else { // Mode 1-1 feedback, later - //LOG_I(PHY,"compute CQI value, TM %d, length 0, Cqi Avg 0 \n", ue->transmission_mode[eNB_id]); + ue->transmission_mode[eNB_id])); + } else { // Mode 1-1 feedback, later + //LOG_I(PHY,"compute CQI value, TM %d, length 0, Cqi Avg 0 \n", ue->transmission_mode[eNB_id]); *len=0; // 2-antenna ports RI=1, 6 bits (2 PMI, 4 CQI) - // 2-antenna ports RI=2, 8 bits (1 PMI, 7 CQI/DIFF CQI) return(0); } @@ -1937,7 +1797,6 @@ int16_t get_pucch2_cqi(PHY_VARS_UE *ue,int eNB_id,int *len) { int16_t get_pucch2_ri(PHY_VARS_UE *ue,int eNB_id) { - return(1); } @@ -1951,15 +1810,12 @@ void get_pucch_param(PHY_VARS_UE *ue, uint8_t cqi_report, uint16_t *pucch_resource, uint8_t *pucch_payload, - uint16_t *plength) -{ - - switch (format) { - case pucch_format1: - { - pucch_resource[0] = ue->scheduling_request_config[eNB_id].sr_PUCCH_ResourceIndex; - pucch_payload[0] = 0; // payload is ignored in case of format1 - pucch_payload[1] = 0; // payload is ignored in case of format1 + uint16_t *plength) { + switch (format) { + case pucch_format1: { + pucch_resource[0] = ue->scheduling_request_config[eNB_id].sr_PUCCH_ResourceIndex; + pucch_payload[0] = 0; // payload is ignored in case of format1 + pucch_payload[1] = 0; // payload is ignored in case of format1 } break; @@ -1967,58 +1823,50 @@ void get_pucch_param(PHY_VARS_UE *ue, case pucch_format1b: case pucch_format1b_csA2: case pucch_format1b_csA3: - case pucch_format1b_csA4: - { - pucch_resource[0] = get_n1_pucch(ue, - proc, - ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->harq_ack, - eNB_id, - ack_payload, - SR); - pucch_payload[0] = ack_payload[0]; - pucch_payload[1] = ack_payload[1]; - //pucch_payload[1] = 1; + case pucch_format1b_csA4: { + pucch_resource[0] = get_n1_pucch(ue, + proc, + ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->harq_ack, + eNB_id, + ack_payload, + SR); + pucch_payload[0] = ack_payload[0]; + pucch_payload[1] = ack_payload[1]; + //pucch_payload[1] = 1; } break; - case pucch_format2: - { - pucch_resource[0] = ue->cqi_report_config[eNB_id].CQI_ReportPeriodic.cqi_PUCCH_ResourceIndex; - if(cqi_report) - { - pucch_payload[0] = get_pucch2_cqi(ue,eNB_id,(int*)plength); - } - else - { - *plength = 1; - pucch_payload[0] = get_pucch2_ri(ue,eNB_id); - } + case pucch_format2: { + pucch_resource[0] = ue->cqi_report_config[eNB_id].CQI_ReportPeriodic.cqi_PUCCH_ResourceIndex; + + if(cqi_report) { + pucch_payload[0] = get_pucch2_cqi(ue,eNB_id,(int *)plength); + } else { + *plength = 1; + pucch_payload[0] = get_pucch2_ri(ue,eNB_id); + } } break; case pucch_format2a: case pucch_format2b: - LOG_E(PHY,"NO Resource available for PUCCH 2a/2b \n"); - break; + LOG_E(PHY,"NO Resource available for PUCCH 2a/2b \n"); + break; case pucch_format3: fprintf(stderr, "PUCCH format 3 not handled\n"); abort(); - } + } } void ue_pucch_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t abstraction_flag) { - - uint8_t pucch_ack_payload[2]; uint16_t pucch_resource; ANFBmode_t bundling_flag; PUCCH_FMT_t format; - uint8_t SR_payload; uint8_t pucch_payload[2]; uint16_t len; - LTE_DL_FRAME_PARMS *frame_parms = &ue->frame_parms; int frame_tx=proc->frame_tx; int subframe_tx=proc->subframe_tx; @@ -2031,30 +1879,24 @@ void ue_pucch_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin uint8_t nb_cw=0; uint8_t cqi_status=0; uint8_t ri_status=0; - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX_PUCCH,VCD_FUNCTION_IN); - SOUNDINGRS_UL_CONFIG_DEDICATED *pSoundingrs_ul_config_dedicated=&ue->soundingrs_ul_config_dedicated[eNB_id]; - // 36.213 8.2 /*if ackNackSRS_SimultaneousTransmission == TRUE and in the cell specific SRS subframes UE shall transmit ACK/NACK and SR using the shortened PUCCH format. This shortened PUCCH format shall be used in a cell specific SRS subframe even if the UE does not transmit SRS in that subframe */ - int harq_pid = subframe2harq_pid(&ue->frame_parms, frame_tx, subframe_tx); - if(ue->ulsch[eNB_id]->harq_processes[harq_pid]->subframe_scheduling_flag) - { - LOG_D(PHY,"PUSCH is programmed on this subframe [pid %d] AbsSuframe %d.%d ==> Skip PUCCH transmission \n",harq_pid,frame_tx,subframe_tx); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX_PUCCH,VCD_FUNCTION_OUT); - return; + if(ue->ulsch[eNB_id]->harq_processes[harq_pid]->subframe_scheduling_flag) { + LOG_D(PHY,"PUSCH is programmed on this subframe [pid %d] AbsSuframe %d.%d ==> Skip PUCCH transmission \n",harq_pid,frame_tx,subframe_tx); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX_PUCCH,VCD_FUNCTION_OUT); + return; } uint8_t isShortenPucch = (pSoundingrs_ul_config_dedicated->srsCellSubframe && frame_parms->soundingrs_ul_config_common.ackNackSRS_SimultaneousTransmission); - bundling_flag = ue->pucch_config_dedicated[eNB_id].tdd_AckNackFeedbackMode; if ((frame_parms->frame_type==FDD) || @@ -2073,52 +1915,45 @@ void ue_pucch_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin // - ACK/NACK // - CQI // - RI - SR_payload = 0; - if (is_SR_TXOp(ue,proc,eNB_id)==1) - { - if (ue->mac_enabled==1) { - SR_payload = ue_get_SR(Mod_id, - CC_id, - frame_tx, - eNB_id, - ue->pdcch_vars[ue->current_thread_id[proc->subframe_rx]][eNB_id]->crnti, - subframe_tx); // subframe used for meas gap - } - else { - SR_payload = 1; - } + + if (is_SR_TXOp(ue,proc,eNB_id)==1) { + if (ue->mac_enabled==1) { + SR_payload = ue_get_SR(Mod_id, + CC_id, + frame_tx, + eNB_id, + ue->pdcch_vars[ue->current_thread_id[proc->subframe_rx]][eNB_id]->crnti, + subframe_tx); // subframe used for meas gap + } else { + SR_payload = 1; + } } ack_status_cw0 = get_ack(&ue->frame_parms, - ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->harq_ack, - subframe_tx, - proc->subframe_rx, - pucch_ack_payload, - 0); - + ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->harq_ack, + subframe_tx, + proc->subframe_rx, + pucch_ack_payload, + 0); ack_status_cw1 = get_ack(&ue->frame_parms, - ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][1]->harq_ack, - subframe_tx, - proc->subframe_rx, - pucch_ack_payload, - 1); - + ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][1]->harq_ack, + subframe_tx, + proc->subframe_rx, + pucch_ack_payload, + 1); nb_cw = ( (ack_status_cw0 != 0) ? 1:0) + ( (ack_status_cw1 != 0) ? 1:0); - cqi_status = ((ue->cqi_report_config[eNB_id].CQI_ReportPeriodic.cqi_PMI_ConfigIndex>0)&& - (is_cqi_TXOp(ue,proc,eNB_id)==1)); - + (is_cqi_TXOp(ue,proc,eNB_id)==1)); ri_status = ((ue->cqi_report_config[eNB_id].CQI_ReportPeriodic.ri_ConfigIndex>0) && - (is_ri_TXOp(ue,proc,eNB_id)==1)); + (is_ri_TXOp(ue,proc,eNB_id)==1)); // Part - II // if nothing to report ==> exit function - if( (nb_cw==0) && (SR_payload==0) && (cqi_status==0) && (ri_status==0) ) - { - LOG_D(PHY,"PUCCH No feedback AbsSubframe %d.%d SR_payload %d nb_cw %d pucch_ack_payload[0] %d pucch_ack_payload[1] %d cqi_status %d Return \n", - frame_tx%1024, subframe_tx, SR_payload, nb_cw, pucch_ack_payload[0], pucch_ack_payload[1], cqi_status); - return; + if( (nb_cw==0) && (SR_payload==0) && (cqi_status==0) && (ri_status==0) ) { + LOG_D(PHY,"PUCCH No feedback AbsSubframe %d.%d SR_payload %d nb_cw %d pucch_ack_payload[0] %d pucch_ack_payload[1] %d cqi_status %d Return \n", + frame_tx%1024, subframe_tx, SR_payload, nb_cw, pucch_ack_payload[0], pucch_ack_payload[1], cqi_status); + return; } // Part - III @@ -2141,184 +1976,169 @@ void ue_pucch_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin &pucch_resource, (uint8_t *)&pucch_payload, &len); - - LOG_D(PHY,"PUCCH feedback AbsSubframe %d.%d SR %d NbCW %d (%d %d) AckNack %d.%d CQI %d RI %d format %d pucch_resource %d pucch_payload %d %d \n", - frame_tx%1024, subframe_tx, SR_payload, nb_cw, ack_status_cw0, ack_status_cw1, pucch_ack_payload[0], pucch_ack_payload[1], cqi_status, ri_status, format, pucch_resource,pucch_payload[0],pucch_payload[1]); - + frame_tx%1024, subframe_tx, SR_payload, nb_cw, ack_status_cw0, ack_status_cw1, pucch_ack_payload[0], pucch_ack_payload[1], cqi_status, ri_status, format, pucch_resource,pucch_payload[0], + pucch_payload[1]); // Part - IV // Generate PUCCH signal ue->generate_ul_signal[eNB_id] = 1; switch (format) { - case pucch_format1: - case pucch_format1a: - case pucch_format1b: - { - if (ue->mac_enabled == 1) { - Po_PUCCH = pucch_power_cntl(ue,proc,subframe_tx,eNB_id,format); - } - else { - Po_PUCCH = ue->tx_power_max_dBm; - } - ue->tx_power_dBm[subframe_tx] = Po_PUCCH; - ue->tx_total_RE[subframe_tx] = 12; - -#if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR) - tx_amp = get_tx_amp(Po_PUCCH, - ue->tx_power_max_dBm, - ue->frame_parms.N_RB_UL, - 1); -#else - tx_amp = AMP; -#endif - - T(T_UE_PHY_PUCCH_TX_POWER, T_INT(eNB_id), T_INT(frame_tx%1024), T_INT(subframe_tx),T_INT(ue->tx_power_dBm[subframe_tx]), - T_INT(tx_amp),T_INT(ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->g_pucch),T_INT(get_PL(ue->Mod_id,ue->CC_id,eNB_id))); - - if(format == pucch_format1) - { - LOG_D(PHY,"[UE %d][SR %x] AbsSubframe %d.%d Generating PUCCH 1 (SR for PUSCH), an_srs_simultanous %d, shorten_pucch %d, n1_pucch %d, Po_PUCCH %d\n", - Mod_id, - ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->rnti, - frame_tx%1024, subframe_tx, - frame_parms->soundingrs_ul_config_common.ackNackSRS_SimultaneousTransmission, - isShortenPucch, - ue->scheduling_request_config[eNB_id].sr_PUCCH_ResourceIndex, - Po_PUCCH); - } - else - { - if (SR_payload>0) { - LOG_D(PHY,"[UE %d][SR %x] AbsSubFrame %d.%d Generating PUCCH %s payload %d,%d (with SR for PUSCH), an_srs_simultanous %d, shorten_pucch %d, n1_pucch %d, Po_PUCCH %d, amp %d\n", - Mod_id, - ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->rnti, - frame_tx % 1024, subframe_tx, - (format == pucch_format1a? "1a": ( - format == pucch_format1b? "1b" : "??")), - pucch_ack_payload[0],pucch_ack_payload[1], - frame_parms->soundingrs_ul_config_common.ackNackSRS_SimultaneousTransmission, - isShortenPucch, - pucch_resource, - Po_PUCCH, - tx_amp); - } else { - LOG_D(PHY,"[UE %d][PDSCH %x] AbsSubFrame %d.%d rx_offset_diff: %d, Generating PUCCH %s, an_srs_simultanous %d, shorten_pucch %d, n1_pucch %d, b[0]=%d,b[1]=%d (SR_Payload %d), Po_PUCCH %d, amp %d\n", - Mod_id, - ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->rnti, - frame_tx%1024, subframe_tx,ue->rx_offset_diff, - (format == pucch_format1a? "1a": ( - format == pucch_format1b? "1b" : "??")), - frame_parms->soundingrs_ul_config_common.ackNackSRS_SimultaneousTransmission, - isShortenPucch, - pucch_resource,pucch_payload[0],pucch_payload[1],SR_payload, - Po_PUCCH, - tx_amp); - } - } - - - if (LOG_DEBUGFLAG(DEBUG_UE_PHYPROC)) { - if(pucch_payload[0]) - { - T(T_UE_PHY_DLSCH_UE_ACK, T_INT(eNB_id), T_INT(frame_tx%1024), T_INT(subframe_tx), T_INT(ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->rnti), - T_INT(ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->current_harq_pid)); - } - else - { - T(T_UE_PHY_DLSCH_UE_NACK, T_INT(eNB_id), T_INT(frame_tx%1024), T_INT(subframe_tx), T_INT(ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->rnti), - T_INT(ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->current_harq_pid)); - } - } - - generate_pucch1x(ue->common_vars.txdataF, - &ue->frame_parms, - ue->ncs_cell, - format, - &ue->pucch_config_dedicated[eNB_id], - pucch_resource, - isShortenPucch, // shortened format - pucch_payload, - tx_amp, - subframe_tx); - - } - break; - - - case pucch_format2: - { + case pucch_format1: + case pucch_format1a: + case pucch_format1b: { if (ue->mac_enabled == 1) { - Po_PUCCH = pucch_power_cntl(ue,proc,subframe_tx,eNB_id,format); - } - else { - Po_PUCCH = ue->tx_power_max_dBm; + Po_PUCCH = pucch_power_cntl(ue,proc,subframe_tx,eNB_id,format); + } else { + Po_PUCCH = ue->tx_power_max_dBm; } + ue->tx_power_dBm[subframe_tx] = Po_PUCCH; ue->tx_total_RE[subframe_tx] = 12; - #if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR) - tx_amp = get_tx_amp(Po_PUCCH, - ue->tx_power_max_dBm, - ue->frame_parms.N_RB_UL, - 1); + tx_amp = get_tx_amp(Po_PUCCH, + ue->tx_power_max_dBm, + ue->frame_parms.N_RB_UL, + 1); #else tx_amp = AMP; #endif T(T_UE_PHY_PUCCH_TX_POWER, T_INT(eNB_id), T_INT(frame_tx%1024), T_INT(subframe_tx),T_INT(ue->tx_power_dBm[subframe_tx]), - T_INT(tx_amp),T_INT(ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->g_pucch),T_INT(get_PL(ue->Mod_id,ue->CC_id,eNB_id))); - if( LOG_DEBUGFLAG(DEBUG_UE_PHYPROC)) { - LOG_D(PHY,"[UE %d][RNTI %x] AbsSubFrame %d.%d Generating PUCCH 2 (RI or CQI), Po_PUCCH %d, isShortenPucch %d, amp %d\n", - Mod_id, - ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->rnti, - frame_tx%1024, subframe_tx, - Po_PUCCH, - isShortenPucch, - tx_amp); - } - generate_pucch2x(ue->common_vars.txdataF, - &ue->frame_parms, - ue->ncs_cell, - format, - &ue->pucch_config_dedicated[eNB_id], - pucch_resource, - pucch_payload, - len, // A - 0, // B2 not needed - tx_amp, - subframe_tx, - ue->pdcch_vars[ue->current_thread_id[proc->subframe_rx]][eNB_id]->crnti); - } - break; + T_INT(tx_amp),T_INT(ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->g_pucch),T_INT(get_PL(ue->Mod_id,ue->CC_id,eNB_id))); - case pucch_format2a: + if(format == pucch_format1) { + LOG_D(PHY,"[UE %d][SR %x] AbsSubframe %d.%d Generating PUCCH 1 (SR for PUSCH), an_srs_simultanous %d, shorten_pucch %d, n1_pucch %d, Po_PUCCH %d\n", + Mod_id, + ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->rnti, + frame_tx%1024, subframe_tx, + frame_parms->soundingrs_ul_config_common.ackNackSRS_SimultaneousTransmission, + isShortenPucch, + ue->scheduling_request_config[eNB_id].sr_PUCCH_ResourceIndex, + Po_PUCCH); + } else { + if (SR_payload>0) { + LOG_D(PHY,"[UE %d][SR %x] AbsSubFrame %d.%d Generating PUCCH %s payload %d,%d (with SR for PUSCH), an_srs_simultanous %d, shorten_pucch %d, n1_pucch %d, Po_PUCCH %d, amp %d\n", + Mod_id, + ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->rnti, + frame_tx % 1024, subframe_tx, + (format == pucch_format1a? "1a": ( + format == pucch_format1b? "1b" : "??")), + pucch_ack_payload[0],pucch_ack_payload[1], + frame_parms->soundingrs_ul_config_common.ackNackSRS_SimultaneousTransmission, + isShortenPucch, + pucch_resource, + Po_PUCCH, + tx_amp); + } else { + LOG_D(PHY,"[UE %d][PDSCH %x] AbsSubFrame %d.%d rx_offset_diff: %d, Generating PUCCH %s, an_srs_simultanous %d, shorten_pucch %d, n1_pucch %d, b[0]=%d,b[1]=%d (SR_Payload %d), Po_PUCCH %d, amp %d\n", + Mod_id, + ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->rnti, + frame_tx%1024, subframe_tx,ue->rx_offset_diff, + (format == pucch_format1a? "1a": ( + format == pucch_format1b? "1b" : "??")), + frame_parms->soundingrs_ul_config_common.ackNackSRS_SimultaneousTransmission, + isShortenPucch, + pucch_resource,pucch_payload[0],pucch_payload[1],SR_payload, + Po_PUCCH, + tx_amp); + } + } + + if (LOG_DEBUGFLAG(DEBUG_UE_PHYPROC)) { + if(pucch_payload[0]) { + T(T_UE_PHY_DLSCH_UE_ACK, T_INT(eNB_id), T_INT(frame_tx%1024), T_INT(subframe_tx), T_INT(ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->rnti), + T_INT(ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->current_harq_pid)); + } else { + T(T_UE_PHY_DLSCH_UE_NACK, T_INT(eNB_id), T_INT(frame_tx%1024), T_INT(subframe_tx), T_INT(ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->rnti), + T_INT(ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->current_harq_pid)); + } + } + + generate_pucch1x(ue->common_vars.txdataF, + &ue->frame_parms, + ue->ncs_cell, + format, + &ue->pucch_config_dedicated[eNB_id], + pucch_resource, + isShortenPucch, // shortened format + pucch_payload, + tx_amp, + subframe_tx); + } + break; + + case pucch_format2: { + if (ue->mac_enabled == 1) { + Po_PUCCH = pucch_power_cntl(ue,proc,subframe_tx,eNB_id,format); + } else { + Po_PUCCH = ue->tx_power_max_dBm; + } + + ue->tx_power_dBm[subframe_tx] = Po_PUCCH; + ue->tx_total_RE[subframe_tx] = 12; +#if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR) + tx_amp = get_tx_amp(Po_PUCCH, + ue->tx_power_max_dBm, + ue->frame_parms.N_RB_UL, + 1); +#else + tx_amp = AMP; +#endif + T(T_UE_PHY_PUCCH_TX_POWER, T_INT(eNB_id), T_INT(frame_tx%1024), T_INT(subframe_tx),T_INT(ue->tx_power_dBm[subframe_tx]), + T_INT(tx_amp),T_INT(ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->g_pucch),T_INT(get_PL(ue->Mod_id,ue->CC_id,eNB_id))); + + if( LOG_DEBUGFLAG(DEBUG_UE_PHYPROC)) { + LOG_D(PHY,"[UE %d][RNTI %x] AbsSubFrame %d.%d Generating PUCCH 2 (RI or CQI), Po_PUCCH %d, isShortenPucch %d, amp %d\n", + Mod_id, + ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->rnti, + frame_tx%1024, subframe_tx, + Po_PUCCH, + isShortenPucch, + tx_amp); + } + + generate_pucch2x(ue->common_vars.txdataF, + &ue->frame_parms, + ue->ncs_cell, + format, + &ue->pucch_config_dedicated[eNB_id], + pucch_resource, + pucch_payload, + len, // A + 0, // B2 not needed + tx_amp, + subframe_tx, + ue->pdcch_vars[ue->current_thread_id[proc->subframe_rx]][eNB_id]->crnti); + } + break; + + case pucch_format2a: LOG_D(PHY,"[UE %d][RNTI %x] AbsSubFrame %d.%d Generating PUCCH 2a (RI or CQI) Ack/Nack 1bit \n", - Mod_id, - ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->rnti, - frame_tx%1024, subframe_tx); + Mod_id, + ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->rnti, + frame_tx%1024, subframe_tx); break; - case pucch_format2b: + + case pucch_format2b: LOG_D(PHY,"[UE %d][RNTI %x] AbsSubFrame %d.%d Generating PUCCH 2b (RI or CQI) Ack/Nack 2bits\n", - Mod_id, - ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->rnti, - frame_tx%1024, subframe_tx); + Mod_id, + ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->rnti, + frame_tx%1024, subframe_tx); break; - default: + + default: break; } VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX_PUCCH,VCD_FUNCTION_OUT); - } void phy_procedures_UE_SL_TX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc) { - int subframe_tx = proc->subframe_tx; int frame_tx = proc->frame_tx; SLSS_t *slss; SLDCH_t *sldch; SLSCH_t *slsch; - LOG_D(PHY,"****** start Sidelink TX-Chain for AbsSubframe %d.%d ******\n", frame_tx, subframe_tx); // check for SLBCH/SLSS @@ -2329,78 +2149,61 @@ void phy_procedures_UE_SL_TX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc) { // check for SLSCH if ((slsch = ue_get_slsch(ue->Mod_id,ue->CC_id,frame_tx,subframe_tx)) != NULL) generate_slsch(ue,slsch,frame_tx,subframe_tx); - } void phy_procedures_UE_TX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t abstraction_flag,runmode_t mode) { - - LTE_DL_FRAME_PARMS *frame_parms=&ue->frame_parms; //int32_t ulsch_start=0; int subframe_tx = proc->subframe_tx; int frame_tx = proc->frame_tx; unsigned int aa; uint8_t isSubframeSRS; - uint8_t next1_thread_id = ue->current_thread_id[proc->subframe_rx]== (RX_NB_TH-1) ? 0:(ue->current_thread_id[proc->subframe_rx]+1); uint8_t next2_thread_id = next1_thread_id== (RX_NB_TH-1) ? 0:(next1_thread_id+1); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX,VCD_FUNCTION_IN); - LOG_D(PHY,"****** start TX-Chain for AbsSubframe %d.%d ******\n", frame_tx, subframe_tx); - T(T_UE_PHY_UL_TICK, T_INT(ue->Mod_id), T_INT(frame_tx%1024), T_INT(subframe_tx)); - - ue->generate_ul_signal[eNB_id] = 0; + if ( LOG_DEBUGFLAG(UE_TIMING)) { start_meas(&ue->phy_proc_tx); } ue->tx_power_dBm[subframe_tx]=-127; - for (aa=0; aanb_antennas_tx; aa++) { memset(&ue->common_vars.txdataF[aa][subframe_tx*frame_parms->ofdm_symbol_size*frame_parms->symbols_per_tti], - 0, - frame_parms->ofdm_symbol_size*frame_parms->symbols_per_tti*sizeof(int32_t)); + 0, + frame_parms->ofdm_symbol_size*frame_parms->symbols_per_tti*sizeof(int32_t)); } - + if (subframe_select(&ue->frame_parms,proc->subframe_tx) == SF_UL || - ue->frame_parms.frame_type == FDD) { + ue->frame_parms.frame_type == FDD) { if (ue->UE_mode[eNB_id] != PRACH ) { // check cell srs subframe and ue srs subframe. This has an impact on pusch encoding isSubframeSRS = is_srs_occasion_common(&ue->frame_parms,proc->frame_tx,proc->subframe_tx); - ue_compute_srs_occasion(ue,proc,eNB_id,isSubframeSRS); - ue_ulsch_uespec_procedures(ue,proc,eNB_id,abstraction_flag); - LOG_D(PHY,"ULPOWERS After ulsch_uespec_procedures : ue->tx_power_dBm[%d]=%d, NPRB %d\n", - subframe_tx,ue->tx_power_dBm[subframe_tx],ue->tx_total_RE[subframe_tx]); + subframe_tx,ue->tx_power_dBm[subframe_tx],ue->tx_total_RE[subframe_tx]); } - + if (ue->UE_mode[eNB_id] == PUSCH) { // check if we need to use PUCCH 1a/1b ue_pucch_procedures(ue,proc,eNB_id,abstraction_flag); // check if we need to use SRS ue_srs_procedures(ue,proc,eNB_id,abstraction_flag); } // UE_mode==PUSCH - } - LOG_D(PHY,"doing ulsch_common_procedures (%d.%d): generate_ul_signal %d\n",frame_tx,subframe_tx, - ue->generate_ul_signal[eNB_id]); + ue->generate_ul_signal[eNB_id]); ulsch_common_procedures(ue,proc, (ue->generate_ul_signal[eNB_id] == 0)); - - if ((ue->UE_mode[eNB_id] == PRACH) && + + if ((ue->UE_mode[eNB_id] == PRACH) && (ue->frame_parms.prach_config_common.prach_Config_enabled==1)) { - // check if we have PRACH opportunity - if (is_prach_subframe(&ue->frame_parms,frame_tx,subframe_tx)) { - ue_prach_procedures(ue,proc,eNB_id,abstraction_flag,mode); } } // mode is PRACH @@ -2410,131 +2213,113 @@ void phy_procedures_UE_TX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,ui // reset DL ACK/NACK status uint8_t N_bundled = 0; - if (ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0] != NULL) - { + + if (ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0] != NULL) { reset_ack(&ue->frame_parms, - ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->harq_ack, - subframe_tx, - proc->subframe_rx, - ue->ulsch[eNB_id]->o_ACK, - &N_bundled, - 0); + ue->dlsch[ue->current_thread_id[proc->subframe_rx]][eNB_id][0]->harq_ack, + subframe_tx, + proc->subframe_rx, + ue->ulsch[eNB_id]->o_ACK, + &N_bundled, + 0); reset_ack(&ue->frame_parms, - ue->dlsch[next1_thread_id][eNB_id][0]->harq_ack, - subframe_tx, - proc->subframe_rx, - ue->ulsch[eNB_id]->o_ACK, - &N_bundled, - 0); + ue->dlsch[next1_thread_id][eNB_id][0]->harq_ack, + subframe_tx, + proc->subframe_rx, + ue->ulsch[eNB_id]->o_ACK, + &N_bundled, + 0); reset_ack(&ue->frame_parms, - ue->dlsch[next2_thread_id][eNB_id][0]->harq_ack, - subframe_tx, - proc->subframe_rx, - ue->ulsch[eNB_id]->o_ACK, - &N_bundled, - 0); + ue->dlsch[next2_thread_id][eNB_id][0]->harq_ack, + subframe_tx, + proc->subframe_rx, + ue->ulsch[eNB_id]->o_ACK, + &N_bundled, + 0); } if (ue->dlsch_SI[eNB_id] != NULL) reset_ack(&ue->frame_parms, - ue->dlsch_SI[eNB_id]->harq_ack, - subframe_tx, - proc->subframe_rx, - ue->ulsch[eNB_id]->o_ACK, - &N_bundled, - 0); - + ue->dlsch_SI[eNB_id]->harq_ack, + subframe_tx, + proc->subframe_rx, + ue->ulsch[eNB_id]->o_ACK, + &N_bundled, + 0); LOG_D(PHY,"****** end TX-Chain for AbsSubframe %d.%d ******\n", frame_tx, subframe_tx); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_TX, VCD_FUNCTION_OUT); + if ( LOG_DEBUGFLAG(UE_TIMING)) { stop_meas(&ue->phy_proc_tx); } } -void phy_procedures_UE_S_TX(PHY_VARS_UE *ue,uint8_t eNB_id,uint8_t abstraction_flag) -{ +void phy_procedures_UE_S_TX(PHY_VARS_UE *ue,uint8_t eNB_id,uint8_t abstraction_flag) { int aa;//i,aa; LTE_DL_FRAME_PARMS *frame_parms=&ue->frame_parms; - for (aa=0; aanb_antennas_tx; aa++) { #if defined(EXMIMO) //this is the EXPRESS MIMO case int i; + // set the whole tx buffer to RX for (i=0; isamples_per_tti; i++) ue->common_vars.txdata[aa][i] = 0x00010001; - + #else //this is the normal case // memset(&ue->common_vars.txdata[aa][0],0, - // (LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*frame_parms->samples_per_tti)*sizeof(int32_t)); + // (LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*frame_parms->samples_per_tti)*sizeof(int32_t)); #endif //else EXMIMO - } - } void ue_measurement_procedures( - uint16_t l, // symbol index of each slot [0..6] - PHY_VARS_UE *ue,UE_rxtx_proc_t *proc, uint8_t eNB_id, - uint16_t slot, // slot index of each radio frame [0..19] - uint8_t abstraction_flag,runmode_t mode) -{ - + uint16_t l, // symbol index of each slot [0..6] + PHY_VARS_UE *ue,UE_rxtx_proc_t *proc, uint8_t eNB_id, + uint16_t slot, // slot index of each radio frame [0..19] + uint8_t abstraction_flag,runmode_t mode) { //LOG_I(PHY,"ue_measurement_procedures l %d Ncp %d\n",l,ue->frame_parms.Ncp); - LTE_DL_FRAME_PARMS *frame_parms=&ue->frame_parms; - int subframe_rx = proc->subframe_rx; - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_MEASUREMENT_PROCEDURES, VCD_FUNCTION_IN); if (l==0) { // UE measurements on symbol 0 - LOG_D(PHY,"Calling measurements subframe %d, rxdata %p\n",subframe_rx,ue->common_vars.rxdata); - LOG_D(PHY,"Calling measurements subframe %d, rxdata %p\n",subframe_rx,ue->common_vars.rxdata); + LOG_D(PHY,"Calling measurements subframe %d, rxdata %p\n",subframe_rx,ue->common_vars.rxdata); + lte_ue_measurements(ue, + (subframe_rx*frame_parms->samples_per_tti+ue->rx_offset)%(frame_parms->samples_per_tti*LTE_NUMBER_OF_SUBFRAMES_PER_FRAME), + (subframe_rx == 1) ? 1 : 0, + 0, + 0, + subframe_rx); - lte_ue_measurements(ue, - (subframe_rx*frame_parms->samples_per_tti+ue->rx_offset)%(frame_parms->samples_per_tti*LTE_NUMBER_OF_SUBFRAMES_PER_FRAME), - (subframe_rx == 1) ? 1 : 0, - 0, - 0, - subframe_rx); - - - if(slot == 0) - T(T_UE_PHY_MEAS, T_INT(eNB_id), T_INT(proc->frame_rx%1024), T_INT(proc->subframe_rx), - T_INT((int)(10*log10(ue->measurements.rsrp[0])-ue->rx_total_gain_dB)), - T_INT((int)ue->measurements.rx_rssi_dBm[0]), - T_INT((int)(ue->measurements.rx_power_avg_dB[0] - ue->measurements.n0_power_avg_dB)), - T_INT((int)ue->measurements.rx_power_avg_dB[0]), - T_INT((int)ue->measurements.n0_power_avg_dB), - T_INT((int)ue->measurements.wideband_cqi_avg[0]), - T_INT((int)ue->common_vars.freq_offset)); + if(slot == 0) + T(T_UE_PHY_MEAS, T_INT(eNB_id), T_INT(proc->frame_rx%1024), T_INT(proc->subframe_rx), + T_INT((int)(10*log10(ue->measurements.rsrp[0])-ue->rx_total_gain_dB)), + T_INT((int)ue->measurements.rx_rssi_dBm[0]), + T_INT((int)(ue->measurements.rx_power_avg_dB[0] - ue->measurements.n0_power_avg_dB)), + T_INT((int)ue->measurements.rx_power_avg_dB[0]), + T_INT((int)ue->measurements.n0_power_avg_dB), + T_INT((int)ue->measurements.wideband_cqi_avg[0]), + T_INT((int)ue->common_vars.freq_offset)); } if (( (slot%2) == 0) && (l==(6-ue->frame_parms.Ncp))) { - // make sure we have signal from PSS/SSS for N0 measurement - // LOG_I(PHY," l==(6-ue->frame_parms.Ncp) ue_rrc_measurements\n"); - + // LOG_I(PHY," l==(6-ue->frame_parms.Ncp) ue_rrc_measurements\n"); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_RRC_MEASUREMENTS, VCD_FUNCTION_IN); ue_rrc_measurements(ue, - slot, - abstraction_flag); + slot, + abstraction_flag); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_RRC_MEASUREMENTS, VCD_FUNCTION_OUT); - } // accumulate and filter timing offset estimation every subframe (instead of every frame) if (( (slot%2) == 0) && (l==(4-frame_parms->Ncp))) { - // AGC - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_GAIN_CONTROL, VCD_FUNCTION_IN); - #ifndef OAI_USRP #ifndef OAI_BLADERF #ifndef OAI_LMSSDR @@ -2542,20 +2327,16 @@ void ue_measurement_procedures( #endif #endif #endif - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_GAIN_CONTROL, VCD_FUNCTION_OUT); - eNB_id = 0; - if (ue->no_timing_correction==0) lte_adjust_synch(&ue->frame_parms, - ue, - eNB_id, - subframe_rx, - 0, - 16384); - + ue, + eNB_id, + subframe_rx, + 0, + 16384); } VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_MEASUREMENT_PROCEDURES, VCD_FUNCTION_OUT); @@ -2563,23 +2344,17 @@ void ue_measurement_procedures( -void ue_pbch_procedures(uint8_t eNB_id,PHY_VARS_UE *ue,UE_rxtx_proc_t *proc, uint8_t abstraction_flag) -{ - +void ue_pbch_procedures(uint8_t eNB_id,PHY_VARS_UE *ue,UE_rxtx_proc_t *proc, uint8_t abstraction_flag) { // int i; int pbch_tx_ant=0; uint8_t pbch_phase; uint16_t frame_tx; static uint8_t first_run = 1; uint8_t pbch_trials = 0; - DevAssert(ue); - int frame_rx = proc->frame_rx; int subframe_rx = proc->subframe_rx; - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_PBCH_PROCEDURES, VCD_FUNCTION_IN); - pbch_phase=(frame_rx%4); if (pbch_phase>=4) @@ -2588,15 +2363,14 @@ void ue_pbch_procedures(uint8_t eNB_id,PHY_VARS_UE *ue,UE_rxtx_proc_t *proc, uin for (pbch_trials=0; pbch_trials<4; pbch_trials++) { //for (pbch_phase=0;pbch_phase<4;pbch_phase++) { //LOG_I(PHY,"[UE %d] Frame %d, Trying PBCH %d (NidCell %d, eNB_id %d)\n",ue->Mod_id,frame_rx,pbch_phase,ue->frame_parms.Nid_cell,eNB_id); - pbch_tx_ant = rx_pbch(&ue->common_vars, - ue->pbch_vars[eNB_id], - &ue->frame_parms, - eNB_id, - ue->frame_parms.nb_antenna_ports_eNB==1?SISO:ALAMOUTI, - ue->high_speed_flag, - pbch_phase); - + ue->pbch_vars[eNB_id], + &ue->frame_parms, + eNB_id, + ue->frame_parms.nb_antenna_ports_eNB==1?SISO:ALAMOUTI, + ue->high_speed_flag, + pbch_phase); + if ((pbch_tx_ant>0) && (pbch_tx_ant<=4)) { break; } @@ -2607,19 +2381,16 @@ void ue_pbch_procedures(uint8_t eNB_id,PHY_VARS_UE *ue,UE_rxtx_proc_t *proc, uin pbch_phase=0; } - - if ((pbch_tx_ant>0) && (pbch_tx_ant<=4)) { - if (opt_enabled) { static uint8_t dummy[3]; dummy[0] = ue->pbch_vars[eNB_id]->decoded_output[2]; dummy[1] = ue->pbch_vars[eNB_id]->decoded_output[1]; dummy[2] = ue->pbch_vars[eNB_id]->decoded_output[0]; trace_pdu( DIRECTION_DOWNLINK, dummy, WS_C_RNTI, ue->Mod_id, 0, 0, - frame_rx, subframe_rx, 0, 0); + frame_rx, subframe_rx, 0, 0); LOG_D(OPT,"[UE %d][PBCH] Frame %d trace pdu for PBCH\n", - ue->Mod_id, subframe_rx); + ue->Mod_id, subframe_rx); } if (pbch_tx_ant>2) { @@ -2628,16 +2399,14 @@ void ue_pbch_procedures(uint8_t eNB_id,PHY_VARS_UE *ue,UE_rxtx_proc_t *proc, uin return; } - ue->pbch_vars[eNB_id]->pdu_errors_conseq = 0; frame_tx = (((int)(ue->pbch_vars[eNB_id]->decoded_output[2]&0x03))<<8); frame_tx += ((int)(ue->pbch_vars[eNB_id]->decoded_output[1]&0xfc)); frame_tx += pbch_phase; if (ue->mac_enabled==1) { - dl_phy_sync_success(ue->Mod_id,frame_rx,eNB_id, - ue->UE_mode[eNB_id]==NOT_SYNCHED ? 1 : 0); + ue->UE_mode[eNB_id]==NOT_SYNCHED ? 1 : 0); } // if this is the first PBCH after initial synchronization, make L1 state = PRACH @@ -2645,78 +2414,62 @@ void ue_pbch_procedures(uint8_t eNB_id,PHY_VARS_UE *ue,UE_rxtx_proc_t *proc, uin if (first_run) { first_run = 0; - proc->frame_rx = (proc->frame_rx & 0xFFFFFC00) | (frame_tx & 0x000003FF); proc->frame_tx = proc->frame_rx; - for(int th_id=0; th_idproc.proc_rxtx[th_id].frame_rx = proc->frame_rx; ue->proc.proc_rxtx[th_id].frame_tx = proc->frame_tx; - printf("[UE %d] frame %d, subframe %d: Adjusting frame counter (PBCH ant_tx=%d, frame_tx=%d, phase %d, rx_offset %d) => new frame %d\n", - ue->Mod_id, - ue->proc.proc_rxtx[th_id].frame_rx, - subframe_rx, - pbch_tx_ant, - frame_tx, - pbch_phase, - ue->rx_offset, - proc->frame_rx); + ue->Mod_id, + ue->proc.proc_rxtx[th_id].frame_rx, + subframe_rx, + pbch_tx_ant, + frame_tx, + pbch_phase, + ue->rx_offset, + proc->frame_rx); } - frame_rx = proc->frame_rx; - } else if (((frame_tx & 0x03FF) != (proc->frame_rx & 0x03FF))) { //(pbch_tx_ant != ue->frame_parms.nb_antennas_tx)) { LOG_D(PHY,"[UE %d] frame %d, subframe %d: Re-adjusting frame counter (PBCH ant_tx=%d, frame_rx=%d, frame%%1024=%d, phase %d).\n", - ue->Mod_id, - proc->frame_rx, - subframe_rx, - pbch_tx_ant, - frame_tx, - frame_rx & 0x03FF, - pbch_phase); - - + ue->Mod_id, + proc->frame_rx, + subframe_rx, + pbch_tx_ant, + frame_tx, + frame_rx & 0x03FF, + pbch_phase); proc->frame_rx = (proc->frame_rx & 0xFFFFFC00) | (frame_tx & 0x000003FF); proc->frame_tx = proc->frame_rx; frame_rx = proc->frame_rx; - - for(int th_id=0; th_idproc.proc_rxtx[th_id].frame_rx = (proc->frame_rx & 0xFFFFFC00) | (frame_tx & 0x000003FF); ue->proc.proc_rxtx[th_id].frame_tx = proc->frame_rx; } - } if (LOG_DEBUGFLAG(DEBUG_UE_PHYPROC)) { - LOG_UI(PHY,"[UE %d] frame %d, subframe %d, Received PBCH (MIB): nb_antenna_ports_eNB %d, tx_ant %d, frame_tx %d. N_RB_DL %d, phich_duration %d, phich_resource %d/6!\n", - ue->Mod_id, - frame_rx, - subframe_rx, - ue->frame_parms.nb_antenna_ports_eNB, - pbch_tx_ant, - frame_tx, - ue->frame_parms.N_RB_DL, - ue->frame_parms.phich_config_common.phich_duration, - ue->frame_parms.phich_config_common.phich_resource); + ue->Mod_id, + frame_rx, + subframe_rx, + ue->frame_parms.nb_antenna_ports_eNB, + pbch_tx_ant, + frame_tx, + ue->frame_parms.N_RB_DL, + ue->frame_parms.phich_config_common.phich_duration, + ue->frame_parms.phich_config_common.phich_resource); } - - } else { - + } else { if (LOG_DUMPFLAG(DEBUG_UE_PHYPROC)) { LOG_E(PHY,"[UE %d] frame %d, subframe %d, Error decoding PBCH!\n", - ue->Mod_id,frame_rx, subframe_rx); - + ue->Mod_id,frame_rx, subframe_rx); LOG_I(PHY,"[UE %d] rx_offset %d\n",ue->Mod_id,ue->rx_offset); - - LOG_M("rxsig0.m","rxs0", ue->common_vars.rxdata[0],ue->frame_parms.samples_per_tti,1,1); - LOG_M("PBCH_rxF0_ext.m","pbch0_ext",ue->pbch_vars[0]->rxdataF_ext[0],12*4*6,1,1); LOG_M("PBCH_rxF0_comp.m","pbch0_comp",ue->pbch_vars[0]->rxdataF_comp[0],12*4*6,1,1); LOG_M("PBCH_rxF_llr.m","pbch_llr",ue->pbch_vars[0]->llr,(ue->frame_parms.Ncp==0) ? 1920 : 1728,1,4); @@ -2728,9 +2481,8 @@ void ue_pbch_procedures(uint8_t eNB_id,PHY_VARS_UE *ue,UE_rxtx_proc_t *proc, uin if (ue->mac_enabled == 1) rrc_out_of_sync_ind(ue->Mod_id,frame_rx,eNB_id); else AssertFatal(ue->pbch_vars[eNB_id]->pdu_errors_conseq<100, - "More that 100 consecutive PBCH errors! Exiting!\n"); + "More that 100 consecutive PBCH errors! Exiting!\n"); } - if (frame_rx % 100 == 0) { ue->pbch_vars[eNB_id]->pdu_fer = ue->pbch_vars[eNB_id]->pdu_errors - ue->pbch_vars[eNB_id]->pdu_errors_last; @@ -2739,277 +2491,242 @@ void ue_pbch_procedures(uint8_t eNB_id,PHY_VARS_UE *ue,UE_rxtx_proc_t *proc, uin if (LOG_DEBUGFLAG(DEBUG_UE_PHYPROC)) { LOG_UI(PHY,"[UE %d] frame %d, slot %d, PBCH errors = %d, consecutive errors = %d!\n", - ue->Mod_id,frame_rx, subframe_rx, - ue->pbch_vars[eNB_id]->pdu_errors, - ue->pbch_vars[eNB_id]->pdu_errors_conseq); + ue->Mod_id,frame_rx, subframe_rx, + ue->pbch_vars[eNB_id]->pdu_errors, + ue->pbch_vars[eNB_id]->pdu_errors_conseq); } + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_PBCH_PROCEDURES, VCD_FUNCTION_OUT); } -int ue_pdcch_procedures(uint8_t eNB_id,PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t abstraction_flag) -{ - +int ue_pdcch_procedures(uint8_t eNB_id,PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t abstraction_flag) { unsigned int dci_cnt=0, i; - int frame_rx = proc->frame_rx; int subframe_rx = proc->subframe_rx; DCI_ALLOC_t dci_alloc_rx[8]; - uint8_t next1_thread_id = ue->current_thread_id[subframe_rx]== (RX_NB_TH-1) ? 0:(ue->current_thread_id[subframe_rx]+1); uint8_t next2_thread_id = next1_thread_id== (RX_NB_TH-1) ? 0:(next1_thread_id+1); - LOG_D(PHY,"DCI Decoding procedure in %d.%d\n",frame_rx,subframe_rx); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_PDCCH_PROCEDURES, VCD_FUNCTION_IN); + if (LOG_DEBUGFLAG(UE_TIMING)) { start_meas(&ue->dlsch_rx_pdcch_stats); } VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RX_PDCCH, VCD_FUNCTION_IN); rx_pdcch(ue, - proc->frame_rx, - subframe_rx, - eNB_id, - ue->frame_parms.nb_antenna_ports_eNB==1?SISO:ALAMOUTI, - ue->high_speed_flag); - + proc->frame_rx, + subframe_rx, + eNB_id, + ue->frame_parms.nb_antenna_ports_eNB==1?SISO:ALAMOUTI, + ue->high_speed_flag); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RX_PDCCH, VCD_FUNCTION_OUT); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DCI_DECODING, VCD_FUNCTION_IN); - - + /*printf("Decode SIB frame param aggregation + DCI %d %d, num_pdcch_symbols %d\n", - ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->agregationLevel, - ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->dciFormat, - ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->num_pdcch_symbols); + ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->agregationLevel, + ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->dciFormat, + ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->num_pdcch_symbols); */ //agregation level == FF means no configuration on - if(ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->agregationLevel == 0xFF || ue->decode_SIB) - { - // search all possible dcis - dci_cnt = dci_decoding_procedure(ue, - dci_alloc_rx, - (ue->UE_mode[eNB_id] < PUSCH)? 1 : 0, // if we're in PUSCH don't listen to common search space, - // later when we need paging or RA during connection, update this ... - eNB_id,subframe_rx); - } - else - { - // search only preconfigured dcis - // search C RNTI dci - dci_cnt = dci_CRNTI_decoding_procedure(ue, - dci_alloc_rx, - ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->dciFormat, - ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->agregationLevel, - eNB_id, - subframe_rx); - } - + if(ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->agregationLevel == 0xFF || ue->decode_SIB) { + // search all possible dcis + dci_cnt = dci_decoding_procedure(ue, + dci_alloc_rx, + (ue->UE_mode[eNB_id] < PUSCH)? 1 : 0, // if we're in PUSCH don't listen to common search space, + // later when we need paging or RA during connection, update this ... + eNB_id,subframe_rx); + } else { + // search only preconfigured dcis + // search C RNTI dci + dci_cnt = dci_CRNTI_decoding_procedure(ue, + dci_alloc_rx, + ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->dciFormat, + ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->agregationLevel, + eNB_id, + subframe_rx); + } + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DCI_DECODING, VCD_FUNCTION_OUT); //LOG_D(PHY,"[UE %d][PUSCH] Frame %d subframe %d PHICH RX\n",ue->Mod_id,frame_rx,subframe_rx); - + if (is_phich_subframe(&ue->frame_parms,subframe_rx)) { VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RX_PHICH, VCD_FUNCTION_IN); rx_phich(ue,proc, - subframe_rx,eNB_id); + subframe_rx,eNB_id); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RX_PHICH, VCD_FUNCTION_OUT); } - + uint8_t *nCCE_current = &ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->nCCE[subframe_rx]; uint8_t *nCCE_dest = &ue->pdcch_vars[next1_thread_id][eNB_id]->nCCE[subframe_rx]; uint8_t *nCCE_dest1 = &ue->pdcch_vars[next2_thread_id][eNB_id]->nCCE[subframe_rx]; memcpy(nCCE_dest, nCCE_current, sizeof(uint8_t)); memcpy(nCCE_dest1, nCCE_current, sizeof(uint8_t)); - LOG_D(PHY,"current_thread %d next1_thread %d next2_thread %d \n", ue->current_thread_id[subframe_rx], next1_thread_id, next2_thread_id); - LOG_D(PHY,"[UE %d] AbsSubFrame %d.%d, Mode %s: DCI found %i --> rnti %x / crnti %x : format %d\n", - ue->Mod_id,frame_rx%1024,subframe_rx,mode_string[ue->UE_mode[eNB_id]], - dci_cnt, - dci_alloc_rx[0].rnti, - ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->crnti, - dci_alloc_rx[0].format ); - + ue->Mod_id,frame_rx%1024,subframe_rx,mode_string[ue->UE_mode[eNB_id]], + dci_cnt, + dci_alloc_rx[0].rnti, + ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->crnti, + dci_alloc_rx[0].format ); ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->dci_received += dci_cnt; for (i=0; iUE_mode[eNB_id]>PRACH) && - (dci_alloc_rx[i].rnti == ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->crnti) && - (dci_alloc_rx[i].format != format0)) { - + (dci_alloc_rx[i].rnti == ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->crnti) && + (dci_alloc_rx[i].format != format0)) { LOG_D(PHY,"[UE %d][DCI][PDSCH %x] AbsSubframe %d.%d: format %d, num_pdcch_symbols %d, nCCE %d, total CCEs %d\n", - ue->Mod_id,dci_alloc_rx[i].rnti, - frame_rx%1024,subframe_rx, - dci_alloc_rx[i].format, - ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->num_pdcch_symbols, - ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->nCCE[subframe_rx], - get_nCCE(3,&ue->frame_parms,get_mi(&ue->frame_parms,0))); - + ue->Mod_id,dci_alloc_rx[i].rnti, + frame_rx%1024,subframe_rx, + dci_alloc_rx[i].format, + ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->num_pdcch_symbols, + ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->nCCE[subframe_rx], + get_nCCE(3,&ue->frame_parms,get_mi(&ue->frame_parms,0))); + //dump_dci(&ue->frame_parms, &dci_alloc_rx[i]); - + if ((ue->UE_mode[eNB_id] > PRACH) && - (generate_ue_dlsch_params_from_dci(frame_rx, - subframe_rx, - (void *)&dci_alloc_rx[i].dci_pdu, - ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->crnti, - dci_alloc_rx[i].format, - ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id], - ue->pdsch_vars[ue->current_thread_id[subframe_rx]][eNB_id], - ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id], - &ue->frame_parms, - ue->pdsch_config_dedicated, - SI_RNTI, - 0, - P_RNTI, - ue->transmission_mode[eNB_id]<7?0:ue->transmission_mode[eNB_id], - ue->pdcch_vars[0%RX_NB_TH][eNB_id]->crnti_is_temporary? ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->crnti: 0)==0)) { - - // update TPC for PUCCH - if((dci_alloc_rx[i].format == format1) || - (dci_alloc_rx[i].format == format1A) || - (dci_alloc_rx[i].format == format1B) || - (dci_alloc_rx[i].format == format2) || - (dci_alloc_rx[i].format == format2A) || - (dci_alloc_rx[i].format == format2B)) - { - //ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0]->g_pucch += ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0]->harq_processes[ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0]->current_harq_pid]->delta_PUCCH; - int32_t delta_pucch = ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0]->harq_processes[ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0]->current_harq_pid]->delta_PUCCH; - for(int th_id=0; th_iddlsch[th_id][eNB_id][0]->g_pucch += delta_pucch; - } - LOG_D(PHY,"update TPC for PUCCH %d.%d / pid %d delta_PUCCH %d g_pucch %d %d \n",frame_rx, subframe_rx,ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0]->current_harq_pid, - delta_pucch, - ue->dlsch[0][eNB_id][0]->g_pucch, - ue->dlsch[1][eNB_id][0]->g_pucch - //ue->dlsch[2][eNB_id][0]->g_pucch - ); + (generate_ue_dlsch_params_from_dci(frame_rx, + subframe_rx, + (void *)&dci_alloc_rx[i].dci_pdu, + ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->crnti, + dci_alloc_rx[i].format, + ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id], + ue->pdsch_vars[ue->current_thread_id[subframe_rx]][eNB_id], + ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id], + &ue->frame_parms, + ue->pdsch_config_dedicated, + SI_RNTI, + 0, + P_RNTI, + ue->transmission_mode[eNB_id]<7?0:ue->transmission_mode[eNB_id], + ue->pdcch_vars[0%RX_NB_TH][eNB_id]->crnti_is_temporary? ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->crnti: 0)==0)) { + // update TPC for PUCCH + if((dci_alloc_rx[i].format == format1) || + (dci_alloc_rx[i].format == format1A) || + (dci_alloc_rx[i].format == format1B) || + (dci_alloc_rx[i].format == format2) || + (dci_alloc_rx[i].format == format2A) || + (dci_alloc_rx[i].format == format2B)) { + //ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0]->g_pucch += ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0]->harq_processes[ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0]->current_harq_pid]->delta_PUCCH; + int32_t delta_pucch = ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0]->harq_processes[ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0]->current_harq_pid]->delta_PUCCH; + + for(int th_id=0; th_iddlsch[th_id][eNB_id][0]->g_pucch += delta_pucch; } - - ue->dlsch_received[eNB_id]++; - + + LOG_D(PHY,"update TPC for PUCCH %d.%d / pid %d delta_PUCCH %d g_pucch %d %d \n",frame_rx, subframe_rx,ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0]->current_harq_pid, + delta_pucch, + ue->dlsch[0][eNB_id][0]->g_pucch, + ue->dlsch[1][eNB_id][0]->g_pucch + //ue->dlsch[2][eNB_id][0]->g_pucch + ); + } + + ue->dlsch_received[eNB_id]++; + if ( LOG_DEBUGFLAG(DEBUG_UE_PHYPROC)) { - LOG_D(PHY,"[UE %d] Generated UE DLSCH C_RNTI format %d\n",ue->Mod_id,dci_alloc_rx[i].format); - dump_dci(&ue->frame_parms, &dci_alloc_rx[i]); - LOG_D(PHY,"[UE %d] *********** dlsch->active in subframe %d=> %d\n",ue->Mod_id,subframe_rx,ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0]->active); + LOG_D(PHY,"[UE %d] Generated UE DLSCH C_RNTI format %d\n",ue->Mod_id,dci_alloc_rx[i].format); + dump_dci(&ue->frame_parms, &dci_alloc_rx[i]); + LOG_D(PHY,"[UE %d] *********** dlsch->active in subframe %d=> %d\n",ue->Mod_id,subframe_rx,ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0]->active); } - - // we received a CRNTI, so we're in PUSCH - if (ue->UE_mode[eNB_id] != PUSCH) { + + // we received a CRNTI, so we're in PUSCH + if (ue->UE_mode[eNB_id] != PUSCH) { if (LOG_DEBUGFLAG(DEBUG_UE_PHYPROC)) { - LOG_D(PHY,"[UE %d] Frame %d, subframe %d: Received DCI with CRNTI %x => Mode PUSCH\n",ue->Mod_id,frame_rx,subframe_rx,ue->pdcch_vars[subframe_rx&1][eNB_id]->crnti); - } - - //dump_dci(&ue->frame_parms, &dci_alloc_rx[i]); - ue->UE_mode[eNB_id] = PUSCH; - } - } else { - LOG_E(PHY,"[UE %d] Frame %d, subframe %d: Problem in DCI!\n",ue->Mod_id,frame_rx,subframe_rx); - dump_dci(&ue->frame_parms, &dci_alloc_rx[i]); - } - } - - else if ((dci_alloc_rx[i].rnti == SI_RNTI) && - ((dci_alloc_rx[i].format == format1A) || (dci_alloc_rx[i].format == format1C))) { + LOG_D(PHY,"[UE %d] Frame %d, subframe %d: Received DCI with CRNTI %x => Mode PUSCH\n",ue->Mod_id,frame_rx,subframe_rx,ue->pdcch_vars[subframe_rx&1][eNB_id]->crnti); + } - - if (LOG_DEBUGFLAG(DEBUG_UE_PHYPROC)) { - LOG_D(PHY,"[UE %d] subframe %d: Found rnti %x, format 1%s, dci_cnt %d\n",ue->Mod_id,subframe_rx,dci_alloc_rx[i].rnti,dci_alloc_rx[i].format==format1A?"A":"C",i); + //dump_dci(&ue->frame_parms, &dci_alloc_rx[i]); + ue->UE_mode[eNB_id] = PUSCH; } - - if (generate_ue_dlsch_params_from_dci(frame_rx, - subframe_rx, - (void *)&dci_alloc_rx[i].dci_pdu, - SI_RNTI, - dci_alloc_rx[i].format, - ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id], - ue->pdsch_vars_SI[eNB_id], - &ue->dlsch_SI[eNB_id], - &ue->frame_parms, - ue->pdsch_config_dedicated, - SI_RNTI, - 0, - P_RNTI, - ue->transmission_mode[eNB_id]<7?0:ue->transmission_mode[eNB_id], - 0)==0) { - - ue->dlsch_SI_received[eNB_id]++; - - LOG_D(PHY,"[UE %d] Frame %d, subframe %d : Generate UE DLSCH SI_RNTI format 1%s\n",ue->Mod_id,frame_rx,subframe_rx,dci_alloc_rx[i].format==format1A?"A":"C"); - //dump_dci(&ue->frame_parms, &dci_alloc_rx[i]); - - } + } else { + LOG_E(PHY,"[UE %d] Frame %d, subframe %d: Problem in DCI!\n",ue->Mod_id,frame_rx,subframe_rx); + dump_dci(&ue->frame_parms, &dci_alloc_rx[i]); } - - else if ((dci_alloc_rx[i].rnti == P_RNTI) && - ((dci_alloc_rx[i].format == format1A) || (dci_alloc_rx[i].format == format1C))) { - + } else if ((dci_alloc_rx[i].rnti == SI_RNTI) && + ((dci_alloc_rx[i].format == format1A) || (dci_alloc_rx[i].format == format1C))) { if (LOG_DEBUGFLAG(DEBUG_UE_PHYPROC)) { LOG_D(PHY,"[UE %d] subframe %d: Found rnti %x, format 1%s, dci_cnt %d\n",ue->Mod_id,subframe_rx,dci_alloc_rx[i].rnti,dci_alloc_rx[i].format==format1A?"A":"C",i); } + if (generate_ue_dlsch_params_from_dci(frame_rx, + subframe_rx, + (void *)&dci_alloc_rx[i].dci_pdu, + SI_RNTI, + dci_alloc_rx[i].format, + ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id], + ue->pdsch_vars_SI[eNB_id], + &ue->dlsch_SI[eNB_id], + &ue->frame_parms, + ue->pdsch_config_dedicated, + SI_RNTI, + 0, + P_RNTI, + ue->transmission_mode[eNB_id]<7?0:ue->transmission_mode[eNB_id], + 0)==0) { + ue->dlsch_SI_received[eNB_id]++; + LOG_D(PHY,"[UE %d] Frame %d, subframe %d : Generate UE DLSCH SI_RNTI format 1%s\n",ue->Mod_id,frame_rx,subframe_rx,dci_alloc_rx[i].format==format1A?"A":"C"); + //dump_dci(&ue->frame_parms, &dci_alloc_rx[i]); + } + } else if ((dci_alloc_rx[i].rnti == P_RNTI) && + ((dci_alloc_rx[i].format == format1A) || (dci_alloc_rx[i].format == format1C))) { + if (LOG_DEBUGFLAG(DEBUG_UE_PHYPROC)) { + LOG_D(PHY,"[UE %d] subframe %d: Found rnti %x, format 1%s, dci_cnt %d\n",ue->Mod_id,subframe_rx,dci_alloc_rx[i].rnti,dci_alloc_rx[i].format==format1A?"A":"C",i); + } if (generate_ue_dlsch_params_from_dci(frame_rx, - subframe_rx, - (void *)&dci_alloc_rx[i].dci_pdu, - P_RNTI, - dci_alloc_rx[i].format, - ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id], - ue->pdsch_vars_p[eNB_id], - &ue->dlsch_SI[eNB_id], - &ue->frame_parms, - ue->pdsch_config_dedicated, - SI_RNTI, - 0, - P_RNTI, - ue->transmission_mode[eNB_id]<7?0:ue->transmission_mode[eNB_id], + subframe_rx, + (void *)&dci_alloc_rx[i].dci_pdu, + P_RNTI, + dci_alloc_rx[i].format, + ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id], + ue->pdsch_vars_p[eNB_id], + &ue->dlsch_SI[eNB_id], + &ue->frame_parms, + ue->pdsch_config_dedicated, + SI_RNTI, + 0, + P_RNTI, + ue->transmission_mode[eNB_id]<7?0:ue->transmission_mode[eNB_id], 0)==0) { - - ue->dlsch_p_received[eNB_id]++; - LOG_D(PHY,"[UE %d] Frame %d, subframe %d : Generate UE DLSCH P_RNTI format 1%s\n",ue->Mod_id,frame_rx,subframe_rx,dci_alloc_rx[i].format==format1A?"A":"C"); - //dump_dci(&ue->frame_parms, &dci_alloc_rx[i]); - + ue->dlsch_p_received[eNB_id]++; + LOG_D(PHY,"[UE %d] Frame %d, subframe %d : Generate UE DLSCH P_RNTI format 1%s\n",ue->Mod_id,frame_rx,subframe_rx,dci_alloc_rx[i].format==format1A?"A":"C"); + //dump_dci(&ue->frame_parms, &dci_alloc_rx[i]); } - } - - else if ((ue->prach_resources[eNB_id]) && - (dci_alloc_rx[i].rnti == ue->prach_resources[eNB_id]->ra_RNTI) && - ((dci_alloc_rx[i].format == format1A) || (dci_alloc_rx[i].format == format1C))) { - + } else if ((ue->prach_resources[eNB_id]) && + (dci_alloc_rx[i].rnti == ue->prach_resources[eNB_id]->ra_RNTI) && + ((dci_alloc_rx[i].format == format1A) || (dci_alloc_rx[i].format == format1C))) { if (LOG_DEBUGFLAG(DEBUG_UE_PHYPROC)) { LOG_D(PHY,"[UE %d][RAPROC] subframe %d: Found RA rnti %x, format 1%s, dci_cnt %d\n",ue->Mod_id,subframe_rx,dci_alloc_rx[i].rnti,dci_alloc_rx[i].format==format1A?"A":"C",i); } - if (generate_ue_dlsch_params_from_dci(frame_rx, - subframe_rx, - (void *)&dci_alloc_rx[i].dci_pdu, - ue->prach_resources[eNB_id]->ra_RNTI, - dci_alloc_rx[i].format, - ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id], - ue->pdsch_vars_ra[eNB_id], - &ue->dlsch_ra[eNB_id], - &ue->frame_parms, - ue->pdsch_config_dedicated, - SI_RNTI, - ue->prach_resources[eNB_id]->ra_RNTI, - P_RNTI, - ue->transmission_mode[eNB_id]<7?0:ue->transmission_mode[eNB_id], + subframe_rx, + (void *)&dci_alloc_rx[i].dci_pdu, + ue->prach_resources[eNB_id]->ra_RNTI, + dci_alloc_rx[i].format, + ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id], + ue->pdsch_vars_ra[eNB_id], + &ue->dlsch_ra[eNB_id], + &ue->frame_parms, + ue->pdsch_config_dedicated, + SI_RNTI, + ue->prach_resources[eNB_id]->ra_RNTI, + P_RNTI, + ue->transmission_mode[eNB_id]<7?0:ue->transmission_mode[eNB_id], 0)==0) { - - ue->dlsch_ra_received[eNB_id]++; + ue->dlsch_ra_received[eNB_id]++; - if (LOG_DEBUGFLAG(DEBUG_UE_PHYPROC)) { - LOG_D(PHY,"[UE %d] Generate UE DLSCH RA_RNTI format 1A, rb_alloc %x, dlsch_ra[eNB_id] %p\n", - ue->Mod_id,ue->dlsch_ra[eNB_id]->harq_processes[0]->rb_alloc_even[0],ue->dlsch_ra[eNB_id]); - } + if (LOG_DEBUGFLAG(DEBUG_UE_PHYPROC)) { + LOG_D(PHY,"[UE %d] Generate UE DLSCH RA_RNTI format 1A, rb_alloc %x, dlsch_ra[eNB_id] %p\n", + ue->Mod_id,ue->dlsch_ra[eNB_id]->harq_processes[0]->rb_alloc_even[0],ue->dlsch_ra[eNB_id]); + } } } else if( (dci_alloc_rx[i].rnti == ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->crnti) && - (dci_alloc_rx[i].format == format0)) { - + (dci_alloc_rx[i].format == format0)) { if (LOG_DEBUGFLAG(DEBUG_UE_PHYPROC)) { LOG_D(PHY,"[UE %d][PUSCH] Frame %d subframe %d: Found rnti %x, format 0, dci_cnt %d\n", ue->Mod_id,frame_rx,subframe_rx,dci_alloc_rx[i].rnti,i); @@ -3017,48 +2734,46 @@ int ue_pdcch_procedures(uint8_t eNB_id,PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint ue->ulsch_no_allocation_counter[eNB_id] = 0; //dump_dci(&ue->frame_parms,&dci_alloc_rx[i]); - - if ((ue->UE_mode[eNB_id] > PRACH) && - (generate_ue_ulsch_params_from_dci((void *)&dci_alloc_rx[i].dci_pdu, - ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->crnti, - subframe_rx, - format0, - ue, - proc, - SI_RNTI, - 0, - P_RNTI, - CBA_RNTI, - eNB_id, - 0)==0)) { - if (LOG_DEBUGFLAG(DEBUG_UE_PHYPROC)) { - - LOG_USEDINLOG_VAR(int8_t,harq_pid) = subframe2harq_pid(&ue->frame_parms, - pdcch_alloc2ul_frame(&ue->frame_parms,proc->frame_rx,proc->subframe_rx), - pdcch_alloc2ul_subframe(&ue->frame_parms,proc->subframe_rx)); - T(T_UE_PHY_ULSCH_UE_DCI, T_INT(eNB_id), T_INT(proc->frame_rx%1024), T_INT(proc->subframe_rx), - T_INT(dci_alloc_rx[i].rnti), - T_INT(harq_pid), - T_INT(ue->ulsch[eNB_id]->harq_processes[harq_pid]->mcs), - T_INT(ue->ulsch[eNB_id]->harq_processes[harq_pid]->round), - T_INT(ue->ulsch[eNB_id]->harq_processes[harq_pid]->first_rb), - T_INT(ue->ulsch[eNB_id]->harq_processes[harq_pid]->nb_rb), - T_INT(ue->ulsch[eNB_id]->harq_processes[harq_pid]->TBS)); - LOG_D(PHY,"[UE %d] Generate UE ULSCH C_RNTI format 0 (subframe %d)\n",ue->Mod_id,subframe_rx); - } + if ((ue->UE_mode[eNB_id] > PRACH) && + (generate_ue_ulsch_params_from_dci((void *)&dci_alloc_rx[i].dci_pdu, + ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->crnti, + subframe_rx, + format0, + ue, + proc, + SI_RNTI, + 0, + P_RNTI, + CBA_RNTI, + eNB_id, + 0)==0)) { + if (LOG_DEBUGFLAG(DEBUG_UE_PHYPROC)) { + LOG_USEDINLOG_VAR(int8_t,harq_pid) = subframe2harq_pid(&ue->frame_parms, + pdcch_alloc2ul_frame(&ue->frame_parms,proc->frame_rx,proc->subframe_rx), + pdcch_alloc2ul_subframe(&ue->frame_parms,proc->subframe_rx)); + T(T_UE_PHY_ULSCH_UE_DCI, T_INT(eNB_id), T_INT(proc->frame_rx%1024), T_INT(proc->subframe_rx), + T_INT(dci_alloc_rx[i].rnti), + T_INT(harq_pid), + T_INT(ue->ulsch[eNB_id]->harq_processes[harq_pid]->mcs), + T_INT(ue->ulsch[eNB_id]->harq_processes[harq_pid]->round), + T_INT(ue->ulsch[eNB_id]->harq_processes[harq_pid]->first_rb), + T_INT(ue->ulsch[eNB_id]->harq_processes[harq_pid]->nb_rb), + T_INT(ue->ulsch[eNB_id]->harq_processes[harq_pid]->TBS)); + LOG_D(PHY,"[UE %d] Generate UE ULSCH C_RNTI format 0 (subframe %d)\n",ue->Mod_id,subframe_rx); + } } } else if( (dci_alloc_rx[i].rnti == ue->ulsch[eNB_id]->cba_rnti[0]) && - (dci_alloc_rx[i].format == format0)) { + (dci_alloc_rx[i].format == format0)) { // UE could belong to more than one CBA group // ue->Mod_id%ue->ulsch[eNB_id]->num_active_cba_groups] if (LOG_DEBUGFLAG(DEBUG_UE_PHYPROC)) { LOG_D(PHY,"[UE %d][PUSCH] Frame %d subframe %d: Found cba rnti %x, format 0, dci_cnt %d\n", - ue->Mod_id,frame_rx,subframe_rx,dci_alloc_rx[i].rnti,i); - /* - if (((frame_rx%100) == 0) || (frame_rx < 20)) - dump_dci(&ue->frame_parms, &dci_alloc_rx[i]); - */ + ue->Mod_id,frame_rx,subframe_rx,dci_alloc_rx[i].rnti,i); + /* + if (((frame_rx%100) == 0) || (frame_rx < 20)) + dump_dci(&ue->frame_parms, &dci_alloc_rx[i]); + */ } ue->ulsch_no_allocation_counter[eNB_id] = 0; @@ -3066,47 +2781,44 @@ int ue_pdcch_procedures(uint8_t eNB_id,PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint if ((ue->UE_mode[eNB_id] > PRACH) && (generate_ue_ulsch_params_from_dci((void *)&dci_alloc_rx[i].dci_pdu, - ue->ulsch[eNB_id]->cba_rnti[0], - subframe_rx, - format0, - ue, - proc, - SI_RNTI, - 0, - P_RNTI, - CBA_RNTI, - eNB_id, - 0)==0)) { - + ue->ulsch[eNB_id]->cba_rnti[0], + subframe_rx, + format0, + ue, + proc, + SI_RNTI, + 0, + P_RNTI, + CBA_RNTI, + eNB_id, + 0)==0)) { if (LOG_DEBUGFLAG(DEBUG_UE_PHYPROC)) { LOG_D(PHY,"[UE %d] Generate UE ULSCH CBA_RNTI format 0 (subframe %d)\n",ue->Mod_id,subframe_rx); } + ue->ulsch[eNB_id]->num_cba_dci[(subframe_rx+4)%10]++; } - } - - else { + } else { if (LOG_DEBUGFLAG(DEBUG_UE_PHYPROC)) { LOG_D(PHY,"[UE %d] frame %d, subframe %d: received DCI %d with RNTI=%x (C-RNTI:%x, CBA_RNTI %x) and format %d!\n",ue->Mod_id,frame_rx,subframe_rx,i,dci_alloc_rx[i].rnti, - ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->crnti, - ue->ulsch[eNB_id]->cba_rnti[0], - dci_alloc_rx[i].format); - - // dump_dci(&ue->frame_parms, &dci_alloc_rx[i]); + ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->crnti, + ue->ulsch[eNB_id]->cba_rnti[0], + dci_alloc_rx[i].format); + // dump_dci(&ue->frame_parms, &dci_alloc_rx[i]); } } + } - } if (LOG_DEBUGFLAG(UE_TIMING)) { - stop_meas(&ue->dlsch_rx_pdcch_stats); + stop_meas(&ue->dlsch_rx_pdcch_stats); } + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_PDCCH_PROCEDURES, VCD_FUNCTION_OUT); return(0); } void ue_pmch_procedures(PHY_VARS_UE *ue, UE_rxtx_proc_t *proc,int eNB_id,int abstraction_flag) { - int subframe_rx = proc->subframe_rx; int frame_rx = proc->frame_rx; int pmch_mcs=-1; @@ -3120,19 +2832,16 @@ void ue_pmch_procedures(PHY_VARS_UE *ue, UE_rxtx_proc_t *proc,int eNB_id,int abs if (is_pmch_subframe(frame_rx,subframe_rx,&ue->frame_parms)) { // LOG_D(PHY,"ue calling pmch subframe ..\n "); - LOG_D(PHY,"[UE %d] Frame %d, subframe %d: Querying for PMCH demodulation\n", - ue->Mod_id,frame_rx,subframe_rx); + ue->Mod_id,frame_rx,subframe_rx); #if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) - pmch_mcs = ue_query_mch(ue->Mod_id, - CC_id, - frame_rx, - subframe_rx, - eNB_id, - &sync_area, - &mcch_active); - + CC_id, + frame_rx, + subframe_rx, + eNB_id, + &sync_area, + &mcch_active); #else pmch_mcs=-1; #endif @@ -3142,107 +2851,100 @@ void ue_pmch_procedures(PHY_VARS_UE *ue, UE_rxtx_proc_t *proc,int eNB_id,int abs fill_UE_dlsch_MCH(ue,pmch_mcs,1,0,0); for (l=2; l<12; l++) { - slot_fep_mbsfn(ue, - l, - subframe_rx, - 0,0);//ue->rx_offset,0); + slot_fep_mbsfn(ue, + l, + subframe_rx, + 0,0);//ue->rx_offset,0); } - + for (l=2; l<12; l++) { - rx_pmch(ue, - 0, - subframe_rx, - l); + rx_pmch(ue, + 0, + subframe_rx, + l); } - - + ue->dlsch_MCH[0]->harq_processes[0]->Qm = get_Qm(pmch_mcs); - ue->dlsch_MCH[0]->harq_processes[0]->G = get_G(&ue->frame_parms, - ue->dlsch_MCH[0]->harq_processes[0]->nb_rb, - ue->dlsch_MCH[0]->harq_processes[0]->rb_alloc_even, - ue->dlsch_MCH[0]->harq_processes[0]->Qm, - 1, - 2, - frame_rx, - subframe_rx, - 0); - + ue->dlsch_MCH[0]->harq_processes[0]->nb_rb, + ue->dlsch_MCH[0]->harq_processes[0]->rb_alloc_even, + ue->dlsch_MCH[0]->harq_processes[0]->Qm, + 1, + 2, + frame_rx, + subframe_rx, + 0); dlsch_unscrambling(&ue->frame_parms,1,ue->dlsch_MCH[0], - ue->dlsch_MCH[0]->harq_processes[0]->G, - ue->pdsch_vars_MCH[0]->llr[0],0,subframe_rx<<1); - + ue->dlsch_MCH[0]->harq_processes[0]->G, + ue->pdsch_vars_MCH[0]->llr[0],0,subframe_rx<<1); LOG_D(PHY,"start turbo decode for MCH %d.%d --> nb_rb %d \n", frame_rx, subframe_rx, ue->dlsch_MCH[0]->harq_processes[0]->nb_rb); LOG_D(PHY,"start turbo decode for MCH %d.%d --> rb_alloc_even %x \n", frame_rx, subframe_rx, (unsigned int)((intptr_t)ue->dlsch_MCH[0]->harq_processes[0]->rb_alloc_even)); LOG_D(PHY,"start turbo decode for MCH %d.%d --> Qm %d \n", frame_rx, subframe_rx, ue->dlsch_MCH[0]->harq_processes[0]->Qm); LOG_D(PHY,"start turbo decode for MCH %d.%d --> Nl %d \n", frame_rx, subframe_rx, ue->dlsch_MCH[0]->harq_processes[0]->Nl); LOG_D(PHY,"start turbo decode for MCH %d.%d --> G %d \n", frame_rx, subframe_rx, ue->dlsch_MCH[0]->harq_processes[0]->G); LOG_D(PHY,"start turbo decode for MCH %d.%d --> Kmimo %d \n", frame_rx, subframe_rx, ue->dlsch_MCH[0]->Kmimo); - ret = dlsch_decoding(ue, - ue->pdsch_vars_MCH[0]->llr[0], - &ue->frame_parms, - ue->dlsch_MCH[0], - ue->dlsch_MCH[0]->harq_processes[0], - frame_rx, - subframe_rx, - 0, - 0,1); + ue->pdsch_vars_MCH[0]->llr[0], + &ue->frame_parms, + ue->dlsch_MCH[0], + ue->dlsch_MCH[0]->harq_processes[0], + frame_rx, + subframe_rx, + 0, + 0,1); + if (mcch_active == 1) - ue->dlsch_mcch_trials[sync_area][0]++; + ue->dlsch_mcch_trials[sync_area][0]++; else - ue->dlsch_mtch_trials[sync_area][0]++; - + ue->dlsch_mtch_trials[sync_area][0]++; + if (ret == (1+ue->dlsch_MCH[0]->max_turbo_iterations)) { - if (mcch_active == 1) - ue->dlsch_mcch_errors[sync_area][0]++; - else - ue->dlsch_mtch_errors[sync_area][0]++; - - LOG_D(PHY,"[UE %d] Frame %d, subframe %d: PMCH in error (%d,%d), not passing to L2 (TBS %d, iter %d,G %d)\n", - ue->Mod_id, + if (mcch_active == 1) + ue->dlsch_mcch_errors[sync_area][0]++; + else + ue->dlsch_mtch_errors[sync_area][0]++; + + LOG_D(PHY,"[UE %d] Frame %d, subframe %d: PMCH in error (%d,%d), not passing to L2 (TBS %d, iter %d,G %d)\n", + ue->Mod_id, frame_rx,subframe_rx, - ue->dlsch_mcch_errors[sync_area][0], - ue->dlsch_mtch_errors[sync_area][0], - ue->dlsch_MCH[0]->harq_processes[0]->TBS>>3, - ue->dlsch_MCH[0]->max_turbo_iterations, - ue->dlsch_MCH[0]->harq_processes[0]->G); - // dump_mch(ue,0,ue->dlsch_MCH[0]->harq_processes[0]->G,subframe_rx); + ue->dlsch_mcch_errors[sync_area][0], + ue->dlsch_mtch_errors[sync_area][0], + ue->dlsch_MCH[0]->harq_processes[0]->TBS>>3, + ue->dlsch_MCH[0]->max_turbo_iterations, + ue->dlsch_MCH[0]->harq_processes[0]->G); + // dump_mch(ue,0,ue->dlsch_MCH[0]->harq_processes[0]->G,subframe_rx); if (LOG_DEBUGFLAG(DEBUG_UE_PHYPROC)) { - for (int i=0; idlsch_MCH[0]->harq_processes[0]->TBS>>3; i++) { - LOG_T(PHY,"%02x.",ue->dlsch_MCH[0]->harq_processes[0]->c[0][i]); - } - - LOG_T(PHY,"\n"); + LOG_T(PHY,"%02x.",ue->dlsch_MCH[0]->harq_processes[0]->c[0][i]); + } + + LOG_T(PHY,"\n"); } - - - // if (subframe_rx==9) - // mac_xface->macphy_exit("Why are we exiting here?"); + + // if (subframe_rx==9) + // mac_xface->macphy_exit("Why are we exiting here?"); } else { // decoding successful #if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) - - ue_send_mch_sdu(ue->Mod_id, - CC_id, - frame_rx, - ue->dlsch_MCH[0]->harq_processes[0]->b, - ue->dlsch_MCH[0]->harq_processes[0]->TBS>>3, - eNB_id,// not relevant in eMBMS context - sync_area); + ue_send_mch_sdu(ue->Mod_id, + CC_id, + frame_rx, + ue->dlsch_MCH[0]->harq_processes[0]->b, + ue->dlsch_MCH[0]->harq_processes[0]->TBS>>3, + eNB_id,// not relevant in eMBMS context + sync_area); - if (mcch_active == 1) - ue->dlsch_mcch_received[sync_area][0]++; - else - ue->dlsch_mtch_received[sync_area][0]++; + if (mcch_active == 1) + ue->dlsch_mcch_received[sync_area][0]++; + else + ue->dlsch_mtch_received[sync_area][0]++; - if (ue->dlsch_mch_received_sf[subframe_rx%5][0] == 1 ) { - ue->dlsch_mch_received_sf[subframe_rx%5][0]=0; - } else { - ue->dlsch_mch_received[0]+=1; - ue->dlsch_mch_received_sf[subframe_rx][0]=1; - } + if (ue->dlsch_mch_received_sf[subframe_rx%5][0] == 1 ) { + ue->dlsch_mch_received_sf[subframe_rx%5][0]=0; + } else { + ue->dlsch_mch_received[0]+=1; + ue->dlsch_mch_received_sf[subframe_rx][0]=1; + } #endif // #if (LTE_RRC_VERSION >= MAKE_VERSION(10, 0, 0)) } // decoding sucessful @@ -3250,50 +2952,47 @@ void ue_pmch_procedures(PHY_VARS_UE *ue, UE_rxtx_proc_t *proc,int eNB_id,int abs } // is_pmch_subframe=true } -void copy_harq_proc_struct(LTE_DL_UE_HARQ_t *harq_processes_dest, LTE_DL_UE_HARQ_t *current_harq_processes) -{ - harq_processes_dest->B = current_harq_processes->B ; - harq_processes_dest->C = current_harq_processes->C ; - harq_processes_dest->Cminus = current_harq_processes->Cminus ; - harq_processes_dest->Cplus = current_harq_processes->Cplus ; - harq_processes_dest->DCINdi = current_harq_processes->DCINdi ; - harq_processes_dest->F = current_harq_processes->F ; - harq_processes_dest->G = current_harq_processes->G ; - harq_processes_dest->Kminus = current_harq_processes->Kminus ; - harq_processes_dest->Kplus = current_harq_processes->Kplus ; - harq_processes_dest->Nl = current_harq_processes->Nl ; - harq_processes_dest->Qm = current_harq_processes->Qm ; - harq_processes_dest->TBS = current_harq_processes->TBS ; - harq_processes_dest->b = current_harq_processes->b ; - harq_processes_dest->codeword = current_harq_processes->codeword ; - harq_processes_dest->delta_PUCCH = current_harq_processes->delta_PUCCH ; - harq_processes_dest->dl_power_off = current_harq_processes->dl_power_off ; - harq_processes_dest->first_tx = current_harq_processes->first_tx ; - harq_processes_dest->mcs = current_harq_processes->mcs ; - harq_processes_dest->mimo_mode = current_harq_processes->mimo_mode ; - harq_processes_dest->nb_rb = current_harq_processes->nb_rb ; - harq_processes_dest->pmi_alloc = current_harq_processes->pmi_alloc ; - harq_processes_dest->rb_alloc_even[0] = current_harq_processes->rb_alloc_even[0] ; - harq_processes_dest->rb_alloc_even[1] = current_harq_processes->rb_alloc_even[1] ; - harq_processes_dest->rb_alloc_even[2] = current_harq_processes->rb_alloc_even[2] ; - harq_processes_dest->rb_alloc_even[3] = current_harq_processes->rb_alloc_even[3] ; - harq_processes_dest->rb_alloc_odd[0] = current_harq_processes->rb_alloc_odd[0] ; - harq_processes_dest->rb_alloc_odd[1] = current_harq_processes->rb_alloc_odd[1] ; - harq_processes_dest->rb_alloc_odd[2] = current_harq_processes->rb_alloc_odd[2] ; - harq_processes_dest->rb_alloc_odd[3] = current_harq_processes->rb_alloc_odd[3] ; - harq_processes_dest->round = current_harq_processes->round ; - harq_processes_dest->rvidx = current_harq_processes->rvidx ; - harq_processes_dest->status = current_harq_processes->status ; - harq_processes_dest->vrb_type = current_harq_processes->vrb_type ; +void copy_harq_proc_struct(LTE_DL_UE_HARQ_t *harq_processes_dest, LTE_DL_UE_HARQ_t *current_harq_processes) { + harq_processes_dest->B = current_harq_processes->B ; + harq_processes_dest->C = current_harq_processes->C ; + harq_processes_dest->Cminus = current_harq_processes->Cminus ; + harq_processes_dest->Cplus = current_harq_processes->Cplus ; + harq_processes_dest->DCINdi = current_harq_processes->DCINdi ; + harq_processes_dest->F = current_harq_processes->F ; + harq_processes_dest->G = current_harq_processes->G ; + harq_processes_dest->Kminus = current_harq_processes->Kminus ; + harq_processes_dest->Kplus = current_harq_processes->Kplus ; + harq_processes_dest->Nl = current_harq_processes->Nl ; + harq_processes_dest->Qm = current_harq_processes->Qm ; + harq_processes_dest->TBS = current_harq_processes->TBS ; + harq_processes_dest->b = current_harq_processes->b ; + harq_processes_dest->codeword = current_harq_processes->codeword ; + harq_processes_dest->delta_PUCCH = current_harq_processes->delta_PUCCH ; + harq_processes_dest->dl_power_off = current_harq_processes->dl_power_off ; + harq_processes_dest->first_tx = current_harq_processes->first_tx ; + harq_processes_dest->mcs = current_harq_processes->mcs ; + harq_processes_dest->mimo_mode = current_harq_processes->mimo_mode ; + harq_processes_dest->nb_rb = current_harq_processes->nb_rb ; + harq_processes_dest->pmi_alloc = current_harq_processes->pmi_alloc ; + harq_processes_dest->rb_alloc_even[0] = current_harq_processes->rb_alloc_even[0] ; + harq_processes_dest->rb_alloc_even[1] = current_harq_processes->rb_alloc_even[1] ; + harq_processes_dest->rb_alloc_even[2] = current_harq_processes->rb_alloc_even[2] ; + harq_processes_dest->rb_alloc_even[3] = current_harq_processes->rb_alloc_even[3] ; + harq_processes_dest->rb_alloc_odd[0] = current_harq_processes->rb_alloc_odd[0] ; + harq_processes_dest->rb_alloc_odd[1] = current_harq_processes->rb_alloc_odd[1] ; + harq_processes_dest->rb_alloc_odd[2] = current_harq_processes->rb_alloc_odd[2] ; + harq_processes_dest->rb_alloc_odd[3] = current_harq_processes->rb_alloc_odd[3] ; + harq_processes_dest->round = current_harq_processes->round ; + harq_processes_dest->rvidx = current_harq_processes->rvidx ; + harq_processes_dest->status = current_harq_processes->status ; + harq_processes_dest->vrb_type = current_harq_processes->vrb_type ; } -void copy_ack_struct(harq_status_t *harq_ack_dest, harq_status_t *current_harq_ack) -{ - memcpy(harq_ack_dest, current_harq_ack, sizeof(harq_status_t)); +void copy_ack_struct(harq_status_t *harq_ack_dest, harq_status_t *current_harq_ack) { + memcpy(harq_ack_dest, current_harq_ack, sizeof(harq_status_t)); } void ue_pdsch_procedures(PHY_VARS_UE *ue, UE_rxtx_proc_t *proc, int eNB_id, PDSCH_t pdsch, LTE_UE_DLSCH_t *dlsch0, LTE_UE_DLSCH_t *dlsch1, int s0, int s1, int abstraction_flag) { - int subframe_rx = proc->subframe_rx; int m; int harq_pid; @@ -3303,8 +3002,7 @@ void ue_pdsch_procedures(PHY_VARS_UE *ue, UE_rxtx_proc_t *proc, int eNB_id, PDSC if (dlsch0->active == 0) return; - for (m=s0;m<=s1;m++) { - + for (m=s0; m<=s1; m++) { if (dlsch0 && (!dlsch1)) { harq_pid = dlsch0->current_harq_pid; LOG_D(PHY,"[UE %d] PDSCH active in subframe %d, harq_pid %d Symbol %d\n",ue->Mod_id,subframe_rx,harq_pid,m); @@ -3316,15 +3014,11 @@ void ue_pdsch_procedures(PHY_VARS_UE *ue, UE_rxtx_proc_t *proc, int eNB_id, PDSC dual_stream_UE = 1; eNB_id_i = ue->n_connected_eNB; i_mod = dlsch0->harq_processes[harq_pid]->Qm; - - } - else if((pdsch==PDSCH) && (ue->transmission_mode[eNB_id]==3)) - { - dual_stream_UE = rx_IC_dual_stream; - eNB_id_i = eNB_id; - i_mod = 0; - } - else { + } else if((pdsch==PDSCH) && (ue->transmission_mode[eNB_id]==3)) { + dual_stream_UE = rx_IC_dual_stream; + eNB_id_i = eNB_id; + i_mod = 0; + } else { dual_stream_UE = 0; eNB_id_i = eNB_id+1; i_mod = 0; @@ -3342,48 +3036,50 @@ void ue_pdsch_procedures(PHY_VARS_UE *ue, UE_rxtx_proc_t *proc, int eNB_id, PDSC } if ((m==s0) && (m<4)) - first_symbol_flag = 1; + first_symbol_flag = 1; else - first_symbol_flag = 0; + first_symbol_flag = 0; if (LOG_DEBUGFLAG(UE_TIMING)) { uint8_t slot = 0; + if(m >= ue->frame_parms.symbols_per_tti>>1) - slot = 1; + slot = 1; + start_meas(&ue->dlsch_llr_stats_parallelization[ue->current_thread_id[subframe_rx]][slot]); } + // process DLSCH received in first slot rx_pdsch(ue, - pdsch, - eNB_id, - eNB_id_i, - proc->frame_rx, - subframe_rx, // subframe, - m, - first_symbol_flag, - dual_stream_UE, - i_mod, - dlsch0->current_harq_pid); + pdsch, + eNB_id, + eNB_id_i, + proc->frame_rx, + subframe_rx, // subframe, + m, + first_symbol_flag, + dual_stream_UE, + i_mod, + dlsch0->current_harq_pid); + if (LOG_DEBUGFLAG(UE_TIMING)) { - uint8_t slot = 0; - if(m >= ue->frame_parms.symbols_per_tti>>1) - slot = 1; - stop_meas(&ue->dlsch_llr_stats_parallelization[ue->current_thread_id[subframe_rx]][slot]); - LOG_I(PHY, "[AbsSFN %d.%d] LLR Computation Symbol %d %5.2f \n",proc->frame_rx,subframe_rx,m,ue->dlsch_llr_stats_parallelization[ue->current_thread_id[subframe_rx]][slot].p_time/(cpuf*1000.0)); + uint8_t slot = 0; + + if(m >= ue->frame_parms.symbols_per_tti>>1) + slot = 1; + + stop_meas(&ue->dlsch_llr_stats_parallelization[ue->current_thread_id[subframe_rx]][slot]); + LOG_I(PHY, "[AbsSFN %d.%d] LLR Computation Symbol %d %5.2f \n",proc->frame_rx,subframe_rx,m,ue->dlsch_llr_stats_parallelization[ue->current_thread_id[subframe_rx]][slot].p_time/(cpuf*1000.0)); } - - - if(first_symbol_flag) - { - proc->first_symbol_available = 1; + if(first_symbol_flag) { + proc->first_symbol_available = 1; } } // CRNTI active } } void process_rar(PHY_VARS_UE *ue, UE_rxtx_proc_t *proc, int eNB_id, runmode_t mode, int abstraction_flag) { - int frame_rx = proc->frame_rx; int subframe_rx = proc->subframe_rx; int timing_advance; @@ -3392,99 +3088,85 @@ void process_rar(PHY_VARS_UE *ue, UE_rxtx_proc_t *proc, int eNB_id, runmode_t mo uint8_t *rar; uint8_t next1_thread_id = ue->current_thread_id[subframe_rx]== (RX_NB_TH-1) ? 0:(ue->current_thread_id[subframe_rx]+1); uint8_t next2_thread_id = next1_thread_id== (RX_NB_TH-1) ? 0:(next1_thread_id+1); - LOG_D(PHY,"[UE %d][RAPROC] Frame %d subframe %d Received RAR mode %d\n", - ue->Mod_id, - frame_rx, - subframe_rx, ue->UE_mode[eNB_id]); - + ue->Mod_id, + frame_rx, + subframe_rx, ue->UE_mode[eNB_id]); if (ue->mac_enabled == 1) { if ((ue->UE_mode[eNB_id] != PUSCH) && - (ue->prach_resources[eNB_id]->Msg3!=NULL)) { + (ue->prach_resources[eNB_id]->Msg3!=NULL)) { LOG_D(PHY,"[UE %d][RAPROC] Frame %d subframe %d Invoking MAC for RAR (current preamble %d)\n", - ue->Mod_id,frame_rx, - subframe_rx, - ue->prach_resources[eNB_id]->ra_PreambleIndex); - + ue->Mod_id,frame_rx, + subframe_rx, + ue->prach_resources[eNB_id]->ra_PreambleIndex); timing_advance = ue_process_rar(ue->Mod_id, - ue->CC_id, - frame_rx, - ue->prach_resources[eNB_id]->ra_RNTI, - dlsch0->harq_processes[0]->b, - &ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->crnti, - ue->prach_resources[eNB_id]->ra_PreambleIndex, - dlsch0->harq_processes[0]->b); // alter the 'b' buffer so it contains only the selected RAR header and RAR payload - + ue->CC_id, + frame_rx, + ue->prach_resources[eNB_id]->ra_RNTI, + dlsch0->harq_processes[0]->b, + &ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->crnti, + ue->prach_resources[eNB_id]->ra_PreambleIndex, + dlsch0->harq_processes[0]->b); // alter the 'b' buffer so it contains only the selected RAR header and RAR payload ue->pdcch_vars[next1_thread_id][eNB_id]->crnti = ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->crnti; ue->pdcch_vars[next2_thread_id][eNB_id]->crnti = ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->crnti; - if (timing_advance!=0xffff) { - - LOG_D(PHY,"[UE %d][RAPROC] Frame %d subframe %d Got rnti %x and timing advance %d from RAR\n", + LOG_D(PHY,"[UE %d][RAPROC] Frame %d subframe %d Got rnti %x and timing advance %d from RAR\n", ue->Mod_id, frame_rx, subframe_rx, ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->crnti, timing_advance); + // remember this c-rnti is still a tc-rnti + ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->crnti_is_temporary = 1; + //timing_advance = 0; + process_timing_advance_rar(ue,proc,timing_advance); - // remember this c-rnti is still a tc-rnti - - ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->crnti_is_temporary = 1; - - //timing_advance = 0; - process_timing_advance_rar(ue,proc,timing_advance); - - if (mode!=debug_prach) { - ue->ulsch_Msg3_active[eNB_id]=1; - get_Msg3_alloc(&ue->frame_parms, - subframe_rx, - frame_rx, - &ue->ulsch_Msg3_frame[eNB_id], - &ue->ulsch_Msg3_subframe[eNB_id]); - - LOG_D(PHY,"[UE %d][RAPROC] Got Msg3_alloc Frame %d subframe %d: Msg3_frame %d, Msg3_subframe %d\n", - ue->Mod_id, - frame_rx, - subframe_rx, - ue->ulsch_Msg3_frame[eNB_id], - ue->ulsch_Msg3_subframe[eNB_id]); - harq_pid = subframe2harq_pid(&ue->frame_parms, - ue->ulsch_Msg3_frame[eNB_id], - ue->ulsch_Msg3_subframe[eNB_id]); - ue->ulsch[eNB_id]->harq_processes[harq_pid]->round = 0; - - ue->UE_mode[eNB_id] = RA_RESPONSE; - // ue->Msg3_timer[eNB_id] = 10; - ue->ulsch[eNB_id]->power_offset = 6; - ue->ulsch_no_allocation_counter[eNB_id] = 0; - } + if (mode!=debug_prach) { + ue->ulsch_Msg3_active[eNB_id]=1; + get_Msg3_alloc(&ue->frame_parms, + subframe_rx, + frame_rx, + &ue->ulsch_Msg3_frame[eNB_id], + &ue->ulsch_Msg3_subframe[eNB_id]); + LOG_D(PHY,"[UE %d][RAPROC] Got Msg3_alloc Frame %d subframe %d: Msg3_frame %d, Msg3_subframe %d\n", + ue->Mod_id, + frame_rx, + subframe_rx, + ue->ulsch_Msg3_frame[eNB_id], + ue->ulsch_Msg3_subframe[eNB_id]); + harq_pid = subframe2harq_pid(&ue->frame_parms, + ue->ulsch_Msg3_frame[eNB_id], + ue->ulsch_Msg3_subframe[eNB_id]); + ue->ulsch[eNB_id]->harq_processes[harq_pid]->round = 0; + ue->UE_mode[eNB_id] = RA_RESPONSE; + // ue->Msg3_timer[eNB_id] = 10; + ue->ulsch[eNB_id]->power_offset = 6; + ue->ulsch_no_allocation_counter[eNB_id] = 0; + } } else { // PRACH preamble doesn't match RAR - LOG_W(PHY,"[UE %d][RAPROC] Received RAR preamble (%d) doesn't match !!!\n", - ue->Mod_id, - ue->prach_resources[eNB_id]->ra_PreambleIndex); + LOG_W(PHY,"[UE %d][RAPROC] Received RAR preamble (%d) doesn't match !!!\n", + ue->Mod_id, + ue->prach_resources[eNB_id]->ra_PreambleIndex); } } // mode != PUSCH - } - else { + } else { rar = dlsch0->harq_processes[0]->b+1; timing_advance = ((((uint16_t)(rar[0]&0x7f))<<4) + (rar[1]>>4)); process_timing_advance_rar(ue,proc,timing_advance); } - } void ue_dlsch_procedures(PHY_VARS_UE *ue, - UE_rxtx_proc_t *proc, - int eNB_id, - PDSCH_t pdsch, - LTE_UE_DLSCH_t *dlsch0, - LTE_UE_DLSCH_t *dlsch1, - int *dlsch_errors, - runmode_t mode, - int abstraction_flag) { - + UE_rxtx_proc_t *proc, + int eNB_id, + PDSCH_t pdsch, + LTE_UE_DLSCH_t *dlsch0, + LTE_UE_DLSCH_t *dlsch1, + int *dlsch_errors, + runmode_t mode, + int abstraction_flag) { int harq_pid; int frame_rx = proc->frame_rx; int subframe_rx = proc->subframe_rx; @@ -3495,7 +3177,7 @@ void ue_dlsch_procedures(PHY_VARS_UE *ue, uint8_t is_cw1_active = 0; if (dlsch0==NULL) - AssertFatal(0,"dlsch0 should be defined at this level \n"); + AssertFatal(0,"dlsch0 should be defined at this level \n"); harq_pid = dlsch0->current_harq_pid; is_cw0_active = dlsch0->harq_processes[harq_pid]->status; @@ -3506,329 +3188,332 @@ void ue_dlsch_procedures(PHY_VARS_UE *ue, LOG_D(PHY,"AbsSubframe %d.%d Start Turbo Decoder for CW0 [harq_pid %d] ? %d \n", frame_rx%1024, subframe_rx, harq_pid, is_cw0_active); LOG_D(PHY,"AbsSubframe %d.%d Start Turbo Decoder for CW1 [harq_pid %d] ? %d \n", frame_rx%1024, subframe_rx, harq_pid, is_cw1_active); - if(is_cw0_active && is_cw1_active) - { - dlsch0->Kmimo = 2; - dlsch1->Kmimo = 2; - } - else - { - dlsch0->Kmimo = 1; + if(is_cw0_active && is_cw1_active) { + dlsch0->Kmimo = 2; + dlsch1->Kmimo = 2; + } else { + dlsch0->Kmimo = 1; } + if (1) { switch (pdsch) { - case SI_PDSCH: - pdsch_vars = ue->pdsch_vars_SI[eNB_id]; - break; - case RA_PDSCH: - pdsch_vars = ue->pdsch_vars_ra[eNB_id]; - break; - case P_PDSCH: - pdsch_vars = ue->pdsch_vars_p[eNB_id]; - break; - case PDSCH: - pdsch_vars = ue->pdsch_vars[ue->current_thread_id[subframe_rx]][eNB_id]; - break; - case PMCH: - case PDSCH1: - LOG_E(PHY,"Illegal PDSCH %d for ue_pdsch_procedures\n",pdsch); - pdsch_vars = NULL; - return; - break; - default: - pdsch_vars = NULL; - return; - break; + case SI_PDSCH: + pdsch_vars = ue->pdsch_vars_SI[eNB_id]; + break; + case RA_PDSCH: + pdsch_vars = ue->pdsch_vars_ra[eNB_id]; + break; + + case P_PDSCH: + pdsch_vars = ue->pdsch_vars_p[eNB_id]; + break; + + case PDSCH: + pdsch_vars = ue->pdsch_vars[ue->current_thread_id[subframe_rx]][eNB_id]; + break; + + case PMCH: + case PDSCH1: + LOG_E(PHY,"Illegal PDSCH %d for ue_pdsch_procedures\n",pdsch); + pdsch_vars = NULL; + return; + break; + + default: + pdsch_vars = NULL; + return; + break; } + if (frame_rx < *dlsch_errors) *dlsch_errors=0; if (pdsch==RA_PDSCH) { - if (ue->prach_resources[eNB_id]!=NULL) - dlsch0->rnti = ue->prach_resources[eNB_id]->ra_RNTI; + dlsch0->rnti = ue->prach_resources[eNB_id]->ra_RNTI; else { - LOG_E(PHY,"[UE %d] Frame %d, subframe %d: FATAL, prach_resources is NULL\n",ue->Mod_id,frame_rx,subframe_rx); - AssertFatal(1==0,"prach_resources is NULL"); + LOG_E(PHY,"[UE %d] Frame %d, subframe %d: FATAL, prach_resources is NULL\n",ue->Mod_id,frame_rx,subframe_rx); + AssertFatal(1==0,"prach_resources is NULL"); } } - - - // start turbo decode for CW 0 - dlsch0->harq_processes[harq_pid]->G = get_G(&ue->frame_parms, - dlsch0->harq_processes[harq_pid]->nb_rb, - dlsch0->harq_processes[harq_pid]->rb_alloc_even, - dlsch0->harq_processes[harq_pid]->Qm, - dlsch0->harq_processes[harq_pid]->Nl, - ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->num_pdcch_symbols, - frame_rx, - subframe_rx, - ue->transmission_mode[eNB_id]<7?0:ue->transmission_mode[eNB_id]); + + // start turbo decode for CW 0 + dlsch0->harq_processes[harq_pid]->G = get_G(&ue->frame_parms, + dlsch0->harq_processes[harq_pid]->nb_rb, + dlsch0->harq_processes[harq_pid]->rb_alloc_even, + dlsch0->harq_processes[harq_pid]->Qm, + dlsch0->harq_processes[harq_pid]->Nl, + ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->num_pdcch_symbols, + frame_rx, + subframe_rx, + ue->transmission_mode[eNB_id]<7?0:ue->transmission_mode[eNB_id]); + + if (LOG_DEBUGFLAG(UE_TIMING)) { + start_meas(&ue->dlsch_unscrambling_stats); + } + + dlsch_unscrambling(&ue->frame_parms, + 0, + dlsch0, + dlsch0->harq_processes[harq_pid]->G, + pdsch_vars->llr[0], + 0, + subframe_rx<<1); + + if (LOG_DEBUGFLAG(UE_TIMING)) { + stop_meas(&ue->dlsch_unscrambling_stats); + } + + LOG_D(PHY," ------ start turbo decoder for AbsSubframe %d.%d / %d ------ \n", frame_rx, subframe_rx, harq_pid); + LOG_D(PHY,"start turbo decode for CW 0 for AbsSubframe %d.%d / %d --> nb_rb %d \n", frame_rx, subframe_rx, harq_pid, dlsch0->harq_processes[harq_pid]->nb_rb); + LOG_D(PHY,"start turbo decode for CW 0 for AbsSubframe %d.%d / %d --> rb_alloc_even %x \n", frame_rx, subframe_rx, harq_pid, + (unsigned int)((intptr_t)dlsch0->harq_processes[harq_pid]->rb_alloc_even)); + LOG_D(PHY,"start turbo decode for CW 0 for AbsSubframe %d.%d / %d --> Qm %d \n", frame_rx, subframe_rx, harq_pid, dlsch0->harq_processes[harq_pid]->Qm); + LOG_D(PHY,"start turbo decode for CW 0 for AbsSubframe %d.%d / %d --> Nl %d \n", frame_rx, subframe_rx, harq_pid, dlsch0->harq_processes[harq_pid]->Nl); + LOG_D(PHY,"start turbo decode for CW 0 for AbsSubframe %d.%d / %d --> G %d \n", frame_rx, subframe_rx, harq_pid, dlsch0->harq_processes[harq_pid]->G); + LOG_D(PHY,"start turbo decode for CW 0 for AbsSubframe %d.%d / %d --> Kmimo %d \n", frame_rx, subframe_rx, harq_pid, dlsch0->Kmimo); + LOG_D(PHY,"start turbo decode for CW 0 for AbsSubframe %d.%d / %d --> Pdcch Sym %d \n", frame_rx, subframe_rx, harq_pid, + ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->num_pdcch_symbols); + + if (LOG_DEBUGFLAG(UE_TIMING)) { + start_meas(&ue->dlsch_decoding_stats[ue->current_thread_id[subframe_rx]]); + } + + ret = dlsch_decoding(ue, + pdsch_vars->llr[0], + &ue->frame_parms, + dlsch0, + dlsch0->harq_processes[harq_pid], + frame_rx, + subframe_rx, + harq_pid, + pdsch==PDSCH?1:0, + dlsch0->harq_processes[harq_pid]->TBS>256?1:0); + + if (LOG_DEBUGFLAG(UE_TIMING)) { + stop_meas(&ue->dlsch_decoding_stats[ue->current_thread_id[subframe_rx]]); + LOG_I(PHY, " --> Unscrambling for CW0 %5.3f\n", + (ue->dlsch_unscrambling_stats.p_time)/(cpuf*1000.0)); + LOG_I(PHY, "AbsSubframe %d.%d --> Turbo Decoding for CW0 %5.3f\n", + frame_rx%1024, subframe_rx,(ue->dlsch_decoding_stats[ue->current_thread_id[subframe_rx]].p_time)/(cpuf*1000.0)); + } + + if(is_cw1_active) { + // start turbo decode for CW 1 + dlsch1->harq_processes[harq_pid]->G = get_G(&ue->frame_parms, + dlsch1->harq_processes[harq_pid]->nb_rb, + dlsch1->harq_processes[harq_pid]->rb_alloc_even, + dlsch1->harq_processes[harq_pid]->Qm, + dlsch1->harq_processes[harq_pid]->Nl, + ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->num_pdcch_symbols, + frame_rx, + subframe_rx, + ue->transmission_mode[eNB_id]<7?0:ue->transmission_mode[eNB_id]); + if (LOG_DEBUGFLAG(UE_TIMING)) { start_meas(&ue->dlsch_unscrambling_stats); } + dlsch_unscrambling(&ue->frame_parms, - 0, - dlsch0, - dlsch0->harq_processes[harq_pid]->G, - pdsch_vars->llr[0], - 0, - subframe_rx<<1); + 0, + dlsch1, + dlsch1->harq_processes[harq_pid]->G, + pdsch_vars->llr[1], + 1, + subframe_rx<<1); + if (LOG_DEBUGFLAG(UE_TIMING)) { stop_meas(&ue->dlsch_unscrambling_stats); } - - LOG_D(PHY," ------ start turbo decoder for AbsSubframe %d.%d / %d ------ \n", frame_rx, subframe_rx, harq_pid); - LOG_D(PHY,"start turbo decode for CW 0 for AbsSubframe %d.%d / %d --> nb_rb %d \n", frame_rx, subframe_rx, harq_pid, dlsch0->harq_processes[harq_pid]->nb_rb); - LOG_D(PHY,"start turbo decode for CW 0 for AbsSubframe %d.%d / %d --> rb_alloc_even %x \n", frame_rx, subframe_rx, harq_pid, (unsigned int)((intptr_t)dlsch0->harq_processes[harq_pid]->rb_alloc_even)); - LOG_D(PHY,"start turbo decode for CW 0 for AbsSubframe %d.%d / %d --> Qm %d \n", frame_rx, subframe_rx, harq_pid, dlsch0->harq_processes[harq_pid]->Qm); - LOG_D(PHY,"start turbo decode for CW 0 for AbsSubframe %d.%d / %d --> Nl %d \n", frame_rx, subframe_rx, harq_pid, dlsch0->harq_processes[harq_pid]->Nl); - LOG_D(PHY,"start turbo decode for CW 0 for AbsSubframe %d.%d / %d --> G %d \n", frame_rx, subframe_rx, harq_pid, dlsch0->harq_processes[harq_pid]->G); - LOG_D(PHY,"start turbo decode for CW 0 for AbsSubframe %d.%d / %d --> Kmimo %d \n", frame_rx, subframe_rx, harq_pid, dlsch0->Kmimo); - LOG_D(PHY,"start turbo decode for CW 0 for AbsSubframe %d.%d / %d --> Pdcch Sym %d \n", frame_rx, subframe_rx, harq_pid, ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->num_pdcch_symbols); - + + LOG_D(PHY,"start turbo decode for CW 1 for AbsSubframe %d.%d / %d --> nb_rb %d \n", frame_rx, subframe_rx, harq_pid, dlsch1->harq_processes[harq_pid]->nb_rb); + LOG_D(PHY,"start turbo decode for CW 1 for AbsSubframe %d.%d / %d --> rb_alloc_even %x \n", frame_rx, subframe_rx, harq_pid, (uint16_t)((intptr_t)dlsch1->harq_processes[harq_pid]->rb_alloc_even)); + LOG_D(PHY,"start turbo decode for CW 1 for AbsSubframe %d.%d / %d --> Qm %d \n", frame_rx, subframe_rx, harq_pid, dlsch1->harq_processes[harq_pid]->Qm); + LOG_D(PHY,"start turbo decode for CW 1 for AbsSubframe %d.%d / %d --> Nl %d \n", frame_rx, subframe_rx, harq_pid, dlsch1->harq_processes[harq_pid]->Nl); + LOG_D(PHY,"start turbo decode for CW 1 for AbsSubframe %d.%d / %d --> G %d \n", frame_rx, subframe_rx, harq_pid, dlsch1->harq_processes[harq_pid]->G); + LOG_D(PHY,"start turbo decode for CW 1 for AbsSubframe %d.%d / %d --> Kmimo %d \n", frame_rx, subframe_rx, harq_pid, dlsch1->Kmimo); + LOG_D(PHY,"start turbo decode for CW 1 for AbsSubframe %d.%d / %d --> Pdcch Sym %d \n", frame_rx, subframe_rx, harq_pid, + ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->num_pdcch_symbols); + if (LOG_DEBUGFLAG(UE_TIMING)) { start_meas(&ue->dlsch_decoding_stats[ue->current_thread_id[subframe_rx]]); } - ret = dlsch_decoding(ue, - pdsch_vars->llr[0], - &ue->frame_parms, - dlsch0, - dlsch0->harq_processes[harq_pid], - frame_rx, - subframe_rx, - harq_pid, - pdsch==PDSCH?1:0, - dlsch0->harq_processes[harq_pid]->TBS>256?1:0); - + + ret1 = dlsch_decoding(ue, + pdsch_vars->llr[1], + &ue->frame_parms, + dlsch1, + dlsch1->harq_processes[harq_pid], + frame_rx, + subframe_rx, + harq_pid, + pdsch==PDSCH?1:0, + dlsch1->harq_processes[harq_pid]->TBS>256?1:0); + if (LOG_DEBUGFLAG(UE_TIMING)) { stop_meas(&ue->dlsch_decoding_stats[ue->current_thread_id[subframe_rx]]); - LOG_I(PHY, " --> Unscrambling for CW0 %5.3f\n", - (ue->dlsch_unscrambling_stats.p_time)/(cpuf*1000.0)); - LOG_I(PHY, "AbsSubframe %d.%d --> Turbo Decoding for CW0 %5.3f\n", - frame_rx%1024, subframe_rx,(ue->dlsch_decoding_stats[ue->current_thread_id[subframe_rx]].p_time)/(cpuf*1000.0)); - + LOG_I(PHY, " --> Unscrambling for CW1 %5.3f\n", + (ue->dlsch_unscrambling_stats.p_time)/(cpuf*1000.0)); + LOG_I(PHY, "AbsSubframe %d.%d --> Turbo Decoding for CW1 %5.3f\n", + frame_rx%1024, subframe_rx,(ue->dlsch_decoding_stats[ue->current_thread_id[subframe_rx]].p_time)/(cpuf*1000.0)); } - if(is_cw1_active) - { - // start turbo decode for CW 1 - dlsch1->harq_processes[harq_pid]->G = get_G(&ue->frame_parms, - dlsch1->harq_processes[harq_pid]->nb_rb, - dlsch1->harq_processes[harq_pid]->rb_alloc_even, - dlsch1->harq_processes[harq_pid]->Qm, - dlsch1->harq_processes[harq_pid]->Nl, - ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->num_pdcch_symbols, - frame_rx, - subframe_rx, - ue->transmission_mode[eNB_id]<7?0:ue->transmission_mode[eNB_id]); - if (LOG_DEBUGFLAG(UE_TIMING)) { - start_meas(&ue->dlsch_unscrambling_stats); - } - dlsch_unscrambling(&ue->frame_parms, - 0, - dlsch1, - dlsch1->harq_processes[harq_pid]->G, - pdsch_vars->llr[1], - 1, - subframe_rx<<1); - if (LOG_DEBUGFLAG(UE_TIMING)) { - stop_meas(&ue->dlsch_unscrambling_stats); - } - - LOG_D(PHY,"start turbo decode for CW 1 for AbsSubframe %d.%d / %d --> nb_rb %d \n", frame_rx, subframe_rx, harq_pid, dlsch1->harq_processes[harq_pid]->nb_rb); - LOG_D(PHY,"start turbo decode for CW 1 for AbsSubframe %d.%d / %d --> rb_alloc_even %x \n", frame_rx, subframe_rx, harq_pid, (uint16_t)((intptr_t)dlsch1->harq_processes[harq_pid]->rb_alloc_even)); - LOG_D(PHY,"start turbo decode for CW 1 for AbsSubframe %d.%d / %d --> Qm %d \n", frame_rx, subframe_rx, harq_pid, dlsch1->harq_processes[harq_pid]->Qm); - LOG_D(PHY,"start turbo decode for CW 1 for AbsSubframe %d.%d / %d --> Nl %d \n", frame_rx, subframe_rx, harq_pid, dlsch1->harq_processes[harq_pid]->Nl); - LOG_D(PHY,"start turbo decode for CW 1 for AbsSubframe %d.%d / %d --> G %d \n", frame_rx, subframe_rx, harq_pid, dlsch1->harq_processes[harq_pid]->G); - LOG_D(PHY,"start turbo decode for CW 1 for AbsSubframe %d.%d / %d --> Kmimo %d \n", frame_rx, subframe_rx, harq_pid, dlsch1->Kmimo); - LOG_D(PHY,"start turbo decode for CW 1 for AbsSubframe %d.%d / %d --> Pdcch Sym %d \n", frame_rx, subframe_rx, harq_pid, ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->num_pdcch_symbols); - - if (LOG_DEBUGFLAG(UE_TIMING)) { - start_meas(&ue->dlsch_decoding_stats[ue->current_thread_id[subframe_rx]]); - } - - ret1 = dlsch_decoding(ue, - pdsch_vars->llr[1], - &ue->frame_parms, - dlsch1, - dlsch1->harq_processes[harq_pid], - frame_rx, - subframe_rx, - harq_pid, - pdsch==PDSCH?1:0, - dlsch1->harq_processes[harq_pid]->TBS>256?1:0); - - if (LOG_DEBUGFLAG(UE_TIMING)) { - stop_meas(&ue->dlsch_decoding_stats[ue->current_thread_id[subframe_rx]]); - LOG_I(PHY, " --> Unscrambling for CW1 %5.3f\n", - (ue->dlsch_unscrambling_stats.p_time)/(cpuf*1000.0)); - LOG_I(PHY, "AbsSubframe %d.%d --> Turbo Decoding for CW1 %5.3f\n", - frame_rx%1024, subframe_rx,(ue->dlsch_decoding_stats[ue->current_thread_id[subframe_rx]].p_time)/(cpuf*1000.0)); - } - LOG_D(PHY,"AbsSubframe %d.%d --> Turbo Decoding for CW1 %5.3f\n", - frame_rx%1024, subframe_rx,(ue->dlsch_decoding_stats[ue->current_thread_id[subframe_rx]].p_time)/(cpuf*1000.0)); - } - - LOG_D(PHY," ------ end turbo decoder for AbsSubframe %d.%d ------ \n", frame_rx, subframe_rx); - - + LOG_D(PHY,"AbsSubframe %d.%d --> Turbo Decoding for CW1 %5.3f\n", + frame_rx%1024, subframe_rx,(ue->dlsch_decoding_stats[ue->current_thread_id[subframe_rx]].p_time)/(cpuf*1000.0)); + } + + LOG_D(PHY," ------ end turbo decoder for AbsSubframe %d.%d ------ \n", frame_rx, subframe_rx); // Check CRC for CW 0 if (ret == (1+dlsch0->max_turbo_iterations)) { *dlsch_errors=*dlsch_errors+1; - if(dlsch0->rnti != 0xffff) - { - - LOG_D(PHY,"[UE %d][PDSCH %x/%d] AbsSubframe %d.%d : DLSCH CW0 in error (rv %d,round %d, mcs %d,TBS %d)\n", - ue->Mod_id,dlsch0->rnti, - harq_pid,frame_rx,subframe_rx, - dlsch0->harq_processes[harq_pid]->rvidx, - dlsch0->harq_processes[harq_pid]->round, - dlsch0->harq_processes[harq_pid]->mcs, - dlsch0->harq_processes[harq_pid]->TBS); + if(dlsch0->rnti != 0xffff) { + LOG_D(PHY,"[UE %d][PDSCH %x/%d] AbsSubframe %d.%d : DLSCH CW0 in error (rv %d,round %d, mcs %d,TBS %d)\n", + ue->Mod_id,dlsch0->rnti, + harq_pid,frame_rx,subframe_rx, + dlsch0->harq_processes[harq_pid]->rvidx, + dlsch0->harq_processes[harq_pid]->round, + dlsch0->harq_processes[harq_pid]->mcs, + dlsch0->harq_processes[harq_pid]->TBS); + } + } else { + if(dlsch0->rnti != 0xffff) { + LOG_D(PHY,"[UE %d][PDSCH %x/%d] AbsSubframe %d.%d : Received DLSCH CW0 (rv %d,round %d, mcs %d,TBS %d)\n", + ue->Mod_id,dlsch0->rnti, + harq_pid,frame_rx,subframe_rx, + dlsch0->harq_processes[harq_pid]->rvidx, + dlsch0->harq_processes[harq_pid]->round, + dlsch0->harq_processes[harq_pid]->mcs, + dlsch0->harq_processes[harq_pid]->TBS); } - - } else { - if(dlsch0->rnti != 0xffff) - { - LOG_D(PHY,"[UE %d][PDSCH %x/%d] AbsSubframe %d.%d : Received DLSCH CW0 (rv %d,round %d, mcs %d,TBS %d)\n", - ue->Mod_id,dlsch0->rnti, - harq_pid,frame_rx,subframe_rx, - dlsch0->harq_processes[harq_pid]->rvidx, - dlsch0->harq_processes[harq_pid]->round, - dlsch0->harq_processes[harq_pid]->mcs, - dlsch0->harq_processes[harq_pid]->TBS); - } - - if ( LOG_DEBUGFLAG(DEBUG_UE_PHYPROC)){ + if ( LOG_DEBUGFLAG(DEBUG_UE_PHYPROC)) { int j; LOG_D(PHY,"dlsch harq_pid %d (rx): \n",dlsch0->current_harq_pid); for (j=0; jharq_processes[dlsch0->current_harq_pid]->TBS>>3; j++) - LOG_T(PHY,"%x.",dlsch0->harq_processes[dlsch0->current_harq_pid]->b[j]); + LOG_T(PHY,"%x.",dlsch0->harq_processes[dlsch0->current_harq_pid]->b[j]); LOG_T(PHY,"\n"); } - if (ue->mac_enabled == 1) { - - switch (pdsch) { - case PDSCH: - ue_send_sdu(ue->Mod_id, - CC_id, - frame_rx, - subframe_rx, - dlsch0->harq_processes[dlsch0->current_harq_pid]->b, - dlsch0->harq_processes[dlsch0->current_harq_pid]->TBS>>3, - eNB_id); - break; - case SI_PDSCH: - ue_decode_si(ue->Mod_id, - CC_id, - frame_rx, - eNB_id, - ue->dlsch_SI[eNB_id]->harq_processes[0]->b, - ue->dlsch_SI[eNB_id]->harq_processes[0]->TBS>>3); - break; - case P_PDSCH: - ue_decode_p(ue->Mod_id, - CC_id, - frame_rx, - eNB_id, - ue->dlsch_SI[eNB_id]->harq_processes[0]->b, - ue->dlsch_SI[eNB_id]->harq_processes[0]->TBS>>3); - break; - case RA_PDSCH: - process_rar(ue,proc,eNB_id,mode,abstraction_flag); - break; - case PDSCH1: - LOG_E(PHY,"Shouldn't have PDSCH1 yet, come back later\n"); - AssertFatal(1==0,"exiting"); - break; - case PMCH: - LOG_E(PHY,"Shouldn't have PMCH here\n"); - AssertFatal(1==0,"exiting"); - break; - } - } - ue->total_TBS[eNB_id] = ue->total_TBS[eNB_id] + - dlsch0->harq_processes[dlsch0->current_harq_pid]->TBS; - ue->total_received_bits[eNB_id] = ue->total_TBS[eNB_id] + - dlsch0->harq_processes[dlsch0->current_harq_pid]->TBS; - } - // Check CRC for CW 1 - if(is_cw1_active) - { - if (ret1 == (1+dlsch0->max_turbo_iterations)) { - LOG_D(PHY,"[UE %d][PDSCH %x/%d] Frame %d subframe %d DLSCH CW1 in error (rv %d,mcs %d,TBS %d)\n", - ue->Mod_id,dlsch0->rnti, - harq_pid,frame_rx,subframe_rx, - dlsch0->harq_processes[harq_pid]->rvidx, - dlsch0->harq_processes[harq_pid]->mcs, - dlsch0->harq_processes[harq_pid]->TBS); - - } else { - LOG_D(PHY,"[UE %d][PDSCH %x/%d] Frame %d subframe %d: Received DLSCH CW1 (rv %d,mcs %d,TBS %d)\n", - ue->Mod_id,dlsch0->rnti, - harq_pid,frame_rx,subframe_rx, - dlsch0->harq_processes[harq_pid]->rvidx, - dlsch0->harq_processes[harq_pid]->mcs, - dlsch0->harq_processes[harq_pid]->TBS); - - - if (ue->mac_enabled == 1) { - switch (pdsch) { - case PDSCH: - if(is_cw1_active) - ue_send_sdu(ue->Mod_id, - CC_id, - frame_rx, - subframe_rx, - dlsch1->harq_processes[dlsch1->current_harq_pid]->b, - dlsch1->harq_processes[dlsch1->current_harq_pid]->TBS>>3, - eNB_id); - break; - case SI_PDSCH: - case P_PDSCH: - case RA_PDSCH: - case PDSCH1: - case PMCH: - AssertFatal(0,"exiting"); - break; - } - } + switch (pdsch) { + case PDSCH: + ue_send_sdu(ue->Mod_id, + CC_id, + frame_rx, + subframe_rx, + dlsch0->harq_processes[dlsch0->current_harq_pid]->b, + dlsch0->harq_processes[dlsch0->current_harq_pid]->TBS>>3, + eNB_id); + break; + + case SI_PDSCH: + ue_decode_si(ue->Mod_id, + CC_id, + frame_rx, + eNB_id, + ue->dlsch_SI[eNB_id]->harq_processes[0]->b, + ue->dlsch_SI[eNB_id]->harq_processes[0]->TBS>>3); + break; + + case P_PDSCH: + ue_decode_p(ue->Mod_id, + CC_id, + frame_rx, + eNB_id, + ue->dlsch_SI[eNB_id]->harq_processes[0]->b, + ue->dlsch_SI[eNB_id]->harq_processes[0]->TBS>>3); + break; + + case RA_PDSCH: + process_rar(ue,proc,eNB_id,mode,abstraction_flag); + break; + + case PDSCH1: + LOG_E(PHY,"Shouldn't have PDSCH1 yet, come back later\n"); + AssertFatal(1==0,"exiting"); + break; + + case PMCH: + LOG_E(PHY,"Shouldn't have PMCH here\n"); + AssertFatal(1==0,"exiting"); + break; } } - + + ue->total_TBS[eNB_id] = ue->total_TBS[eNB_id] + + dlsch0->harq_processes[dlsch0->current_harq_pid]->TBS; + ue->total_received_bits[eNB_id] = ue->total_TBS[eNB_id] + + dlsch0->harq_processes[dlsch0->current_harq_pid]->TBS; + } + + // Check CRC for CW 1 + if(is_cw1_active) { + if (ret1 == (1+dlsch0->max_turbo_iterations)) { + LOG_D(PHY,"[UE %d][PDSCH %x/%d] Frame %d subframe %d DLSCH CW1 in error (rv %d,mcs %d,TBS %d)\n", + ue->Mod_id,dlsch0->rnti, + harq_pid,frame_rx,subframe_rx, + dlsch0->harq_processes[harq_pid]->rvidx, + dlsch0->harq_processes[harq_pid]->mcs, + dlsch0->harq_processes[harq_pid]->TBS); + } else { + LOG_D(PHY,"[UE %d][PDSCH %x/%d] Frame %d subframe %d: Received DLSCH CW1 (rv %d,mcs %d,TBS %d)\n", + ue->Mod_id,dlsch0->rnti, + harq_pid,frame_rx,subframe_rx, + dlsch0->harq_processes[harq_pid]->rvidx, + dlsch0->harq_processes[harq_pid]->mcs, + dlsch0->harq_processes[harq_pid]->TBS); + + if (ue->mac_enabled == 1) { + switch (pdsch) { + case PDSCH: + if(is_cw1_active) + ue_send_sdu(ue->Mod_id, + CC_id, + frame_rx, + subframe_rx, + dlsch1->harq_processes[dlsch1->current_harq_pid]->b, + dlsch1->harq_processes[dlsch1->current_harq_pid]->TBS>>3, + eNB_id); + + break; + + case SI_PDSCH: + case P_PDSCH: + case RA_PDSCH: + case PDSCH1: + case PMCH: + AssertFatal(0,"exiting"); + break; + } + } + } + } + if (LOG_DEBUGFLAG(DEBUG_UE_PHYPROC)) { LOG_D(PHY,"[UE %d][PDSCH %x/%d] Frame %d subframe %d: PDSCH/DLSCH decoding iter %d (mcs %d, rv %d, TBS %d)\n", - ue->Mod_id, - dlsch0->rnti,harq_pid, - frame_rx,subframe_rx,ret, - dlsch0->harq_processes[harq_pid]->mcs, - dlsch0->harq_processes[harq_pid]->rvidx, - dlsch0->harq_processes[harq_pid]->TBS); - + ue->Mod_id, + dlsch0->rnti,harq_pid, + frame_rx,subframe_rx,ret, + dlsch0->harq_processes[harq_pid]->mcs, + dlsch0->harq_processes[harq_pid]->rvidx, + dlsch0->harq_processes[harq_pid]->TBS); + if (frame_rx%100==0) { - LOG_D(PHY,"[UE %d][PDSCH %x] Frame %d subframe %d dlsch_errors %d, dlsch_received %d, dlsch_fer %d, current_dlsch_cqi %d\n", - ue->Mod_id,dlsch0->rnti, - frame_rx,subframe_rx, - ue->dlsch_errors[eNB_id], - ue->dlsch_received[eNB_id], - ue->dlsch_fer[eNB_id], - ue->measurements.wideband_cqi_tot[eNB_id]); + LOG_D(PHY,"[UE %d][PDSCH %x] Frame %d subframe %d dlsch_errors %d, dlsch_received %d, dlsch_fer %d, current_dlsch_cqi %d\n", + ue->Mod_id,dlsch0->rnti, + frame_rx,subframe_rx, + ue->dlsch_errors[eNB_id], + ue->dlsch_received[eNB_id], + ue->dlsch_fer[eNB_id], + ue->measurements.wideband_cqi_tot[eNB_id]); } - } /*LOG_DEBUGFLAG(DEBUG_UE_PHYPROC) */ - } - - } /*! @@ -3840,258 +3525,256 @@ void ue_dlsch_procedures(PHY_VARS_UE *ue, #ifdef UE_SLOT_PARALLELISATION #define FIFO_PRIORITY 40 void *UE_thread_slot1_dl_processing(void *arg) { + static __thread int UE_dl_slot1_processing_retval; + struct rx_tx_thread_data *rtd = arg; + UE_rxtx_proc_t *proc = rtd->proc; + PHY_VARS_UE *ue = rtd->UE; + int frame_rx; + uint8_t subframe_rx; + uint8_t pilot0; + uint8_t pilot1; + uint8_t slot1; + uint8_t next_subframe_rx; + uint8_t next_subframe_slot0; + proc->instance_cnt_slot1_dl_processing=-1; + proc->subframe_rx=proc->sub_frame_start; + char threadname[256]; + sprintf(threadname,"UE_thread_slot1_dl_processing_%d", proc->sub_frame_start); + cpu_set_t cpuset; + CPU_ZERO(&cpuset); - static __thread int UE_dl_slot1_processing_retval; - struct rx_tx_thread_data *rtd = arg; - UE_rxtx_proc_t *proc = rtd->proc; - PHY_VARS_UE *ue = rtd->UE; + if ( (proc->sub_frame_start+1)%RX_NB_TH == 0 && threads.slot1_proc_one != -1 ) + CPU_SET(threads.slot1_proc_one, &cpuset); - int frame_rx; - uint8_t subframe_rx; - uint8_t pilot0; - uint8_t pilot1; - uint8_t slot1; + if ( (proc->sub_frame_start+1)%RX_NB_TH == 1 && threads.slot1_proc_two != -1 ) + CPU_SET(threads.slot1_proc_two, &cpuset); - uint8_t next_subframe_rx; - uint8_t next_subframe_slot0; + if ( (proc->sub_frame_start+1)%RX_NB_TH == 2 && threads.slot1_proc_three != -1 ) + CPU_SET(threads.slot1_proc_three, &cpuset); - proc->instance_cnt_slot1_dl_processing=-1; - proc->subframe_rx=proc->sub_frame_start; + init_thread(900000,1000000, FIFO_PRIORITY-1, &cpuset, + threadname); - char threadname[256]; - sprintf(threadname,"UE_thread_slot1_dl_processing_%d", proc->sub_frame_start); + while (!oai_exit) { + if (pthread_mutex_lock(&proc->mutex_slot1_dl_processing) != 0) { + LOG_E( PHY, "[SCHED][UE] error locking mutex for UE slot1 dl processing\n" ); + exit_fun("nothing to add"); + } - cpu_set_t cpuset; - CPU_ZERO(&cpuset); - if ( (proc->sub_frame_start+1)%RX_NB_TH == 0 && threads.slot1_proc_one != -1 ) - CPU_SET(threads.slot1_proc_one, &cpuset); - if ( (proc->sub_frame_start+1)%RX_NB_TH == 1 && threads.slot1_proc_two != -1 ) - CPU_SET(threads.slot1_proc_two, &cpuset); - if ( (proc->sub_frame_start+1)%RX_NB_TH == 2 && threads.slot1_proc_three != -1 ) - CPU_SET(threads.slot1_proc_three, &cpuset); + while (proc->instance_cnt_slot1_dl_processing < 0) { + // most of the time, the thread is waiting here + pthread_cond_wait( &proc->cond_slot1_dl_processing, &proc->mutex_slot1_dl_processing ); + } - init_thread(900000,1000000 , FIFO_PRIORITY-1, &cpuset, - threadname); + if (pthread_mutex_unlock(&proc->mutex_slot1_dl_processing) != 0) { + LOG_E( PHY, "[SCHED][UE] error unlocking mutex for UE slot1 dl processing \n" ); + exit_fun("nothing to add"); + } - while (!oai_exit) { - if (pthread_mutex_lock(&proc->mutex_slot1_dl_processing) != 0) { - LOG_E( PHY, "[SCHED][UE] error locking mutex for UE slot1 dl processing\n" ); - exit_fun("nothing to add"); - } - while (proc->instance_cnt_slot1_dl_processing < 0) { - // most of the time, the thread is waiting here - pthread_cond_wait( &proc->cond_slot1_dl_processing, &proc->mutex_slot1_dl_processing ); - } - if (pthread_mutex_unlock(&proc->mutex_slot1_dl_processing) != 0) { - LOG_E( PHY, "[SCHED][UE] error unlocking mutex for UE slot1 dl processing \n" ); - exit_fun("nothing to add"); - } + /*for(int th_idx=0; th_idx< RX_NB_TH; th_idx++) + { + frame_rx = ue->proc.proc_rxtx[0].frame_rx; + subframe_rx = ue->proc.proc_rxtx[0].subframe_rx; + printf("AbsSubframe %d.%d execute dl slot1 processing \n", frame_rx, subframe_rx); + }*/ + frame_rx = proc->frame_rx; + subframe_rx = proc->subframe_rx; + next_subframe_rx = (1+subframe_rx)%10; + next_subframe_slot0 = next_subframe_rx<<1; + slot1 = (subframe_rx<<1) + 1; + pilot0 = 0; - /*for(int th_idx=0; th_idx< RX_NB_TH; th_idx++) - { - frame_rx = ue->proc.proc_rxtx[0].frame_rx; - subframe_rx = ue->proc.proc_rxtx[0].subframe_rx; - printf("AbsSubframe %d.%d execute dl slot1 processing \n", frame_rx, subframe_rx); - }*/ - frame_rx = proc->frame_rx; - subframe_rx = proc->subframe_rx; - next_subframe_rx = (1+subframe_rx)%10; - next_subframe_slot0 = next_subframe_rx<<1; + //printf("AbsSubframe %d.%d execute dl slot1 processing \n", frame_rx, subframe_rx); - slot1 = (subframe_rx<<1) + 1; - pilot0 = 0; + if (ue->frame_parms.Ncp == 0) { // normal prefix + pilot1 = 4; + } else { // extended prefix + pilot1 = 3; + } - //printf("AbsSubframe %d.%d execute dl slot1 processing \n", frame_rx, subframe_rx); - - if (ue->frame_parms.Ncp == 0) { // normal prefix - pilot1 = 4; - } else { // extended prefix - pilot1 = 3; - } - - /**** Slot1 FE Processing ****/ - if (LOG_DEBUGFLAG(UE_TIMING)) { - start_meas(&ue->ue_front_end_per_slot_stat[ue->current_thread_id[subframe_rx]][1]); - } - // I- start dl slot1 processing - // do first symbol of next downlink subframe for channel estimation - /* - // 1- perform FFT for pilot ofdm symbols first (ofdmSym0 next subframe ofdmSym11) - if (subframe_select(&ue->frame_parms,next_subframe_rx) != SF_UL) - { - front_end_fft(ue, - pilot0, - next_subframe_slot0, - 0, - 0); - } + /**** Slot1 FE Processing ****/ + if (LOG_DEBUGFLAG(UE_TIMING)) { + start_meas(&ue->ue_front_end_per_slot_stat[ue->current_thread_id[subframe_rx]][1]); + } + // I- start dl slot1 processing + // do first symbol of next downlink subframe for channel estimation + /* + // 1- perform FFT for pilot ofdm symbols first (ofdmSym0 next subframe ofdmSym11) + if (subframe_select(&ue->frame_parms,next_subframe_rx) != SF_UL) + { front_end_fft(ue, - pilot1, - slot1, - 0, - 0); - */ - // 1- perform FFT - for (int l=1; lframe_parms.symbols_per_tti>>1; l++) - { - //if( (l != pilot0) && (l != pilot1)) - { - if (LOG_DEBUGFLAG(UE_TIMING)) { - start_meas(&ue->ofdm_demod_stats); - } - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP, VCD_FUNCTION_IN); - //printf("AbsSubframe %d.%d FFT slot %d, symbol %d\n", frame_rx,subframe_rx,slot1,l); - front_end_fft(ue, - l, - slot1, - 0, - 0); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP, VCD_FUNCTION_OUT); - if (LOG_DEBUGFLAG(UE_TIMING)) { - stop_meas(&ue->ofdm_demod_stats); - } - } - } // for l=1..l2 - - if (subframe_select(&ue->frame_parms,next_subframe_rx) != SF_UL) - { - //printf("AbsSubframe %d.%d FFT slot %d, symbol %d\n", frame_rx,subframe_rx,next_subframe_slot0,pilot0); - front_end_fft(ue, - pilot0, - next_subframe_slot0, - 0, - 0); - } - - // 2- perform Channel Estimation for slot1 - for (int l=1; lframe_parms.symbols_per_tti>>1; l++) - { - if(l == pilot1) - { - //wait until channel estimation for pilot0/slot1 is available - uint32_t wait = 0; - while(proc->chan_est_pilot0_slot1_available == 0) - { - usleep(1); - wait++; - } - //printf("[slot1 dl processing] ChanEst symbol %d slot %d wait%d\n",l,slot1,wait); - } - //printf("AbsSubframe %d.%d ChanEst slot %d, symbol %d\n", frame_rx,subframe_rx,slot1,l); - front_end_chanEst(ue, - l, - slot1, - 0); - ue_measurement_procedures(l-1,ue,proc,0,1+(subframe_rx<<1),0,ue->mode); - } - //printf("AbsSubframe %d.%d ChanEst slot %d, symbol %d\n", frame_rx,subframe_rx,next_subframe_slot0,pilot0); - front_end_chanEst(ue, pilot0, next_subframe_slot0, + 0, 0); + } - if ( (subframe_rx == 0) && (ue->decode_MIB == 1)) - { - ue_pbch_procedures(0,ue,proc,0); + front_end_fft(ue, + pilot1, + slot1, + 0, + 0); + */ + // 1- perform FFT + for (int l=1; lframe_parms.symbols_per_tti>>1; l++) { + //if( (l != pilot0) && (l != pilot1)) + { + if (LOG_DEBUGFLAG(UE_TIMING)) { + start_meas(&ue->ofdm_demod_stats); } - proc->chan_est_slot1_available = 1; - //printf("Set available slot 1channelEst to 1 AbsSubframe %d.%d \n",frame_rx,subframe_rx); - //printf(" [slot1 dl processing] ==> FFT/CHanEst Done for AbsSubframe %d.%d \n", proc->frame_rx, proc->subframe_rx); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP, VCD_FUNCTION_IN); + //printf("AbsSubframe %d.%d FFT slot %d, symbol %d\n", frame_rx,subframe_rx,slot1,l); + front_end_fft(ue, + l, + slot1, + 0, + 0); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP, VCD_FUNCTION_OUT); - //printf(" [slot1 dl processing] ==> Start LLR Comuptation slot1 for AbsSubframe %d.%d \n", proc->frame_rx, proc->subframe_rx); + if (LOG_DEBUGFLAG(UE_TIMING)) { + stop_meas(&ue->ofdm_demod_stats); + } + } + } // for l=1..l2 + if (subframe_select(&ue->frame_parms,next_subframe_rx) != SF_UL) { + //printf("AbsSubframe %d.%d FFT slot %d, symbol %d\n", frame_rx,subframe_rx,next_subframe_slot0,pilot0); + front_end_fft(ue, + pilot0, + next_subframe_slot0, + 0, + 0); + } - if ( LOG_DEBUGFLAG(UE_TIMING)) { - stop_meas(&ue->ue_front_end_per_slot_stat[ue->current_thread_id[subframe_rx]][1]); - LOG_I(PHY, "[AbsSFN %d.%d] Slot1: FFT + Channel Estimate + Pdsch Proc Slot0 %5.2f \n",frame_rx,subframe_rx,ue->ue_front_end_per_slot_stat[ue->current_thread_id[subframe_rx]][1].p_time/(cpuf*1000.0)); + // 2- perform Channel Estimation for slot1 + for (int l=1; lframe_parms.symbols_per_tti>>1; l++) { + if(l == pilot1) { + //wait until channel estimation for pilot0/slot1 is available + uint32_t wait = 0; + + while(proc->chan_est_pilot0_slot1_available == 0) { + usleep(1); + wait++; } + //printf("[slot1 dl processing] ChanEst symbol %d slot %d wait%d\n",l,slot1,wait); + } + + //printf("AbsSubframe %d.%d ChanEst slot %d, symbol %d\n", frame_rx,subframe_rx,slot1,l); + front_end_chanEst(ue, + l, + slot1, + 0); + ue_measurement_procedures(l-1,ue,proc,0,1+(subframe_rx<<1),0,ue->mode); + } + + //printf("AbsSubframe %d.%d ChanEst slot %d, symbol %d\n", frame_rx,subframe_rx,next_subframe_slot0,pilot0); + front_end_chanEst(ue, + pilot0, + next_subframe_slot0, + 0); + + if ( (subframe_rx == 0) && (ue->decode_MIB == 1)) { + ue_pbch_procedures(0,ue,proc,0); + } + + proc->chan_est_slot1_available = 1; + //printf("Set available slot 1channelEst to 1 AbsSubframe %d.%d \n",frame_rx,subframe_rx); + //printf(" [slot1 dl processing] ==> FFT/CHanEst Done for AbsSubframe %d.%d \n", proc->frame_rx, proc->subframe_rx); + + //printf(" [slot1 dl processing] ==> Start LLR Comuptation slot1 for AbsSubframe %d.%d \n", proc->frame_rx, proc->subframe_rx); + + if ( LOG_DEBUGFLAG(UE_TIMING)) { + stop_meas(&ue->ue_front_end_per_slot_stat[ue->current_thread_id[subframe_rx]][1]); + LOG_I(PHY, "[AbsSFN %d.%d] Slot1: FFT + Channel Estimate + Pdsch Proc Slot0 %5.2f \n",frame_rx,subframe_rx,ue->ue_front_end_per_slot_stat[ue->current_thread_id[subframe_rx]][1].p_time/(cpuf*1000.0)); + } //wait until pdcch is decoded uint32_t wait = 0; - while(proc->dci_slot0_available == 0) - { - usleep(1); - wait++; - } - //printf("[slot1 dl processing] AbsSubframe %d.%d LLR Computation Start wait DCI %d\n",frame_rx,subframe_rx,wait); + while(proc->dci_slot0_available == 0) { + usleep(1); + wait++; + } + + //printf("[slot1 dl processing] AbsSubframe %d.%d LLR Computation Start wait DCI %d\n",frame_rx,subframe_rx,wait); /**** Pdsch Procedure Slot1 ****/ // start slot1 thread for Pdsch Procedure (slot1) // do procedures for C-RNTI //printf("AbsSubframe %d.%d Pdsch Procedure (slot1)\n",frame_rx,subframe_rx); - if ( LOG_DEBUGFLAG(UE_TIMING)) { start_meas(&ue->pdsch_procedures_per_slot_stat[ue->current_thread_id[subframe_rx]][1]); } + // start slave thread for Pdsch Procedure (slot1) // do procedures for C-RNTI uint8_t eNB_id = 0; uint8_t abstraction_flag = 0; - if (ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0]->active == 1) { - //wait until first ofdm symbol is processed - //wait = 0; - //while(proc->first_symbol_available == 0) - //{ - // usleep(1); - // wait++; - //} - //printf("[slot1 dl processing] AbsSubframe %d.%d LLR Computation Start wait First Ofdm Sym %d\n",frame_rx,subframe_rx,wait); - //VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC, VCD_FUNCTION_IN); - ue_pdsch_procedures(ue, - proc, - eNB_id, - PDSCH, - ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0], - NULL, - (ue->frame_parms.symbols_per_tti>>1), - ue->frame_parms.symbols_per_tti-1, - abstraction_flag); - LOG_D(PHY," ------ end PDSCH ChannelComp/LLR slot 0: AbsSubframe %d.%d ------ \n", frame_rx%1024, subframe_rx); - LOG_D(PHY," ------ --> PDSCH Turbo Decoder slot 0/1: AbsSubframe %d.%d ------ \n", frame_rx%1024, subframe_rx); + if (ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0]->active == 1) { + //wait until first ofdm symbol is processed + //wait = 0; + //while(proc->first_symbol_available == 0) + //{ + // usleep(1); + // wait++; + //} + //printf("[slot1 dl processing] AbsSubframe %d.%d LLR Computation Start wait First Ofdm Sym %d\n",frame_rx,subframe_rx,wait); + //VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC, VCD_FUNCTION_IN); + ue_pdsch_procedures(ue, + proc, + eNB_id, + PDSCH, + ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0], + NULL, + (ue->frame_parms.symbols_per_tti>>1), + ue->frame_parms.symbols_per_tti-1, + abstraction_flag); + LOG_D(PHY," ------ end PDSCH ChannelComp/LLR slot 0: AbsSubframe %d.%d ------ \n", frame_rx%1024, subframe_rx); + LOG_D(PHY," ------ --> PDSCH Turbo Decoder slot 0/1: AbsSubframe %d.%d ------ \n", frame_rx%1024, subframe_rx); } // do procedures for SI-RNTI if ((ue->dlsch_SI[eNB_id]) && (ue->dlsch_SI[eNB_id]->active == 1)) { - ue_pdsch_procedures(ue, - proc, - eNB_id, - SI_PDSCH, - ue->dlsch_SI[eNB_id], - NULL, - (ue->frame_parms.symbols_per_tti>>1), - ue->frame_parms.symbols_per_tti-1, - abstraction_flag); + ue_pdsch_procedures(ue, + proc, + eNB_id, + SI_PDSCH, + ue->dlsch_SI[eNB_id], + NULL, + (ue->frame_parms.symbols_per_tti>>1), + ue->frame_parms.symbols_per_tti-1, + abstraction_flag); } // do procedures for P-RNTI if ((ue->dlsch_p[eNB_id]) && (ue->dlsch_p[eNB_id]->active == 1)) { - ue_pdsch_procedures(ue, - proc, - eNB_id, - P_PDSCH, - ue->dlsch_p[eNB_id], - NULL, - (ue->frame_parms.symbols_per_tti>>1), - ue->frame_parms.symbols_per_tti-1, - abstraction_flag); + ue_pdsch_procedures(ue, + proc, + eNB_id, + P_PDSCH, + ue->dlsch_p[eNB_id], + NULL, + (ue->frame_parms.symbols_per_tti>>1), + ue->frame_parms.symbols_per_tti-1, + abstraction_flag); } + // do procedures for RA-RNTI if ((ue->dlsch_ra[eNB_id]) && (ue->dlsch_ra[eNB_id]->active == 1)) { - ue_pdsch_procedures(ue, - proc, - eNB_id, - RA_PDSCH, - ue->dlsch_ra[eNB_id], - NULL, - (ue->frame_parms.symbols_per_tti>>1), - ue->frame_parms.symbols_per_tti-1, - abstraction_flag); + ue_pdsch_procedures(ue, + proc, + eNB_id, + RA_PDSCH, + ue->dlsch_ra[eNB_id], + NULL, + (ue->frame_parms.symbols_per_tti>>1), + ue->frame_parms.symbols_per_tti-1, + abstraction_flag); } proc->llr_slot1_available=1; @@ -4102,529 +3785,518 @@ void *UE_thread_slot1_dl_processing(void *arg) { LOG_I(PHY, "[AbsSFN %d.%d] Slot1: LLR Computation %5.2f \n",frame_rx,subframe_rx,ue->pdsch_procedures_per_slot_stat[ue->current_thread_id[subframe_rx]][1].p_time/(cpuf*1000.0)); } - - if (pthread_mutex_lock(&proc->mutex_slot1_dl_processing) != 0) { - LOG_E( PHY, "[SCHED][UE] error locking mutex for UE RXTX\n" ); - exit_fun("noting to add"); - } - proc->instance_cnt_slot1_dl_processing--; - if (pthread_mutex_unlock(&proc->mutex_slot1_dl_processing) != 0) { - LOG_E( PHY, "[SCHED][UE] error unlocking mutex for UE FEP Slo1\n" ); - exit_fun("noting to add"); - } + if (pthread_mutex_lock(&proc->mutex_slot1_dl_processing) != 0) { + LOG_E( PHY, "[SCHED][UE] error locking mutex for UE RXTX\n" ); + exit_fun("noting to add"); } - // thread finished - free(arg); - return &UE_dl_slot1_processing_retval; + + proc->instance_cnt_slot1_dl_processing--; + + if (pthread_mutex_unlock(&proc->mutex_slot1_dl_processing) != 0) { + LOG_E( PHY, "[SCHED][UE] error unlocking mutex for UE FEP Slo1\n" ); + exit_fun("noting to add"); + } + } + + // thread finished + free(arg); + return &UE_dl_slot1_processing_retval; } #endif #ifdef UE_SLOT_PARALLELISATION int phy_procedures_slot_parallelization_UE_RX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id, - uint8_t abstraction_flag,uint8_t do_pdcch_flag,runmode_t mode) { + uint8_t abstraction_flag,uint8_t do_pdcch_flag,runmode_t mode) { + int l,l2; + int pmch_flag=0; + int frame_rx = proc->frame_rx; + int subframe_rx = proc->subframe_rx; + uint8_t pilot0; + uint8_t pilot1; + uint8_t slot0; + uint8_t slot1; + uint8_t first_ofdm_sym; + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_RX, VCD_FUNCTION_IN); + T(T_UE_PHY_DL_TICK, T_INT(ue->Mod_id), T_INT(frame_rx%1024), T_INT(subframe_rx)); + T(T_UE_PHY_INPUT_SIGNAL, T_INT(ue->Mod_id), T_INT(frame_rx%1024), T_INT(subframe_rx), T_INT(0), + T_BUFFER(&ue->common_vars.rxdata[0][subframe_rx*ue->frame_parms.samples_per_tti], + ue->frame_parms.samples_per_tti * 4)); - int l,l2; - int pmch_flag=0; - int frame_rx = proc->frame_rx; - int subframe_rx = proc->subframe_rx; - uint8_t pilot0; - uint8_t pilot1; - uint8_t slot0; - uint8_t slot1; - uint8_t first_ofdm_sym; + // start timers + if (LOG_DEBUGFLAG(DEBUG_UE_PHYPROC)) { + LOG_D(PHY," ****** start RX-Chain for AbsSubframe %d.%d ****** \n", frame_rx%1024, subframe_rx); + } - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_RX, VCD_FUNCTION_IN); + if (LOG_DEBUGFLAG(UE_TIMING)) { + start_meas(&ue->phy_proc_rx[ue->current_thread_id[subframe_rx]]); + start_meas(&ue->ue_front_end_stat[ue->current_thread_id[subframe_rx]]); + } + pmch_flag = is_pmch_subframe(frame_rx,subframe_rx,&ue->frame_parms) ? 1 : 0; - T(T_UE_PHY_DL_TICK, T_INT(ue->Mod_id), T_INT(frame_rx%1024), T_INT(subframe_rx)); + if (do_pdcch_flag) { + // deactivate reception until we scan pdcch + if (ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0]) + ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0]->active = 0; - T(T_UE_PHY_INPUT_SIGNAL, T_INT(ue->Mod_id), T_INT(frame_rx%1024), T_INT(subframe_rx), T_INT(0), - T_BUFFER(&ue->common_vars.rxdata[0][subframe_rx*ue->frame_parms.samples_per_tti], - ue->frame_parms.samples_per_tti * 4)); + if (ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][1]) + ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][1]->active = 0; + if (ue->dlsch_SI[eNB_id]) + ue->dlsch_SI[eNB_id]->active = 0; - // start timers - if (LOG_DEBUGFLAG(DEBUG_UE_PHYPROC)) { - LOG_D(PHY," ****** start RX-Chain for AbsSubframe %d.%d ****** \n", frame_rx%1024, subframe_rx); - } + if (ue->dlsch_p[eNB_id]) + ue->dlsch_p[eNB_id]->active = 0; - if (LOG_DEBUGFLAG(UE_TIMING)) { - start_meas(&ue->phy_proc_rx[ue->current_thread_id[subframe_rx]]); - start_meas(&ue->ue_front_end_stat[ue->current_thread_id[subframe_rx]]); - } + if (ue->dlsch_ra[eNB_id]) + ue->dlsch_ra[eNB_id]->active = 0; + } - pmch_flag = is_pmch_subframe(frame_rx,subframe_rx,&ue->frame_parms) ? 1 : 0; + if ( LOG_DEBUG_FLAG(DEBUG_UE_PHYPROC)) { + LOG_D(PHY,"[UE %d] Frame %d subframe %d: Doing phy_procedures_UE_RX\n", + ue->Mod_id,frame_rx, subframe_rx); + } - if (do_pdcch_flag) { - // deactivate reception until we scan pdcch - if (ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0]) - ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0]->active = 0; - if (ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][1]) - ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][1]->active = 0; + if (subframe_select(&ue->frame_parms,subframe_rx) == SF_S) { // S-subframe, do first 5 symbols only + l2 = 4; + } else if (pmch_flag == 1) { // do first 2 symbols only + l2 = 1; + } else { // normal subframe, last symbol to be processed is the first of the second slot + l2 = (ue->frame_parms.symbols_per_tti/2)-1; + } - if (ue->dlsch_SI[eNB_id]) - ue->dlsch_SI[eNB_id]->active = 0; - if (ue->dlsch_p[eNB_id]) - ue->dlsch_p[eNB_id]->active = 0; - if (ue->dlsch_ra[eNB_id]) - ue->dlsch_ra[eNB_id]->active = 0; - } + int prev_subframe_rx = (subframe_rx - 1)<0? 9: (subframe_rx - 1); - if ( LOG_DEBUG_FLAG(DEBUG_UE_PHYPROC)) { - LOG_D(PHY,"[UE %d] Frame %d subframe %d: Doing phy_procedures_UE_RX\n", - ue->Mod_id,frame_rx, subframe_rx); - } + if (subframe_select(&ue->frame_parms,prev_subframe_rx) != SF_DL) { + //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + // RX processing of symbols l=0...l2 + //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + first_ofdm_sym = 0; + } else { + //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + // RX processing of symbols l=1...l2 (l=0 is done in last scheduling epoch) + //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + first_ofdm_sym = 1; + } + slot0 = (subframe_rx<<1); + slot1 = (subframe_rx<<1) + 1; + pilot0 = 0; + if (ue->frame_parms.Ncp == 0) { // normal prefix + pilot1 = 4; + } else { // extended prefix + pilot1 = 3; + } + //LOG_I(PHY,"Set available channelEst to 0 AbsSubframe %d.%d \n",frame_rx,subframe_rx); + //LOG_I(PHY,"Set available llrs slot1 to 0 AbsSubframe %d.%d \n",frame_rx,subframe_rx); + //LOG_I(PHY,"Set available dci info slot0 to 0 AbsSubframe %d.%d \n",frame_rx,subframe_rx); + proc->chan_est_pilot0_slot1_available=0; + proc->llr_slot1_available=0; + proc->dci_slot0_available=0; + proc->first_symbol_available=0; + proc->chan_est_slot1_available=0; + //proc->channel_level=0; - if (subframe_select(&ue->frame_parms,subframe_rx) == SF_S) { // S-subframe, do first 5 symbols only - l2 = 4; - } else if (pmch_flag == 1) { // do first 2 symbols only - l2 = 1; - } else { // normal subframe, last symbol to be processed is the first of the second slot - l2 = (ue->frame_parms.symbols_per_tti/2)-1; - } + if (pthread_mutex_lock(&proc->mutex_slot1_dl_processing) != 0) { + LOG_E( PHY, "[SCHED][UE %d][Slot0] error locking mutex for UE slot1 dl processing\n",ue->Mod_id ); + exit_fun("nothing to add"); + } - int prev_subframe_rx = (subframe_rx - 1)<0? 9: (subframe_rx - 1); - if (subframe_select(&ue->frame_parms,prev_subframe_rx) != SF_DL) { - //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - // RX processing of symbols l=0...l2 - //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - first_ofdm_sym = 0; - } else { - //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - // RX processing of symbols l=1...l2 (l=0 is done in last scheduling epoch) - //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - first_ofdm_sym = 1; - } - slot0 = (subframe_rx<<1); - slot1 = (subframe_rx<<1) + 1; - pilot0 = 0; - if (ue->frame_parms.Ncp == 0) { // normal prefix - pilot1 = 4; - } else { // extended prefix - pilot1 = 3; - } + proc->instance_cnt_slot1_dl_processing++; - //LOG_I(PHY,"Set available channelEst to 0 AbsSubframe %d.%d \n",frame_rx,subframe_rx); - //LOG_I(PHY,"Set available llrs slot1 to 0 AbsSubframe %d.%d \n",frame_rx,subframe_rx); - //LOG_I(PHY,"Set available dci info slot0 to 0 AbsSubframe %d.%d \n",frame_rx,subframe_rx); - proc->chan_est_pilot0_slot1_available=0; - proc->llr_slot1_available=0; - proc->dci_slot0_available=0; - proc->first_symbol_available=0; - proc->chan_est_slot1_available=0; - //proc->channel_level=0; - - if (pthread_mutex_lock(&proc->mutex_slot1_dl_processing) != 0) { - LOG_E( PHY, "[SCHED][UE %d][Slot0] error locking mutex for UE slot1 dl processing\n",ue->Mod_id ); - exit_fun("nothing to add"); - } - - proc->instance_cnt_slot1_dl_processing++; - if (proc->instance_cnt_slot1_dl_processing == 0) - { + if (proc->instance_cnt_slot1_dl_processing == 0) { LOG_D(PHY,"unblock slot1 dl processing thread blocked on instance_cnt_slot1_dl_processing : %d \n", proc->instance_cnt_slot1_dl_processing ); - if (pthread_cond_signal(&proc->cond_slot1_dl_processing) != 0) { - LOG_E( PHY, "[SCHED][UE %d][Slot0] ERROR pthread_cond_signal for UE slot1 processing thread\n", ue->Mod_id); - exit_fun("nothing to add"); - } - if (pthread_mutex_unlock(&proc->mutex_slot1_dl_processing) != 0) { - LOG_E( PHY, "[SCHED][UE %d][Slot0] error unlocking mutex for UE slot1 dl processing \n",ue->Mod_id ); - exit_fun("nothing to add"); - } - } else - { - LOG_E( PHY, "[SCHED][UE %d] UE RX thread busy (IC %d)!!\n", ue->Mod_id, proc->instance_cnt_slot1_dl_processing); - if (proc->instance_cnt_slot1_dl_processing > 2) - exit_fun("instance_cnt_slot1_dl_processing > 2"); + if (pthread_cond_signal(&proc->cond_slot1_dl_processing) != 0) { + LOG_E( PHY, "[SCHED][UE %d][Slot0] ERROR pthread_cond_signal for UE slot1 processing thread\n", ue->Mod_id); + exit_fun("nothing to add"); } - //AssertFatal(pthread_cond_signal(&proc->cond_slot1_dl_processing) ==0 ,""); - AssertFatal(pthread_mutex_unlock(&proc->mutex_slot1_dl_processing) ==0,""); - - /**** Slot0 FE Processing ****/ - // I- start main thread for FFT/ChanEst symbol: 0/1 --> 7 - if ( LOG_DEBUGFLAG(UE_TIMING)) { - start_meas(&ue->ue_front_end_per_slot_stat[ue->current_thread_id[subframe_rx]][0]); + if (pthread_mutex_unlock(&proc->mutex_slot1_dl_processing) != 0) { + LOG_E( PHY, "[SCHED][UE %d][Slot0] error unlocking mutex for UE slot1 dl processing \n",ue->Mod_id ); + exit_fun("nothing to add"); } - // 1- perform FFT for pilot ofdm symbols first (ofdmSym7 ofdmSym4 or (ofdmSym6 ofdmSym3)) - //printf("AbsSubframe %d.%d FFT slot %d, symbol %d\n", frame_rx,subframe_rx,slot1,pilot0); - front_end_fft(ue, - pilot0, - slot1, - 0, - 0); - //printf("AbsSubframe %d.%d FFT slot %d, symbol %d\n", frame_rx,subframe_rx,slot0,pilot1); - front_end_fft(ue, - pilot1, - slot0, - 0, - 0); - //printf("AbsSubframe %d.%d ChanEst slot %d, symbol %d\n", frame_rx,subframe_rx,slot0,pilot1); - front_end_chanEst(ue, - pilot1, - slot0, - 0); - //printf("AbsSubframe %d.%d ChanEst slot %d, symbol %d\n", frame_rx,subframe_rx,slot1,pilot0); - front_end_chanEst(ue, - pilot0, - slot1, - 0); - proc->chan_est_pilot0_slot1_available = 1; - //printf("Set available channelEst to 1 AbsSubframe %d.%d \n",frame_rx,subframe_rx); + } else { + LOG_E( PHY, "[SCHED][UE %d] UE RX thread busy (IC %d)!!\n", ue->Mod_id, proc->instance_cnt_slot1_dl_processing); - // 2- perform FFT for other ofdm symbols other than pilots - for (l=first_ofdm_sym; l<=l2; l++) - { - if( (l != pilot0) && (l != pilot1)) - { - //printf("AbsSubframe %d.%d FFT slot %d, symbol %d\n", frame_rx,subframe_rx,slot0,l); - if (LOG_DEBUGFLAG(UE_TIMING)) { - start_meas(&ue->ofdm_demod_stats); - } - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP, VCD_FUNCTION_IN); - front_end_fft(ue, + if (proc->instance_cnt_slot1_dl_processing > 2) + exit_fun("instance_cnt_slot1_dl_processing > 2"); + } + + //AssertFatal(pthread_cond_signal(&proc->cond_slot1_dl_processing) ==0 ,""); + AssertFatal(pthread_mutex_unlock(&proc->mutex_slot1_dl_processing) ==0,""); + + /**** Slot0 FE Processing ****/ + // I- start main thread for FFT/ChanEst symbol: 0/1 --> 7 + if ( LOG_DEBUGFLAG(UE_TIMING)) { + start_meas(&ue->ue_front_end_per_slot_stat[ue->current_thread_id[subframe_rx]][0]); + } + + // 1- perform FFT for pilot ofdm symbols first (ofdmSym7 ofdmSym4 or (ofdmSym6 ofdmSym3)) + //printf("AbsSubframe %d.%d FFT slot %d, symbol %d\n", frame_rx,subframe_rx,slot1,pilot0); + front_end_fft(ue, + pilot0, + slot1, + 0, + 0); + //printf("AbsSubframe %d.%d FFT slot %d, symbol %d\n", frame_rx,subframe_rx,slot0,pilot1); + front_end_fft(ue, + pilot1, + slot0, + 0, + 0); + //printf("AbsSubframe %d.%d ChanEst slot %d, symbol %d\n", frame_rx,subframe_rx,slot0,pilot1); + front_end_chanEst(ue, + pilot1, + slot0, + 0); + //printf("AbsSubframe %d.%d ChanEst slot %d, symbol %d\n", frame_rx,subframe_rx,slot1,pilot0); + front_end_chanEst(ue, + pilot0, + slot1, + 0); + proc->chan_est_pilot0_slot1_available = 1; + //printf("Set available channelEst to 1 AbsSubframe %d.%d \n",frame_rx,subframe_rx); + + // 2- perform FFT for other ofdm symbols other than pilots + for (l=first_ofdm_sym; l<=l2; l++) { + if( (l != pilot0) && (l != pilot1)) { + //printf("AbsSubframe %d.%d FFT slot %d, symbol %d\n", frame_rx,subframe_rx,slot0,l); + if (LOG_DEBUGFLAG(UE_TIMING)) { + start_meas(&ue->ofdm_demod_stats); + } + + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP, VCD_FUNCTION_IN); + front_end_fft(ue, l, slot0, 0, 0); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP, VCD_FUNCTION_OUT); - if (LOG_DEBUGFLAG(UE_TIMING)) { - stop_meas(&ue->ofdm_demod_stats); - } - } - } // for l=1..l2 + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP, VCD_FUNCTION_OUT); - // 3- perform Channel Estimation for slot0 - for (l=first_ofdm_sym; l<=l2; l++) - { - if( (l != pilot0) && (l != pilot1)) - { - //printf("AbsSubframe %d.%d ChanEst slot %d, symbol %d\n", frame_rx,subframe_rx,slot0,l); - front_end_chanEst(ue, - l, - slot0, - 0); - } - ue_measurement_procedures(l-1,ue,proc,eNB_id,(subframe_rx<<1),abstraction_flag,mode); + if (LOG_DEBUGFLAG(UE_TIMING)) { + stop_meas(&ue->ofdm_demod_stats); + } + } + } // for l=1..l2 + + // 3- perform Channel Estimation for slot0 + for (l=first_ofdm_sym; l<=l2; l++) { + if( (l != pilot0) && (l != pilot1)) { + //printf("AbsSubframe %d.%d ChanEst slot %d, symbol %d\n", frame_rx,subframe_rx,slot0,l); + front_end_chanEst(ue, + l, + slot0, + 0); } - if (do_pdcch_flag) { - if (LOG_DEBUGFLAG(UE_TIMING)) { - start_meas(&ue->pdcch_procedures_stat[ue->current_thread_id[subframe_rx]]); - } - if (ue_pdcch_procedures(eNB_id,ue,proc,abstraction_flag) == -1) { - LOG_E(PHY,"[UE %d] Frame %d, subframe %d: Error in pdcch procedures\n",ue->Mod_id,frame_rx,subframe_rx); - if (LOG_DEBUGFLAG(UE_TIMING)) { - LOG_I(PHY, "[AbsSFN %d.%d] Slot0: PDCCH %5.2f \n",frame_rx,subframe_rx,ue->pdcch_procedures_stat[ue->current_thread_id[subframe_rx]].p_time/(cpuf*1000.0)); - } + ue_measurement_procedures(l-1,ue,proc,eNB_id,(subframe_rx<<1),abstraction_flag,mode); + } - //proc->dci_slot0_available = 1; - return(-1); - } - //proc->dci_slot0_available=1; - if (LOG_DEBUGFLAG(UE_TIMING)) { - stop_meas(&ue->pdcch_procedures_stat[ue->current_thread_id[subframe_rx]]); - LOG_I(PHY, "[AbsSFN %d.%d] Slot0: PDCCH %5.2f \n",frame_rx,subframe_rx,ue->pdcch_procedures_stat[ue->current_thread_id[subframe_rx]].p_time/(cpuf*1000.0)); - } - } - - //printf("num_pdcch_symbols %d\n",ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->num_pdcch_symbols); - - // first slot has been processed (FFTs + Channel Estimation, PCFICH/PHICH/PDCCH) + if (do_pdcch_flag) { if (LOG_DEBUGFLAG(UE_TIMING)) { - stop_meas(&ue->ue_front_end_per_slot_stat[ue->current_thread_id[subframe_rx]][0]); - LOG_I(PHY, "[AbsSFN %d.%d] Slot0: FFT + Channel Estimate + PCFICH/PHICH/PDCCH %5.2f \n",frame_rx,subframe_rx,ue->ue_front_end_per_slot_stat[ue->current_thread_id[subframe_rx]][0].p_time/(cpuf*1000.0)); + start_meas(&ue->pdcch_procedures_stat[ue->current_thread_id[subframe_rx]]); } - //wait until slot1 FE is done - uint32_t wait = 0; - while(proc->chan_est_slot1_available == 0) - { - usleep(1); - wait++; + if (ue_pdcch_procedures(eNB_id,ue,proc,abstraction_flag) == -1) { + LOG_E(PHY,"[UE %d] Frame %d, subframe %d: Error in pdcch procedures\n",ue->Mod_id,frame_rx,subframe_rx); + + if (LOG_DEBUGFLAG(UE_TIMING)) { + LOG_I(PHY, "[AbsSFN %d.%d] Slot0: PDCCH %5.2f \n",frame_rx,subframe_rx,ue->pdcch_procedures_stat[ue->current_thread_id[subframe_rx]].p_time/(cpuf*1000.0)); + } + + //proc->dci_slot0_available = 1; + return(-1); } - if (LOG_DEBUGFLAG(UE_TIMING)) { - stop_meas(&ue->ue_front_end_stat[ue->current_thread_id[subframe_rx]]); - LOG_I(PHY, "[AbsSFN %d.%d] FULL FE Processing %5.2f \n",frame_rx,subframe_rx,ue->ue_front_end_per_slot_stat[ue->current_thread_id[subframe_rx]][0].p_time/(cpuf*1000.0)); - } - /**** End Subframe FE Processing ****/ - - - //Trigger LLR parallelized for Slot 1 //proc->dci_slot0_available=1; - //printf("Set available dci slot0 to 1 AbsSubframe %d.%d \n",frame_rx%1024,subframe_rx); - - /**** Pdsch Procedure Slot0 ****/ - // start main thread for Pdsch Procedure (slot0) - // do procedures for C-RNTI - //printf("AbsSubframe %d.%d Pdsch Procedure (slot0)\n",frame_rx%1024,subframe_rx); - //printf("AbsSubframe %d.%d Pdsch Procedure PDSCH Active %d \n",frame_rx%1024,subframe_rx, ue->dlsch[ue->current_thread_id[subframe_rx]][0][0]->active); - if (LOG_DEBUGFLAG(UE_TIMING)) { - start_meas(&ue->pdsch_procedures_stat[ue->current_thread_id[subframe_rx]]); + stop_meas(&ue->pdcch_procedures_stat[ue->current_thread_id[subframe_rx]]); + LOG_I(PHY, "[AbsSFN %d.%d] Slot0: PDCCH %5.2f \n",frame_rx,subframe_rx,ue->pdcch_procedures_stat[ue->current_thread_id[subframe_rx]].p_time/(cpuf*1000.0)); } + } - if (LOG_DEBUGFLAG(UE_TIMING)) { - start_meas(&ue->pdsch_procedures_per_slot_stat[ue->current_thread_id[subframe_rx]][0]); - } - if (ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0]->active == 1) { - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC, VCD_FUNCTION_IN); - ue_pdsch_procedures(ue, - proc, - eNB_id, - PDSCH, - ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0], - NULL, - ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->num_pdcch_symbols, - (ue->frame_parms.symbols_per_tti>>1)-1, - abstraction_flag); + //printf("num_pdcch_symbols %d\n",ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->num_pdcch_symbols); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC, VCD_FUNCTION_OUT); - } + // first slot has been processed (FFTs + Channel Estimation, PCFICH/PHICH/PDCCH) + if (LOG_DEBUGFLAG(UE_TIMING)) { + stop_meas(&ue->ue_front_end_per_slot_stat[ue->current_thread_id[subframe_rx]][0]); + LOG_I(PHY, "[AbsSFN %d.%d] Slot0: FFT + Channel Estimate + PCFICH/PHICH/PDCCH %5.2f \n",frame_rx,subframe_rx, + ue->ue_front_end_per_slot_stat[ue->current_thread_id[subframe_rx]][0].p_time/(cpuf*1000.0)); + } - // do procedures for SI-RNTI - if ((ue->dlsch_SI[eNB_id]) && (ue->dlsch_SI[eNB_id]->active == 1)) { - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_SI, VCD_FUNCTION_IN); - ue_pdsch_procedures(ue, - proc, - eNB_id, - SI_PDSCH, - ue->dlsch_SI[eNB_id], - NULL, - ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->num_pdcch_symbols, - (ue->frame_parms.symbols_per_tti>>1)-1, - abstraction_flag); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_SI, VCD_FUNCTION_OUT); - } + //wait until slot1 FE is done + uint32_t wait = 0; - // do procedures for SI-RNTI - if ((ue->dlsch_p[eNB_id]) && (ue->dlsch_p[eNB_id]->active == 1)) { - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_P, VCD_FUNCTION_IN); - ue_pdsch_procedures(ue, - proc, - eNB_id, - P_PDSCH, - ue->dlsch_p[eNB_id], - NULL, - ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->num_pdcch_symbols, - (ue->frame_parms.symbols_per_tti>>1)-1, - abstraction_flag); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_P, VCD_FUNCTION_OUT); - } + while(proc->chan_est_slot1_available == 0) { + usleep(1); + wait++; + } - // do procedures for RA-RNTI - if ((ue->dlsch_ra[eNB_id]) && (ue->dlsch_ra[eNB_id]->active == 1)) { - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_RA, VCD_FUNCTION_IN); - ue_pdsch_procedures(ue, - proc, - eNB_id, - RA_PDSCH, - ue->dlsch_ra[eNB_id], - NULL, - ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->num_pdcch_symbols, - (ue->frame_parms.symbols_per_tti>>1)-1, - abstraction_flag); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_RA, VCD_FUNCTION_OUT); - } + if (LOG_DEBUGFLAG(UE_TIMING)) { + stop_meas(&ue->ue_front_end_stat[ue->current_thread_id[subframe_rx]]); + LOG_I(PHY, "[AbsSFN %d.%d] FULL FE Processing %5.2f \n",frame_rx,subframe_rx,ue->ue_front_end_per_slot_stat[ue->current_thread_id[subframe_rx]][0].p_time/(cpuf*1000.0)); + } - // LLR linear - proc->dci_slot0_available=1; - //printf("Set available dci slot0 to 1 AbsSubframe %d.%d \n",frame_rx%1024,subframe_rx); + /**** End Subframe FE Processing ****/ + //Trigger LLR parallelized for Slot 1 + //proc->dci_slot0_available=1; + //printf("Set available dci slot0 to 1 AbsSubframe %d.%d \n",frame_rx%1024,subframe_rx); - if (LOG_DEBUGFLAG(UE_TIMING)){ - stop_meas(&ue->pdsch_procedures_per_slot_stat[ue->current_thread_id[subframe_rx]][0]); - LOG_I(PHY, "[AbsSFN %d.%d] Slot0: LLR Computation %5.2f \n",frame_rx,subframe_rx,ue->pdsch_procedures_per_slot_stat[ue->current_thread_id[subframe_rx]][0].p_time/(cpuf*1000.0)); - } + /**** Pdsch Procedure Slot0 ****/ + // start main thread for Pdsch Procedure (slot0) + // do procedures for C-RNTI + //printf("AbsSubframe %d.%d Pdsch Procedure (slot0)\n",frame_rx%1024,subframe_rx); + //printf("AbsSubframe %d.%d Pdsch Procedure PDSCH Active %d \n",frame_rx%1024,subframe_rx, ue->dlsch[ue->current_thread_id[subframe_rx]][0][0]->active); + if (LOG_DEBUGFLAG(UE_TIMING)) { + start_meas(&ue->pdsch_procedures_stat[ue->current_thread_id[subframe_rx]]); + } - //wait until LLR Slot1 is done - wait = 0; - while(proc->llr_slot1_available == 0) - { - usleep(1); - wait++; - } + if (LOG_DEBUGFLAG(UE_TIMING)) { + start_meas(&ue->pdsch_procedures_per_slot_stat[ue->current_thread_id[subframe_rx]][0]); + } + if (ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0]->active == 1) { + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC, VCD_FUNCTION_IN); + ue_pdsch_procedures(ue, + proc, + eNB_id, + PDSCH, + ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0], + NULL, + ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->num_pdcch_symbols, + (ue->frame_parms.symbols_per_tti>>1)-1, + abstraction_flag); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC, VCD_FUNCTION_OUT); + } + // do procedures for SI-RNTI + if ((ue->dlsch_SI[eNB_id]) && (ue->dlsch_SI[eNB_id]->active == 1)) { + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_SI, VCD_FUNCTION_IN); + ue_pdsch_procedures(ue, + proc, + eNB_id, + SI_PDSCH, + ue->dlsch_SI[eNB_id], + NULL, + ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->num_pdcch_symbols, + (ue->frame_parms.symbols_per_tti>>1)-1, + abstraction_flag); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_SI, VCD_FUNCTION_OUT); + } - if (LOG_DEBUGFLAG(UE_TIMING)){ - stop_meas(&ue->pdsch_procedures_stat[ue->current_thread_id[subframe_rx]]); - LOG_I(PHY, "[AbsSFN %d.%d] Full LLR Computation %5.2f \n",frame_rx,subframe_rx,ue->pdsch_procedures_stat[ue->current_thread_id[subframe_rx]].p_time/(cpuf*1000.0)); - } + // do procedures for SI-RNTI + if ((ue->dlsch_p[eNB_id]) && (ue->dlsch_p[eNB_id]->active == 1)) { + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_P, VCD_FUNCTION_IN); + ue_pdsch_procedures(ue, + proc, + eNB_id, + P_PDSCH, + ue->dlsch_p[eNB_id], + NULL, + ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->num_pdcch_symbols, + (ue->frame_parms.symbols_per_tti>>1)-1, + abstraction_flag); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_P, VCD_FUNCTION_OUT); + } + // do procedures for RA-RNTI + if ((ue->dlsch_ra[eNB_id]) && (ue->dlsch_ra[eNB_id]->active == 1)) { + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_RA, VCD_FUNCTION_IN); + ue_pdsch_procedures(ue, + proc, + eNB_id, + RA_PDSCH, + ue->dlsch_ra[eNB_id], + NULL, + ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->num_pdcch_symbols, + (ue->frame_parms.symbols_per_tti>>1)-1, + abstraction_flag); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_RA, VCD_FUNCTION_OUT); + } - //=====================================================================// - if (LOG_DEBUGFLAG(UE_TIMING)){ - start_meas(&ue->dlsch_procedures_stat[ue->current_thread_id[subframe_rx]]); - } + // LLR linear + proc->dci_slot0_available=1; + //printf("Set available dci slot0 to 1 AbsSubframe %d.%d \n",frame_rx%1024,subframe_rx); - LOG_D(PHY,"==> Start Turbo Decoder active dlsch %d SI %d RA %d \n",ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0]->active, - ue->dlsch_SI[eNB_id]->active, - //ue->dlsch_p[eNB_id]->active, - ue->dlsch_ra[eNB_id]->active); - // Start Turbo decoder - if (ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0]->active == 1) { - //VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC, VCD_FUNCTION_IN); - ue_dlsch_procedures(ue, - proc, - eNB_id, - PDSCH, - ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0], - ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][1], - &ue->dlsch_errors[eNB_id], - mode, - abstraction_flag); - //VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC, VCD_FUNCTION_OUT); - } + if (LOG_DEBUGFLAG(UE_TIMING)) { + stop_meas(&ue->pdsch_procedures_per_slot_stat[ue->current_thread_id[subframe_rx]][0]); + LOG_I(PHY, "[AbsSFN %d.%d] Slot0: LLR Computation %5.2f \n",frame_rx,subframe_rx,ue->pdsch_procedures_per_slot_stat[ue->current_thread_id[subframe_rx]][0].p_time/(cpuf*1000.0)); + } - // do procedures for SI-RNTI - if ((ue->dlsch_SI[eNB_id]) && (ue->dlsch_SI[eNB_id]->active == 1)) { - ue_dlsch_procedures(ue, - proc, - eNB_id, - SI_PDSCH, - ue->dlsch_SI[eNB_id], - NULL, - &ue->dlsch_SI_errors[eNB_id], - mode, - abstraction_flag); - ue->dlsch_SI[eNB_id]->active = 0; - } + //wait until LLR Slot1 is done + wait = 0; - // do procedures for P-RNTI - if ((ue->dlsch_p[eNB_id]) && (ue->dlsch_p[eNB_id]->active == 1)) { - ue_dlsch_procedures(ue, - proc, - eNB_id, - P_PDSCH, - ue->dlsch_p[eNB_id], - NULL, - &ue->dlsch_p_errors[eNB_id], - mode, - abstraction_flag); - ue->dlsch_p[eNB_id]->active = 0; - } - // do procedures for RA-RNTI - if ((ue->dlsch_ra[eNB_id]) && (ue->dlsch_ra[eNB_id]->active == 1)) { - ue_dlsch_procedures(ue, - proc, - eNB_id, - RA_PDSCH, - ue->dlsch_ra[eNB_id], - NULL, - &ue->dlsch_ra_errors[eNB_id], - mode, - abstraction_flag); - ue->dlsch_ra[eNB_id]->active = 0; - } + while(proc->llr_slot1_available == 0) { + usleep(1); + wait++; + } - if (LOG_DEBUGFLAG(UE_TIMING) + if (LOG_DEBUGFLAG(UE_TIMING)) { + stop_meas(&ue->pdsch_procedures_stat[ue->current_thread_id[subframe_rx]]); + LOG_I(PHY, "[AbsSFN %d.%d] Full LLR Computation %5.2f \n",frame_rx,subframe_rx,ue->pdsch_procedures_stat[ue->current_thread_id[subframe_rx]].p_time/(cpuf*1000.0)); + } + + //=====================================================================// + if (LOG_DEBUGFLAG(UE_TIMING)) { + start_meas(&ue->dlsch_procedures_stat[ue->current_thread_id[subframe_rx]]); + } + + LOG_D(PHY,"==> Start Turbo Decoder active dlsch %d SI %d RA %d \n",ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0]->active, + ue->dlsch_SI[eNB_id]->active, + //ue->dlsch_p[eNB_id]->active, + ue->dlsch_ra[eNB_id]->active); + + // Start Turbo decoder + if (ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0]->active == 1) { + //VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC, VCD_FUNCTION_IN); + ue_dlsch_procedures(ue, + proc, + eNB_id, + PDSCH, + ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0], + ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][1], + &ue->dlsch_errors[eNB_id], + mode, + abstraction_flag); + //VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC, VCD_FUNCTION_OUT); + } + + // do procedures for SI-RNTI + if ((ue->dlsch_SI[eNB_id]) && (ue->dlsch_SI[eNB_id]->active == 1)) { + ue_dlsch_procedures(ue, + proc, + eNB_id, + SI_PDSCH, + ue->dlsch_SI[eNB_id], + NULL, + &ue->dlsch_SI_errors[eNB_id], + mode, + abstraction_flag); + ue->dlsch_SI[eNB_id]->active = 0; + } + + // do procedures for P-RNTI + if ((ue->dlsch_p[eNB_id]) && (ue->dlsch_p[eNB_id]->active == 1)) { + ue_dlsch_procedures(ue, + proc, + eNB_id, + P_PDSCH, + ue->dlsch_p[eNB_id], + NULL, + &ue->dlsch_p_errors[eNB_id], + mode, + abstraction_flag); + ue->dlsch_p[eNB_id]->active = 0; + } + + // do procedures for RA-RNTI + if ((ue->dlsch_ra[eNB_id]) && (ue->dlsch_ra[eNB_id]->active == 1)) { + ue_dlsch_procedures(ue, + proc, + eNB_id, + RA_PDSCH, + ue->dlsch_ra[eNB_id], + NULL, + &ue->dlsch_ra_errors[eNB_id], + mode, + abstraction_flag); + ue->dlsch_ra[eNB_id]->active = 0; + } + + if (LOG_DEBUGFLAG(UE_TIMING) stop_meas(&ue->dlsch_procedures_stat[ue->current_thread_id[subframe_rx]]); LOG_I(PHY, "[AbsSFN %d.%d] Channel Decoder: %5.2f \n",frame_rx,subframe_rx,ue->dlsch_procedures_stat[ue->current_thread_id[subframe_rx]].p_time/(cpuf*1000.0)); - } +} - // duplicate harq structure - uint8_t current_harq_pid = ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0]->current_harq_pid; - LTE_DL_UE_HARQ_t *current_harq_processes = ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0]->harq_processes[current_harq_pid]; - harq_status_t *current_harq_ack = &ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0]->harq_ack[subframe_rx]; +// duplicate harq structure +uint8_t current_harq_pid = ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0]->current_harq_pid; +LTE_DL_UE_HARQ_t *current_harq_processes = ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0]->harq_processes[current_harq_pid]; +harq_status_t *current_harq_ack = &ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0]->harq_ack[subframe_rx]; - // For Debug parallelisation - //if (current_harq_ack->ack == 0) { - //printf("[slot0 dl processing][End of Channel Decoding] AbsSubframe %d.%d Decode Fail for HarqId%d Round%d\n",frame_rx,subframe_rx,current_harq_pid,current_harq_processes->round); - //} - for(uint8_t rx_th_idx=1; rx_th_idxdlsch[ue->current_thread_id[(subframe_rx+rx_th_idx)%10]][eNB_id][0]->harq_processes[current_harq_pid]; - harq_status_t *harq_ack_dest = &ue->dlsch[ue->current_thread_id[(subframe_rx+rx_th_idx)%10]][eNB_id][0]->harq_ack[subframe_rx]; +// For Debug parallelisation +//if (current_harq_ack->ack == 0) { +//printf("[slot0 dl processing][End of Channel Decoding] AbsSubframe %d.%d Decode Fail for HarqId%d Round%d\n",frame_rx,subframe_rx,current_harq_pid,current_harq_processes->round); +//} +for(uint8_t rx_th_idx=1; rx_th_idxdlsch[ue->current_thread_id[(subframe_rx+rx_th_idx)%10]][eNB_id][0]->harq_processes[current_harq_pid]; + harq_status_t *harq_ack_dest = &ue->dlsch[ue->current_thread_id[(subframe_rx+rx_th_idx)%10]][eNB_id][0]->harq_ack[subframe_rx]; + copy_harq_proc_struct(harq_processes_dest, current_harq_processes); + copy_ack_struct(harq_ack_dest, current_harq_ack); +} - copy_harq_proc_struct(harq_processes_dest, current_harq_processes); - copy_ack_struct(harq_ack_dest, current_harq_ack); +/* +LTE_DL_UE_HARQ_t *harq_processes_dest = ue->dlsch[(subframe_rx+1)%RX_NB_TH][eNB_id][0]->harq_processes[current_harq_pid]; +LTE_DL_UE_HARQ_t *harq_processes_dest1 = ue->dlsch[(subframe_rx+2)%RX_NB_TH][eNB_id][0]->harq_processes[current_harq_pid]; - } - /* - LTE_DL_UE_HARQ_t *harq_processes_dest = ue->dlsch[(subframe_rx+1)%RX_NB_TH][eNB_id][0]->harq_processes[current_harq_pid]; - LTE_DL_UE_HARQ_t *harq_processes_dest1 = ue->dlsch[(subframe_rx+2)%RX_NB_TH][eNB_id][0]->harq_processes[current_harq_pid]; +harq_status_t *current_harq_ack = &ue->dlsch[subframe_rx%RX_NB_TH][eNB_id][0]->harq_ack[subframe_rx]; +harq_status_t *harq_ack_dest = &ue->dlsch[(subframe_rx+1)%RX_NB_TH][eNB_id][0]->harq_ack[subframe_rx]; +harq_status_t *harq_ack_dest1 = &ue->dlsch[(subframe_rx+2)%RX_NB_TH][eNB_id][0]->harq_ack[subframe_rx]; - harq_status_t *current_harq_ack = &ue->dlsch[subframe_rx%RX_NB_TH][eNB_id][0]->harq_ack[subframe_rx]; - harq_status_t *harq_ack_dest = &ue->dlsch[(subframe_rx+1)%RX_NB_TH][eNB_id][0]->harq_ack[subframe_rx]; - harq_status_t *harq_ack_dest1 = &ue->dlsch[(subframe_rx+2)%RX_NB_TH][eNB_id][0]->harq_ack[subframe_rx]; +copy_harq_proc_struct(harq_processes_dest, current_harq_processes); +copy_ack_struct(harq_ack_dest, current_harq_ack); - copy_harq_proc_struct(harq_processes_dest, current_harq_processes); - copy_ack_struct(harq_ack_dest, current_harq_ack); +copy_harq_proc_struct(harq_processes_dest1, current_harq_processes); +copy_ack_struct(harq_ack_dest1, current_harq_ack); +*/ +if (subframe_rx==9) { + if (frame_rx % 10 == 0) { + if ((ue->dlsch_received[eNB_id] - ue->dlsch_received_last[eNB_id]) != 0) + ue->dlsch_fer[eNB_id] = (100*(ue->dlsch_errors[eNB_id] - ue->dlsch_errors_last[eNB_id]))/(ue->dlsch_received[eNB_id] - ue->dlsch_received_last[eNB_id]); - copy_harq_proc_struct(harq_processes_dest1, current_harq_processes); - copy_ack_struct(harq_ack_dest1, current_harq_ack); - */ - if (subframe_rx==9) { - if (frame_rx % 10 == 0) { - if ((ue->dlsch_received[eNB_id] - ue->dlsch_received_last[eNB_id]) != 0) - ue->dlsch_fer[eNB_id] = (100*(ue->dlsch_errors[eNB_id] - ue->dlsch_errors_last[eNB_id]))/(ue->dlsch_received[eNB_id] - ue->dlsch_received_last[eNB_id]); - - ue->dlsch_errors_last[eNB_id] = ue->dlsch_errors[eNB_id]; - ue->dlsch_received_last[eNB_id] = ue->dlsch_received[eNB_id]; - } - - - ue->bitrate[eNB_id] = (ue->total_TBS[eNB_id] - ue->total_TBS_last[eNB_id])*100; - ue->total_TBS_last[eNB_id] = ue->total_TBS[eNB_id]; - LOG_D(PHY,"[UE %d] Calculating bitrate Frame %d: total_TBS = %d, total_TBS_last = %d, bitrate %f kbits\n", - ue->Mod_id,frame_rx,ue->total_TBS[eNB_id], - ue->total_TBS_last[eNB_id],(float) ue->bitrate[eNB_id]/1000.0); + ue->dlsch_errors_last[eNB_id] = ue->dlsch_errors[eNB_id]; + ue->dlsch_received_last[eNB_id] = ue->dlsch_received[eNB_id]; + } + ue->bitrate[eNB_id] = (ue->total_TBS[eNB_id] - ue->total_TBS_last[eNB_id])*100; + ue->total_TBS_last[eNB_id] = ue->total_TBS[eNB_id]; + LOG_D(PHY,"[UE %d] Calculating bitrate Frame %d: total_TBS = %d, total_TBS_last = %d, bitrate %f kbits\n", + ue->Mod_id,frame_rx,ue->total_TBS[eNB_id], + ue->total_TBS_last[eNB_id],(float) ue->bitrate[eNB_id]/1000.0); #if UE_AUTOTEST_TRACE - if ((frame_rx % 100 == 0)) { - LOG_I(PHY,"[UE %d] AUTOTEST Metric : UE_DLSCH_BITRATE = %5.2f kbps (frame = %d) \n", ue->Mod_id, (float) ue->bitrate[eNB_id]/1000.0, frame_rx); - } + + if ((frame_rx % 100 == 0)) { + LOG_I(PHY,"[UE %d] AUTOTEST Metric : UE_DLSCH_BITRATE = %5.2f kbps (frame = %d) \n", ue->Mod_id, (float) ue->bitrate[eNB_id]/1000.0, frame_rx); + } + #endif +} - } +VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_RX, VCD_FUNCTION_OUT); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_RX, VCD_FUNCTION_OUT); +if (LOG_DEBUGFLAG(UE_TIMING)) { + stop_meas(&ue->phy_proc_rx[ue->current_thread_id[subframe_rx]]); + LOG_I(PHY, "------FULL RX PROC [AbsSFN %d.%d]: %5.2f ------\n",frame_rx,subframe_rx,ue->phy_proc_rx[ue->current_thread_id[subframe_rx]].p_time/(cpuf*1000.0)); +} - if (LOG_DEBUGFLAG(UE_TIMING)){ - stop_meas(&ue->phy_proc_rx[ue->current_thread_id[subframe_rx]]); - LOG_I(PHY, "------FULL RX PROC [AbsSFN %d.%d]: %5.2f ------\n",frame_rx,subframe_rx,ue->phy_proc_rx[ue->current_thread_id[subframe_rx]].p_time/(cpuf*1000.0)); - } - - LOG_D(PHY," ****** end RX-Chain for AbsSubframe %d.%d ****** \n", frame_rx%1024, subframe_rx); - return (0); +LOG_D(PHY," ****** end RX-Chain for AbsSubframe %d.%d ****** \n", frame_rx%1024, subframe_rx); +return (0); } #endif /*UE_SLOT_PARALLELISATION */ void phy_procedures_UE_SL_RX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc) { - - } int phy_procedures_UE_RX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id, - uint8_t abstraction_flag,uint8_t do_pdcch_flag,runmode_t mode) { - + uint8_t abstraction_flag,uint8_t do_pdcch_flag,runmode_t mode) { int l,l2; int pilot1; int pmch_flag=0; int frame_rx = proc->frame_rx; int subframe_rx = proc->subframe_rx; - uint8_t next1_thread_id = ue->current_thread_id[subframe_rx]== (RX_NB_TH-1) ? 0:(ue->current_thread_id[subframe_rx]+1); uint8_t next2_thread_id = next1_thread_id== (RX_NB_TH-1) ? 0:(next1_thread_id+1); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_RX, VCD_FUNCTION_IN); - - T(T_UE_PHY_DL_TICK, T_INT(ue->Mod_id), T_INT(frame_rx%1024), T_INT(subframe_rx)); - T(T_UE_PHY_INPUT_SIGNAL, T_INT(ue->Mod_id), T_INT(frame_rx%1024), T_INT(subframe_rx), T_INT(0), T_BUFFER(&ue->common_vars.rxdata[0][subframe_rx*ue->frame_parms.samples_per_tti], ue->frame_parms.samples_per_tti * 4)); - // start timers if ( LOG_DEBUGFLAG(DEBUG_UE_PHYPROC)) { LOG_I(PHY," ****** start RX-Chain for AbsSubframe %d.%d ****** \n", frame_rx%1024, subframe_rx); @@ -4638,23 +4310,26 @@ int phy_procedures_UE_RX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id, pmch_flag = is_pmch_subframe(frame_rx,subframe_rx,&ue->frame_parms) ? 1 : 0; if (do_pdcch_flag) { - // deactivate reception until we scan pdcch - if (ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0]) - ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0]->active = 0; - if (ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][1]) - ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][1]->active = 0; + // deactivate reception until we scan pdcch + if (ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0]) + ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0]->active = 0; - if (ue->dlsch_SI[eNB_id]) - ue->dlsch_SI[eNB_id]->active = 0; - if (ue->dlsch_p[eNB_id]) - ue->dlsch_p[eNB_id]->active = 0; - if (ue->dlsch_ra[eNB_id]) - ue->dlsch_ra[eNB_id]->active = 0; + if (ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][1]) + ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][1]->active = 0; + + if (ue->dlsch_SI[eNB_id]) + ue->dlsch_SI[eNB_id]->active = 0; + + if (ue->dlsch_p[eNB_id]) + ue->dlsch_p[eNB_id]->active = 0; + + if (ue->dlsch_ra[eNB_id]) + ue->dlsch_ra[eNB_id]->active = 0; } if (LOG_DEBUGFLAG(DEBUG_UE_PHYPROC)) { - LOG_D(PHY,"[UE %d] Frame %d subframe %d: Doing phy_procedures_UE_RX\n", - ue->Mod_id,frame_rx, subframe_rx); + LOG_D(PHY,"[UE %d] Frame %d subframe %d: Doing phy_procedures_UE_RX\n", + ue->Mod_id,frame_rx, subframe_rx); } if (ue->frame_parms.Ncp == 0) { // normal prefix @@ -4663,7 +4338,6 @@ int phy_procedures_UE_RX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id, pilot1 = 3; } - if (subframe_select(&ue->frame_parms,subframe_rx) == SF_S) { // S-subframe, do first 5 symbols only l2 = 4; } else if (pmch_flag == 1) { // do first 2 symbols only @@ -4673,6 +4347,7 @@ int phy_procedures_UE_RX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id, } int prev_subframe_rx = (subframe_rx - 1)<0? 9: (subframe_rx - 1); + if (subframe_select(&ue->frame_parms,prev_subframe_rx) != SF_DL) { //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ // RX processing of symbols l=0...l2 @@ -4687,73 +4362,75 @@ int phy_procedures_UE_RX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id, LOG_D(PHY," ------ slot 0 Processing: AbsSubframe %d.%d ------ \n", frame_rx%1024, subframe_rx); LOG_D(PHY," ------ --> FFT/ChannelEst/PDCCH slot 0: AbsSubframe %d.%d ------ \n", frame_rx%1024, subframe_rx); + for (; l<=l2; l++) { if (abstraction_flag == 0) { - if (LOG_DEBUGFLAG(UE_TIMING)) { - start_meas(&ue->ofdm_demod_stats); - } + if (LOG_DEBUGFLAG(UE_TIMING)) { + start_meas(&ue->ofdm_demod_stats); + } + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP, VCD_FUNCTION_IN); slot_fep(ue, - l, - (subframe_rx<<1), - 0, - 0, - 0); + l, + (subframe_rx<<1), + 0, + 0, + 0); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP, VCD_FUNCTION_OUT); + if (LOG_DEBUGFLAG(UE_TIMING)) { stop_meas(&ue->ofdm_demod_stats); - } + } } ue_measurement_procedures(l-1,ue,proc,eNB_id,(subframe_rx<<1),abstraction_flag,mode); if (do_pdcch_flag) { if ((l==pilot1) || - ((pmch_flag==1)&&(l==l2))) { - LOG_D(PHY,"[UE %d] Frame %d: Calling pdcch procedures (eNB %d)\n",ue->Mod_id,frame_rx,eNB_id); + ((pmch_flag==1)&&(l==l2))) { + LOG_D(PHY,"[UE %d] Frame %d: Calling pdcch procedures (eNB %d)\n",ue->Mod_id,frame_rx,eNB_id); - //start_meas(&ue->rx_pdcch_stats[ue->current_thread_id[subframe_rx]]); - if (ue_pdcch_procedures(eNB_id,ue,proc,abstraction_flag) == -1) { - LOG_E(PHY,"[UE %d] Frame %d, subframe %d: Error in pdcch procedures\n",ue->Mod_id,frame_rx,subframe_rx); - return(-1); - } - //stop_meas(&ue->rx_pdcch_stats[ue->current_thread_id[subframe_rx]]); - //printf("subframe %d n_pdcch_sym %d pdcch procedures %5.3f \n", - // subframe_rx, ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->num_pdcch_symbols, - // (ue->rx_pdcch_stats[ue->current_thread_id[subframe_rx]].p_time)/(cpuf*1000.0)); - LOG_D(PHY,"num_pdcch_symbols %d\n",ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->num_pdcch_symbols); + //start_meas(&ue->rx_pdcch_stats[ue->current_thread_id[subframe_rx]]); + if (ue_pdcch_procedures(eNB_id,ue,proc,abstraction_flag) == -1) { + LOG_E(PHY,"[UE %d] Frame %d, subframe %d: Error in pdcch procedures\n",ue->Mod_id,frame_rx,subframe_rx); + return(-1); + } + + //stop_meas(&ue->rx_pdcch_stats[ue->current_thread_id[subframe_rx]]); + //printf("subframe %d n_pdcch_sym %d pdcch procedures %5.3f \n", + // subframe_rx, ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->num_pdcch_symbols, + // (ue->rx_pdcch_stats[ue->current_thread_id[subframe_rx]].p_time)/(cpuf*1000.0)); + LOG_D(PHY,"num_pdcch_symbols %d\n",ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->num_pdcch_symbols); } } - } // for l=1..l2 - ue_measurement_procedures(l-1,ue,proc,eNB_id,(subframe_rx<<1),abstraction_flag,mode); + ue_measurement_procedures(l-1,ue,proc,eNB_id,(subframe_rx<<1),abstraction_flag,mode); LOG_D(PHY," ------ end FFT/ChannelEst/PDCCH slot 0: AbsSubframe %d.%d ------ \n", frame_rx%1024, subframe_rx); // If this is PMCH, call procedures, do channel estimation for first symbol of next DL subframe and return if (pmch_flag == 1) { ue_pmch_procedures(ue,proc,eNB_id,abstraction_flag); - int next_subframe_rx = (1+subframe_rx)%10; - if (subframe_select(&ue->frame_parms,next_subframe_rx) != SF_UL) - { + + if (subframe_select(&ue->frame_parms,next_subframe_rx) != SF_UL) { slot_fep(ue, - 0, - (next_subframe_rx<<1), - 0, - 0, - 0); + 0, + (next_subframe_rx<<1), + 0, + 0, + 0); } return 0; } slot_fep(ue, - 0, - 1+(subframe_rx<<1), - 0, - 0, - 0); + 0, + 1+(subframe_rx<<1), + 0, + 0, + 0); // first slot has been processed (FFTs + Channel Estimation, PCFICH/PHICH/PDCCH) if (LOG_DEBUGFLAG(UE_TIMING)) { @@ -4761,8 +4438,8 @@ int phy_procedures_UE_RX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id, LOG_I(PHY, "[SFN %d] Slot0: FFT + Channel Estimate + PCFICH/PHICH/PDCCH %5.2f \n",subframe_rx,ue->ue_front_end_stat[ue->current_thread_id[subframe_rx]].p_time/(cpuf*1000.0)); } - LOG_D(PHY," ------ --> PDSCH ChannelComp/LLR slot 0: AbsSubframe %d.%d ------ \n", frame_rx%1024, subframe_rx); + if (LOG_DEBUGFLAG(UE_TIMING)) { start_meas(&ue->generic_stat); start_meas(&ue->crnti_procedures_stats); @@ -4772,34 +4449,35 @@ int phy_procedures_UE_RX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id, if (ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0]->active == 1) { VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC, VCD_FUNCTION_IN); ue_pdsch_procedures(ue, - proc, - eNB_id, - PDSCH, - ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0], - NULL, - ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->num_pdcch_symbols, - ue->frame_parms.symbols_per_tti>>1, - abstraction_flag); - + proc, + eNB_id, + PDSCH, + ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0], + NULL, + ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->num_pdcch_symbols, + ue->frame_parms.symbols_per_tti>>1, + abstraction_flag); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC, VCD_FUNCTION_OUT); } if (LOG_DEBUGFLAG(UE_TIMING)) { stop_meas(&ue->crnti_procedures_stats); } + LOG_D(PHY," ------ end PDSCH ChannelComp/LLR slot 0: AbsSubframe %d.%d ------ \n", frame_rx%1024, subframe_rx); + // do procedures for SI-RNTI if ((ue->dlsch_SI[eNB_id]) && (ue->dlsch_SI[eNB_id]->active == 1)) { VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_SI, VCD_FUNCTION_IN); ue_pdsch_procedures(ue, - proc, - eNB_id, - SI_PDSCH, - ue->dlsch_SI[eNB_id], - NULL, - ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->num_pdcch_symbols, - ue->frame_parms.symbols_per_tti>>1, - abstraction_flag); + proc, + eNB_id, + SI_PDSCH, + ue->dlsch_SI[eNB_id], + NULL, + ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->num_pdcch_symbols, + ue->frame_parms.symbols_per_tti>>1, + abstraction_flag); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_SI, VCD_FUNCTION_OUT); } @@ -4807,14 +4485,14 @@ int phy_procedures_UE_RX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id, if ((ue->dlsch_p[eNB_id]) && (ue->dlsch_p[eNB_id]->active == 1)) { VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_P, VCD_FUNCTION_IN); ue_pdsch_procedures(ue, - proc, - eNB_id, - P_PDSCH, - ue->dlsch_p[eNB_id], - NULL, - ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->num_pdcch_symbols, - ue->frame_parms.symbols_per_tti>>1, - abstraction_flag); + proc, + eNB_id, + P_PDSCH, + ue->dlsch_p[eNB_id], + NULL, + ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->num_pdcch_symbols, + ue->frame_parms.symbols_per_tti>>1, + abstraction_flag); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_P, VCD_FUNCTION_OUT); } @@ -4822,14 +4500,14 @@ int phy_procedures_UE_RX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id, if ((ue->dlsch_ra[eNB_id]) && (ue->dlsch_ra[eNB_id]->active == 1)) { VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_RA, VCD_FUNCTION_IN); ue_pdsch_procedures(ue, - proc, - eNB_id, - RA_PDSCH, - ue->dlsch_ra[eNB_id], - NULL, - ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->num_pdcch_symbols, - ue->frame_parms.symbols_per_tti>>1, - abstraction_flag); + proc, + eNB_id, + RA_PDSCH, + ue->dlsch_ra[eNB_id], + NULL, + ue->pdcch_vars[ue->current_thread_id[subframe_rx]][eNB_id]->num_pdcch_symbols, + ue->frame_parms.symbols_per_tti>>1, + abstraction_flag); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC_RA, VCD_FUNCTION_OUT); } @@ -4842,36 +4520,38 @@ int phy_procedures_UE_RX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id, if (LOG_DEBUGFLAG(UE_TIMING)) { start_meas(&ue->ofdm_demod_stats); } - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP, VCD_FUNCTION_IN); - slot_fep(ue, - l, - 1+(subframe_rx<<1), - 0, - 0, - 0); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP, VCD_FUNCTION_OUT); + + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP, VCD_FUNCTION_IN); + slot_fep(ue, + l, + 1+(subframe_rx<<1), + 0, + 0, + 0); + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP, VCD_FUNCTION_OUT); + if (LOG_DEBUGFLAG(UE_TIMING)) { stop_meas(&ue->ofdm_demod_stats); } } ue_measurement_procedures(l-1,ue,proc,eNB_id,1+(subframe_rx<<1),abstraction_flag,mode); - } // for l=1..l2 - ue_measurement_procedures(l-1,ue,proc,eNB_id,1+(subframe_rx<<1),abstraction_flag,mode); + ue_measurement_procedures(l-1,ue,proc,eNB_id,1+(subframe_rx<<1),abstraction_flag,mode); // do first symbol of next downlink subframe for channel estimation int next_subframe_rx = (1+subframe_rx)%10; - if (subframe_select(&ue->frame_parms,next_subframe_rx) != SF_UL) - { + + if (subframe_select(&ue->frame_parms,next_subframe_rx) != SF_UL) { slot_fep(ue, - 0, - (next_subframe_rx<<1), - 0, - 0, - 0); + 0, + (next_subframe_rx<<1), + 0, + 0, + 0); } } // not an S-subframe + if(LOG_DEBUGFLAG(UE_TIMING)) { stop_meas(&ue->generic_stat); LOG_I(PHY, "[SFN %d] Slot1: FFT + Channel Estimate + Pdsch Proc Slot0 %5.2f \n",subframe_rx,ue->generic_stat.p_time/(cpuf*1000.0)); @@ -4879,186 +4559,179 @@ int phy_procedures_UE_RX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id, LOG_D(PHY," ------ end FFT/ChannelEst/PDCCH slot 1: AbsSubframe %d.%d ------ \n", frame_rx%1024, subframe_rx); - if ( (subframe_rx == 0) && (ue->decode_MIB == 1)) - { + if ( (subframe_rx == 0) && (ue->decode_MIB == 1)) { ue_pbch_procedures(eNB_id,ue,proc,abstraction_flag); } - - // do procedures for C-RNTI LOG_D(PHY," ------ --> PDSCH ChannelComp/LLR slot 0: AbsSubframe %d.%d ------ \n", frame_rx%1024, subframe_rx); + if (ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0]->active == 1) { VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC, VCD_FUNCTION_IN); - if (LOG_DEBUGFLAG(UE_TIMING)) { + + if (LOG_DEBUGFLAG(UE_TIMING)) { start_meas(&ue->pdsch_procedures_stat[ue->current_thread_id[subframe_rx]]); } + ue_pdsch_procedures(ue, - proc, - eNB_id, - PDSCH, - ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0], - NULL, - 1+(ue->frame_parms.symbols_per_tti>>1), - ue->frame_parms.symbols_per_tti-1, - abstraction_flag); + proc, + eNB_id, + PDSCH, + ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0], + NULL, + 1+(ue->frame_parms.symbols_per_tti>>1), + ue->frame_parms.symbols_per_tti-1, + abstraction_flag); LOG_D(PHY," ------ end PDSCH ChannelComp/LLR slot 0: AbsSubframe %d.%d ------ \n", frame_rx%1024, subframe_rx); LOG_D(PHY," ------ --> PDSCH Turbo Decoder slot 0/1: AbsSubframe %d.%d ------ \n", frame_rx%1024, subframe_rx); - if (LOG_DEBUGFLAG(UE_TIMING)) { + + if (LOG_DEBUGFLAG(UE_TIMING)) { stop_meas(&ue->pdsch_procedures_stat[ue->current_thread_id[subframe_rx]]); start_meas(&ue->dlsch_procedures_stat[ue->current_thread_id[subframe_rx]]); } + ue_dlsch_procedures(ue, - proc, - eNB_id, - PDSCH, - ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0], - ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][1], - &ue->dlsch_errors[eNB_id], - mode, - abstraction_flag); - if (LOG_DEBUGFLAG(UE_TIMING)) { + proc, + eNB_id, + PDSCH, + ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0], + ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][1], + &ue->dlsch_errors[eNB_id], + mode, + abstraction_flag); + + if (LOG_DEBUGFLAG(UE_TIMING)) { stop_meas(&ue->dlsch_procedures_stat[ue->current_thread_id[subframe_rx]]); LOG_I(PHY, "[SFN %d] Slot1: Pdsch Proc %5.2f\n",subframe_rx,ue->pdsch_procedures_stat[ue->current_thread_id[subframe_rx]].p_time/(cpuf*1000.0)); LOG_I(PHY, "[SFN %d] Slot0 Slot1: Dlsch Proc %5.2f\n",subframe_rx,ue->dlsch_procedures_stat[ue->current_thread_id[subframe_rx]].p_time/(cpuf*1000.0)); } VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDSCH_PROC, VCD_FUNCTION_OUT); - } + if (LOG_DEBUGFLAG(UE_TIMING)) { start_meas(&ue->generic_stat); } if (LOG_DUMPFLAG(DEBUG_UE_PHYPROC)) { - if(subframe_rx==5 && ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0]->harq_processes[ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0]->current_harq_pid]->nb_rb > 20){ - //LOG_M("decoder_llr.m","decllr",dlsch_llr,G,1,0); - //LOG_M("llr.m","llr", &ue->pdsch_vars[eNB_id]->llr[0][0],(14*nb_rb*12*dlsch1_harq->Qm) - 4*(nb_rb*4*dlsch1_harq->Qm),1,0); - - LOG_M("rxdataF0_current.m" , "rxdataF0", &ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe_rx]].rxdataF[0][0],14*ue->frame_parms.ofdm_symbol_size,1,1); - //LOG_M("rxdataF0_previous.m" , "rxdataF0_prev_sss", &ue->common_vars.common_vars_rx_data_per_thread[next_thread_id].rxdataF[0][0],14*ue->frame_parms.ofdm_symbol_size,1,1); - - //LOG_M("rxdataF0_previous.m" , "rxdataF0_prev", &ue->common_vars.common_vars_rx_data_per_thread[next_thread_id].rxdataF[0][0],14*ue->frame_parms.ofdm_symbol_size,1,1); - - LOG_M("dl_ch_estimates.m", "dl_ch_estimates_sfn5", &ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe_rx]].dl_ch_estimates[0][0][0],14*ue->frame_parms.ofdm_symbol_size,1,1); - LOG_M("dl_ch_estimates_ext.m", "dl_ch_estimatesExt_sfn5", &ue->pdsch_vars[ue->current_thread_id[subframe_rx]][0]->dl_ch_estimates_ext[0][0],14*ue->frame_parms.N_RB_DL*12,1,1); - LOG_M("rxdataF_comp00.m","rxdataF_comp00", &ue->pdsch_vars[ue->current_thread_id[subframe_rx]][0]->rxdataF_comp0[0][0],14*ue->frame_parms.N_RB_DL*12,1,1); - //LOG_M("magDLFirst.m", "magDLFirst", &phy_vars_ue->pdsch_vars[ue->current_thread_id[subframe_rx]][0]->dl_ch_mag0[0][0],14*frame_parms->N_RB_DL*12,1,1); - //LOG_M("magDLSecond.m", "magDLSecond", &phy_vars_ue->pdsch_vars[ue->current_thread_id[subframe_rx]][0]->dl_ch_magb0[0][0],14*frame_parms->N_RB_DL*12,1,1); - - AssertFatal (0,""); + if(subframe_rx==5 && ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0]->harq_processes[ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0]->current_harq_pid]->nb_rb > 20) { + //LOG_M("decoder_llr.m","decllr",dlsch_llr,G,1,0); + //LOG_M("llr.m","llr", &ue->pdsch_vars[eNB_id]->llr[0][0],(14*nb_rb*12*dlsch1_harq->Qm) - 4*(nb_rb*4*dlsch1_harq->Qm),1,0); + LOG_M("rxdataF0_current.m", "rxdataF0", &ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe_rx]].rxdataF[0][0],14*ue->frame_parms.ofdm_symbol_size,1,1); + //LOG_M("rxdataF0_previous.m" , "rxdataF0_prev_sss", &ue->common_vars.common_vars_rx_data_per_thread[next_thread_id].rxdataF[0][0],14*ue->frame_parms.ofdm_symbol_size,1,1); + //LOG_M("rxdataF0_previous.m" , "rxdataF0_prev", &ue->common_vars.common_vars_rx_data_per_thread[next_thread_id].rxdataF[0][0],14*ue->frame_parms.ofdm_symbol_size,1,1); + LOG_M("dl_ch_estimates.m", "dl_ch_estimates_sfn5", &ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe_rx]].dl_ch_estimates[0][0][0],14*ue->frame_parms.ofdm_symbol_size,1, + 1); + LOG_M("dl_ch_estimates_ext.m", "dl_ch_estimatesExt_sfn5", &ue->pdsch_vars[ue->current_thread_id[subframe_rx]][0]->dl_ch_estimates_ext[0][0],14*ue->frame_parms.N_RB_DL*12,1,1); + LOG_M("rxdataF_comp00.m","rxdataF_comp00", &ue->pdsch_vars[ue->current_thread_id[subframe_rx]][0]->rxdataF_comp0[0][0],14*ue->frame_parms.N_RB_DL*12,1,1); + //LOG_M("magDLFirst.m", "magDLFirst", &phy_vars_ue->pdsch_vars[ue->current_thread_id[subframe_rx]][0]->dl_ch_mag0[0][0],14*frame_parms->N_RB_DL*12,1,1); + //LOG_M("magDLSecond.m", "magDLSecond", &phy_vars_ue->pdsch_vars[ue->current_thread_id[subframe_rx]][0]->dl_ch_magb0[0][0],14*frame_parms->N_RB_DL*12,1,1); + AssertFatal (0,""); } } // do procedures for SI-RNTI if ((ue->dlsch_SI[eNB_id]) && (ue->dlsch_SI[eNB_id]->active == 1)) { ue_pdsch_procedures(ue, - proc, - eNB_id, - SI_PDSCH, - ue->dlsch_SI[eNB_id], - NULL, - 1+(ue->frame_parms.symbols_per_tti>>1), - ue->frame_parms.symbols_per_tti-1, - abstraction_flag); - + proc, + eNB_id, + SI_PDSCH, + ue->dlsch_SI[eNB_id], + NULL, + 1+(ue->frame_parms.symbols_per_tti>>1), + ue->frame_parms.symbols_per_tti-1, + abstraction_flag); ue_dlsch_procedures(ue, - proc, - eNB_id, - SI_PDSCH, - ue->dlsch_SI[eNB_id], - NULL, - &ue->dlsch_SI_errors[eNB_id], - mode, - abstraction_flag); + proc, + eNB_id, + SI_PDSCH, + ue->dlsch_SI[eNB_id], + NULL, + &ue->dlsch_SI_errors[eNB_id], + mode, + abstraction_flag); ue->dlsch_SI[eNB_id]->active = 0; } // do procedures for P-RNTI if ((ue->dlsch_p[eNB_id]) && (ue->dlsch_p[eNB_id]->active == 1)) { ue_pdsch_procedures(ue, - proc, - eNB_id, - P_PDSCH, - ue->dlsch_p[eNB_id], - NULL, - 1+(ue->frame_parms.symbols_per_tti>>1), - ue->frame_parms.symbols_per_tti-1, - abstraction_flag); - + proc, + eNB_id, + P_PDSCH, + ue->dlsch_p[eNB_id], + NULL, + 1+(ue->frame_parms.symbols_per_tti>>1), + ue->frame_parms.symbols_per_tti-1, + abstraction_flag); ue_dlsch_procedures(ue, - proc, - eNB_id, - P_PDSCH, - ue->dlsch_p[eNB_id], - NULL, - &ue->dlsch_p_errors[eNB_id], - mode, - abstraction_flag); + proc, + eNB_id, + P_PDSCH, + ue->dlsch_p[eNB_id], + NULL, + &ue->dlsch_p_errors[eNB_id], + mode, + abstraction_flag); ue->dlsch_p[eNB_id]->active = 0; } + // do procedures for RA-RNTI if ((ue->dlsch_ra[eNB_id]) && (ue->dlsch_ra[eNB_id]->active == 1)) { ue_pdsch_procedures(ue, - proc, - eNB_id, - RA_PDSCH, - ue->dlsch_ra[eNB_id], - NULL, - 1+(ue->frame_parms.symbols_per_tti>>1), - ue->frame_parms.symbols_per_tti-1, - abstraction_flag); + proc, + eNB_id, + RA_PDSCH, + ue->dlsch_ra[eNB_id], + NULL, + 1+(ue->frame_parms.symbols_per_tti>>1), + ue->frame_parms.symbols_per_tti-1, + abstraction_flag); ue_dlsch_procedures(ue, - proc, - eNB_id, - RA_PDSCH, - ue->dlsch_ra[eNB_id], - NULL, - &ue->dlsch_ra_errors[eNB_id], - mode, - abstraction_flag); + proc, + eNB_id, + RA_PDSCH, + ue->dlsch_ra[eNB_id], + NULL, + &ue->dlsch_ra_errors[eNB_id], + mode, + abstraction_flag); ue->dlsch_ra[eNB_id]->active = 0; } // duplicate harq structure - uint8_t current_harq_pid = ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0]->current_harq_pid; LTE_DL_UE_HARQ_t *current_harq_processes = ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0]->harq_processes[current_harq_pid]; LTE_DL_UE_HARQ_t *harq_processes_dest = ue->dlsch[next1_thread_id][eNB_id][0]->harq_processes[current_harq_pid]; LTE_DL_UE_HARQ_t *harq_processes_dest1 = ue->dlsch[next2_thread_id][eNB_id][0]->harq_processes[current_harq_pid]; - harq_status_t *current_harq_ack = &ue->dlsch[ue->current_thread_id[subframe_rx]][eNB_id][0]->harq_ack[subframe_rx]; harq_status_t *harq_ack_dest = &ue->dlsch[next1_thread_id][eNB_id][0]->harq_ack[subframe_rx]; harq_status_t *harq_ack_dest1 = &ue->dlsch[next2_thread_id][eNB_id][0]->harq_ack[subframe_rx]; - copy_harq_proc_struct(harq_processes_dest, current_harq_processes); copy_ack_struct(harq_ack_dest, current_harq_ack); - copy_harq_proc_struct(harq_processes_dest1, current_harq_processes); copy_ack_struct(harq_ack_dest1, current_harq_ack); if (subframe_rx==9) { if (frame_rx % 10 == 0) { if ((ue->dlsch_received[eNB_id] - ue->dlsch_received_last[eNB_id]) != 0) - ue->dlsch_fer[eNB_id] = (100*(ue->dlsch_errors[eNB_id] - ue->dlsch_errors_last[eNB_id]))/(ue->dlsch_received[eNB_id] - ue->dlsch_received_last[eNB_id]); + ue->dlsch_fer[eNB_id] = (100*(ue->dlsch_errors[eNB_id] - ue->dlsch_errors_last[eNB_id]))/(ue->dlsch_received[eNB_id] - ue->dlsch_received_last[eNB_id]); ue->dlsch_errors_last[eNB_id] = ue->dlsch_errors[eNB_id]; ue->dlsch_received_last[eNB_id] = ue->dlsch_received[eNB_id]; } - ue->bitrate[eNB_id] = (ue->total_TBS[eNB_id] - ue->total_TBS_last[eNB_id])*100; ue->total_TBS_last[eNB_id] = ue->total_TBS[eNB_id]; LOG_D(PHY,"[UE %d] Calculating bitrate Frame %d: total_TBS = %d, total_TBS_last = %d, bitrate %f kbits\n", - ue->Mod_id,frame_rx,ue->total_TBS[eNB_id], - ue->total_TBS_last[eNB_id],(float) ue->bitrate[eNB_id]/1000.0); + ue->Mod_id,frame_rx,ue->total_TBS[eNB_id], + ue->total_TBS_last[eNB_id],(float) ue->bitrate[eNB_id]/1000.0); if ( LOG_DEBUGFLAG(DEBUG_UE_PHYPROC)) { if ((frame_rx % 100 == 0)) { LOG_UI(PHY,"[UE %d] AUTOTEST Metric : UE_DLSCH_BITRATE = %5.2f kbps (frame = %d) \n", ue->Mod_id, (float) ue->bitrate[eNB_id]/1000.0, frame_rx); } } - } if ( LOG_DEBUGFLAG(UE_TIMING)) { @@ -5079,19 +4752,15 @@ int phy_procedures_UE_RX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id, -void phy_procedures_UE_lte(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t abstraction_flag,uint8_t do_pdcch_flag,runmode_t mode) -{ +void phy_procedures_UE_lte(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uint8_t abstraction_flag,uint8_t do_pdcch_flag,runmode_t mode) { #if defined(ENABLE_ITTI) MessageDef *msg_p; int result; #endif - int frame_rx = proc->frame_rx; int frame_tx = proc->frame_tx; int subframe_rx = proc->subframe_rx; int subframe_tx = proc->subframe_tx; - - UE_L2_STATE_t ret; int slot; @@ -5099,8 +4768,8 @@ void phy_procedures_UE_lte(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,u ue->UE_mode[eNB_id]=PUSCH; } - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_LTE,1); + if ( LOG_DEBUGFLAG(UE_TIMING)) { start_meas(&ue->phy_proc[ue->current_thread_id[subframe_rx]]); } @@ -5113,15 +4782,14 @@ void phy_procedures_UE_lte(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,u if (msg_p != NULL) { switch (ITTI_MSG_ID(msg_p)) { - case PHY_FIND_CELL_REQ: - LOG_I(PHY, "[UE %d] Received %s\n", ITTI_MSG_INSTANCE (msg_p) - NB_eNB_INST, ITTI_MSG_NAME (msg_p)); + case PHY_FIND_CELL_REQ: + LOG_I(PHY, "[UE %d] Received %s\n", ITTI_MSG_INSTANCE (msg_p) - NB_eNB_INST, ITTI_MSG_NAME (msg_p)); + /* TODO process the message */ + break; - /* TODO process the message */ - break; - - default: - LOG_E(PHY, "[UE %d] Received unexpected message %s\n", ITTI_MSG_INSTANCE (msg_p) - NB_eNB_INST, ITTI_MSG_NAME (msg_p)); - break; + default: + LOG_E(PHY, "[UE %d] Received unexpected message %s\n", ITTI_MSG_INSTANCE (msg_p) - NB_eNB_INST, ITTI_MSG_NAME (msg_p)); + break; } result = itti_free (ITTI_MSG_ORIGIN_ID(msg_p), msg_p); @@ -5131,62 +4799,61 @@ void phy_procedures_UE_lte(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,u #endif - for (slot=0;slot<2;slot++) { - + for (slot=0; slot<2; slot++) { if ((subframe_select(&ue->frame_parms,subframe_tx)==SF_UL)|| - (ue->frame_parms.frame_type == FDD)) { + (ue->frame_parms.frame_type == FDD)) { phy_procedures_UE_TX(ue,proc,eNB_id,abstraction_flag,mode); } if ((subframe_select(&ue->frame_parms,subframe_rx)==SF_DL) || - (ue->frame_parms.frame_type == FDD)) { + (ue->frame_parms.frame_type == FDD)) { phy_procedures_UE_RX(ue,proc,eNB_id,abstraction_flag,do_pdcch_flag,mode); } if ((subframe_select(&ue->frame_parms,subframe_tx)==SF_S) && - (slot==1)) { + (slot==1)) { phy_procedures_UE_S_TX(ue,eNB_id,abstraction_flag); } if ((subframe_select(&ue->frame_parms,subframe_rx)==SF_S) && - (slot==0)) { - phy_procedures_UE_RX(ue,proc,eNB_id,abstraction_flag,do_pdcch_flag,mode); + (slot==0)) { + phy_procedures_UE_RX(ue,proc,eNB_id,abstraction_flag,do_pdcch_flag,mode); } if (ue->mac_enabled==1) { if (slot==0) { - - //LOG_I(PHY,"[UE %d] Frame %d, subframe %d, star ue_scheduler\n", ue->Mod_id,frame_rx,subframe_tx); + //LOG_I(PHY,"[UE %d] Frame %d, subframe %d, star ue_scheduler\n", ue->Mod_id,frame_rx,subframe_tx); ret = ue_scheduler(ue->Mod_id, - frame_rx, - subframe_rx, - frame_tx, - subframe_tx, - subframe_select(&ue->frame_parms,subframe_tx), - eNB_id, - 0/*FIXME CC_id*/); - - if (ret == CONNECTION_LOST) { - LOG_E(PHY,"[UE %d] Frame %d, subframe %d RRC Connection lost, returning to PRACH\n",ue->Mod_id, - frame_rx,subframe_tx); - ue->UE_mode[eNB_id] = PRACH; - // mac_xface->macphy_exit("Connection lost"); - } else if (ret == PHY_RESYNCH) { - LOG_E(PHY,"[UE %d] Frame %d, subframe %d RRC Connection lost, trying to resynch\n", - ue->Mod_id, - frame_rx,subframe_tx); - ue->UE_mode[eNB_id] = RESYNCH; - // mac_xface->macphy_exit("Connection lost"); - } 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", - ue->Mod_id,frame_rx,subframe_tx); - ue->UE_mode[eNB_id] = PRACH; - } + frame_rx, + subframe_rx, + frame_tx, + subframe_tx, + subframe_select(&ue->frame_parms,subframe_tx), + eNB_id, + 0/*FIXME CC_id*/); + + if (ret == CONNECTION_LOST) { + LOG_E(PHY,"[UE %d] Frame %d, subframe %d RRC Connection lost, returning to PRACH\n",ue->Mod_id, + frame_rx,subframe_tx); + ue->UE_mode[eNB_id] = PRACH; + // mac_xface->macphy_exit("Connection lost"); + } else if (ret == PHY_RESYNCH) { + LOG_E(PHY,"[UE %d] Frame %d, subframe %d RRC Connection lost, trying to resynch\n", + ue->Mod_id, + frame_rx,subframe_tx); + ue->UE_mode[eNB_id] = RESYNCH; + // mac_xface->macphy_exit("Connection lost"); + } 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", + ue->Mod_id,frame_rx,subframe_tx); + ue->UE_mode[eNB_id] = PRACH; + } } } - + VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_UE_LTE,0); - if (LOG_DEBUGFLAG(UE_TIMING)) { + + if (LOG_DEBUGFLAG(UE_TIMING)) { stop_meas(&ue->phy_proc[ue->current_thread_id[subframe_rx]]); } } // slot From bfb65b57f74e061ca54c8e665b5d3f06d30c9d7b Mon Sep 17 00:00:00 2001 From: Louis Adrien Dufrene Date: Fri, 16 Nov 2018 11:36:44 +0100 Subject: [PATCH 149/233] astyle applied --- openair2/ENB_APP/enb_config.c | 2 +- targets/RT/USER/lte-enb.c | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/openair2/ENB_APP/enb_config.c b/openair2/ENB_APP/enb_config.c index 3eaa2ad7ad..efbceb49bd 100644 --- a/openair2/ENB_APP/enb_config.c +++ b/openair2/ENB_APP/enb_config.c @@ -2308,7 +2308,7 @@ int RCconfig_S1( default: { LOG_E(S1AP, "Default I-DRX value in conf file is invalid (%i). Should be 32, 64, 128 or 256. \ - Default DRX set to 32 in MME configuration\n", + Default DRX set to 32 in MME configuration\n", pcch_defaultPagingCycle); S1AP_REGISTER_ENB_REQ(msg_p).default_drx = 0; } diff --git a/targets/RT/USER/lte-enb.c b/targets/RT/USER/lte-enb.c index cef0232932..fdbb80e025 100644 --- a/targets/RT/USER/lte-enb.c +++ b/targets/RT/USER/lte-enb.c @@ -684,8 +684,6 @@ void wakeup_prach_eNB_br(PHY_VARS_eNB *eNB,RU_t *ru,int frame,int subframe) { } } - <<<<<<< HEAD - // check if we have to detect PRACH first if (is_prach_subframe(fp,frame,subframe)>0) { LOG_D(PHY,"Triggering prach br processing, frame %d, subframe %d\n",frame,subframe); From 04a3cda0b2621b6b78c7ebf8f86b0322d10c56fc Mon Sep 17 00:00:00 2001 From: Louis Adrien Dufrene Date: Fri, 16 Nov 2018 11:42:13 +0100 Subject: [PATCH 150/233] wrong manipulation had modified lte-enb.c --- targets/RT/USER/lte-enb.c | 1067 ++++++++++++++++--------------------- 1 file changed, 463 insertions(+), 604 deletions(-) diff --git a/targets/RT/USER/lte-enb.c b/targets/RT/USER/lte-enb.c index fdbb80e025..bba8878316 100644 --- a/targets/RT/USER/lte-enb.c +++ b/targets/RT/USER/lte-enb.c @@ -691,709 +691,568 @@ void wakeup_prach_eNB_br(PHY_VARS_eNB *eNB,RU_t *ru,int frame,int subframe) { if (proc->instance_cnt_prach_br == 0) { LOG_W(PHY,"[eNB] Frame %d Subframe %d, dropping PRACH BR\n", frame,subframe); return; - ======= } - eNB_thread_asynch_rxtx_status=0; - return(&eNB_thread_asynch_rxtx_status); - } - - void rx_rf(PHY_VARS_eNB *eNB,int *frame,int *subframe) { - eNB_proc_t *proc = &eNB->proc; - LTE_DL_FRAME_PARMS *fp = &eNB->frame_parms; - void *rxp[fp->nb_antennas_rx],*txp[fp->nb_antennas_tx]; - unsigned int rxs,txs; - int i; - int tx_sfoffset = (eNB->single_thread_flag == 1) ? 3 : 2; - openair0_timestamp ts,old_ts; - - if (proc->first_rx==0) { - // Transmit TX buffer based on timestamp from RX - // printf("trx_write -> USRP TS %llu (sf %d)\n", (proc->timestamp_rx+(3*fp->samples_per_tti)),(proc->subframe_rx+2)%10); - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TST, (proc->timestamp_rx+(tx_sfoffset*fp->samples_per_tti)-openair0_cfg[0].tx_sample_advance)&0xffffffff ); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE, 1 ); - // prepare tx buffer pointers - lte_subframe_t SF_type = subframe_select(fp,(proc->subframe_rx+tx_sfoffset)%10); - lte_subframe_t prevSF_type = subframe_select(fp,(proc->subframe_rx+tx_sfoffset+9)%10); - lte_subframe_t nextSF_type = subframe_select(fp,(proc->subframe_rx+tx_sfoffset+1)%10); - int sf_extension = 0; - - if ((SF_type == SF_DL) || - (SF_type == SF_S)) { - int siglen=fp->samples_per_tti,flags=1; - - if (SF_type == SF_S) { - siglen = (fp->dl_symbols_in_S_subframe+1)*(fp->ofdm_symbol_size+fp->nb_prefix_samples0); - flags=3; // end of burst - } - - if ((fp->frame_type == TDD) && - (SF_type == SF_DL)&& - (prevSF_type == SF_UL) && - (nextSF_type == SF_DL)) { - flags = 2; // start of burst - sf_extension = eNB->N_TA_offset<<1; - } - - if ((fp->frame_type == TDD) && - (SF_type == SF_DL)&& - (prevSF_type == SF_UL) && - (nextSF_type == SF_UL)) { - flags = 4; // start of burst and end of burst (only one DL SF between two UL) - sf_extension = eNB->N_TA_offset<<1; - } - - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE, 1 ); - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_WRITE_FLAGS,flags); - - for (i=0; inb_antennas_tx; i++) - txp[i] = (void *)&eNB->common_vars.txdata[0][i][((proc->subframe_rx+tx_sfoffset)%10)*fp->samples_per_tti-sf_extension]; - - txs = eNB->rfdevice.trx_write_func(&eNB->rfdevice, - proc->timestamp_rx+eNB->ts_offset+(tx_sfoffset*fp->samples_per_tti)-openair0_cfg[0].tx_sample_advance-sf_extension, - txp, - siglen+sf_extension, - fp->nb_antennas_tx, - flags); - clock_gettime( CLOCK_MONOTONIC, &end_rf); - end_rf_ts = proc->timestamp_rx+eNB->ts_offset+(tx_sfoffset*fp->samples_per_tti)-openair0_cfg[0].tx_sample_advance; - - if (recv_if_count != 0 ) { - recv_if_count = recv_if_count-1; - LOG_D(HW,"[From Timestamp %"PRId64" to Timestamp %"PRId64"] RTT_RF: %"PRId64"; RTT_RF\n", start_rf_prev_ts, end_rf_ts, clock_difftime_ns(start_rf_prev, end_rf)); - LOG_D(HW,"[From Timestamp %"PRId64" to Timestamp %"PRId64"] RTT_RF: %"PRId64"; RTT_RF\n",start_rf_prev2_ts, end_rf_ts, clock_difftime_ns(start_rf_prev2, end_rf)); - } - - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE, 0 ); - - if (txs != siglen+sf_extension) { - LOG_E(PHY,"TX : Timeout (sent %d/%d)\n",txs, fp->samples_per_tti); - exit_fun( "problem transmitting samples" ); - } - } + // wake up thread for PRACH RX + if (pthread_mutex_lock(&proc->mutex_prach_br) != 0) { + LOG_E( PHY, "[eNB] ERROR pthread_mutex_lock for eNB PRACH thread %d (IC %d)\n", proc->thread_index, proc->instance_cnt_prach_br); + exit_fun( "error locking mutex_prach" ); + return; } - - for (i=0; inb_antennas_rx; i++) - rxp[i] = (void *)&eNB->common_vars.rxdata[0][i][*subframe*fp->samples_per_tti]; - - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ, 1 ); - old_ts = proc->timestamp_rx; - rxs = eNB->rfdevice.trx_read_func(&eNB->rfdevice, - &ts, - rxp, - fp->samples_per_tti, - fp->nb_antennas_rx); - start_rf_prev2= start_rf_prev; - start_rf_prev2_ts= start_rf_prev_ts; - start_rf_prev = start_rf_new; - start_rf_prev_ts = start_rf_new_ts; - clock_gettime( CLOCK_MONOTONIC, &start_rf_new); - start_rf_new_ts = ts; - LOG_D(PHY,"rx_rf: first_rx %d received ts %"PRId64" (sptti %d)\n",proc->first_rx,ts,fp->samples_per_tti); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ, 0 ); - proc->timestamp_rx = ts-eNB->ts_offset; - - if (rxs != fp->samples_per_tti) - LOG_E(PHY,"rx_rf: Asked for %d samples, got %d from USRP\n",fp->samples_per_tti,rxs); - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ, 0 ); + ++proc->instance_cnt_prach_br; + // set timing for prach thread + proc->frame_prach_br = frame; + proc->subframe_prach_br = subframe; - if (proc->first_rx == 1) { - eNB->ts_offset = proc->timestamp_rx; - proc->timestamp_rx=0; - } else { - if (proc->timestamp_rx - old_ts != fp->samples_per_tti) { - LOG_I(PHY,"rx_rf: rfdevice timing drift of %"PRId64" samples (ts_off %"PRId64")\n",proc->timestamp_rx - old_ts - fp->samples_per_tti,eNB->ts_offset); - eNB->ts_offset += (proc->timestamp_rx - old_ts - fp->samples_per_tti); - proc->timestamp_rx = ts-eNB->ts_offset; - } + // the thread can now be woken up + if (pthread_cond_signal(&proc->cond_prach_br) != 0) { + LOG_E( PHY, "[eNB] ERROR pthread_cond_signal for eNB PRACH BR thread %d\n", proc->thread_index); + exit_fun( "ERROR pthread_cond_signal" ); + return; } - proc->frame_rx = (proc->timestamp_rx / (fp->samples_per_tti*10))&1023; - proc->subframe_rx = (proc->timestamp_rx / fp->samples_per_tti)%10; - proc->frame_rx = (proc->frame_rx+proc->frame_offset)&1023; - proc->frame_tx = proc->frame_rx; - - if (proc->subframe_rx > 5) proc->frame_tx=(proc->frame_tx+1)&1023; - - // synchronize first reception to frame 0 subframe 0 - proc->timestamp_tx = proc->timestamp_rx+(4*fp->samples_per_tti); - // printf("trx_read <- USRP TS %lu (offset %d sf %d, f %d, first_rx %d)\n", proc->timestamp_rx,eNB->ts_offset,proc->subframe_rx,proc->frame_rx,proc->first_rx); - - if (proc->first_rx == 0) { - if (proc->subframe_rx != *subframe) { - LOG_E(PHY,"rx_rf: Received Timestamp (%"PRId64") doesn't correspond to the time we think it is (proc->subframe_rx %d, subframe %d)\n",proc->timestamp_rx,proc->subframe_rx,*subframe); - exit_fun("Exiting"); - } - - int f2 = (*frame+proc->frame_offset)&1023; - - if (proc->frame_rx != f2) { - LOG_E(PHY,"rx_rf: Received Timestamp (%"PRId64") doesn't correspond to the time we think it is (proc->frame_rx %d frame %d, frame_offset %d, f2 %d)\n",proc->timestamp_rx,proc->frame_rx,*frame, - proc->frame_offset,f2); - exit_fun("Exiting"); - } - } else { - proc->first_rx--; - *frame = proc->frame_rx; - *subframe = proc->subframe_rx; - } - - //printf("timestamp_rx %lu, frame %d(%d), subframe %d(%d)\n",proc->timestamp_rx,proc->frame_rx,frame,proc->subframe_rx,subframe); - VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_TRX_TS, proc->timestamp_rx&0xffffffff ); - - if (rxs != fp->samples_per_tti) - exit_fun( "problem receiving samples" ); - } - void rx_fh_if5(PHY_VARS_eNB *eNB,int *frame, int *subframe) { - LTE_DL_FRAME_PARMS *fp = &eNB->frame_parms; - eNB_proc_t *proc = &eNB->proc; - recv_IF5(eNB, &proc->timestamp_rx, *subframe, IF5_RRH_GW_UL); - proc->frame_rx = (proc->timestamp_rx / (fp->samples_per_tti*10))&1023; - proc->subframe_rx = (proc->timestamp_rx / fp->samples_per_tti)%10; - - if (proc->first_rx == 0) { - if (proc->subframe_rx != *subframe) { - LOG_E(PHY,"rx_fh_if5: Received Timestamp doesn't correspond to the time we think it is (proc->subframe_rx %d, subframe %d)\n",proc->subframe_rx,*subframe); - exit_fun("Exiting"); - >>>>>>> ae0494b0bc431bf664e300b0b5a10f348d6b6757 - } - - // wake up thread for PRACH RX - if (pthread_mutex_lock(&proc->mutex_prach_br) != 0) { - LOG_E( PHY, "[eNB] ERROR pthread_mutex_lock for eNB PRACH thread %d (IC %d)\n", proc->thread_index, proc->instance_cnt_prach_br); - exit_fun( "error locking mutex_prach" ); - return; - } - - ++proc->instance_cnt_prach_br; - // set timing for prach thread - proc->frame_prach_br = frame; - proc->subframe_prach_br = subframe; - - // the thread can now be woken up - if (pthread_cond_signal(&proc->cond_prach_br) != 0) { - LOG_E( PHY, "[eNB] ERROR pthread_cond_signal for eNB PRACH BR thread %d\n", proc->thread_index); - exit_fun( "ERROR pthread_cond_signal" ); - return; - } - - pthread_mutex_unlock( &proc->mutex_prach_br ); - } + pthread_mutex_unlock( &proc->mutex_prach_br ); } +} #endif - /*! - * \brief The prach receive thread of eNB. - * \param param is a \ref eNB_proc_t structure which contains the info what to process. - * \returns a pointer to an int. The storage is not on the heap and must not be freed. - */ - static void *eNB_thread_prach( void *param ) { - static int eNB_thread_prach_status; - PHY_VARS_eNB *eNB= (PHY_VARS_eNB *)param; - eNB_proc_t *proc = &eNB->proc; - // set default return value - eNB_thread_prach_status = 0; - thread_top_init("eNB_thread_prach",1,500000,1000000,20000000); - //wait_sync("eNB_thread_prach"); - while (!oai_exit) { - if (wait_on_condition(&proc->mutex_prach,&proc->cond_prach,&proc->instance_cnt_prach,"eNB_prach_thread") < 0) break; +/*! + * \brief The prach receive thread of eNB. + * \param param is a \ref eNB_proc_t structure which contains the info what to process. + * \returns a pointer to an int. The storage is not on the heap and must not be freed. + */ +static void *eNB_thread_prach( void *param ) { + static int eNB_thread_prach_status; + PHY_VARS_eNB *eNB= (PHY_VARS_eNB *)param; + eNB_proc_t *proc = &eNB->proc; + // set default return value + eNB_thread_prach_status = 0; + thread_top_init("eNB_thread_prach",1,500000,1000000,20000000); - if (oai_exit) break; + //wait_sync("eNB_thread_prach"); - LOG_D(PHY,"Running eNB prach procedures\n"); - prach_procedures(eNB + while (!oai_exit) { + if (wait_on_condition(&proc->mutex_prach,&proc->cond_prach,&proc->instance_cnt_prach,"eNB_prach_thread") < 0) break; + + if (oai_exit) break; + + LOG_D(PHY,"Running eNB prach procedures\n"); + prach_procedures(eNB #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - ,0 + ,0 #endif - ); + ); - if (release_thread(&proc->mutex_prach,&proc->instance_cnt_prach,"eNB_prach_thread") < 0) break; - } - - LOG_I(PHY, "Exiting eNB thread PRACH\n"); - eNB_thread_prach_status = 0; - return &eNB_thread_prach_status; + if (release_thread(&proc->mutex_prach,&proc->instance_cnt_prach,"eNB_prach_thread") < 0) break; } + + LOG_I(PHY, "Exiting eNB thread PRACH\n"); + eNB_thread_prach_status = 0; + return &eNB_thread_prach_status; +} + #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - /*! - * \brief The prach receive thread of eNB for BL/CE UEs. - * \param param is a \ref eNB_proc_t structure which contains the info what to process. - * \returns a pointer to an int. The storage is not on the heap and must not be freed. - */ - static void *eNB_thread_prach_br( void *param ) { - static int eNB_thread_prach_status; - PHY_VARS_eNB *eNB= (PHY_VARS_eNB *)param; - eNB_proc_t *proc = &eNB->proc; - // set default return value - eNB_thread_prach_status = 0; - thread_top_init("eNB_thread_prach_br",1,500000,1000000,20000000); +/*! + * \brief The prach receive thread of eNB for BL/CE UEs. + * \param param is a \ref eNB_proc_t structure which contains the info what to process. + * \returns a pointer to an int. The storage is not on the heap and must not be freed. + */ +static void *eNB_thread_prach_br( void *param ) { + static int eNB_thread_prach_status; + PHY_VARS_eNB *eNB= (PHY_VARS_eNB *)param; + eNB_proc_t *proc = &eNB->proc; + // set default return value + eNB_thread_prach_status = 0; + thread_top_init("eNB_thread_prach_br",1,500000,1000000,20000000); - while (!oai_exit) { - if (wait_on_condition(&proc->mutex_prach_br,&proc->cond_prach_br,&proc->instance_cnt_prach_br,"eNB_prach_thread_br") < 0) break; + while (!oai_exit) { + if (wait_on_condition(&proc->mutex_prach_br,&proc->cond_prach_br,&proc->instance_cnt_prach_br,"eNB_prach_thread_br") < 0) break; - if (oai_exit) break; + if (oai_exit) break; - LOG_D(PHY,"Running eNB prach procedures for BL/CE UEs\n"); - prach_procedures(eNB,1); + LOG_D(PHY,"Running eNB prach procedures for BL/CE UEs\n"); + prach_procedures(eNB,1); - if (release_thread(&proc->mutex_prach_br,&proc->instance_cnt_prach_br,"eNB_prach_thread_br") < 0) break; - } - - LOG_I(PHY, "Exiting eNB thread PRACH BR\n"); - eNB_thread_prach_status = 0; - return &eNB_thread_prach_status; + if (release_thread(&proc->mutex_prach_br,&proc->instance_cnt_prach_br,"eNB_prach_thread_br") < 0) break; } + + LOG_I(PHY, "Exiting eNB thread PRACH BR\n"); + eNB_thread_prach_status = 0; + return &eNB_thread_prach_status; +} + #endif - extern void init_td_thread(PHY_VARS_eNB *); - extern void init_te_thread(PHY_VARS_eNB *); - extern void kill_td_thread(PHY_VARS_eNB *); - extern void kill_te_thread(PHY_VARS_eNB *); - static void *process_stats_thread(void *param) { - PHY_VARS_eNB *eNB = (PHY_VARS_eNB *)param; - wait_sync("process_stats_thread"); - while (!oai_exit) { - sleep(1); - if (opp_enabled == 1) { - if (eNB->td) print_meas(&eNB->ulsch_decoding_stats,"ulsch_decoding",NULL,NULL); - if (eNB->te) { - print_meas(&eNB->dlsch_turbo_encoding_preperation_stats,"dlsch_coding_crc",NULL,NULL); - print_meas(&eNB->dlsch_turbo_encoding_segmentation_stats,"dlsch_segmentation",NULL,NULL); - print_meas(&eNB->dlsch_encoding_stats,"dlsch_encoding",NULL,NULL); - print_meas(&eNB->dlsch_turbo_encoding_signal_stats,"coding_signal",NULL,NULL); - print_meas(&eNB->dlsch_turbo_encoding_main_stats,"coding_main",NULL,NULL); - print_meas(&eNB->dlsch_turbo_encoding_stats,"turbo_encoding",NULL,NULL); - print_meas(&eNB->dlsch_interleaving_stats,"turbo_interleaving",NULL,NULL); - print_meas(&eNB->dlsch_rate_matching_stats,"turbo_rate_matching",NULL,NULL); - print_meas(&eNB->dlsch_turbo_encoding_waiting_stats,"coding_wait",NULL,NULL); - print_meas(&eNB->dlsch_turbo_encoding_wakeup_stats0,"coding_worker_0",NULL,NULL); - print_meas(&eNB->dlsch_turbo_encoding_wakeup_stats1,"coding_worker_1",NULL,NULL); - } +extern void init_td_thread(PHY_VARS_eNB *); +extern void init_te_thread(PHY_VARS_eNB *); +extern void kill_td_thread(PHY_VARS_eNB *); +extern void kill_te_thread(PHY_VARS_eNB *); - print_meas(&eNB->dlsch_modulation_stats,"dlsch_modulation",NULL,NULL); +static void *process_stats_thread(void *param) { + PHY_VARS_eNB *eNB = (PHY_VARS_eNB *)param; + wait_sync("process_stats_thread"); + + while (!oai_exit) { + sleep(1); + + if (opp_enabled == 1) { + if (eNB->td) print_meas(&eNB->ulsch_decoding_stats,"ulsch_decoding",NULL,NULL); + + if (eNB->te) { + print_meas(&eNB->dlsch_turbo_encoding_preperation_stats,"dlsch_coding_crc",NULL,NULL); + print_meas(&eNB->dlsch_turbo_encoding_segmentation_stats,"dlsch_segmentation",NULL,NULL); + print_meas(&eNB->dlsch_encoding_stats,"dlsch_encoding",NULL,NULL); + print_meas(&eNB->dlsch_turbo_encoding_signal_stats,"coding_signal",NULL,NULL); + print_meas(&eNB->dlsch_turbo_encoding_main_stats,"coding_main",NULL,NULL); + print_meas(&eNB->dlsch_turbo_encoding_stats,"turbo_encoding",NULL,NULL); + print_meas(&eNB->dlsch_interleaving_stats,"turbo_interleaving",NULL,NULL); + print_meas(&eNB->dlsch_rate_matching_stats,"turbo_rate_matching",NULL,NULL); + print_meas(&eNB->dlsch_turbo_encoding_waiting_stats,"coding_wait",NULL,NULL); + print_meas(&eNB->dlsch_turbo_encoding_wakeup_stats0,"coding_worker_0",NULL,NULL); + print_meas(&eNB->dlsch_turbo_encoding_wakeup_stats1,"coding_worker_1",NULL,NULL); } + + print_meas(&eNB->dlsch_modulation_stats,"dlsch_modulation",NULL,NULL); } - - return(NULL); } - void init_eNB_proc(int inst) { - /*int i=0;*/ - int CC_id; - PHY_VARS_eNB *eNB; - eNB_proc_t *proc; - eNB_rxtx_proc_t *proc_rxtx; - pthread_attr_t *attr0=NULL,*attr1=NULL,*attr_prach=NULL; -#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - pthread_attr_t *attr_prach_br=NULL; -#endif - LOG_I(PHY,"%s(inst:%d) RC.nb_CC[inst]:%d \n",__FUNCTION__,inst,RC.nb_CC[inst]); - for (CC_id=0; CC_id= MAKE_VERSION(14, 0, 0)) + pthread_attr_t *attr_prach_br=NULL; +#endif + LOG_I(PHY,"%s(inst:%d) RC.nb_CC[inst]:%d \n",__FUNCTION__,inst,RC.nb_CC[inst]); + + for (CC_id=0; CC_idproc; - proc_rxtx = proc->proc_rxtx; - proc_rxtx[0].instance_cnt_rxtx = -1; - proc_rxtx[1].instance_cnt_rxtx = -1; - proc_rxtx[0].pipe_ready = 0; - proc_rxtx[1].pipe_ready = 0; - proc->instance_cnt_prach = -1; - proc->instance_cnt_asynch_rxtx = -1; - proc->instance_cnt_synch = -1; - proc->CC_id = CC_id; - proc->first_rx=1; - proc->first_tx=1; - proc->RU_mask=0; - proc->RU_mask_prach=0; - pthread_mutex_init( &eNB->UL_INFO_mutex, NULL); - pthread_mutex_init( &proc_rxtx[0].mutex_rxtx, NULL); - pthread_mutex_init( &proc_rxtx[1].mutex_rxtx, NULL); - pthread_cond_init( &proc_rxtx[0].cond_rxtx, NULL); - pthread_cond_init( &proc_rxtx[1].cond_rxtx, NULL); - pthread_mutex_init( &proc->mutex_prach, NULL); - pthread_mutex_init( &proc->mutex_asynch_rxtx, NULL); - pthread_mutex_init( &proc->mutex_RU,NULL); - pthread_mutex_init( &proc->mutex_RU_PRACH,NULL); - pthread_cond_init( &proc->cond_prach, NULL); - pthread_cond_init( &proc->cond_asynch_rxtx, NULL); - pthread_attr_init( &proc->attr_prach); - pthread_attr_init( &proc->attr_asynch_rxtx); - pthread_attr_init( &proc_rxtx[0].attr_rxtx); - pthread_attr_init( &proc_rxtx[1].attr_rxtx); + proc = &eNB->proc; + proc_rxtx = proc->proc_rxtx; + proc_rxtx[0].instance_cnt_rxtx = -1; + proc_rxtx[1].instance_cnt_rxtx = -1; + proc_rxtx[0].pipe_ready = 0; + proc_rxtx[1].pipe_ready = 0; + proc->instance_cnt_prach = -1; + proc->instance_cnt_asynch_rxtx = -1; + proc->instance_cnt_synch = -1; + proc->CC_id = CC_id; + proc->first_rx=1; + proc->first_tx=1; + proc->RU_mask=0; + proc->RU_mask_prach=0; + pthread_mutex_init( &eNB->UL_INFO_mutex, NULL); + pthread_mutex_init( &proc_rxtx[0].mutex_rxtx, NULL); + pthread_mutex_init( &proc_rxtx[1].mutex_rxtx, NULL); + pthread_cond_init( &proc_rxtx[0].cond_rxtx, NULL); + pthread_cond_init( &proc_rxtx[1].cond_rxtx, NULL); + pthread_mutex_init( &proc->mutex_prach, NULL); + pthread_mutex_init( &proc->mutex_asynch_rxtx, NULL); + pthread_mutex_init( &proc->mutex_RU,NULL); + pthread_mutex_init( &proc->mutex_RU_PRACH,NULL); + pthread_cond_init( &proc->cond_prach, NULL); + pthread_cond_init( &proc->cond_asynch_rxtx, NULL); + pthread_attr_init( &proc->attr_prach); + pthread_attr_init( &proc->attr_asynch_rxtx); + pthread_attr_init( &proc_rxtx[0].attr_rxtx); + pthread_attr_init( &proc_rxtx[1].attr_rxtx); #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - proc->instance_cnt_prach_br = -1; - proc->RU_mask_prach_br=0; - pthread_mutex_init( &proc->mutex_prach_br, NULL); - pthread_mutex_init( &proc->mutex_RU_PRACH_br,NULL); - pthread_cond_init( &proc->cond_prach_br, NULL); - pthread_attr_init( &proc->attr_prach_br); + proc->instance_cnt_prach_br = -1; + proc->RU_mask_prach_br=0; + pthread_mutex_init( &proc->mutex_prach_br, NULL); + pthread_mutex_init( &proc->mutex_RU_PRACH_br,NULL); + pthread_cond_init( &proc->cond_prach_br, NULL); + pthread_attr_init( &proc->attr_prach_br); #endif #ifndef DEADLINE_SCHEDULER - attr0 = &proc_rxtx[0].attr_rxtx; - attr1 = &proc_rxtx[1].attr_rxtx; - attr_prach = &proc->attr_prach; + attr0 = &proc_rxtx[0].attr_rxtx; + attr1 = &proc_rxtx[1].attr_rxtx; + attr_prach = &proc->attr_prach; #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - attr_prach_br = &proc->attr_prach_br; + attr_prach_br = &proc->attr_prach_br; #endif - // attr_td = &proc->attr_td; - // attr_te = &proc->attr_te; + // attr_td = &proc->attr_td; + // attr_te = &proc->attr_te; #endif - if(get_thread_worker_conf() == WORKER_ENABLE) { - init_te_thread(eNB); - init_td_thread(eNB); - } + if(get_thread_worker_conf() == WORKER_ENABLE) { + init_te_thread(eNB); + init_td_thread(eNB); + } - LOG_I(PHY,"eNB->single_thread_flag:%d\n", eNB->single_thread_flag); + LOG_I(PHY,"eNB->single_thread_flag:%d\n", eNB->single_thread_flag); - if ((get_thread_parallel_conf() == PARALLEL_RU_L1_SPLIT || get_thread_parallel_conf() == PARALLEL_RU_L1_TRX_SPLIT) && nfapi_mode!=2) { - pthread_create( &proc_rxtx[0].pthread_rxtx, attr0, eNB_thread_rxtx, proc ); - pthread_create( &proc_rxtx[1].pthread_rxtx, attr1, tx_thread, proc); - } + if ((get_thread_parallel_conf() == PARALLEL_RU_L1_SPLIT || get_thread_parallel_conf() == PARALLEL_RU_L1_TRX_SPLIT) && nfapi_mode!=2) { + pthread_create( &proc_rxtx[0].pthread_rxtx, attr0, eNB_thread_rxtx, proc ); + pthread_create( &proc_rxtx[1].pthread_rxtx, attr1, tx_thread, proc); + } - pthread_create( &proc->pthread_prach, attr_prach, eNB_thread_prach, eNB ); + pthread_create( &proc->pthread_prach, attr_prach, eNB_thread_prach, eNB ); #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - pthread_create( &proc->pthread_prach_br, attr_prach_br, eNB_thread_prach_br, eNB ); + pthread_create( &proc->pthread_prach_br, attr_prach_br, eNB_thread_prach_br, eNB ); #endif - /*char name[16]; - if (eNB->single_thread_flag==0) { - snprintf( name, sizeof(name), "RXTX0 %d", i ); - pthread_setname_np( proc_rxtx[0].pthread_rxtx, name ); - snprintf( name, sizeof(name), "RXTX1 %d", i ); - pthread_setname_np( proc_rxtx[1].pthread_rxtx, name ); - }*/ - AssertFatal(proc->instance_cnt_prach == -1,"instance_cnt_prach = %d\n",proc->instance_cnt_prach); + /*char name[16]; + if (eNB->single_thread_flag==0) { + snprintf( name, sizeof(name), "RXTX0 %d", i ); + pthread_setname_np( proc_rxtx[0].pthread_rxtx, name ); + snprintf( name, sizeof(name), "RXTX1 %d", i ); + pthread_setname_np( proc_rxtx[1].pthread_rxtx, name ); + }*/ + AssertFatal(proc->instance_cnt_prach == -1,"instance_cnt_prach = %d\n",proc->instance_cnt_prach); - if (opp_enabled == 1) pthread_create(&proc->process_stats_thread,NULL,process_stats_thread,(void *)eNB); + if (opp_enabled == 1) pthread_create(&proc->process_stats_thread,NULL,process_stats_thread,(void *)eNB); + } + + //for multiple CCs: setup master and slaves + /* + for (CC_id=0; CC_idnode_timing == synch_to_ext_device) { //master + eNB->proc.num_slaves = MAX_NUM_CCs-1; + eNB->proc.slave_proc = (eNB_proc_t**)malloc(eNB->proc.num_slaves*sizeof(eNB_proc_t*)); + + for (i=0; i< eNB->proc.num_slaves; i++) { + if (i < CC_id) eNB->proc.slave_proc[i] = &(PHY_vars_eNB_g[inst][i]->proc); + if (i >= CC_id) eNB->proc.slave_proc[i] = &(PHY_vars_eNB_g[inst][i+1]->proc); + } + } + } + */ + /* setup PHY proc TX sync mechanism */ + pthread_mutex_init(&sync_phy_proc.mutex_phy_proc_tx, NULL); + pthread_cond_init(&sync_phy_proc.cond_phy_proc_tx, NULL); + sync_phy_proc.phy_proc_CC_id = 0; +} + + + +/*! + * \brief Terminate eNB TX and RX threads. + */ +void kill_eNB_proc(int inst) { + int *status; + PHY_VARS_eNB *eNB; + eNB_proc_t *proc; + eNB_rxtx_proc_t *proc_rxtx; + int i; + + for (int CC_id=0; CC_idproc; + proc_rxtx = &proc->proc_rxtx[0]; + + if(get_thread_worker_conf() == WORKER_ENABLE) { + kill_td_thread(eNB); + kill_te_thread(eNB); } - //for multiple CCs: setup master and slaves - /* - for (CC_id=0; CC_idnode_timing == synch_to_ext_device) { //master - eNB->proc.num_slaves = MAX_NUM_CCs-1; - eNB->proc.slave_proc = (eNB_proc_t**)malloc(eNB->proc.num_slaves*sizeof(eNB_proc_t*)); + for (i=0; i<2; i++) { + pthread_mutex_lock(&proc_rxtx[i].mutex_rxtx); + proc_rxtx[i].instance_cnt_rxtx = 0; + proc_rxtx[i].pipe_ready = 0; + pthread_cond_signal(&proc_rxtx[i].cond_rxtx); + pthread_mutex_unlock(&proc_rxtx[i].mutex_rxtx); + } - for (i=0; i< eNB->proc.num_slaves; i++) { - if (i < CC_id) eNB->proc.slave_proc[i] = &(PHY_vars_eNB_g[inst][i]->proc); - if (i >= CC_id) eNB->proc.slave_proc[i] = &(PHY_vars_eNB_g[inst][i+1]->proc); - } - } - } - */ - /* setup PHY proc TX sync mechanism */ - pthread_mutex_init(&sync_phy_proc.mutex_phy_proc_tx, NULL); - pthread_cond_init(&sync_phy_proc.cond_phy_proc_tx, NULL); - sync_phy_proc.phy_proc_CC_id = 0; - } - /*! - * \brief Terminate eNB TX and RX threads. - */ - void kill_eNB_proc(int inst) { - int *status; - PHY_VARS_eNB *eNB; - eNB_proc_t *proc; - eNB_rxtx_proc_t *proc_rxtx; - int i; - - for (int CC_id=0; CC_idproc; - proc_rxtx = &proc->proc_rxtx[0]; - - if(get_thread_worker_conf() == WORKER_ENABLE) { - kill_td_thread(eNB); - kill_te_thread(eNB); - } - - LOG_I(PHY, "Killing TX CC_id %d inst %d\n", CC_id, inst ); - - for (i=0; i<2; i++) { - pthread_mutex_lock(&proc_rxtx[i].mutex_rxtx); - proc_rxtx[i].instance_cnt_rxtx = 0; - proc_rxtx[i].pipe_ready = 0; - pthread_cond_signal(&proc_rxtx[i].cond_rxtx); - pthread_mutex_unlock(&proc_rxtx[i].mutex_rxtx); - } - - pthread_mutex_lock(&proc->mutex_prach); - proc->instance_cnt_prach = 0; - pthread_cond_signal( &proc->cond_prach ); - pthread_mutex_unlock(&proc->mutex_prach); - pthread_cond_signal( &proc->cond_asynch_rxtx ); - pthread_cond_broadcast(&sync_phy_proc.cond_phy_proc_tx); - LOG_D(PHY, "joining pthread_prach\n"); - pthread_join( proc->pthread_prach, (void **)&status ); - LOG_I(PHY, "Destroying prach mutex/cond\n"); - pthread_mutex_destroy( &proc->mutex_prach ); - pthread_cond_destroy( &proc->cond_prach ); + pthread_mutex_lock(&proc->mutex_prach); + proc->instance_cnt_prach = 0; + pthread_cond_signal( &proc->cond_prach ); + pthread_mutex_unlock(&proc->mutex_prach); + pthread_cond_signal( &proc->cond_asynch_rxtx ); + pthread_cond_broadcast(&sync_phy_proc.cond_phy_proc_tx); + LOG_D(PHY, "joining pthread_prach\n"); + pthread_join( proc->pthread_prach, (void **)&status ); + LOG_I(PHY, "Destroying prach mutex/cond\n"); + pthread_mutex_destroy( &proc->mutex_prach ); + pthread_cond_destroy( &proc->cond_prach ); #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - proc->instance_cnt_prach_br = 0; - pthread_cond_signal( &proc->cond_prach_br ); - pthread_join( proc->pthread_prach_br, (void **)&status ); - pthread_mutex_destroy( &proc->mutex_prach_br ); - pthread_cond_destroy( &proc->cond_prach_br ); + proc->instance_cnt_prach_br = 0; + pthread_cond_signal( &proc->cond_prach_br ); + pthread_join( proc->pthread_prach_br, (void **)&status ); + pthread_mutex_destroy( &proc->mutex_prach_br ); + pthread_cond_destroy( &proc->cond_prach_br ); #endif - LOG_I(PHY, "Destroying UL_INFO mutex\n"); - pthread_mutex_destroy(&eNB->UL_INFO_mutex); + LOG_I(PHY, "Destroying UL_INFO mutex\n"); + pthread_mutex_destroy(&eNB->UL_INFO_mutex); - for (i=0; i<2; i++) { - LOG_I(PHY, "Joining rxtx[%d] mutex/cond\n",i); - pthread_join( proc_rxtx[i].pthread_rxtx, (void **)&status ); - LOG_I(PHY, "Destroying rxtx[%d] mutex/cond\n",i); - pthread_mutex_destroy( &proc_rxtx[i].mutex_rxtx ); - pthread_cond_destroy( &proc_rxtx[i].cond_rxtx ); - } + for (i=0; i<2; i++) { + LOG_I(PHY, "Joining rxtx[%d] mutex/cond\n",i); + pthread_join( proc_rxtx[i].pthread_rxtx, (void **)&status ); + LOG_I(PHY, "Destroying rxtx[%d] mutex/cond\n",i); + pthread_mutex_destroy( &proc_rxtx[i].mutex_rxtx ); + pthread_cond_destroy( &proc_rxtx[i].cond_rxtx ); + } - pthread_attr_destroy(&proc->attr_prach); - pthread_attr_destroy(&proc->attr_asynch_rxtx); - pthread_attr_destroy(&proc_rxtx[0].attr_rxtx); - pthread_attr_destroy(&proc_rxtx[1].attr_rxtx); + pthread_attr_destroy(&proc->attr_prach); + pthread_attr_destroy(&proc->attr_asynch_rxtx); + pthread_attr_destroy(&proc_rxtx[0].attr_rxtx); + pthread_attr_destroy(&proc_rxtx[1].attr_rxtx); #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - pthread_mutex_destroy(&proc->mutex_RU_PRACH_br); - pthread_attr_destroy(&proc->attr_prach_br); + pthread_mutex_destroy(&proc->mutex_RU_PRACH_br); + pthread_attr_destroy(&proc->attr_prach_br); #endif - } } - void reset_opp_meas(void) { - int sfn; - reset_meas(&softmodem_stats_mt); - reset_meas(&softmodem_stats_hw); +} - for (sfn=0; sfn < 10; sfn++) { - reset_meas(&softmodem_stats_rxtx_sf); - reset_meas(&softmodem_stats_rx_sf); - } + + + +void reset_opp_meas(void) { + int sfn; + reset_meas(&softmodem_stats_mt); + reset_meas(&softmodem_stats_hw); + + for (sfn=0; sfn < 10; sfn++) { + reset_meas(&softmodem_stats_rxtx_sf); + reset_meas(&softmodem_stats_rx_sf); } - void print_opp_meas(void) { - int sfn=0; - print_meas(&softmodem_stats_mt, "Main ENB Thread", NULL, NULL); - print_meas(&softmodem_stats_hw, "HW Acquisation", NULL, NULL); +} - for (sfn=0; sfn < 10; sfn++) { - print_meas(&softmodem_stats_rxtx_sf,"[eNB][total_phy_proc_rxtx]",NULL, NULL); - print_meas(&softmodem_stats_rx_sf,"[eNB][total_phy_proc_rx]",NULL,NULL); - } + +void print_opp_meas(void) { + int sfn=0; + print_meas(&softmodem_stats_mt, "Main ENB Thread", NULL, NULL); + print_meas(&softmodem_stats_hw, "HW Acquisation", NULL, NULL); + + for (sfn=0; sfn < 10; sfn++) { + print_meas(&softmodem_stats_rxtx_sf,"[eNB][total_phy_proc_rxtx]",NULL, NULL); + print_meas(&softmodem_stats_rx_sf,"[eNB][total_phy_proc_rx]",NULL,NULL); } - void free_transport(PHY_VARS_eNB *eNB) { - int i; - int j; +} - for (i=0; idlsch[i][j]); + for (i=0; iulsch[1+i]); - } + for (j=0; j<2; j++) free_eNB_dlsch(eNB->dlsch[i][j]); - free_eNB_ulsch(eNB->ulsch[0]); + LOG_D(PHY, "Freeing Transport Channel Buffer for ULSCH, UE %d\n",i); + free_eNB_ulsch(eNB->ulsch[1+i]); } - void init_transport(PHY_VARS_eNB *eNB) { - int i; - int j; - LTE_DL_FRAME_PARMS *fp = &eNB->frame_parms; - LOG_I(PHY, "Initialise transport\n"); - for (i=0; iulsch[0]); +} - for (j=0; j<2; j++) { - eNB->dlsch[i][j] = new_eNB_dlsch(1,8,NSOFT,fp->N_RB_DL,0,fp); +void init_transport(PHY_VARS_eNB *eNB) { + int i; + int j; + LTE_DL_FRAME_PARMS *fp = &eNB->frame_parms; + LOG_I(PHY, "Initialise transport\n"); - if (!eNB->dlsch[i][j]) { - LOG_E(PHY,"Can't get eNB dlsch structures for UE %d \n", i); - exit(-1); - } else { - eNB->dlsch[i][j]->rnti=0; - LOG_D(PHY,"dlsch[%d][%d] => %p rnti:%d\n",i,j,eNB->dlsch[i][j], eNB->dlsch[i][j]->rnti); - } - } + for (i=0; iulsch[1+i] = new_eNB_ulsch(MAX_TURBO_ITERATIONS,fp->N_RB_UL, 0); + for (j=0; j<2; j++) { + eNB->dlsch[i][j] = new_eNB_dlsch(1,8,NSOFT,fp->N_RB_DL,0,fp); - if (!eNB->ulsch[1+i]) { - LOG_E(PHY,"Can't get eNB ulsch structures\n"); + if (!eNB->dlsch[i][j]) { + LOG_E(PHY,"Can't get eNB dlsch structures for UE %d \n", i); exit(-1); + } else { + eNB->dlsch[i][j]->rnti=0; + LOG_D(PHY,"dlsch[%d][%d] => %p rnti:%d\n",i,j,eNB->dlsch[i][j], eNB->dlsch[i][j]->rnti); } - - // this is the transmission mode for the signalling channels - // this will be overwritten with the real transmission mode by the RRC once the UE is connected - eNB->transmission_mode[i] = fp->nb_antenna_ports_eNB==1 ? 1 : 2; } - // ULSCH for RA - eNB->ulsch[0] = new_eNB_ulsch(MAX_TURBO_ITERATIONS, fp->N_RB_UL, 0); + LOG_D(PHY,"Allocating Transport Channel Buffer for ULSCH, UE %d\n",i); + eNB->ulsch[1+i] = new_eNB_ulsch(MAX_TURBO_ITERATIONS,fp->N_RB_UL, 0); - if (!eNB->ulsch[0]) { + if (!eNB->ulsch[1+i]) { LOG_E(PHY,"Can't get eNB ulsch structures\n"); exit(-1); } - eNB->dlsch_SI = new_eNB_dlsch(1,8,NSOFT,fp->N_RB_DL, 0, fp); - LOG_D(PHY,"eNB %d.%d : SI %p\n",eNB->Mod_id,eNB->CC_id,eNB->dlsch_SI); - eNB->dlsch_ra = new_eNB_dlsch(1,8,NSOFT,fp->N_RB_DL, 0, fp); - LOG_D(PHY,"eNB %d.%d : RA %p\n",eNB->Mod_id,eNB->CC_id,eNB->dlsch_ra); - eNB->dlsch_MCH = new_eNB_dlsch(1,8,NSOFT,fp->N_RB_DL, 0, fp); - LOG_D(PHY,"eNB %d.%d : MCH %p\n",eNB->Mod_id,eNB->CC_id,eNB->dlsch_MCH); - eNB->rx_total_gain_dB=130; - - for(i=0; imu_mimo_mode[i].dl_pow_off = 2; - - eNB->check_for_total_transmissions = 0; - eNB->check_for_MUMIMO_transmissions = 0; - eNB->FULL_MUMIMO_transmissions = 0; - eNB->check_for_SUMIMO_transmissions = 0; - fp->pucch_config_common.deltaPUCCH_Shift = 1; + // this is the transmission mode for the signalling channels + // this will be overwritten with the real transmission mode by the RRC once the UE is connected + eNB->transmission_mode[i] = fp->nb_antenna_ports_eNB==1 ? 1 : 2; } - void init_eNB_afterRU(void) { - int inst,CC_id,ru_id,i,aa; - PHY_VARS_eNB *eNB; - LOG_I(PHY,"%s() RC.nb_inst:%d\n", __FUNCTION__, RC.nb_inst); - for (inst=0; instulsch[0] = new_eNB_ulsch(MAX_TURBO_ITERATIONS, fp->N_RB_UL, 0); - for (CC_id=0; CC_idulsch[0]) { + LOG_E(PHY,"Can't get eNB ulsch structures\n"); + exit(-1); + } - // map antennas and PRACH signals to eNB RX - if (0) AssertFatal(eNB->num_RU>0,"Number of RU attached to eNB %d is zero\n",eNB->Mod_id); + eNB->dlsch_SI = new_eNB_dlsch(1,8,NSOFT,fp->N_RB_DL, 0, fp); + LOG_D(PHY,"eNB %d.%d : SI %p\n",eNB->Mod_id,eNB->CC_id,eNB->dlsch_SI); + eNB->dlsch_ra = new_eNB_dlsch(1,8,NSOFT,fp->N_RB_DL, 0, fp); + LOG_D(PHY,"eNB %d.%d : RA %p\n",eNB->Mod_id,eNB->CC_id,eNB->dlsch_ra); + eNB->dlsch_MCH = new_eNB_dlsch(1,8,NSOFT,fp->N_RB_DL, 0, fp); + LOG_D(PHY,"eNB %d.%d : MCH %p\n",eNB->Mod_id,eNB->CC_id,eNB->dlsch_MCH); + eNB->rx_total_gain_dB=130; - LOG_I(PHY,"Mapping RX ports from %d RUs to eNB %d\n",eNB->num_RU,eNB->Mod_id); - eNB->frame_parms.nb_antennas_rx = 0; - LOG_I(PHY,"Overwriting eNB->prach_vars.rxsigF[0]:%p\n", eNB->prach_vars.rxsigF[0]); - eNB->prach_vars.rxsigF[0] = (int16_t **)malloc16(64*sizeof(int16_t *)); + for(i=0; imu_mimo_mode[i].dl_pow_off = 2; + + eNB->check_for_total_transmissions = 0; + eNB->check_for_MUMIMO_transmissions = 0; + eNB->FULL_MUMIMO_transmissions = 0; + eNB->check_for_SUMIMO_transmissions = 0; + fp->pucch_config_common.deltaPUCCH_Shift = 1; +} + +void init_eNB_afterRU(void) { + int inst,CC_id,ru_id,i,aa; + PHY_VARS_eNB *eNB; + LOG_I(PHY,"%s() RC.nb_inst:%d\n", __FUNCTION__, RC.nb_inst); + + for (inst=0; instnum_RU>0,"Number of RU attached to eNB %d is zero\n",eNB->Mod_id); + + LOG_I(PHY,"Mapping RX ports from %d RUs to eNB %d\n",eNB->num_RU,eNB->Mod_id); + eNB->frame_parms.nb_antennas_rx = 0; + LOG_I(PHY,"Overwriting eNB->prach_vars.rxsigF[0]:%p\n", eNB->prach_vars.rxsigF[0]); + eNB->prach_vars.rxsigF[0] = (int16_t **)malloc16(64*sizeof(int16_t *)); #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - for (int ce_level=0; ce_level<4; ce_level++) { - LOG_I(PHY,"Overwriting eNB->prach_vars_br.rxsigF.rxsigF[0]:%p\n", eNB->prach_vars_br.rxsigF[ce_level]); - eNB->prach_vars_br.rxsigF[ce_level] = (int16_t **)malloc16(64*sizeof(int16_t *)); - } - -#endif - LOG_I(PHY,"eNB->num_RU:%d\n", eNB->num_RU); - - for (ru_id=0,aa=0; ru_idnum_RU; ru_id++) { - eNB->frame_parms.nb_antennas_rx += eNB->RU_list[ru_id]->nb_rx; - AssertFatal(eNB->RU_list[ru_id]->common.rxdataF!=NULL, - "RU %d : common.rxdataF is NULL\n", - eNB->RU_list[ru_id]->idx); - AssertFatal(eNB->RU_list[ru_id]->prach_rxsigF!=NULL, - "RU %d : prach_rxsigF is NULL\n", - eNB->RU_list[ru_id]->idx); - - for (i=0; iRU_list[ru_id]->nb_rx; aa++,i++) { - LOG_I(PHY,"Attaching RU %d antenna %d to eNB antenna %d\n",eNB->RU_list[ru_id]->idx,i,aa); - eNB->prach_vars.rxsigF[0][aa] = eNB->RU_list[ru_id]->prach_rxsigF[i]; -#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - - for (int ce_level=0; ce_level<4; ce_level++) - eNB->prach_vars_br.rxsigF[ce_level][aa] = eNB->RU_list[ru_id]->prach_rxsigF_br[ce_level][i]; - -#endif - eNB->common_vars.rxdataF[aa] = eNB->RU_list[ru_id]->common.rxdataF[i]; - } - } - - /* TODO: review this code, there is something wrong. - * In monolithic mode, we come here with nb_antennas_rx == 0 - * (not tested in other modes). - */ - if (eNB->frame_parms.nb_antennas_rx < 1) { - LOG_I(PHY, "%s() ************* DJP ***** eNB->frame_parms.nb_antennas_rx:%d - GOING TO HARD CODE TO 1", __FUNCTION__, eNB->frame_parms.nb_antennas_rx); - eNB->frame_parms.nb_antennas_rx = 1; - } else { - //LOG_I(PHY," Delete code\n"); - } - - if (eNB->frame_parms.nb_antennas_tx < 1) { - LOG_I(PHY, "%s() ************* DJP ***** eNB->frame_parms.nb_antennas_tx:%d - GOING TO HARD CODE TO 1", __FUNCTION__, eNB->frame_parms.nb_antennas_tx); - eNB->frame_parms.nb_antennas_tx = 1; - } else { - //LOG_I(PHY," Delete code\n"); - } - - AssertFatal(eNB->frame_parms.nb_antennas_rx >0, - "inst %d, CC_id %d : nb_antennas_rx %d\n",inst,CC_id,eNB->frame_parms.nb_antennas_rx); - LOG_I(PHY,"inst %d, CC_id %d : nb_antennas_rx %d\n",inst,CC_id,eNB->frame_parms.nb_antennas_rx); - init_transport(eNB); - //init_precoding_weights(RC.eNB[inst][CC_id]); + for (int ce_level=0; ce_level<4; ce_level++) { + LOG_I(PHY,"Overwriting eNB->prach_vars_br.rxsigF.rxsigF[0]:%p\n", eNB->prach_vars_br.rxsigF[ce_level]); + eNB->prach_vars_br.rxsigF[ce_level] = (int16_t **)malloc16(64*sizeof(int16_t *)); } - init_eNB_proc(inst); - } - - for (ru_id=0; ru_idwakeup_rxtx = wakeup_rxtx; - RC.ru[ru_id]->wakeup_prach_eNB = wakeup_prach_eNB; -#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) - RC.ru[ru_id]->wakeup_prach_eNB_br = wakeup_prach_eNB_br; #endif - RC.ru[ru_id]->eNB_top = eNB_top; + LOG_I(PHY,"eNB->num_RU:%d\n", eNB->num_RU); + + for (ru_id=0,aa=0; ru_idnum_RU; ru_id++) { + eNB->frame_parms.nb_antennas_rx += eNB->RU_list[ru_id]->nb_rx; + AssertFatal(eNB->RU_list[ru_id]->common.rxdataF!=NULL, + "RU %d : common.rxdataF is NULL\n", + eNB->RU_list[ru_id]->idx); + AssertFatal(eNB->RU_list[ru_id]->prach_rxsigF!=NULL, + "RU %d : prach_rxsigF is NULL\n", + eNB->RU_list[ru_id]->idx); + + for (i=0; iRU_list[ru_id]->nb_rx; aa++,i++) { + LOG_I(PHY,"Attaching RU %d antenna %d to eNB antenna %d\n",eNB->RU_list[ru_id]->idx,i,aa); + eNB->prach_vars.rxsigF[0][aa] = eNB->RU_list[ru_id]->prach_rxsigF[i]; +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + + for (int ce_level=0; ce_level<4; ce_level++) + eNB->prach_vars_br.rxsigF[ce_level][aa] = eNB->RU_list[ru_id]->prach_rxsigF_br[ce_level][i]; + +#endif + eNB->common_vars.rxdataF[aa] = eNB->RU_list[ru_id]->common.rxdataF[i]; + } + } + + /* TODO: review this code, there is something wrong. + * In monolithic mode, we come here with nb_antennas_rx == 0 + * (not tested in other modes). + */ + if (eNB->frame_parms.nb_antennas_rx < 1) { + LOG_I(PHY, "%s() ************* DJP ***** eNB->frame_parms.nb_antennas_rx:%d - GOING TO HARD CODE TO 1", __FUNCTION__, eNB->frame_parms.nb_antennas_rx); + eNB->frame_parms.nb_antennas_rx = 1; + } else { + //LOG_I(PHY," Delete code\n"); + } + + if (eNB->frame_parms.nb_antennas_tx < 1) { + LOG_I(PHY, "%s() ************* DJP ***** eNB->frame_parms.nb_antennas_tx:%d - GOING TO HARD CODE TO 1", __FUNCTION__, eNB->frame_parms.nb_antennas_tx); + eNB->frame_parms.nb_antennas_tx = 1; + } else { + //LOG_I(PHY," Delete code\n"); + } + + AssertFatal(eNB->frame_parms.nb_antennas_rx >0, + "inst %d, CC_id %d : nb_antennas_rx %d\n",inst,CC_id,eNB->frame_parms.nb_antennas_rx); + LOG_I(PHY,"inst %d, CC_id %d : nb_antennas_rx %d\n",inst,CC_id,eNB->frame_parms.nb_antennas_rx); + init_transport(eNB); + //init_precoding_weights(RC.eNB[inst][CC_id]); } + + init_eNB_proc(inst); } - void init_eNB(int single_thread_flag,int wait_for_sync) { - int CC_id; - int inst; - PHY_VARS_eNB *eNB; - LOG_I(PHY,"[lte-softmodem.c] eNB structure about to allocated RC.nb_L1_inst:%d RC.nb_L1_CC[0]:%d\n",RC.nb_L1_inst,RC.nb_L1_CC[0]); - if (RC.eNB == NULL) RC.eNB = (PHY_VARS_eNB ***) malloc(RC.nb_L1_inst*sizeof(PHY_VARS_eNB **)); + for (ru_id=0; ru_idwakeup_rxtx = wakeup_rxtx; + RC.ru[ru_id]->wakeup_prach_eNB = wakeup_prach_eNB; +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + RC.ru[ru_id]->wakeup_prach_eNB_br = wakeup_prach_eNB_br; +#endif + RC.ru[ru_id]->eNB_top = eNB_top; + } +} - LOG_I(PHY,"[lte-softmodem.c] eNB structure RC.eNB allocated\n"); +void init_eNB(int single_thread_flag,int wait_for_sync) { + int CC_id; + int inst; + PHY_VARS_eNB *eNB; + LOG_I(PHY,"[lte-softmodem.c] eNB structure about to allocated RC.nb_L1_inst:%d RC.nb_L1_CC[0]:%d\n",RC.nb_L1_inst,RC.nb_L1_CC[0]); - for (inst=0; instabstraction_flag = 0; - eNB->single_thread_flag = single_thread_flag; - LOG_I(PHY,"Initializing eNB %d CC_id %d single_thread_flag:%d\n",inst,CC_id,single_thread_flag); + for (inst=0; instabstraction_flag = 0; + eNB->single_thread_flag = single_thread_flag; + LOG_I(PHY,"Initializing eNB %d CC_id %d single_thread_flag:%d\n",inst,CC_id,single_thread_flag); #ifndef OCP_FRAMEWORK - LOG_I(PHY,"Initializing eNB %d CC_id %d\n",inst,CC_id); + LOG_I(PHY,"Initializing eNB %d CC_id %d\n",inst,CC_id); #endif - eNB->td = ulsch_decoding_data_all; - eNB->te = dlsch_encoding_all; - LOG_I(PHY,"Registering with MAC interface module\n"); - AssertFatal((eNB->if_inst = IF_Module_init(inst))!=NULL,"Cannot register interface"); - eNB->if_inst->schedule_response = schedule_response; - eNB->if_inst->PHY_config_req = phy_config_request; - memset((void *)&eNB->UL_INFO,0,sizeof(eNB->UL_INFO)); - memset((void *)&eNB->Sched_INFO,0,sizeof(eNB->Sched_INFO)); - LOG_I(PHY,"Setting indication lists\n"); - eNB->UL_INFO.rx_ind.rx_indication_body.rx_pdu_list = eNB->rx_pdu_list; - eNB->UL_INFO.crc_ind.crc_indication_body.crc_pdu_list = eNB->crc_pdu_list; - eNB->UL_INFO.sr_ind.sr_indication_body.sr_pdu_list = eNB->sr_pdu_list; - eNB->UL_INFO.harq_ind.harq_indication_body.harq_pdu_list = eNB->harq_pdu_list; - eNB->UL_INFO.cqi_ind.cqi_pdu_list = eNB->cqi_pdu_list; - eNB->UL_INFO.cqi_ind.cqi_raw_pdu_list = eNB->cqi_raw_pdu_list; - eNB->prach_energy_counter = 0; - } + eNB->td = ulsch_decoding_data_all; + eNB->te = dlsch_encoding_all; + LOG_I(PHY,"Registering with MAC interface module\n"); + AssertFatal((eNB->if_inst = IF_Module_init(inst))!=NULL,"Cannot register interface"); + eNB->if_inst->schedule_response = schedule_response; + eNB->if_inst->PHY_config_req = phy_config_request; + memset((void *)&eNB->UL_INFO,0,sizeof(eNB->UL_INFO)); + memset((void *)&eNB->Sched_INFO,0,sizeof(eNB->Sched_INFO)); + LOG_I(PHY,"Setting indication lists\n"); + eNB->UL_INFO.rx_ind.rx_indication_body.rx_pdu_list = eNB->rx_pdu_list; + eNB->UL_INFO.crc_ind.crc_indication_body.crc_pdu_list = eNB->crc_pdu_list; + eNB->UL_INFO.sr_ind.sr_indication_body.sr_pdu_list = eNB->sr_pdu_list; + eNB->UL_INFO.harq_ind.harq_indication_body.harq_pdu_list = eNB->harq_pdu_list; + eNB->UL_INFO.cqi_ind.cqi_pdu_list = eNB->cqi_pdu_list; + eNB->UL_INFO.cqi_ind.cqi_raw_pdu_list = eNB->cqi_raw_pdu_list; + eNB->prach_energy_counter = 0; } - - LOG_I(PHY,"[lte-softmodem.c] eNB structure allocated\n"); } - void stop_eNB(int nb_inst) { - for (int inst=0; inst Date: Fri, 16 Nov 2018 15:12:55 +0100 Subject: [PATCH 151/233] CI: initial python support for CAT-M devices -- Works for a Skywire 4G LTE CAT M1 device Single-module environment Signed-off-by: Raphael Defosseux --- ci-scripts/main.py | 140 +++++++++++++++++- .../xml_files/test_case_list_template.xml | 22 +++ 2 files changed, 157 insertions(+), 5 deletions(-) diff --git a/ci-scripts/main.py b/ci-scripts/main.py index f617d6f40a..0092234b95 100644 --- a/ci-scripts/main.py +++ b/ci-scripts/main.py @@ -103,12 +103,14 @@ class SSHConnection(): self.iperf_packetloss_threshold = '' self.iperf_profile = '' self.UEDevices = [] + self.CatMDevices = [] self.UEIPAddresses = [] self.htmlFile = '' self.htmlHeaderCreated = False self.htmlFooterCreated = False self.htmlUEConnected = 0 self.htmleNBFailureMsg = '' + self.picocom_closure = False def open(self, ipaddress, username, password): count = 0 @@ -170,8 +172,9 @@ class SSHConnection(): elif self.sshresponse == 2: logging.debug('\u001B[1;37;41m Unexpected TIMEOUT \u001B[0m') logging.debug('Expected Line : ' + expectedline) - result = re.search('ping |iperf ', str(commandline)) + result = re.search('ping |iperf |picocom', str(commandline)) if result is None: + logging.debug(str(self.ssh.before)) sys.exit(self.sshresponse) else: return -1 @@ -187,9 +190,10 @@ class SSHConnection(): if self.sshresponse == 0: pass elif self.sshresponse == 1: - logging.debug('\u001B[1;37;41m Unexpected TIMEOUT \u001B[0m') + if not self.picocom_closure: + logging.debug('\u001B[1;37;41m Unexpected TIMEOUT during closing\u001B[0m') else: - logging.debug('\u001B[1;37;41m Unexpected Others \u001B[0m') + logging.debug('\u001B[1;37;41m Unexpected Others during closing\u001B[0m') def copyin(self, ipaddress, username, password, source, destination): logging.debug('scp '+ username + '@' + ipaddress + ':' + source + ' ' + destination) @@ -440,6 +444,109 @@ class SSHConnection(): job.join() self.CreateHtmlTestRow('N/A', 'OK', ALL_PROCESSES_OK) + def checkDevTTYisUnlocked(self): + self.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword) + count = 0 + while count < 5: + self.command('echo ' + self.ADBPassword + ' | sudo -S lsof | grep ttyUSB0', '\$', 10) + result = re.search('picocom', str(self.ssh.before)) + if result is None: + count = 10 + else: + time.sleep(5) + count = count + 1 + self.close() + + def InitializeCatM(self): + if self.ADBIPAddress == '' or self.ADBUserName == '' or self.ADBPassword == '': + Usage() + sys.exit('Insufficient Parameter') + self.picocom_closure = True + self.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword) + # dummy call to start a sudo session. The picocom command does NOT handle well the `sudo -S` + self.command('echo ' + self.ADBPassword + ' | sudo -S ls', '\$', 10) + self.command('sudo picocom --baud 921600 --flow n --databits 8 /dev/ttyUSB0', 'Terminal ready', 10) + time.sleep(1) + # Calling twice AT to clear all buffers + self.command('AT', 'OK|ERROR', 5) + self.command('AT', 'OK', 5) + # Disabling the Radio + self.command('AT+CFUN=0', 'OK', 5) + logging.debug('\u001B[1m Cellular Functionality disabled\u001B[0m') + # Checking if auto-attach is enabled + self.command('AT^AUTOATT?', 'OK', 5) + result = re.search('AUTOATT: (?P[0-9\-]+)', str(self.ssh.before)) + if result is not None: + if result.group('state') is not None: + autoAttachState = int(result.group('state')) + if autoAttachState is not None: + if autoAttachState == 0: + self.command('AT^AUTOATT=1', 'OK', 5) + logging.debug('\u001B[1m Auto-Attach enabled\u001B[0m') + else: + logging.debug('\u001B[1;37;41m Could not check Auto-Attach! \u001B[0m') + # Force closure of picocom but device might still be locked + self.close() + self.picocom_closure = False + self.CreateHtmlTestRow('N/A', 'OK', ALL_PROCESSES_OK) + self.checkDevTTYisUnlocked() + + def TerminateCatM(self): + if self.ADBIPAddress == '' or self.ADBUserName == '' or self.ADBPassword == '': + Usage() + sys.exit('Insufficient Parameter') + self.picocom_closure = True + self.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword) + # dummy call to start a sudo session. The picocom command does NOT handle well the `sudo -S` + self.command('echo ' + self.ADBPassword + ' | sudo -S ls', '\$', 10) + self.command('sudo picocom --baud 921600 --flow n --databits 8 /dev/ttyUSB0', 'Terminal ready', 10) + time.sleep(1) + # Calling twice AT to clear all buffers + self.command('AT', 'OK|ERROR', 5) + self.command('AT', 'OK', 5) + # Disabling the Radio + self.command('AT+CFUN=0', 'OK', 5) + logging.debug('\u001B[1m Cellular Functionality disabled\u001B[0m') + self.close() + self.picocom_closure = False + self.CreateHtmlTestRow('N/A', 'OK', ALL_PROCESSES_OK) + self.checkDevTTYisUnlocked() + + def AttachCatM(self): + if self.ADBIPAddress == '' or self.ADBUserName == '' or self.ADBPassword == '': + Usage() + sys.exit('Insufficient Parameter') + self.picocom_closure = True + self.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword) + # dummy call to start a sudo session. The picocom command does NOT handle well the `sudo -S` + self.command('echo ' + self.ADBPassword + ' | sudo -S ls', '\$', 10) + self.command('sudo picocom --baud 921600 --flow n --databits 8 /dev/ttyUSB0', 'Terminal ready', 10) + time.sleep(1) + # Calling twice AT to clear all buffers + self.command('AT', 'OK|ERROR', 5) + self.command('AT', 'OK', 5) + # Enabling the Radio + self.command('AT+CFUN=1', 'SIMSTORE,READY', 5) + logging.debug('\u001B[1m Cellular Functionality enabled\u001B[0m') + time.sleep(4) + # We should check if we register + count = 0 + while count < 3: + self.command('AT+CEREG?', 'OK', 5) + result = re.search('CEREG: 2,(?P[0-9\-]+)', str(self.ssh.before)) + if result is not None: + mDataConnectionState = int(result.group('state')) + if mDataConnectionState is not None: + logging.debug('+CEREG: 2,' + str(mDataConnectionState)) + else: + logging.debug(str(self.ssh.before)) + count = count + 1 + time.sleep(1) + self.close() + self.picocom_closure = False + self.CreateHtmlTestRow('N/A', 'OK', ALL_PROCESSES_OK) + self.checkDevTTYisUnlocked() + def AttachUE_common(self, device_id, statusQueue, lock): try: self.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword) @@ -638,6 +745,19 @@ class SSHConnection(): sys.exit(1) self.close() + def GetAllCatMDevices(self, terminate_ue_flag): + if self.ADBIPAddress == '' or self.ADBUserName == '' or self.ADBPassword == '': + Usage() + sys.exit('Insufficient Parameter') + self.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword) + self.command('lsusb | egrep "Future Technology Devices International, Ltd FT2232C" | sed -e "s#:.*##" -e "s# #_#g"', '\$', 15) + self.CatMDevices = re.findall("\\\\r\\\\n([A-Za-z0-9_]+)",str(self.ssh.before)) + if terminate_ue_flag == False: + if len(self.CatMDevices) == 0: + logging.debug('\u001B[1;37;41m CAT-M UE Not Found! \u001B[0m') + sys.exit(1) + self.close() + def GetAllUEIPAddresses(self): if self.ADBIPAddress == '' or self.ADBUserName == '' or self.ADBPassword == '': Usage() @@ -1771,12 +1891,14 @@ class SSHConnection(): terminate_ue_flag = True SSH.GetAllUEDevices(terminate_ue_flag) + SSH.GetAllCatMDevices(terminate_ue_flag) self.htmlUEConnected = len(self.UEDevices) self.htmlFile.write('

    Jump to Final Status

    \n') self.htmlFile.write('
    \n') - self.htmlFile.write('

    ' + str(self.htmlUEConnected) + ' UE(s) is(are) connected to ADB bench server

    \n') + self.htmlFile.write('

    ' + str(len(self.UEDevices)) + ' UE(s) is(are) connected to ADB bench server

    \n') + self.htmlFile.write('

    ' + str(len(self.CatMDevices)) + ' CAT-M UE(s) is(are) connected to bench server

    \n') self.htmlFile.write('
    \n') self.htmlFile.write('

    Test Summary for ' + SSH.testXMLfile + '

    \n') @@ -1929,7 +2051,7 @@ def Usage(): print('------------------------------------------------------------') def CheckClassValidity(action,id): - if action != 'Build_eNB' and action != 'Initialize_eNB' and action != 'Terminate_eNB' and action != 'Initialize_UE' and action != 'Terminate_UE' and action != 'Attach_UE' and action != 'Detach_UE' and action != 'Ping' and action != 'Iperf' and action != 'Reboot_UE' and action != 'Initialize_HSS' and action != 'Terminate_HSS' and action != 'Initialize_MME' and action != 'Terminate_MME' and action != 'Initialize_SPGW' and action != 'Terminate_SPGW': + if action != 'Build_eNB' and action != 'Initialize_eNB' and action != 'Terminate_eNB' and action != 'Initialize_UE' and action != 'Terminate_UE' and action != 'Attach_UE' and action != 'Detach_UE' and action != 'Ping' and action != 'Iperf' and action != 'Reboot_UE' and action != 'Initialize_HSS' and action != 'Terminate_HSS' and action != 'Initialize_MME' and action != 'Terminate_MME' and action != 'Initialize_SPGW' and action != 'Terminate_SPGW' and action != 'Initialize_CatM_module' and action != 'Terminate_CatM_module' and action != 'Attach_CatM_module' and action != 'Detach_CatM_module': logging.debug('ERROR: test-case ' + id + ' has wrong class ' + action) return False return True @@ -2206,6 +2328,14 @@ elif re.match('^TesteNB$', mode, re.IGNORECASE): SSH.AttachUE() elif action == 'Detach_UE': SSH.DetachUE() + elif action == 'Initialize_CatM_module': + SSH.InitializeCatM() + elif action == 'Terminate_CatM_module': + SSH.TerminateCatM() + elif action == 'Attach_CatM_module': + SSH.AttachCatM() + elif action == 'Detach_CatM_module': + SSH.TerminateCatM() elif action == 'Ping': SSH.Ping() elif action == 'Iperf': diff --git a/ci-scripts/xml_files/test_case_list_template.xml b/ci-scripts/xml_files/test_case_list_template.xml index 25519dcd03..bdf16af0e3 100644 --- a/ci-scripts/xml_files/test_case_list_template.xml +++ b/ci-scripts/xml_files/test_case_list_template.xml @@ -107,6 +107,28 @@ Reboot UE + + + + Initialize_CatM_module + Initialize CAT-M Module + + + + Terminate_CatM_module + Terminate CAT-M Module + + + + Attach_CatM_module + Attach CAT-M Module + + + + Detach_CatM_module + Detach CAT-M Module + + From 00f4890b14b917fe80010b30072b1cf04f3c4815 Mon Sep 17 00:00:00 2001 From: frtabu Date: Fri, 16 Nov 2018 17:53:51 +0100 Subject: [PATCH 152/233] write logging tool documentation --- common/utils/DOC/loader/devusage.md | 7 +- common/utils/LOG/DOC/arch.md | 9 + common/utils/LOG/DOC/devusage.md | 119 +++++++++++ common/utils/LOG/DOC/log.md | 19 ++ common/utils/LOG/DOC/rtusage.md | 265 ++++++++++++++++++++++++ common/utils/telnetsrv/DOC/telnetlog.md | 3 +- 6 files changed, 417 insertions(+), 5 deletions(-) create mode 100644 common/utils/LOG/DOC/arch.md create mode 100644 common/utils/LOG/DOC/devusage.md create mode 100644 common/utils/LOG/DOC/log.md create mode 100644 common/utils/LOG/DOC/rtusage.md diff --git a/common/utils/DOC/loader/devusage.md b/common/utils/DOC/loader/devusage.md index 4b82e18362..915075c361 100644 --- a/common/utils/DOC/loader/devusage.md +++ b/common/utils/DOC/loader/devusage.md @@ -1,7 +1,6 @@ -The configuration module objectives are -1. Allow easy parameters management in oai, helping the development of a flexible, modularized and fully configurable softmodem. -1. Use a common configuration API in all oai modules -1. Allow development of alternative configuration sources without modifying the oai code. Today the only delivered configuration source is the libconfig format configuration file. +The loader objectives are +1. provides a common mechanism to prevent an executable to include code that is only used under specific configurations, without rebuilding the code +1. Provide a common mechanism to allow to choose between different implementations of a given set of functions, without rebuilding the code As a developer you may need to look at these sections: diff --git a/common/utils/LOG/DOC/arch.md b/common/utils/LOG/DOC/arch.md new file mode 100644 index 0000000000..f774655771 --- /dev/null +++ b/common/utils/LOG/DOC/arch.md @@ -0,0 +1,9 @@ +# logging facility source files + +The oai logging facility is implemented in two source files, located in [common/utils](https://gitlab.eurecom.fr/oai/openairinterface5g/tree/develop/common/utils) +1. [log.c](https://gitlab.eurecom.fr/oai/openairinterface5g/tree/develop/common/utils/log.c) contains logging implementation +1. [log.h](https://gitlab.eurecom.fr/oai/openairinterface5g/tree/develop/common/utils/log.h) is the logging facility include file containing both private and public data type definitions. It also contain API prototypes. + + +[logging facility main page](log.md) +[oai Wikis home](https://gitlab.eurecom.fr/oai/openairinterface5g/wikis/home) \ No newline at end of file diff --git a/common/utils/LOG/DOC/devusage.md b/common/utils/LOG/DOC/devusage.md new file mode 100644 index 0000000000..2d5582ff7c --- /dev/null +++ b/common/utils/LOG/DOC/devusage.md @@ -0,0 +1,119 @@ +### logging facility usage +The logging facility objectives are +1. provide a common console tracing mechanism +1. Allow a flexible activation of console traces, by configuration or dynamically at any time while code is running. + +Once the logging facility has been initialized and configured developpers use C preprocessor macros to include console messages in their code. At execution time, these traces will be printed or not to the console depending on the configuration, as described [here](rtusage.md). The logging facility also defines preprocessor macros to include condtional code, to dump memory blocks (buffers, messages...). + +All macros are defined in [log.h](https://gitlab.eurecom.fr/oai/openairinterface5g/blob/develop/common/utils/LOG/log.h) include file, which must be included in any source file using the logging facility macros. + + [log.h](https://gitlab.eurecom.fr/oai/openairinterface5g/blob/develop/common/utils/LOG/log.h) also includes the prototypes of the functions that have to be called to initialize, configure or get the status of console logs. + +#### console messages macros +```C +LOG_E(,,,...) +LOG_W(,,,...) +LOG_I(,,,...) +LOG_D(,,,...) +LOG_T(,,,...) +) +``` +these macros are used in place of the printf C function. The additionnal ***component*** parameter identifies the functionnal module which generates the message. At run time, the message will only be printed if the configured log level for the component is greater or equal than the macro level used in the code. + +| macro | level letter | level value | level name | +|:---------|:---------------|:---------------|----------------:| +| LOG_E | E | 0 | error | +| LOG_W | W | 1 | warning | +| LOG_I | I | 2 | informational | +| LOG_D | D | 3 | debug | +| LOG_T | T | 4 | trace | + +component list is defined as an `enum` in [log.h](https://gitlab.eurecom.fr/oai/openairinterface5g/blob/develop/common/utils/LOG/log.h). A new component can be defined by adding an item in this type, it must also be defined in the T tracer [T_messages.txt ](https://gitlab.eurecom.fr/oai/openairinterface5g/blob/develop/common/utils/T/T_messages.txt). + +Most oai sources are including LOG macros. + +#### conditional code macros + +```C +LOG_DEBUGFLAG() +``` +this macro is to be used in if statements. The condition is true if the flag has been set, as described in the [run time usage page](rtusage.md) +```C +if ( LOG_DEBUGFLAG() { +/* + the code below is only executed if the corresponding + _debug option is set. + */ +...................... +...................... +} +``` +[example in oai code](https://gitlab.eurecom.fr/oai/openairinterface5g/blob/develop/openair1/PHY/LTE_TRANSPORT/ulsch_demodulation.c#L396) + +#### memory dump macros +```C +LOG_DUMPFLAG() +``` +this macro is to be used in if statements. The condition is true if the flag has been set, as described in the [run time usage page](rtusage.md). It is mainly provided to surround LOG_M macros or direct calls to `log_dump`which otherwise would be unconditionals. +```C +if ( LOG_DUMPFLAG() { +/* + the code below is only executed if the corresponding + _dump option is set. + */ +LOG_M(............. +LOG_M(............. +log_dump(... +} + +[example in oai code](https://gitlab.eurecom.fr/oai/openairinterface5g/blob/develop/openair1/PHY/LTE_TRANSPORT/prach.c#L205) +#### matlab format dump +```C +LOG_M(file, vector, data, len, dec, format) +``` +|argument| type| description | +|:-----------|:-------|-----------------:| +| file | char* |path to the fle which will contain the dump | +|vector |char * |name of the dump, printed at the top of the dump file | +|data| void *| pointer to the memory to be dumpped | +|len | int | length of the data to be dumpped, in `dec` unit| +| dec| int | length of each data item.Interpretation depends on format| +|format| int | defines the type of data to be dumped| + +This macro can be used to dump a buffer in a format that can be used for analyze via tools like matlab or octave. **It must be surrounded by LOG_DEBUGFLAG or LOG_DUMPFLAG macros, to prevent the dump to be built unconditionally.** The LOG_M macro points to the `write_file_matlab` function implemented in [log.c](https://gitlab.eurecom.fr/oai/openairinterface5g/blob/develop/common/utils/LOG/log.c). **This function should be revisited for more understandable implementation and ease of use (format parameter ???)** +[example in oai code](https://gitlab.eurecom.fr/oai/openairinterface5g/blob/develop/openair1/PHY/LTE_TRANSPORT/prach.c#L205) + +#### hexadecimal format dump +```C +LOG_DUMPMSG(c, f, b, s, x...) +``` +dumps a memory region if the corresponding debug flag `f` is set as explained here [run time usage page](rtusage.md) + +|argument| type| description | +|:-----------|:-------|-----------------:| +| c | int, component id (in `comp_name_t` enum)| used to print the message, as specified by the s and x arguments | +|f |int |flag used to filter the dump depending on the logs configuration. flag list is defined by the LOG_MASKMAP_INIT macro in [log.h](https://gitlab.eurecom.fr/oai/openairinterface5g/blob/develop/common/utils/LOG/log.h) | +|b| void *| pointer to the memory to be dumpped | +|s | int | length of the data to be dumpped in char| +| x...| printf format and arguments| text string to be printed at the top of the dump| + +This macro can be used to conditionaly dump a buffer, bytes by bytes, giving the integer value of each byte in hexadecimal form. +[example in oai code](https://gitlab.eurecom.fr/oai/openairinterface5g/blob/develop/openair2/RRC/LTE/rrc_eNB.c#L1181) + +This macro points to the `log_dump` function, implemented in [log.c](https://gitlab.eurecom.fr/oai/openairinterface5g/blob/develop/common/utils/LOG/log.c). This function can also dump buffers containing `double` data via the LOG_UDUMPMSG macro + +```C +LOG_UDUMPMSG(c, b, s, f, x...) +``` +|argument| type| description | +|:-----------|:-------|-----------------:| +| c | int, component id (in `comp_name_t` enum)| used to print the message, as specified by the s and x arguments | +|b| void *| pointer to the memory to be dumpped | +|s | int | length of the data to be dumpped in char| +|f| int | format of dumped data LOG_DUMP_CHAR or LOG_DUMP_DOUBLE| +| x...| printf format and arguments| text string to be printed at the top of the dump| + +[example in oai code](https://gitlab.eurecom.fr/oai/openairinterface5g/blob/develop/openair1/SIMULATION/LTE_PHY/dlsim.c#L1974) + +[logging facility main page](log.md) +[oai Wikis home](https://gitlab.eurecom.fr/oai/openairinterface5g/wikis/home) diff --git a/common/utils/LOG/DOC/log.md b/common/utils/LOG/DOC/log.md new file mode 100644 index 0000000000..d7a94d5bbd --- /dev/null +++ b/common/utils/LOG/DOC/log.md @@ -0,0 +1,19 @@ +# OAI console logging facility + +oai includes a console logging facility that any component should use when writting informational or debugging messages to the softmodem or uesoftmodem stdout stream. +By default, this facility is included at build-time and activated at run-time. The T Tracer and the Logging facility share common options for activation: + +- To disable the logging facility (and T Tracer) at build-time use the *--disable-T-Tracer* switch: + +```bash +/build_oai --disable-T-Tracer +``` +- To use the the T-Tracer instead of the console logging facility, use the command line option *T_stdout*. *T_stdout* is a boolean option, which, when set to 0 (false) disable the console logging facility. All stdout messages are then sent to the T-Tracer. + +## Documentation + +* [runtime usage](rtusage.md) +* [developer usage](config/devusage.md) +* [module architecture](arch.md) + +[oai Wikis home](https://gitlab.eurecom.fr/oai/openairinterface5g/wikis/home) diff --git a/common/utils/LOG/DOC/rtusage.md b/common/utils/LOG/DOC/rtusage.md new file mode 100644 index 0000000000..60835bafaf --- /dev/null +++ b/common/utils/LOG/DOC/rtusage.md @@ -0,0 +1,265 @@ +## configuring the logging facility +The logging facility is fully configurable and it uses the [config module](../../../config/config.md) to get its parameters at init time. The [telnet server](../../telnetsrv/DOC/telnetsrv.md) includes a set of commands which can be used to dynamically modify the logging facility behavior + +All logging facility parameters are defined in the log_config section. Some parameters are global to the logging facility, they modify the way messages are printed to stdout. Conversely, some parameters are specific to a component and only modify the behavior for messages issued by a given component. A third type of parameters can be used to activate conditional debug code or dump messages or buffers. + +### global parameters + +| name | type | default | description | +|:---:|:---:|:---:|:----| +| `global_log_level` | `pre-defined string of char` | `info` | Allows printing of messages up to the specified level. Available levels, from lower to higher are `error`,`warn`,`info`,`debug`,`trace` | +| `global_log_online` | `boolean` | 1 (=true) | If false, all console messages are discarded, whatever their level | +| `global_log_options` | `list of pre-defined string of char` | | 3 options can be specified to trigger the information added in the header of the message: `nocolor`, disable color usage in log messages, usefull when redirecting logs to a file, where escape sequences used for color selection can be annoying, `level`, add a one letter level id in the message header (T,D,I,W,E for trace, debug, info, warning, error),`thread`, add the thread name in the message header| + +### Component specific parameters +| name | type | default | description | +|:---:|:---:|:---:|:----| +| `_log_level` | `boolean` | global log level, as defined by the `global_log_level ` parameter) | +| `_log_infile` | `boolean` | 0 = false| Triggers the redirection of log messages printed by the specified component in a file. The file path and name is /tmp/.[extension] the extension is optional and component dependant, it can be `log `, `dat `, `txt `| + +The list of components defined within oai can be retrieved from the [config module](../../../config/config.md) traces, when asking for config module debugging info on the command line: + +```bash +./lte-softmodem -O libconfig::dbgl5 + +[LIBCONFIG] log_config.global_log_level: "info" +[CONFIG] global_log_online: 1 +[CONFIG] log_config.global_log_online set to default value +[LIBCONFIG] log_config: 3/3 parameters successfully set, (1 to default value) +[LIBCONFIG] global_log_options[0]: nocolor +[LIBCONFIG] global_log_options[1]: level +[LIBCONFIG] global_log_options[2]: thread +[CONFIG] log_config 1 options set from command line +[LIBCONFIG] log_config.phy_log_level: "info" +[LIBCONFIG] log_config.mac_log_level: "info" +[CONFIG] log_config.sim_log_level set to default value "info" +[CONFIG] log_config.ocg_log_level set to default value "info" +[CONFIG] log_config.omg_log_level set to default value "info" +[CONFIG] log_config.opt_log_level set to default value "info" +[CONFIG] log_config.otg_log_level set to default value "info" +[CONFIG] log_config.otg_latency_log_level set to default value "info" +[CONFIG] log_config.otg_latency_bg_log_level set to default value "info" +[CONFIG] log_config.otg_gp_log_level set to default value "info" +[CONFIG] log_config.otg_gp_bg_log_level set to default value "info" +[CONFIG] log_config.otg_jitter_log_level set to default value "info" +[LIBCONFIG] log_config.rlc_log_level: "info" +[LIBCONFIG] log_config.pdcp_log_level: "info" +[LIBCONFIG] log_config.rrc_log_level: "info" +[CONFIG] log_config.nas_log_level set to default value "info" +[CONFIG] log_config.perf_log_level set to default value "info" +[CONFIG] log_config.oip_log_level set to default value "info" +[CONFIG] log_config.cli_log_level set to default value "info" +[CONFIG] log_config.msc_log_level set to default value "info" +[CONFIG] log_config.ocm_log_level set to default value "info" +[CONFIG] log_config.udp_log_level set to default value "info" +[CONFIG] log_config.gtpv1u_log_level set to default value "info" +[CONFIG] log_config.comp23?_log_level set to default value "info" +[CONFIG] log_config.s1ap_log_level set to default value "info" +[CONFIG] log_config.sctp_log_level set to default value "info" +[LIBCONFIG] log_config.hw_log_level: "info" +[CONFIG] log_config.osa_log_level set to default value "info" +[CONFIG] log_config.eral_log_level set to default value "info" +[CONFIG] log_config.mral_log_level set to default value "info" +[CONFIG] log_config.enb_app_log_level set to default value "info" +[CONFIG] log_config.flexran_agent_log_level set to default value "info" +[CONFIG] log_config.tmr_log_level set to default value "info" +[CONFIG] log_config.usim_log_level set to default value "info" +[CONFIG] log_config.localize_log_level set to default value "info" +[CONFIG] log_config.x2ap_log_level set to default value "info" +[CONFIG] log_config.loader_log_level set to default value "info" +[CONFIG] log_config.asn_log_level set to default value "info" +[LIBCONFIG] log_config: 38/38 parameters successfully set, (32 to default value) +[CONFIG] log_config 0 options set from command line +[CONFIG] phy_log_infile: 0 +[CONFIG] log_config.phy_log_infile set to default value +[CONFIG] mac_log_infile: 0 +[CONFIG] log_config.mac_log_infile set to default value +[CONFIG] sim_log_infile: 0 +[CONFIG] log_config.sim_log_infile set to default value +[CONFIG] ocg_log_infile: 0 +[CONFIG] log_config.ocg_log_infile set to default value +[CONFIG] omg_log_infile: 0 +[CONFIG] log_config.omg_log_infile set to default value +[CONFIG] opt_log_infile: 0 +[CONFIG] log_config.opt_log_infile set to default value +[CONFIG] otg_log_infile: 0 +[CONFIG] log_config.otg_log_infile set to default value +[CONFIG] otg_latency_log_infile: 0 +[CONFIG] log_config.otg_latency_log_infile set to default value +[CONFIG] otg_latency_bg_log_infile: 0 +[CONFIG] log_config.otg_latency_bg_log_infile set to default value +[CONFIG] otg_gp_log_infile: 0 +[CONFIG] log_config.otg_gp_log_infile set to default value +[CONFIG] otg_gp_bg_log_infile: 0 +[CONFIG] log_config.otg_gp_bg_log_infile set to default value +[CONFIG] otg_jitter_log_infile: 0 +[CONFIG] log_config.otg_jitter_log_infile set to default value +[CONFIG] rlc_log_infile: 0 +[CONFIG] log_config.rlc_log_infile set to default value +[CONFIG] pdcp_log_infile: 0 +[CONFIG] log_config.pdcp_log_infile set to default value +[CONFIG] rrc_log_infile: 0 +[CONFIG] log_config.rrc_log_infile set to default value +[CONFIG] nas_log_infile: 0 +[CONFIG] log_config.nas_log_infile set to default value +[CONFIG] perf_log_infile: 0 +[CONFIG] log_config.perf_log_infile set to default value +[CONFIG] oip_log_infile: 0 +[CONFIG] log_config.oip_log_infile set to default value +[CONFIG] cli_log_infile: 0 +[CONFIG] log_config.cli_log_infile set to default value +[CONFIG] msc_log_infile: 0 +[CONFIG] log_config.msc_log_infile set to default value +[CONFIG] ocm_log_infile: 0 +[CONFIG] log_config.ocm_log_infile set to default value +[CONFIG] udp_log_infile: 0 +[CONFIG] log_config.udp_log_infile set to default value +[CONFIG] gtpv1u_log_infile: 0 +[CONFIG] log_config.gtpv1u_log_infile set to default value +[CONFIG] comp23?_log_infile: 0 +[CONFIG] log_config.comp23?_log_infile set to default value +[CONFIG] s1ap_log_infile: 0 +[CONFIG] log_config.s1ap_log_infile set to default value +[CONFIG] sctp_log_infile: 0 +[CONFIG] log_config.sctp_log_infile set to default value +[CONFIG] hw_log_infile: 0 +[CONFIG] log_config.hw_log_infile set to default value +[CONFIG] osa_log_infile: 0 +[CONFIG] log_config.osa_log_infile set to default value +[CONFIG] eral_log_infile: 0 +[CONFIG] log_config.eral_log_infile set to default value +[CONFIG] mral_log_infile: 0 +[CONFIG] log_config.mral_log_infile set to default value +[CONFIG] enb_app_log_infile: 0 +[CONFIG] log_config.enb_app_log_infile set to default value +[CONFIG] flexran_agent_log_infile: 0 +[CONFIG] log_config.flexran_agent_log_infile set to default value +[CONFIG] tmr_log_infile: 0 +[CONFIG] log_config.tmr_log_infile set to default value +[CONFIG] usim_log_infile: 0 +[CONFIG] log_config.usim_log_infile set to default value +[CONFIG] localize_log_infile: 0 +[CONFIG] log_config.localize_log_infile set to default value +[CONFIG] x2ap_log_infile: 0 +[CONFIG] log_config.x2ap_log_infile set to default value +[CONFIG] loader_log_infile: 0 +[CONFIG] log_config.loader_log_infile set to default value +[CONFIG] asn_log_infile: 0 +[CONFIG] log_config.asn_log_infile set to default value +[LIBCONFIG] log_config: 38/38 parameters successfully set, (38 to default value) +[CONFIG] log_config 0 options set from command line +[CONFIG] PRACH_debug: 0 +[CONFIG] log_config.PRACH_debug set to default value +[CONFIG] RU_debug: 0 +[CONFIG] log_config.RU_debug set to default value +[CONFIG] UE_PHYPROC_debug: 0 +[CONFIG] log_config.UE_PHYPROC_debug set to default value +[CONFIG] LTEESTIM_debug: 0 +[CONFIG] log_config.LTEESTIM_debug set to default value +[CONFIG] DLCELLSPEC_debug: 0 +[CONFIG] log_config.DLCELLSPEC_debug set to default value +[CONFIG] ULSCH_debug: 0 +[CONFIG] log_config.ULSCH_debug set to default value +[CONFIG] RRC_debug: 0 +[CONFIG] log_config.RRC_debug set to default value +[CONFIG] PDCP_debug: 0 +[CONFIG] log_config.PDCP_debug set to default value +[CONFIG] DFT_debug: 0 +[CONFIG] log_config.DFT_debug set to default value +[CONFIG] ASN1_debug: 0 +[CONFIG] log_config.ASN1_debug set to default value +[CONFIG] CTRLSOCKET_debug: 0 +[CONFIG] log_config.CTRLSOCKET_debug set to default value +[CONFIG] SECURITY_debug: 0 +[CONFIG] log_config.SECURITY_debug set to default value +[CONFIG] NAS_debug: 0 +[CONFIG] log_config.NAS_debug set to default value +[CONFIG] RLC_debug: 0 +[CONFIG] log_config.RLC_debug set to default value +[CONFIG] UE_TIMING_debug: 0 +[CONFIG] log_config.UE_TIMING_debug set to default value +[LIBCONFIG] log_config: 15/15 parameters successfully set, (15 to default value) +[CONFIG] log_config 0 options set from command line +[CONFIG] PRACH_dump: 0 +[CONFIG] log_config.PRACH_dump set to default value +[CONFIG] RU_dump: 0 +[CONFIG] log_config.RU_dump set to default value +[CONFIG] UE_PHYPROC_dump: 0 +[CONFIG] log_config.UE_PHYPROC_dump set to default value +[CONFIG] LTEESTIM_dump: 0 +[CONFIG] log_config.LTEESTIM_dump set to default value +[CONFIG] DLCELLSPEC_dump: 0 +[CONFIG] log_config.DLCELLSPEC_dump set to default value +[CONFIG] ULSCH_dump: 0 +[CONFIG] log_config.ULSCH_dump set to default value +[CONFIG] RRC_dump: 0 +[CONFIG] log_config.RRC_dump set to default value +[CONFIG] PDCP_dump: 0 +[CONFIG] log_config.PDCP_dump set to default value +[CONFIG] DFT_dump: 0 +[CONFIG] log_config.DFT_dump set to default value +[CONFIG] ASN1_dump: 0 +[CONFIG] log_config.ASN1_dump set to default value +[CONFIG] CTRLSOCKET_dump: 0 +[CONFIG] log_config.CTRLSOCKET_dump set to default value +[CONFIG] SECURITY_dump: 0 +[CONFIG] log_config.SECURITY_dump set to default value +[CONFIG] NAS_dump: 0 +[CONFIG] log_config.NAS_dump set to default value +[CONFIG] RLC_dump: 0 +[CONFIG] log_config.RLC_dump set to default value +[CONFIG] UE_TIMING_dump: 0 +[CONFIG] log_config.UE_TIMING_dump set to default value +[LIBCONFIG] log_config: 15/15 parameters successfully set, (15 to default value) +[CONFIG] log_config 0 options set from command line +log init done + +``` +It can also be retrieved when using the telnet server, as explained [below](### Using the telnet server to configure the logging facility) + +### parameters to activate conditional code +| name | type | default | description | +|:---:|:---:|:---:|:----| +| `_debug` | `boolean` | 0 = false | Triggers the activation of conditional code identified by the specified flag. +| `_dump` | `boolean` | 0 = false| Triggers buffer dump, on the console in text form or in a file in matlab format, depending on the developper choice and forcasted usage| + +### Using the configuration file to configure the logging facility +The following example sets all components log level to info, exept for hw,phy,mac,rlc,pdcp,rrc which log levels are set to error or warning. +```bash + log_config : + { + global_log_level ="info"; + hw_log_level ="error"; + phy_log_level ="error"; + mac_log_level ="warn"; + rlc_log_level ="error" + pdcp_log_level ="error"; + rrc_log_level ="error"; + }; +``` +### Using the command line to configure the logging facility +Command line parameter values supersedes values specified in the configuration file. +```bash +./lte-softmodem -O --log_config.global_log_options nocolor,level,thread --log_config.prach_log_level debug --log_config.PRACH_debug +``` +In this example to get all the debug PRACH messages it is necessary to also set the PRACH_debug flag. This is a choice from the developper. +The log messages will be printed whithout color and the header will include the lmessage evel and the thread name: +```bash +[PHY]I ru thread Time in secs now: 104652566 +[PHY]I ru thread Time in secs last pps: 91827117 +[PHY]I ru thread RU 0 rf device ready +[PHY]I ru thread RU 0 no asynch_south interface +[MAC]E rxtx processing SCHED_MODE=0 +[PHY]I lte-softmodem PRACH (eNB) : running rx_prach for subframe 1, prach_FreqOffset 2, prach_ConfigIndex 0 , rootSequenceIndex 0 +[PHY]I lte-softmodem prach_I0 = 0.0 dB +[PHY]I rxtx processing max_I0 21, min_I0 0 +[PHY]I lte-softmodem PRACH (eNB) : running rx_prach for subframe 1, prach_FreqOffset 2, prach_ConfigIndex 0 , rootSequenceIndex 0 +[PHY]I lte-softmodem PRACH (eNB) : running rx_prach for subframe 1, prach_FreqOffset 2, prach_ConfigIndex 0 , rootSequenceIndex 0 +``` + +### Using the telnet server to configure the logging facility +The telnet server includes a `log` command which can be used to dymically modify the logging facility configuration parameters. +[telnet server ***softmodem log*** commands](../../telnetsrv/DOC/telnetlog.md) + +[logging facility main page](log.md) +[oai Wikis home](https://gitlab.eurecom.fr/oai/openairinterface5g/wikis/home) diff --git a/common/utils/telnetsrv/DOC/telnetlog.md b/common/utils/telnetsrv/DOC/telnetlog.md index 7c1d4f0384..0faaf9c02e 100644 --- a/common/utils/telnetsrv/DOC/telnetlog.md +++ b/common/utils/telnetsrv/DOC/telnetlog.md @@ -92,4 +92,5 @@ Connection closed by foreign host. ``` [oai telnetserver home](telnetsrv.md) -[oai telnetserver usage home](telnetusage.md) \ No newline at end of file +[oai telnetserver usage home](telnetusage.md) +[oai Wikis home](https://gitlab.eurecom.fr/oai/openairinterface5g/wikis/home) \ No newline at end of file From 2f8c3d6eaaafae786bcf02e9786d1276303925a6 Mon Sep 17 00:00:00 2001 From: Francois TABURET Date: Fri, 16 Nov 2018 18:04:49 +0100 Subject: [PATCH 153/233] fix broken links --- common/utils/LOG/DOC/arch.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/common/utils/LOG/DOC/arch.md b/common/utils/LOG/DOC/arch.md index f774655771..348216983b 100644 --- a/common/utils/LOG/DOC/arch.md +++ b/common/utils/LOG/DOC/arch.md @@ -1,8 +1,8 @@ # logging facility source files -The oai logging facility is implemented in two source files, located in [common/utils](https://gitlab.eurecom.fr/oai/openairinterface5g/tree/develop/common/utils) -1. [log.c](https://gitlab.eurecom.fr/oai/openairinterface5g/tree/develop/common/utils/log.c) contains logging implementation -1. [log.h](https://gitlab.eurecom.fr/oai/openairinterface5g/tree/develop/common/utils/log.h) is the logging facility include file containing both private and public data type definitions. It also contain API prototypes. +The oai logging facility is implemented in two source files, located in [common/utils/LOG](LOG) +1. [log.c](../log.c) contains logging implementation +1. [log.h](../log.h) is the logging facility include file containing both private and public data type definitions. It also contain API prototypes. [logging facility main page](log.md) From 382981b7576ced16d957e4096b206260550285f0 Mon Sep 17 00:00:00 2001 From: Francois TABURET Date: Fri, 16 Nov 2018 18:05:54 +0100 Subject: [PATCH 154/233] fix broken link --- common/utils/LOG/DOC/log.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/utils/LOG/DOC/log.md b/common/utils/LOG/DOC/log.md index d7a94d5bbd..121e227f3d 100644 --- a/common/utils/LOG/DOC/log.md +++ b/common/utils/LOG/DOC/log.md @@ -13,7 +13,7 @@ By default, this facility is included at build-time and activated at run-time. T ## Documentation * [runtime usage](rtusage.md) -* [developer usage](config/devusage.md) +* [developer usage](devusage.md) * [module architecture](arch.md) [oai Wikis home](https://gitlab.eurecom.fr/oai/openairinterface5g/wikis/home) From 220080741eef482ec8451c956ad24d59ab586a4f Mon Sep 17 00:00:00 2001 From: Francois TABURET Date: Fri, 16 Nov 2018 19:31:58 +0100 Subject: [PATCH 155/233] Update devusage.md --- common/utils/LOG/DOC/devusage.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/common/utils/LOG/DOC/devusage.md b/common/utils/LOG/DOC/devusage.md index 2d5582ff7c..f3d972a05d 100644 --- a/common/utils/LOG/DOC/devusage.md +++ b/common/utils/LOG/DOC/devusage.md @@ -115,5 +115,7 @@ LOG_UDUMPMSG(c, b, s, f, x...) [example in oai code](https://gitlab.eurecom.fr/oai/openairinterface5g/blob/develop/openair1/SIMULATION/LTE_PHY/dlsim.c#L1974) +### logging facility APIs + [logging facility main page](log.md) [oai Wikis home](https://gitlab.eurecom.fr/oai/openairinterface5g/wikis/home) From 682be3e2b4a5f4d58272e197a605ecd7596a6b5d Mon Sep 17 00:00:00 2001 From: frtabu Date: Mon, 19 Nov 2018 11:27:43 +0100 Subject: [PATCH 156/233] completing logging facility doc --- common/utils/LOG/DOC/addconsoletrace.md | 110 ++++++++++++++++++++++ common/utils/LOG/DOC/configurelog.md | 49 ++++++++++ common/utils/LOG/DOC/devusage.md | 116 +----------------------- 3 files changed, 163 insertions(+), 112 deletions(-) create mode 100644 common/utils/LOG/DOC/addconsoletrace.md create mode 100644 common/utils/LOG/DOC/configurelog.md diff --git a/common/utils/LOG/DOC/addconsoletrace.md b/common/utils/LOG/DOC/addconsoletrace.md new file mode 100644 index 0000000000..502e9d39d2 --- /dev/null +++ b/common/utils/LOG/DOC/addconsoletrace.md @@ -0,0 +1,110 @@ +### Adding console traces in oai code +#### console messages macros +```C +LOG_E(,,,...) +LOG_W(,,,...) +LOG_I(,,,...) +LOG_D(,,,...) +LOG_T(,,,...) +) +``` +these macros are used in place of the printf C function. The additionnal ***component*** parameter identifies the functionnal module which generates the message. At run time, the message will only be printed if the configured log level for the component is greater or equal than the macro level used in the code. + +| macro | level letter | level value | level name | +|:---------|:---------------|:---------------|----------------:| +| LOG_E | E | 0 | error | +| LOG_W | W | 1 | warning | +| LOG_I | I | 2 | informational | +| LOG_D | D | 3 | debug | +| LOG_T | T | 4 | trace | + +component list is defined as an `enum` in [log.h](https://gitlab.eurecom.fr/oai/openairinterface5g/blob/develop/common/utils/LOG/log.h). A new component can be defined by adding an item in this type, it must also be defined in the T tracer [T_messages.txt ](https://gitlab.eurecom.fr/oai/openairinterface5g/blob/develop/common/utils/T/T_messages.txt). + +Most oai sources are including LOG macros. + +#### conditional code macros + +```C +LOG_DEBUGFLAG() +``` +this macro is to be used in if statements. The condition is true if the flag has been set, as described in the [run time usage page](rtusage.md) +```C +if ( LOG_DEBUGFLAG() { +/* + the code below is only executed if the corresponding + _debug option is set. + */ +...................... +...................... +} +``` +[example in oai code](https://gitlab.eurecom.fr/oai/openairinterface5g/blob/develop/openair1/PHY/LTE_TRANSPORT/ulsch_demodulation.c#L396) + +#### memory dump macros +```C +LOG_DUMPFLAG() +``` +this macro is to be used in if statements. The condition is true if the flag has been set, as described in the [run time usage page](rtusage.md). It is mainly provided to surround LOG_M macros or direct calls to `log_dump`which otherwise would be unconditionals. +```C +if ( LOG_DUMPFLAG() { +/* + the code below is only executed if the corresponding + _dump option is set. + */ +LOG_M(............. +LOG_M(............. +log_dump(... +} + +[example in oai code](https://gitlab.eurecom.fr/oai/openairinterface5g/blob/develop/openair1/PHY/LTE_TRANSPORT/prach.c#L205) +#### matlab format dump +```C +LOG_M(file, vector, data, len, dec, format) +``` +|argument| type| description | +|:-----------|:-------|-----------------:| +| file | char* |path to the fle which will contain the dump | +|vector |char * |name of the dump, printed at the top of the dump file | +|data| void *| pointer to the memory to be dumpped | +|len | int | length of the data to be dumpped, in `dec` unit| +| dec| int | length of each data item.Interpretation depends on format| +|format| int | defines the type of data to be dumped| + +This macro can be used to dump a buffer in a format that can be used for analyze via tools like matlab or octave. **It must be surrounded by LOG_DEBUGFLAG or LOG_DUMPFLAG macros, to prevent the dump to be built unconditionally.** The LOG_M macro points to the `write_file_matlab` function implemented in [log.c](https://gitlab.eurecom.fr/oai/openairinterface5g/blob/develop/common/utils/LOG/log.c). **This function should be revisited for more understandable implementation and ease of use (format parameter ???)** +[example in oai code](https://gitlab.eurecom.fr/oai/openairinterface5g/blob/develop/openair1/PHY/LTE_TRANSPORT/prach.c#L205) + +#### hexadecimal format dump +```C +LOG_DUMPMSG(c, f, b, s, x...) +``` +dumps a memory region if the corresponding debug flag `f` is set as explained here [run time usage page](rtusage.md) + +|argument| type| description | +|:-----------|:-------|-----------------:| +| c | int, component id (in `comp_name_t` enum)| used to print the message, as specified by the s and x arguments | +|f |int |flag used to filter the dump depending on the logs configuration. flag list is defined by the LOG_MASKMAP_INIT macro in [log.h](https://gitlab.eurecom.fr/oai/openairinterface5g/blob/develop/common/utils/LOG/log.h) | +|b| void *| pointer to the memory to be dumpped | +|s | int | length of the data to be dumpped in char| +| x...| printf format and arguments| text string to be printed at the top of the dump| + +This macro can be used to conditionaly dump a buffer, bytes by bytes, giving the integer value of each byte in hexadecimal form. +[example in oai code](https://gitlab.eurecom.fr/oai/openairinterface5g/blob/develop/openair2/RRC/LTE/rrc_eNB.c#L1181) + +This macro points to the `log_dump` function, implemented in [log.c](https://gitlab.eurecom.fr/oai/openairinterface5g/blob/develop/common/utils/LOG/log.c). This function can also dump buffers containing `double` data via the LOG_UDUMPMSG macro + +```C +LOG_UDUMPMSG(c, b, s, f, x...) +``` +|argument| type| description | +|:-----------|:-------|-----------------:| +| c | int, component id (in `comp_name_t` enum)| used to print the message, as specified by the s and x arguments | +|b| void *| pointer to the memory to be dumpped | +|s | int | length of the data to be dumpped in char| +|f| int | format of dumped data LOG_DUMP_CHAR or LOG_DUMP_DOUBLE| +| x...| printf format and arguments| text string to be printed at the top of the dump| + +[example in oai code](https://gitlab.eurecom.fr/oai/openairinterface5g/blob/develop/openair1/SIMULATION/LTE_PHY/dlsim.c#L1974) + +[logging facility developer main page](ldevusage.md) +[logging facility main page](log.md) +[oai Wikis home](https://gitlab.eurecom.fr/oai/openairinterface5g/wikis/home) \ No newline at end of file diff --git a/common/utils/LOG/DOC/configurelog.md b/common/utils/LOG/DOC/configurelog.md new file mode 100644 index 0000000000..ee8c0972e6 --- /dev/null +++ b/common/utils/LOG/DOC/configurelog.md @@ -0,0 +1,49 @@ +### Initializing and configuring the logging facility + +#### logging facility APIs +```C +int logInit (void); +``` +Allocate the internal data used by the logging utility, set the configuration, using the [configuration module](../../../config/DOC/config.md) + +```C +void logClean (void) +``` +Reset console attributes (color settings) and possibly close opened log files. Logging facility is still usable after this call, the internal data are not freed. + +```C +int set_log(int component, int level) +void set_glog(int level) +``` +Set a component or all components logiing level. Messages which level is lower than this level are not printed to the console. + +```C +void set_glog_onlinelog(int enable) +``` +Enable or disable all logging messages. Even error level messages are discarded, which is not advised. This can be usefull to temporarily workaround high rate of logging messages. + +```C +void set_component_filelog(int comp) +void close_component_filelog(int comp) +``` + +Redirect or reset to stdout the output stream used by the logging facility. When the output stream is redirected to a file, it is created under /tmp with a hard-coded filename including the componemt name. + +```C +SET_LOG_DEBUG(flag) +CLEAR_LOG_DEBUG(flag) +SET_LOG_DUMP(flag) +CLEAR_LOG_DUMP(flag) +``` + These macros are used to set or clear the corresponding bit flag, trigerring the activation or un-activation of conditional code or memory dumps generation. + +Example of using the logging utility APIs can be found, for initialization and cleanup, in [lte-softmodem.c](../../../../targets/RT/USER/lte-softmodem.c) and in the [telnet server log command implementation](../../telnetsrv/telnetsrv_proccmd.c) for a complete access to the logging facility features. + +#### components and debug flags definitions + +Adding a new component is just adding an item in the `comp_name_t` enum defined in [log.h](../log.h) . You must also declare it in the T Tracer facility [message fefinitions](../../T/T_messages.txt). +To add a flag than can then be used for adding conditional code or memory dumps you have to add the flag definition in the `LOG_MASKMAP_INIT` macro, in [log.h](../log.h). + +[logging facility developer main page](ldevusage.md) +[logging facility main page](log.md) +[oai Wikis home](https://gitlab.eurecom.fr/oai/openairinterface5g/wikis/home) \ No newline at end of file diff --git a/common/utils/LOG/DOC/devusage.md b/common/utils/LOG/DOC/devusage.md index f3d972a05d..0e68be4414 100644 --- a/common/utils/LOG/DOC/devusage.md +++ b/common/utils/LOG/DOC/devusage.md @@ -1,121 +1,13 @@ -### logging facility usage +### logging facility developer usage The logging facility objectives are 1. provide a common console tracing mechanism 1. Allow a flexible activation of console traces, by configuration or dynamically at any time while code is running. -Once the logging facility has been initialized and configured developpers use C preprocessor macros to include console messages in their code. At execution time, these traces will be printed or not to the console depending on the configuration, as described [here](rtusage.md). The logging facility also defines preprocessor macros to include condtional code, to dump memory blocks (buffers, messages...). +Most developpers will only use the log macros to add console messages to the code. The logging facility also provides an api that is used for initialization and configuration. -All macros are defined in [log.h](https://gitlab.eurecom.fr/oai/openairinterface5g/blob/develop/common/utils/LOG/log.h) include file, which must be included in any source file using the logging facility macros. +[Adding console traces in oaicode](addconsoletrace.md) +[Configuring the logging facility](configurelog.md) - [log.h](https://gitlab.eurecom.fr/oai/openairinterface5g/blob/develop/common/utils/LOG/log.h) also includes the prototypes of the functions that have to be called to initialize, configure or get the status of console logs. - -#### console messages macros -```C -LOG_E(,,,...) -LOG_W(,,,...) -LOG_I(,,,...) -LOG_D(,,,...) -LOG_T(,,,...) -) -``` -these macros are used in place of the printf C function. The additionnal ***component*** parameter identifies the functionnal module which generates the message. At run time, the message will only be printed if the configured log level for the component is greater or equal than the macro level used in the code. - -| macro | level letter | level value | level name | -|:---------|:---------------|:---------------|----------------:| -| LOG_E | E | 0 | error | -| LOG_W | W | 1 | warning | -| LOG_I | I | 2 | informational | -| LOG_D | D | 3 | debug | -| LOG_T | T | 4 | trace | - -component list is defined as an `enum` in [log.h](https://gitlab.eurecom.fr/oai/openairinterface5g/blob/develop/common/utils/LOG/log.h). A new component can be defined by adding an item in this type, it must also be defined in the T tracer [T_messages.txt ](https://gitlab.eurecom.fr/oai/openairinterface5g/blob/develop/common/utils/T/T_messages.txt). - -Most oai sources are including LOG macros. - -#### conditional code macros - -```C -LOG_DEBUGFLAG() -``` -this macro is to be used in if statements. The condition is true if the flag has been set, as described in the [run time usage page](rtusage.md) -```C -if ( LOG_DEBUGFLAG() { -/* - the code below is only executed if the corresponding - _debug option is set. - */ -...................... -...................... -} -``` -[example in oai code](https://gitlab.eurecom.fr/oai/openairinterface5g/blob/develop/openair1/PHY/LTE_TRANSPORT/ulsch_demodulation.c#L396) - -#### memory dump macros -```C -LOG_DUMPFLAG() -``` -this macro is to be used in if statements. The condition is true if the flag has been set, as described in the [run time usage page](rtusage.md). It is mainly provided to surround LOG_M macros or direct calls to `log_dump`which otherwise would be unconditionals. -```C -if ( LOG_DUMPFLAG() { -/* - the code below is only executed if the corresponding - _dump option is set. - */ -LOG_M(............. -LOG_M(............. -log_dump(... -} - -[example in oai code](https://gitlab.eurecom.fr/oai/openairinterface5g/blob/develop/openair1/PHY/LTE_TRANSPORT/prach.c#L205) -#### matlab format dump -```C -LOG_M(file, vector, data, len, dec, format) -``` -|argument| type| description | -|:-----------|:-------|-----------------:| -| file | char* |path to the fle which will contain the dump | -|vector |char * |name of the dump, printed at the top of the dump file | -|data| void *| pointer to the memory to be dumpped | -|len | int | length of the data to be dumpped, in `dec` unit| -| dec| int | length of each data item.Interpretation depends on format| -|format| int | defines the type of data to be dumped| - -This macro can be used to dump a buffer in a format that can be used for analyze via tools like matlab or octave. **It must be surrounded by LOG_DEBUGFLAG or LOG_DUMPFLAG macros, to prevent the dump to be built unconditionally.** The LOG_M macro points to the `write_file_matlab` function implemented in [log.c](https://gitlab.eurecom.fr/oai/openairinterface5g/blob/develop/common/utils/LOG/log.c). **This function should be revisited for more understandable implementation and ease of use (format parameter ???)** -[example in oai code](https://gitlab.eurecom.fr/oai/openairinterface5g/blob/develop/openair1/PHY/LTE_TRANSPORT/prach.c#L205) - -#### hexadecimal format dump -```C -LOG_DUMPMSG(c, f, b, s, x...) -``` -dumps a memory region if the corresponding debug flag `f` is set as explained here [run time usage page](rtusage.md) - -|argument| type| description | -|:-----------|:-------|-----------------:| -| c | int, component id (in `comp_name_t` enum)| used to print the message, as specified by the s and x arguments | -|f |int |flag used to filter the dump depending on the logs configuration. flag list is defined by the LOG_MASKMAP_INIT macro in [log.h](https://gitlab.eurecom.fr/oai/openairinterface5g/blob/develop/common/utils/LOG/log.h) | -|b| void *| pointer to the memory to be dumpped | -|s | int | length of the data to be dumpped in char| -| x...| printf format and arguments| text string to be printed at the top of the dump| - -This macro can be used to conditionaly dump a buffer, bytes by bytes, giving the integer value of each byte in hexadecimal form. -[example in oai code](https://gitlab.eurecom.fr/oai/openairinterface5g/blob/develop/openair2/RRC/LTE/rrc_eNB.c#L1181) - -This macro points to the `log_dump` function, implemented in [log.c](https://gitlab.eurecom.fr/oai/openairinterface5g/blob/develop/common/utils/LOG/log.c). This function can also dump buffers containing `double` data via the LOG_UDUMPMSG macro - -```C -LOG_UDUMPMSG(c, b, s, f, x...) -``` -|argument| type| description | -|:-----------|:-------|-----------------:| -| c | int, component id (in `comp_name_t` enum)| used to print the message, as specified by the s and x arguments | -|b| void *| pointer to the memory to be dumpped | -|s | int | length of the data to be dumpped in char| -|f| int | format of dumped data LOG_DUMP_CHAR or LOG_DUMP_DOUBLE| -| x...| printf format and arguments| text string to be printed at the top of the dump| - -[example in oai code](https://gitlab.eurecom.fr/oai/openairinterface5g/blob/develop/openair1/SIMULATION/LTE_PHY/dlsim.c#L1974) - -### logging facility APIs [logging facility main page](log.md) [oai Wikis home](https://gitlab.eurecom.fr/oai/openairinterface5g/wikis/home) From 3df8f96bba15acdef401fdb1fd871024115172b2 Mon Sep 17 00:00:00 2001 From: Francois TABURET Date: Mon, 19 Nov 2018 11:30:54 +0100 Subject: [PATCH 157/233] fix wrong formatting --- common/utils/LOG/DOC/devusage.md | 1 + 1 file changed, 1 insertion(+) diff --git a/common/utils/LOG/DOC/devusage.md b/common/utils/LOG/DOC/devusage.md index 0e68be4414..d7790917fc 100644 --- a/common/utils/LOG/DOC/devusage.md +++ b/common/utils/LOG/DOC/devusage.md @@ -6,6 +6,7 @@ The logging facility objectives are Most developpers will only use the log macros to add console messages to the code. The logging facility also provides an api that is used for initialization and configuration. [Adding console traces in oaicode](addconsoletrace.md) + [Configuring the logging facility](configurelog.md) From 884d4b631d2c4023558ad70b5a605d3a966b22a3 Mon Sep 17 00:00:00 2001 From: Francois TABURET Date: Mon, 19 Nov 2018 11:34:38 +0100 Subject: [PATCH 158/233] fix broken link --- common/utils/LOG/DOC/addconsoletrace.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/utils/LOG/DOC/addconsoletrace.md b/common/utils/LOG/DOC/addconsoletrace.md index 502e9d39d2..d850ac1036 100644 --- a/common/utils/LOG/DOC/addconsoletrace.md +++ b/common/utils/LOG/DOC/addconsoletrace.md @@ -105,6 +105,6 @@ LOG_UDUMPMSG(c, b, s, f, x...) [example in oai code](https://gitlab.eurecom.fr/oai/openairinterface5g/blob/develop/openair1/SIMULATION/LTE_PHY/dlsim.c#L1974) -[logging facility developer main page](ldevusage.md) +[logging facility developer main page](devusage.md) [logging facility main page](log.md) [oai Wikis home](https://gitlab.eurecom.fr/oai/openairinterface5g/wikis/home) \ No newline at end of file From 0f0665e9e7f88cb6b9cb1c0cab68b027e0a97276 Mon Sep 17 00:00:00 2001 From: Francois TABURET Date: Mon, 19 Nov 2018 11:35:37 +0100 Subject: [PATCH 159/233] fix broken link --- common/utils/LOG/DOC/configurelog.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/utils/LOG/DOC/configurelog.md b/common/utils/LOG/DOC/configurelog.md index ee8c0972e6..c671c043bd 100644 --- a/common/utils/LOG/DOC/configurelog.md +++ b/common/utils/LOG/DOC/configurelog.md @@ -44,6 +44,6 @@ Example of using the logging utility APIs can be found, for initialization and c Adding a new component is just adding an item in the `comp_name_t` enum defined in [log.h](../log.h) . You must also declare it in the T Tracer facility [message fefinitions](../../T/T_messages.txt). To add a flag than can then be used for adding conditional code or memory dumps you have to add the flag definition in the `LOG_MASKMAP_INIT` macro, in [log.h](../log.h). -[logging facility developer main page](ldevusage.md) +[logging facility developer main page](devusage.md) [logging facility main page](log.md) [oai Wikis home](https://gitlab.eurecom.fr/oai/openairinterface5g/wikis/home) \ No newline at end of file From a86ca815411e8ee9990fbe4d3855f6ba5e097cad Mon Sep 17 00:00:00 2001 From: Francois TABURET Date: Mon, 19 Nov 2018 13:17:23 +0100 Subject: [PATCH 160/233] Update arch.md --- common/utils/LOG/DOC/arch.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/common/utils/LOG/DOC/arch.md b/common/utils/LOG/DOC/arch.md index 348216983b..a472107d50 100644 --- a/common/utils/LOG/DOC/arch.md +++ b/common/utils/LOG/DOC/arch.md @@ -4,6 +4,9 @@ The oai logging facility is implemented in two source files, located in [common/ 1. [log.c](../log.c) contains logging implementation 1. [log.h](../log.h) is the logging facility include file containing both private and public data type definitions. It also contain API prototypes. +The logging facility doesn't create any thread, all api's are executed in the context of the caller. The tracing macro's LOG_ are all using the logRecord_mt function to output the messages. To keep this function thread safe it must perform a single system call the output stream. The buffer used to build the message must be specific to the calling thread, which is today enforced by using a variable in the logRecord_mt stack. + +Data used by the logging utility are defined by the `log_t` structure which is allocated at init time, when calling the `logInit` function. [logging facility main page](log.md) [oai Wikis home](https://gitlab.eurecom.fr/oai/openairinterface5g/wikis/home) \ No newline at end of file From 117e2a145ef47ae091a05b94b8887ff7d7163285 Mon Sep 17 00:00:00 2001 From: Francois TABURET Date: Mon, 19 Nov 2018 13:20:14 +0100 Subject: [PATCH 161/233] Update arch.md --- common/utils/LOG/DOC/arch.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/utils/LOG/DOC/arch.md b/common/utils/LOG/DOC/arch.md index a472107d50..b9302927be 100644 --- a/common/utils/LOG/DOC/arch.md +++ b/common/utils/LOG/DOC/arch.md @@ -4,7 +4,7 @@ The oai logging facility is implemented in two source files, located in [common/ 1. [log.c](../log.c) contains logging implementation 1. [log.h](../log.h) is the logging facility include file containing both private and public data type definitions. It also contain API prototypes. -The logging facility doesn't create any thread, all api's are executed in the context of the caller. The tracing macro's LOG_ are all using the logRecord_mt function to output the messages. To keep this function thread safe it must perform a single system call the output stream. The buffer used to build the message must be specific to the calling thread, which is today enforced by using a variable in the logRecord_mt stack. +The logging facility doesn't create any thread, all api's are executed in the context of the caller. The tracing macro's `LOG_` are all using the logRecord_mt function to output the messages. To keep this function thread safe it must perform a single system call to the output stream. The buffer used to build the message must be specific to the calling thread, which is today enforced by using a variable in the logRecord_mt stack. Data used by the logging utility are defined by the `log_t` structure which is allocated at init time, when calling the `logInit` function. From e6cd6ba21f05ea6e3160fa3c054dbcdbb940c6d0 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Tue, 20 Nov 2018 13:03:31 +0100 Subject: [PATCH 162/233] T: minor: fix typo --- common/utils/T/genids.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/common/utils/T/genids.c b/common/utils/T/genids.c index 8e5adbf587..112fe9de5a 100644 --- a/common/utils/T/genids.c +++ b/common/utils/T/genids.c @@ -24,11 +24,11 @@ int new_unique_id(char *s, char *input_file) if (unique_ids_size == unique_ids_maxsize) { unique_ids_maxsize += 256; unique_ids = realloc(unique_ids, unique_ids_maxsize * sizeof(char *)); - if (unique_ids == NULL) { printf("erorr: out of memory\n"); abort(); } + if (unique_ids == NULL) { printf("error: out of memory\n"); abort(); } } unique_ids[unique_ids_size] = strdup(s); if (unique_ids[unique_ids_size] == NULL) - { printf("erorr: out of memory\n"); abort(); } + { printf("error: out of memory\n"); abort(); } unique_ids_size++; qsort(unique_ids, unique_ids_size, sizeof(char *), cmp); return 1; @@ -44,7 +44,7 @@ void putname(int c) bufname_maxsize += 256; bufname = realloc(bufname, bufname_maxsize); if (bufname == NULL) - { printf("erorr: memory allocation error\n"); exit(1); } + { printf("error: memory allocation error\n"); exit(1); } } bufname[bufname_size] = c; bufname_size++; From c194956da34fb8ca686bbf4b738e7fa327e54720 Mon Sep 17 00:00:00 2001 From: Louis Adrien Dufrene Date: Tue, 20 Nov 2018 14:15:50 +0100 Subject: [PATCH 163/233] RRC timer thres removed from UE context and added to eNB RRC context, value 0 of thres equivalent to infinity --- common/utils/T/tracer/gui/x.c | 2 +- openair2/COMMON/rrc_messages_types.h | 1 + openair2/ENB_APP/enb_config.c | 4 +++- openair2/RRC/LTE/rrc_defs.h | 2 +- openair2/RRC/LTE/rrc_eNB.c | 20 ++++++++++++-------- 5 files changed, 18 insertions(+), 11 deletions(-) diff --git a/common/utils/T/tracer/gui/x.c b/common/utils/T/tracer/gui/x.c index 3176810ec3..71bd805455 100644 --- a/common/utils/T/tracer/gui/x.c +++ b/common/utils/T/tracer/gui/x.c @@ -135,7 +135,7 @@ x_image *x_create_image(x_connection *_x, unsigned char *data, if (ret == NULL) OOM; template.class = TrueColor; - template.depth = 32; + template.depth = 24; template.red_mask = 0xff0000; template.green_mask = 0x00ff00; template.blue_mask = 0x0000ff; diff --git a/openair2/COMMON/rrc_messages_types.h b/openair2/COMMON/rrc_messages_types.h index aeacd09fde..d7f6a67d78 100644 --- a/openair2/COMMON/rrc_messages_types.h +++ b/openair2/COMMON/rrc_messages_types.h @@ -102,6 +102,7 @@ typedef struct RrcConfigurationReq_s { uint8_t mnc_digit_length[PLMN_LIST_MAX_SIZE]; uint8_t num_plmn; + uint32_t rrc_inactivity_timer_thres; // for testing, maybe change later paging_drx_t default_drx; int16_t nb_cc; diff --git a/openair2/ENB_APP/enb_config.c b/openair2/ENB_APP/enb_config.c index efbceb49bd..cde9364f2b 100644 --- a/openair2/ENB_APP/enb_config.c +++ b/openair2/ENB_APP/enb_config.c @@ -579,8 +579,10 @@ int RCconfig_RRC(MessageDef *msg_p, uint32_t i, eNB_RRC_INST *rrc) { for (int I = 0; I < sizeof(PLMNParams) / sizeof(paramdef_t); ++I) PLMNParams[I].chkPptr = &(config_check_PLMNParams[I]); + RRC_CONFIGURATION_REQ (msg_p).rrc_inactivity_timer_thres = 10000; + RRC_CONFIGURATION_REQ (msg_p).cell_identity = enb_id; - RRC_CONFIGURATION_REQ(msg_p).tac = *ENBParamList.paramarray[i][ENB_TRACKING_AREA_CODE_IDX].uptr; + RRC_CONFIGURATION_REQ (msg_p).tac = *ENBParamList.paramarray[i][ENB_TRACKING_AREA_CODE_IDX].uptr; AssertFatal(!ENBParamList.paramarray[i][ENB_MOBILE_COUNTRY_CODE_IDX_OLD].strptr && !ENBParamList.paramarray[i][ENB_MOBILE_NETWORK_CODE_IDX_OLD].strptr, "It seems that you use an old configuration file. Please change the existing\n" diff --git a/openair2/RRC/LTE/rrc_defs.h b/openair2/RRC/LTE/rrc_defs.h index 1d9e447984..9a84b8e8e7 100644 --- a/openair2/RRC/LTE/rrc_defs.h +++ b/openair2/RRC/LTE/rrc_defs.h @@ -601,7 +601,7 @@ typedef struct eNB_RRC_UE_s { uint32_t ue_reestablishment_timer_thres; /* RRC inactivity timer: on timeout, should release RRC connection for inactivity on all E-RABs */ uint32_t ue_rrc_inactivity_timer; - uint32_t ue_rrc_inactivity_timer_thres; + // uint32_t ue_rrc_inactivity_timer_thres; uint8_t e_rab_release_command_flag; int8_t reestablishment_xid; } eNB_RRC_UE_t; diff --git a/openair2/RRC/LTE/rrc_eNB.c b/openair2/RRC/LTE/rrc_eNB.c index 3f3248aaca..5ebc462468 100644 --- a/openair2/RRC/LTE/rrc_eNB.c +++ b/openair2/RRC/LTE/rrc_eNB.c @@ -835,7 +835,8 @@ rrc_eNB_free_UE( return; } - if((ue_context_pP->ue_context.ue_rrc_inactivity_timer >= ue_context_pP->ue_context.ue_rrc_inactivity_timer_thres) && + // if((ue_context_pP->ue_context.ue_rrc_inactivity_timer >= ue_context_pP->ue_context.ue_rrc_inactivity_timer_thres) && + if((ue_context_pP->ue_context.ue_rrc_inactivity_timer >= RC.rrc[enb_mod_idP]->configuration.rrc_inactivity_timer_thres) && (mac_eNB_get_rrc_status(enb_mod_idP, rnti) >= RRC_CONNECTED)) { LOG_I(RRC, "[eNB %d] S1AP_UE_CONTEXT_RELEASE_REQ sent for RNTI %x, cause 20, user inactivity\n", enb_mod_idP, @@ -1008,7 +1009,7 @@ rrc_eNB_process_RRCConnectionSetupComplete( ue_context_pP->ue_context.Srb1.Active = 1; ue_context_pP->ue_context.Status = RRC_CONNECTED; ue_context_pP->ue_context.ue_rrc_inactivity_timer = 1; // set rrc inactivity when UE goes into RRC_CONNECTED - ue_context_pP->ue_context.ue_rrc_inactivity_timer_thres = 10000; // The value should come from config file + // ue_context_pP->ue_context.ue_rrc_inactivity_timer_thres = 10000; // The value should come from config file T(T_ENB_RRC_CONNECTION_SETUP_COMPLETE, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame), T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti)); @@ -1314,7 +1315,7 @@ rrc_eNB_process_RRCConnectionReestablishmentComplete( uint8_t next_xid = rrc_eNB_get_next_transaction_identifier(ctxt_pP->module_id); ue_context_pP->ue_context.Status = RRC_CONNECTED; ue_context_pP->ue_context.ue_rrc_inactivity_timer = 1; // set rrc inactivity when UE goes into RRC_CONNECTED - ue_context_pP->ue_context.ue_rrc_inactivity_timer_thres = 10000; // The value should come from config file + // ue_context_pP->ue_context.ue_rrc_inactivity_timer_thres = 10000; // The value should come from config file ue_context_pP->ue_context.reestablishment_xid = next_xid; SRB_configList2 = &ue_context_pP->ue_context.SRB_configList2[xid]; @@ -7379,9 +7380,10 @@ rrc_rx_tx( pthread_mutex_unlock(&rrc_release_freelist); - if (ue_context_p->ue_context.ue_rrc_inactivity_timer > 0) { - // ue_context_p->ue_context.ue_rrc_inactivity_timer++; // (un)comment this line to (de)activate the RRC inactivity timer - if (ue_context_p->ue_context.ue_rrc_inactivity_timer >= ue_context_p->ue_context.ue_rrc_inactivity_timer_thres) { + if ((ue_context_p->ue_context.ue_rrc_inactivity_timer > 0) && (RC.rrc[enb_mod_idP]->configuration.rrc_inactivity_timer_thres > 0)) { + ue_context_p->ue_context.ue_rrc_inactivity_timer++; // (un)comment this line to (de)activate the RRC inactivity timer + //if (ue_context_p->ue_context.ue_rrc_inactivity_timer >= ue_context_p->ue_context.ue_rrc_inactivity_timer_thres) { + if (ue_context_p->ue_context.ue_rrc_inactivity_timer >= RC.rrc[ctxt_pP->module_id]->configuration.rrc_inactivity_timer_thres){ LOG_I(RRC, "Removing UE %x instance because of rrc_inactivity_timer timeout\n", ue_context_p->ue_context.rnti); ue_to_be_removed = ue_context_p; @@ -7422,7 +7424,8 @@ rrc_rx_tx( if (ue_to_be_removed) { if ((ue_to_be_removed->ue_context.ul_failure_timer >= 20000) || - (ue_to_be_removed->ue_context.ue_rrc_inactivity_timer >= ue_to_be_removed->ue_context.ue_rrc_inactivity_timer_thres)) { + (ue_to_be_removed->ue_context.ue_rrc_inactivity_timer >= RC.rrc[ctxt_pP->module_id]->configuration.rrc_inactivity_timer_thres)) { + //(ue_to_be_removed->ue_context.ue_rrc_inactivity_timer >= ue_to_be_removed->ue_context.ue_rrc_inactivity_timer_thres)) { ue_to_be_removed->ue_context.ue_release_timer_s1 = 1; ue_to_be_removed->ue_context.ue_release_timer_thres_s1 = 100; ue_to_be_removed->ue_context.ue_release_timer = 0; @@ -7435,7 +7438,8 @@ rrc_rx_tx( ue_to_be_removed->ue_context.ul_failure_timer = 0; } - if (ue_to_be_removed->ue_context.ue_rrc_inactivity_timer >= ue_to_be_removed->ue_context.ue_rrc_inactivity_timer_thres) { + //if (ue_to_be_removed->ue_context.ue_rrc_inactivity_timer >= ue_to_be_removed->ue_context.ue_rrc_inactivity_timer_thres) { + if (ue_to_be_removed->ue_context.ue_rrc_inactivity_timer >= RC.rrc[ctxt_pP->module_id]->configuration.rrc_inactivity_timer_thres) { ue_to_be_removed->ue_context.ue_rrc_inactivity_timer = 0; //reset timer after S1 command UE context release request is sent } } From 1094835db149179914464d647f1ae6c16a965c4a Mon Sep 17 00:00:00 2001 From: OAI-admin Date: Tue, 20 Nov 2018 15:07:43 +0100 Subject: [PATCH 164/233] RRC timer fixed and tested --- openair2/ENB_APP/enb_config.c | 2 +- openair2/RRC/LTE/rrc_defs.h | 1 - openair2/RRC/LTE/rrc_eNB.c | 17 +++++++---------- 3 files changed, 8 insertions(+), 12 deletions(-) diff --git a/openair2/ENB_APP/enb_config.c b/openair2/ENB_APP/enb_config.c index cde9364f2b..ebd194b80e 100644 --- a/openair2/ENB_APP/enb_config.c +++ b/openair2/ENB_APP/enb_config.c @@ -579,7 +579,7 @@ int RCconfig_RRC(MessageDef *msg_p, uint32_t i, eNB_RRC_INST *rrc) { for (int I = 0; I < sizeof(PLMNParams) / sizeof(paramdef_t); ++I) PLMNParams[I].chkPptr = &(config_check_PLMNParams[I]); - RRC_CONFIGURATION_REQ (msg_p).rrc_inactivity_timer_thres = 10000; + RRC_CONFIGURATION_REQ (msg_p).rrc_inactivity_timer_thres = 0; // set to 0 to deactivate RRC_CONFIGURATION_REQ (msg_p).cell_identity = enb_id; RRC_CONFIGURATION_REQ (msg_p).tac = *ENBParamList.paramarray[i][ENB_TRACKING_AREA_CODE_IDX].uptr; diff --git a/openair2/RRC/LTE/rrc_defs.h b/openair2/RRC/LTE/rrc_defs.h index 9a84b8e8e7..9d42883086 100644 --- a/openair2/RRC/LTE/rrc_defs.h +++ b/openair2/RRC/LTE/rrc_defs.h @@ -601,7 +601,6 @@ typedef struct eNB_RRC_UE_s { uint32_t ue_reestablishment_timer_thres; /* RRC inactivity timer: on timeout, should release RRC connection for inactivity on all E-RABs */ uint32_t ue_rrc_inactivity_timer; - // uint32_t ue_rrc_inactivity_timer_thres; uint8_t e_rab_release_command_flag; int8_t reestablishment_xid; } eNB_RRC_UE_t; diff --git a/openair2/RRC/LTE/rrc_eNB.c b/openair2/RRC/LTE/rrc_eNB.c index 5ebc462468..01d4e511de 100644 --- a/openair2/RRC/LTE/rrc_eNB.c +++ b/openair2/RRC/LTE/rrc_eNB.c @@ -835,9 +835,9 @@ rrc_eNB_free_UE( return; } - // if((ue_context_pP->ue_context.ue_rrc_inactivity_timer >= ue_context_pP->ue_context.ue_rrc_inactivity_timer_thres) && if((ue_context_pP->ue_context.ue_rrc_inactivity_timer >= RC.rrc[enb_mod_idP]->configuration.rrc_inactivity_timer_thres) && - (mac_eNB_get_rrc_status(enb_mod_idP, rnti) >= RRC_CONNECTED)) { + (mac_eNB_get_rrc_status(enb_mod_idP, rnti) >= RRC_CONNECTED) && + (RC.rrc[enb_mod_idP]->configuration.rrc_inactivity_timer_thres > 0)) { LOG_I(RRC, "[eNB %d] S1AP_UE_CONTEXT_RELEASE_REQ sent for RNTI %x, cause 20, user inactivity\n", enb_mod_idP, rnti); @@ -1009,7 +1009,6 @@ rrc_eNB_process_RRCConnectionSetupComplete( ue_context_pP->ue_context.Srb1.Active = 1; ue_context_pP->ue_context.Status = RRC_CONNECTED; ue_context_pP->ue_context.ue_rrc_inactivity_timer = 1; // set rrc inactivity when UE goes into RRC_CONNECTED - // ue_context_pP->ue_context.ue_rrc_inactivity_timer_thres = 10000; // The value should come from config file T(T_ENB_RRC_CONNECTION_SETUP_COMPLETE, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->frame), T_INT(ctxt_pP->subframe), T_INT(ctxt_pP->rnti)); @@ -1315,7 +1314,6 @@ rrc_eNB_process_RRCConnectionReestablishmentComplete( uint8_t next_xid = rrc_eNB_get_next_transaction_identifier(ctxt_pP->module_id); ue_context_pP->ue_context.Status = RRC_CONNECTED; ue_context_pP->ue_context.ue_rrc_inactivity_timer = 1; // set rrc inactivity when UE goes into RRC_CONNECTED - // ue_context_pP->ue_context.ue_rrc_inactivity_timer_thres = 10000; // The value should come from config file ue_context_pP->ue_context.reestablishment_xid = next_xid; SRB_configList2 = &ue_context_pP->ue_context.SRB_configList2[xid]; @@ -7380,9 +7378,8 @@ rrc_rx_tx( pthread_mutex_unlock(&rrc_release_freelist); - if ((ue_context_p->ue_context.ue_rrc_inactivity_timer > 0) && (RC.rrc[enb_mod_idP]->configuration.rrc_inactivity_timer_thres > 0)) { + if ((ue_context_p->ue_context.ue_rrc_inactivity_timer > 0) && (RC.rrc[ctxt_pP->module_id]->configuration.rrc_inactivity_timer_thres > 0)) { ue_context_p->ue_context.ue_rrc_inactivity_timer++; // (un)comment this line to (de)activate the RRC inactivity timer - //if (ue_context_p->ue_context.ue_rrc_inactivity_timer >= ue_context_p->ue_context.ue_rrc_inactivity_timer_thres) { if (ue_context_p->ue_context.ue_rrc_inactivity_timer >= RC.rrc[ctxt_pP->module_id]->configuration.rrc_inactivity_timer_thres){ LOG_I(RRC, "Removing UE %x instance because of rrc_inactivity_timer timeout\n", ue_context_p->ue_context.rnti); @@ -7424,8 +7421,8 @@ rrc_rx_tx( if (ue_to_be_removed) { if ((ue_to_be_removed->ue_context.ul_failure_timer >= 20000) || - (ue_to_be_removed->ue_context.ue_rrc_inactivity_timer >= RC.rrc[ctxt_pP->module_id]->configuration.rrc_inactivity_timer_thres)) { - //(ue_to_be_removed->ue_context.ue_rrc_inactivity_timer >= ue_to_be_removed->ue_context.ue_rrc_inactivity_timer_thres)) { + ((ue_to_be_removed->ue_context.ue_rrc_inactivity_timer >= RC.rrc[ctxt_pP->module_id]->configuration.rrc_inactivity_timer_thres) && + (RC.rrc[ctxt_pP->module_id]->configuration.rrc_inactivity_timer_thres > 0))) { ue_to_be_removed->ue_context.ue_release_timer_s1 = 1; ue_to_be_removed->ue_context.ue_release_timer_thres_s1 = 100; ue_to_be_removed->ue_context.ue_release_timer = 0; @@ -7438,8 +7435,8 @@ rrc_rx_tx( ue_to_be_removed->ue_context.ul_failure_timer = 0; } - //if (ue_to_be_removed->ue_context.ue_rrc_inactivity_timer >= ue_to_be_removed->ue_context.ue_rrc_inactivity_timer_thres) { - if (ue_to_be_removed->ue_context.ue_rrc_inactivity_timer >= RC.rrc[ctxt_pP->module_id]->configuration.rrc_inactivity_timer_thres) { + if ((ue_to_be_removed->ue_context.ue_rrc_inactivity_timer >= RC.rrc[ctxt_pP->module_id]->configuration.rrc_inactivity_timer_thres) && + (RC.rrc[ctxt_pP->module_id]->configuration.rrc_inactivity_timer_thres > 0)) { ue_to_be_removed->ue_context.ue_rrc_inactivity_timer = 0; //reset timer after S1 command UE context release request is sent } } From d082b50896c3a1eb97d15cb30536d47421d18b3d Mon Sep 17 00:00:00 2001 From: Louis Adrien Dufrene Date: Tue, 20 Nov 2018 16:19:37 +0100 Subject: [PATCH 165/233] add MACRO for timer threshold --- openair2/ENB_APP/enb_config.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/openair2/ENB_APP/enb_config.c b/openair2/ENB_APP/enb_config.c index ebd194b80e..45f369365b 100644 --- a/openair2/ENB_APP/enb_config.c +++ b/openair2/ENB_APP/enb_config.c @@ -60,6 +60,8 @@ #include "RRC_config_tools.h" #include "enb_paramdef.h" +#define RRC_INACTIVITY_THRESH 0 + extern uint16_t sf_ahead; extern void set_parallel_conf(char *parallel_conf); extern void set_worker_conf(char *worker_conf); @@ -579,7 +581,7 @@ int RCconfig_RRC(MessageDef *msg_p, uint32_t i, eNB_RRC_INST *rrc) { for (int I = 0; I < sizeof(PLMNParams) / sizeof(paramdef_t); ++I) PLMNParams[I].chkPptr = &(config_check_PLMNParams[I]); - RRC_CONFIGURATION_REQ (msg_p).rrc_inactivity_timer_thres = 0; // set to 0 to deactivate + RRC_CONFIGURATION_REQ (msg_p).rrc_inactivity_timer_thres = RRC_INACTIVITY_THRESH; // set to 0 to deactivate RRC_CONFIGURATION_REQ (msg_p).cell_identity = enb_id; RRC_CONFIGURATION_REQ (msg_p).tac = *ENBParamList.paramarray[i][ENB_TRACKING_AREA_CODE_IDX].uptr; From cf07c4d394a4c1bfc17dac27d3fbc539b58cd618 Mon Sep 17 00:00:00 2001 From: Louis Adrien Dufrene Date: Tue, 20 Nov 2018 16:39:05 +0100 Subject: [PATCH 166/233] astyle applied --- openair2/COMMON/rrc_messages_types.h | 130 +++++++++++++-------------- openair2/ENB_APP/enb_config.c | 3 +- openair2/RRC/LTE/rrc_eNB.c | 9 +- 3 files changed, 71 insertions(+), 71 deletions(-) diff --git a/openair2/COMMON/rrc_messages_types.h b/openair2/COMMON/rrc_messages_types.h index d7f6a67d78..c1b554c216 100644 --- a/openair2/COMMON/rrc_messages_types.h +++ b/openair2/COMMON/rrc_messages_types.h @@ -33,9 +33,9 @@ #include "rrc_types.h" #include "s1ap_messages_types.h" #ifdef CMAKER -#include "LTE_SystemInformationBlockType2.h" + #include "LTE_SystemInformationBlockType2.h" #else -#include "RRC/LTE/MESSAGES/LTE_SystemInformationBlockType2.h" + #include "RRC/LTE/MESSAGES/LTE_SystemInformationBlockType2.h" #endif #include "LTE_SL-OffsetIndicator-r12.h" #include "LTE_SubframeBitmapSL-r12.h" @@ -47,19 +47,19 @@ //-------------------------------------------------------------------------------------------// // Messages for RRC logging #if defined(DISABLE_ITTI_XER_PRINT) -#include "LTE_BCCH-DL-SCH-Message.h" -#include "LTE_DL-CCCH-Message.h" -#include "LTE_DL-DCCH-Message.h" -#include "LTE_UE-EUTRA-Capability.h" -#include "LTE_UL-CCCH-Message.h" -#include "LTE_UL-DCCH-Message.h" + #include "LTE_BCCH-DL-SCH-Message.h" + #include "LTE_DL-CCCH-Message.h" + #include "LTE_DL-DCCH-Message.h" + #include "LTE_UE-EUTRA-Capability.h" + #include "LTE_UL-CCCH-Message.h" + #include "LTE_UL-DCCH-Message.h" -typedef BCCH_DL_SCH_Message_t RrcDlBcchMessage; -typedef DL_CCCH_Message_t RrcDlCcchMessage; -typedef DL_DCCH_Message_t RrcDlDcchMessage; -typedef UE_EUTRA_Capability_t RrcUeEutraCapability; -typedef UL_CCCH_Message_t RrcUlCcchMessage; -typedef UL_DCCH_Message_t RrcUlDcchMessage; + typedef BCCH_DL_SCH_Message_t RrcDlBcchMessage; + typedef DL_CCCH_Message_t RrcDlCcchMessage; + typedef DL_DCCH_Message_t RrcDlDcchMessage; + typedef UE_EUTRA_Capability_t RrcUeEutraCapability; + typedef UL_CCCH_Message_t RrcUlCcchMessage; + typedef UL_DCCH_Message_t RrcUlDcchMessage; #endif //-------------------------------------------------------------------------------------------// @@ -103,7 +103,7 @@ typedef struct RrcConfigurationReq_s { uint8_t num_plmn; uint32_t rrc_inactivity_timer_thres; // for testing, maybe change later - + paging_drx_t default_drx; int16_t nb_cc; lte_frame_type_t frame_type[MAX_NUM_CCs]; @@ -125,9 +125,9 @@ typedef struct RrcConfigurationReq_s { long pucch_delta_shift[MAX_NUM_CCs]; long pucch_nRB_CQI[MAX_NUM_CCs]; long pucch_nCS_AN[MAX_NUM_CCs]; -//#if (LTE_RRC_VERSION < MAKE_VERSION(10, 0, 0)) + //#if (LTE_RRC_VERSION < MAKE_VERSION(10, 0, 0)) long pucch_n1_AN[MAX_NUM_CCs]; -//#endif + //#endif long pdsch_referenceSignalPower[MAX_NUM_CCs]; long pdsch_p_b[MAX_NUM_CCs]; long pusch_n_SB[MAX_NUM_CCs]; @@ -189,7 +189,7 @@ typedef struct RrcConfigurationReq_s { LTE_SL_OffsetIndicator_r12_PR rxPool_ResourceConfig_offsetIndicator_present[MAX_NUM_CCs]; long rxPool_ResourceConfig_offsetIndicator_choice[MAX_NUM_CCs]; LTE_SubframeBitmapSL_r12_PR rxPool_ResourceConfig_subframeBitmap_present[MAX_NUM_CCs]; - char* rxPool_ResourceConfig_subframeBitmap_choice_bs_buf[MAX_NUM_CCs]; + char *rxPool_ResourceConfig_subframeBitmap_choice_bs_buf[MAX_NUM_CCs]; long rxPool_ResourceConfig_subframeBitmap_choice_bs_size[MAX_NUM_CCs]; long rxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused[MAX_NUM_CCs]; @@ -205,7 +205,7 @@ typedef struct RrcConfigurationReq_s { LTE_SL_OffsetIndicator_r12_PR discRxPool_ResourceConfig_offsetIndicator_present[MAX_NUM_CCs]; long discRxPool_ResourceConfig_offsetIndicator_choice[MAX_NUM_CCs]; LTE_SubframeBitmapSL_r12_PR discRxPool_ResourceConfig_subframeBitmap_present[MAX_NUM_CCs]; - char* discRxPool_ResourceConfig_subframeBitmap_choice_bs_buf[MAX_NUM_CCs]; + char *discRxPool_ResourceConfig_subframeBitmap_choice_bs_buf[MAX_NUM_CCs]; long discRxPool_ResourceConfig_subframeBitmap_choice_bs_size[MAX_NUM_CCs]; long discRxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused[MAX_NUM_CCs]; //for discRxPoolPS @@ -219,7 +219,7 @@ typedef struct RrcConfigurationReq_s { LTE_SL_OffsetIndicator_r12_PR discRxPoolPS_ResourceConfig_offsetIndicator_present[MAX_NUM_CCs]; long discRxPoolPS_ResourceConfig_offsetIndicator_choice[MAX_NUM_CCs]; LTE_SubframeBitmapSL_r12_PR discRxPoolPS_ResourceConfig_subframeBitmap_present[MAX_NUM_CCs]; - char* discRxPoolPS_ResourceConfig_subframeBitmap_choice_bs_buf[MAX_NUM_CCs]; + char *discRxPoolPS_ResourceConfig_subframeBitmap_choice_bs_buf[MAX_NUM_CCs]; long discRxPoolPS_ResourceConfig_subframeBitmap_choice_bs_size[MAX_NUM_CCs]; long discRxPoolPS_ResourceConfig_subframeBitmap_choice_bs_bits_unused[MAX_NUM_CCs]; } RrcConfigurationReq; @@ -231,69 +231,69 @@ typedef struct NbIoTRrcConfigurationReq_s { uint16_t tac; - uint16_t mcc; - uint16_t mnc; - uint8_t mnc_digit_length; - lte_frame_type_t frame_type; + uint16_t mcc; + uint16_t mnc; + uint8_t mnc_digit_length; + lte_frame_type_t frame_type; uint8_t tdd_config; uint8_t tdd_config_s; lte_prefix_type_t prefix_type; - lte_prefix_type_t prefix_type_UL; + lte_prefix_type_t prefix_type_UL; int16_t eutra_band; uint32_t downlink_frequency; int32_t uplink_frequency_offset; int16_t Nid_cell;// for testing, change later int16_t N_RB_DL;// for testing, change later //RACH - long rach_raResponseWindowSize_NB; - long rach_macContentionResolutionTimer_NB; - long rach_powerRampingStep_NB; - long rach_preambleInitialReceivedTargetPower_NB; - long rach_preambleTransMax_CE_NB; + long rach_raResponseWindowSize_NB; + long rach_macContentionResolutionTimer_NB; + long rach_powerRampingStep_NB; + long rach_preambleInitialReceivedTargetPower_NB; + long rach_preambleTransMax_CE_NB; //BCCH - long bcch_modificationPeriodCoeff_NB; + long bcch_modificationPeriodCoeff_NB; //PCCH - long pcch_defaultPagingCycle_NB; - long pcch_nB_NB; - long pcch_npdcch_NumRepetitionPaging_NB; + long pcch_defaultPagingCycle_NB; + long pcch_nB_NB; + long pcch_npdcch_NumRepetitionPaging_NB; //NPRACH - long nprach_CP_Length; - long nprach_rsrp_range; - long nprach_Periodicity[MAX_NUM_NBIOT_CELEVELS]; - long nprach_StartTime[MAX_NUM_NBIOT_CELEVELS]; - long nprach_SubcarrierOffset[MAX_NUM_NBIOT_CELEVELS]; - long nprach_NumSubcarriers[MAX_NUM_NBIOT_CELEVELS]; - long numRepetitionsPerPreambleAttempt_NB[MAX_NUM_NBIOT_CELEVELS]; - long nprach_SubcarrierMSG3_RangeStart; - long maxNumPreambleAttemptCE_NB; - long npdcch_NumRepetitions_RA[MAX_NUM_NBIOT_CELEVELS]; - long npdcch_StartSF_CSS_RA[MAX_NUM_NBIOT_CELEVELS]; - long npdcch_Offset_RA[MAX_NUM_NBIOT_CELEVELS]; + long nprach_CP_Length; + long nprach_rsrp_range; + long nprach_Periodicity[MAX_NUM_NBIOT_CELEVELS]; + long nprach_StartTime[MAX_NUM_NBIOT_CELEVELS]; + long nprach_SubcarrierOffset[MAX_NUM_NBIOT_CELEVELS]; + long nprach_NumSubcarriers[MAX_NUM_NBIOT_CELEVELS]; + long numRepetitionsPerPreambleAttempt_NB[MAX_NUM_NBIOT_CELEVELS]; + long nprach_SubcarrierMSG3_RangeStart; + long maxNumPreambleAttemptCE_NB; + long npdcch_NumRepetitions_RA[MAX_NUM_NBIOT_CELEVELS]; + long npdcch_StartSF_CSS_RA[MAX_NUM_NBIOT_CELEVELS]; + long npdcch_Offset_RA[MAX_NUM_NBIOT_CELEVELS]; //NPDSCH - long npdsch_nrs_Power; + long npdsch_nrs_Power; //NPUSCH - long npusch_ack_nack_numRepetitions_NB; - long npusch_srs_SubframeConfig_NB; - long npusch_threeTone_CyclicShift_r13; - long npusch_sixTone_CyclicShift_r13; - BOOLEAN_t npusch_groupHoppingEnabled; - long npusch_groupAssignmentNPUSCH_r13; + long npusch_ack_nack_numRepetitions_NB; + long npusch_srs_SubframeConfig_NB; + long npusch_threeTone_CyclicShift_r13; + long npusch_sixTone_CyclicShift_r13; + BOOLEAN_t npusch_groupHoppingEnabled; + long npusch_groupAssignmentNPUSCH_r13; //DL_GapConfig - long dl_GapThreshold_NB; - long dl_GapPeriodicity_NB; - long dl_GapDurationCoeff_NB; + long dl_GapThreshold_NB; + long dl_GapPeriodicity_NB; + long dl_GapDurationCoeff_NB; //Uplink power control Common - long npusch_p0_NominalNPUSCH; - long npusch_alpha; - long deltaPreambleMsg3; + long npusch_p0_NominalNPUSCH; + long npusch_alpha; + long deltaPreambleMsg3; //UE timers and constants - long ue_TimersAndConstants_t300_NB; - long ue_TimersAndConstants_t301_NB; - long ue_TimersAndConstants_t310_NB; - long ue_TimersAndConstants_t311_NB; - long ue_TimersAndConstants_n310_NB; - long ue_TimersAndConstants_n311_NB; + long ue_TimersAndConstants_t300_NB; + long ue_TimersAndConstants_t301_NB; + long ue_TimersAndConstants_t310_NB; + long ue_TimersAndConstants_t311_NB; + long ue_TimersAndConstants_n310_NB; + long ue_TimersAndConstants_n311_NB; } NbIoTRrcConfigurationReq; diff --git a/openair2/ENB_APP/enb_config.c b/openair2/ENB_APP/enb_config.c index 45f369365b..8ad536c5f9 100644 --- a/openair2/ENB_APP/enb_config.c +++ b/openair2/ENB_APP/enb_config.c @@ -582,7 +582,6 @@ int RCconfig_RRC(MessageDef *msg_p, uint32_t i, eNB_RRC_INST *rrc) { PLMNParams[I].chkPptr = &(config_check_PLMNParams[I]); RRC_CONFIGURATION_REQ (msg_p).rrc_inactivity_timer_thres = RRC_INACTIVITY_THRESH; // set to 0 to deactivate - RRC_CONFIGURATION_REQ (msg_p).cell_identity = enb_id; RRC_CONFIGURATION_REQ (msg_p).tac = *ENBParamList.paramarray[i][ENB_TRACKING_AREA_CODE_IDX].uptr; AssertFatal(!ENBParamList.paramarray[i][ENB_MOBILE_COUNTRY_CODE_IDX_OLD].strptr @@ -2312,7 +2311,7 @@ int RCconfig_S1( default: { LOG_E(S1AP, "Default I-DRX value in conf file is invalid (%i). Should be 32, 64, 128 or 256. \ - Default DRX set to 32 in MME configuration\n", + Default DRX set to 32 in MME configuration\n", pcch_defaultPagingCycle); S1AP_REGISTER_ENB_REQ(msg_p).default_drx = 0; } diff --git a/openair2/RRC/LTE/rrc_eNB.c b/openair2/RRC/LTE/rrc_eNB.c index 01d4e511de..eab4ce4ed3 100644 --- a/openair2/RRC/LTE/rrc_eNB.c +++ b/openair2/RRC/LTE/rrc_eNB.c @@ -7380,7 +7380,8 @@ rrc_rx_tx( if ((ue_context_p->ue_context.ue_rrc_inactivity_timer > 0) && (RC.rrc[ctxt_pP->module_id]->configuration.rrc_inactivity_timer_thres > 0)) { ue_context_p->ue_context.ue_rrc_inactivity_timer++; // (un)comment this line to (de)activate the RRC inactivity timer - if (ue_context_p->ue_context.ue_rrc_inactivity_timer >= RC.rrc[ctxt_pP->module_id]->configuration.rrc_inactivity_timer_thres){ + + if (ue_context_p->ue_context.ue_rrc_inactivity_timer >= RC.rrc[ctxt_pP->module_id]->configuration.rrc_inactivity_timer_thres) { LOG_I(RRC, "Removing UE %x instance because of rrc_inactivity_timer timeout\n", ue_context_p->ue_context.rnti); ue_to_be_removed = ue_context_p; @@ -7421,8 +7422,8 @@ rrc_rx_tx( if (ue_to_be_removed) { if ((ue_to_be_removed->ue_context.ul_failure_timer >= 20000) || - ((ue_to_be_removed->ue_context.ue_rrc_inactivity_timer >= RC.rrc[ctxt_pP->module_id]->configuration.rrc_inactivity_timer_thres) && - (RC.rrc[ctxt_pP->module_id]->configuration.rrc_inactivity_timer_thres > 0))) { + ((ue_to_be_removed->ue_context.ue_rrc_inactivity_timer >= RC.rrc[ctxt_pP->module_id]->configuration.rrc_inactivity_timer_thres) && + (RC.rrc[ctxt_pP->module_id]->configuration.rrc_inactivity_timer_thres > 0))) { ue_to_be_removed->ue_context.ue_release_timer_s1 = 1; ue_to_be_removed->ue_context.ue_release_timer_thres_s1 = 100; ue_to_be_removed->ue_context.ue_release_timer = 0; @@ -7436,7 +7437,7 @@ rrc_rx_tx( } if ((ue_to_be_removed->ue_context.ue_rrc_inactivity_timer >= RC.rrc[ctxt_pP->module_id]->configuration.rrc_inactivity_timer_thres) && - (RC.rrc[ctxt_pP->module_id]->configuration.rrc_inactivity_timer_thres > 0)) { + (RC.rrc[ctxt_pP->module_id]->configuration.rrc_inactivity_timer_thres > 0)) { ue_to_be_removed->ue_context.ue_rrc_inactivity_timer = 0; //reset timer after S1 command UE context release request is sent } } From 0fb80c0cff7fc30fea0169997c0bffffb789fbf0 Mon Sep 17 00:00:00 2001 From: "yoshio.inoue" Date: Wed, 21 Nov 2018 11:44:18 +0900 Subject: [PATCH 167/233] Fixed problem that u-plane does not transferr with noS1 in L2 nFAPI Simulator --- openair2/NETWORK_DRIVER/MESH/local.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openair2/NETWORK_DRIVER/MESH/local.h b/openair2/NETWORK_DRIVER/MESH/local.h index 82dfc0ac88..f3f30f9224 100755 --- a/openair2/NETWORK_DRIVER/MESH/local.h +++ b/openair2/NETWORK_DRIVER/MESH/local.h @@ -162,7 +162,7 @@ typedef struct pdcp_data_req_header_s { sdu_size_t data_size; signed int inst; ip_traffic_type_t traffic_type; -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) uint32_t sourceL2Id; uint32_t destinationL2Id; #endif @@ -173,7 +173,7 @@ typedef struct pdcp_data_ind_header_s { sdu_size_t data_size; signed int inst; ip_traffic_type_t dummy_traffic_type; -#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0)) +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) uint32_t sourceL2Id; uint32_t destinationL2Id; #endif From e77d910398f55a9a8977d56eee28a9d025ce3071 Mon Sep 17 00:00:00 2001 From: Louis Adrien Dufrene Date: Wed, 21 Nov 2018 13:26:12 +0100 Subject: [PATCH 168/233] Macro removed in enb_config.c, but rrc timer thresh still set to 0 (deactivated) --- openair2/ENB_APP/enb_config.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openair2/ENB_APP/enb_config.c b/openair2/ENB_APP/enb_config.c index 8ad536c5f9..c0bbf42808 100644 --- a/openair2/ENB_APP/enb_config.c +++ b/openair2/ENB_APP/enb_config.c @@ -60,7 +60,7 @@ #include "RRC_config_tools.h" #include "enb_paramdef.h" -#define RRC_INACTIVITY_THRESH 0 +// #define RRC_INACTIVITY_THRESH 0 extern uint16_t sf_ahead; extern void set_parallel_conf(char *parallel_conf); @@ -581,7 +581,7 @@ int RCconfig_RRC(MessageDef *msg_p, uint32_t i, eNB_RRC_INST *rrc) { for (int I = 0; I < sizeof(PLMNParams) / sizeof(paramdef_t); ++I) PLMNParams[I].chkPptr = &(config_check_PLMNParams[I]); - RRC_CONFIGURATION_REQ (msg_p).rrc_inactivity_timer_thres = RRC_INACTIVITY_THRESH; // set to 0 to deactivate + RRC_CONFIGURATION_REQ (msg_p).rrc_inactivity_timer_thres = 0; //RRC_INACTIVITY_THRESH; // set to 0 to deactivate RRC_CONFIGURATION_REQ (msg_p).cell_identity = enb_id; RRC_CONFIGURATION_REQ (msg_p).tac = *ENBParamList.paramarray[i][ENB_TRACKING_AREA_CODE_IDX].uptr; AssertFatal(!ENBParamList.paramarray[i][ENB_MOBILE_COUNTRY_CODE_IDX_OLD].strptr From ed61d774f631357327c049d3a7b99fb1c5f5e469 Mon Sep 17 00:00:00 2001 From: Louis Adrien Dufrene Date: Wed, 21 Nov 2018 17:03:52 +0100 Subject: [PATCH 169/233] add test on ue_context --- openair2/ENB_APP/enb_config.c | 4 +-- openair2/LAYER2/MAC/eNB_scheduler_dlsch.c | 9 +++++- openair2/LAYER2/MAC/eNB_scheduler_ulsch.c | 11 +++++-- openair2/RRC/LTE/rrc_eNB_S1AP.c | 37 +++++++++++++++++------ 4 files changed, 46 insertions(+), 15 deletions(-) diff --git a/openair2/ENB_APP/enb_config.c b/openair2/ENB_APP/enb_config.c index c0bbf42808..8ad536c5f9 100644 --- a/openair2/ENB_APP/enb_config.c +++ b/openair2/ENB_APP/enb_config.c @@ -60,7 +60,7 @@ #include "RRC_config_tools.h" #include "enb_paramdef.h" -// #define RRC_INACTIVITY_THRESH 0 +#define RRC_INACTIVITY_THRESH 0 extern uint16_t sf_ahead; extern void set_parallel_conf(char *parallel_conf); @@ -581,7 +581,7 @@ int RCconfig_RRC(MessageDef *msg_p, uint32_t i, eNB_RRC_INST *rrc) { for (int I = 0; I < sizeof(PLMNParams) / sizeof(paramdef_t); ++I) PLMNParams[I].chkPptr = &(config_check_PLMNParams[I]); - RRC_CONFIGURATION_REQ (msg_p).rrc_inactivity_timer_thres = 0; //RRC_INACTIVITY_THRESH; // set to 0 to deactivate + RRC_CONFIGURATION_REQ (msg_p).rrc_inactivity_timer_thres = RRC_INACTIVITY_THRESH; // set to 0 to deactivate RRC_CONFIGURATION_REQ (msg_p).cell_identity = enb_id; RRC_CONFIGURATION_REQ (msg_p).tac = *ENBParamList.paramarray[i][ENB_TRACKING_AREA_CODE_IDX].uptr; AssertFatal(!ENBParamList.paramarray[i][ENB_MOBILE_COUNTRY_CODE_IDX_OLD].strptr diff --git a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c index 4073c54846..9a26460fa3 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c @@ -1084,7 +1084,14 @@ schedule_ue_spec(module_id_t module_idP, int slice_idxP, UE_list->UE_sched_ctrl[UE_id].uplane_inactivity_timer = 0; // reset RRC inactivity timer after uplane activity ue_contextP = rrc_eNB_get_ue_context(RC.rrc[module_idP], rnti); - ue_contextP->ue_context.ue_rrc_inactivity_timer = 1; + if (ue_contextP != NULL) { + ue_contextP->ue_context.ue_rrc_inactivity_timer = 1; + } else { + LOG_E(MAC, "[eNB %d] CC_id %d Couldn't find the context associated to UE (RNTI %d) and reset RRC inactivity timer\n", + module_idP, + CC_id, + rnti); + } } // end if (rlc_status.bytes_in_buffer > 0) } else { // no TBS left break; // break for (lcid = NB_RB_MAX - 1; lcid >= DTCH; lcid--) diff --git a/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c b/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c index e67ddb6aae..9a6340a72b 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c @@ -716,8 +716,15 @@ rx_sdu(const module_id_t enb_mod_idP, //clear uplane_inactivity_timer UE_list->UE_sched_ctrl[UE_id].uplane_inactivity_timer = 0; // reset RRC inactivity timer after uplane activity - ue_contextP = rrc_eNB_get_ue_context(RC.rrc[enb_mod_idP], rntiP); - ue_contextP->ue_context.ue_rrc_inactivity_timer = 1; + ue_contextP = rrc_eNB_get_ue_context(RC.rrc[enb_mod_idP], current_rnti); + if (ue_contextP != NULL) { + ue_contextP->ue_context.ue_rrc_inactivity_timer = 1; + } else { + LOG_E(MAC, "[eNB %d] CC_id %d Couldn't find the context associated to UE (RNTI %d) and reset RRC inactivity timer\n", + enb_mod_idP, + CC_idP, + current_rnti); + } } else { /* rx_length[i] */ UE_list->eNB_UE_stats[CC_idP][UE_id].num_errors_rx += 1; LOG_E(MAC, "[eNB %d] CC_id %d Frame %d : Max size of transport block reached LCID %d from UE %d ", diff --git a/openair2/RRC/LTE/rrc_eNB_S1AP.c b/openair2/RRC/LTE/rrc_eNB_S1AP.c index 2c2ab0ec49..56219d9ebd 100644 --- a/openair2/RRC/LTE/rrc_eNB_S1AP.c +++ b/openair2/RRC/LTE/rrc_eNB_S1AP.c @@ -216,6 +216,8 @@ rrc_eNB_S1AP_get_ue_ids( result2->ue_initial_id, result->eNB_ue_s1ap_id, result2->eNB_ue_s1ap_id); + + // Still return *result } } } // end if if (eNB_ue_s1ap_id > 0) @@ -223,6 +225,8 @@ rrc_eNB_S1AP_get_ue_ids( LOG_E(S1AP, "[eNB %ld] In hashtable_get, couldn't find in initial_id2_s1ap_ids ue_initial_id %"PRIu16"\n", rrc_instance_pP - RC.rrc[0], ue_initial_id); + + return NULL; /* * At the moment this is written, this case shouldn't (cannot) happen and is equivalent to an error. * One could try to find the struct instance based on s1ap_id2_s1ap_ids and eNB_ue_s1ap_id (if > 0), @@ -245,25 +249,38 @@ rrc_eNB_S1AP_get_ue_ids( eNB_ue_s1ap_id); instance = ENB_MODULE_ID_TO_INSTANCE(rrc_instance_pP - RC.rrc[0]); // get eNB instance s1ap_eNB_instance_p = s1ap_eNB_get_instance(instance); // get s1ap_eNB_instance - ue_desc_p = s1ap_eNB_get_ue_context(s1ap_eNB_instance_p, eNB_ue_s1ap_id); // get s1ap_eNB_ue_context + + if (s1ap_eNB_instance_p != NULL) { + ue_desc_p = s1ap_eNB_get_ue_context(s1ap_eNB_instance_p, eNB_ue_s1ap_id); // get s1ap_eNB_ue_context + } else { + LOG_E(S1AP, "[eNB instance %d] Couldn't find the eNB S1AP context\n", + instance); + + return NULL; + } if (ue_desc_p != NULL) { result = rrc_eNB_S1AP_get_ue_ids(rrc_instance_pP, ue_desc_p->ue_initial_id, eNB_ue_s1ap_id); - ue_context_p = rrc_eNB_get_ue_context(RC.rrc[ENB_INSTANCE_TO_MODULE_ID(instance)], result->ue_rnti); - if ((ue_context_p != NULL) && (ue_context_p->ue_context.eNB_ue_s1ap_id == 0)) { - ue_context_p->ue_context.eNB_ue_s1ap_id = eNB_ue_s1ap_id; - } else { - LOG_E(RRC, "[eNB %ld] Incoherence between RRC context and S1AP context (%d != %d) for UE RNTI %d or UE RRC context doesn't exist\n", - rrc_instance_pP - RC.rrc[0], - ue_context_p->ue_context.eNB_ue_s1ap_id, - eNB_ue_s1ap_id, - result->ue_rnti); + if (result != NULL) { + ue_context_p = rrc_eNB_get_ue_context(RC.rrc[ENB_INSTANCE_TO_MODULE_ID(instance)], result->ue_rnti); + + if ((ue_context_p != NULL) && (ue_context_p->ue_context.eNB_ue_s1ap_id == 0)) { + ue_context_p->ue_context.eNB_ue_s1ap_id = eNB_ue_s1ap_id; + } else { + LOG_E(RRC, "[eNB %ld] Incoherence between RRC context and S1AP context (%d != %d) for UE RNTI %d or UE RRC context doesn't exist\n", + rrc_instance_pP - RC.rrc[0], + ue_context_p->ue_context.eNB_ue_s1ap_id, + eNB_ue_s1ap_id, + result->ue_rnti); + } } } else { LOG_E(S1AP, "[eNB %ld] In hashtable_get, couldn't find in s1ap_id2_s1ap_ids eNB_ue_s1ap_id %"PRIu32", even when looking at S1AP context\n", rrc_instance_pP - RC.rrc[0], eNB_ue_s1ap_id); + + return NULL; } } // end if (h_rc != HASH_TABLE_OK) } // end if (eNB_ue_s1ap_id > 0) From b89f9284dd74bc8b85682c54efcdbdc917869bc5 Mon Sep 17 00:00:00 2001 From: Raymond Knopp Date: Wed, 21 Nov 2018 20:24:24 +0100 Subject: [PATCH 170/233] adds a mac_MainConfig information element to RRCConnectionSetup. This is to configure PHR reporting during the first part of the Attach procedure. --- cmake_targets/CMakeLists.txt | 2 +- openair2/RRC/LTE/MESSAGES/asn1_msg.c | 50 ++++++++++++++++++---------- 2 files changed, 33 insertions(+), 19 deletions(-) diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt index f205e3f5fa..97720f723a 100644 --- a/cmake_targets/CMakeLists.txt +++ b/cmake_targets/CMakeLists.txt @@ -232,7 +232,7 @@ add_definitions("-DPACKAGE_BUGREPORT=\"openair4g-devel@lists.eurecom.fr\"") # Debug related options ######################################### add_boolean_option(ASN_DEBUG False "ASN1 coder/decoder Debug") -add_boolean_option(EMIT_ASN_DEBUG False "ASN1 coder/decoder Debug") +add_boolean_option(ASN_EMIT_DEBUG False "ASN1 coder/decoder Debug") add_boolean_option(MSG_PRINT False "print debug messages") add_boolean_option(DISABLE_XER_PRINT False "print XER Format") add_boolean_option(XER_PRINT False "print XER Format") diff --git a/openair2/RRC/LTE/MESSAGES/asn1_msg.c b/openair2/RRC/LTE/MESSAGES/asn1_msg.c index 8d0992f17a..55afee7021 100644 --- a/openair2/RRC/LTE/MESSAGES/asn1_msg.c +++ b/openair2/RRC/LTE/MESSAGES/asn1_msg.c @@ -1797,14 +1797,14 @@ do_RRCConnectionReconfigurationComplete( //------------------------------------------------------------------------------ uint8_t do_RRCConnectionSetup( - const protocol_ctxt_t* const ctxt_pP, - rrc_eNB_ue_context_t* const ue_context_pP, - int CC_id, - uint8_t* const buffer, - const uint8_t transmission_mode, - const uint8_t Transaction_id, - LTE_SRB_ToAddModList_t **SRB_configList, - struct LTE_PhysicalConfigDedicated **physicalConfigDedicated) + const protocol_ctxt_t* const ctxt_pP, + rrc_eNB_ue_context_t* const ue_context_pP, + int CC_id, + uint8_t* const buffer, + const uint8_t transmission_mode, + const uint8_t Transaction_id, + LTE_SRB_ToAddModList_t **SRB_configList, + struct LTE_PhysicalConfigDedicated **physicalConfigDedicated) { asn_enc_rval_t enc_rval; @@ -1830,6 +1830,7 @@ do_RRCConnectionSetup( LTE_DL_FRAME_PARMS *frame_parms = &RC.eNB[ctxt_pP->module_id][CC_id]->frame_parms; + memset((void *)&dl_ccch_msg,0,sizeof(LTE_DL_CCCH_Message_t)); dl_ccch_msg.message.present = LTE_DL_CCCH_MessageType_PR_c1; dl_ccch_msg.message.choice.c1.present = LTE_DL_CCCH_MessageType__c1_PR_rrcConnectionSetup; @@ -2156,18 +2157,31 @@ do_RRCConnectionSetup( rrcConnectionSetup->criticalExtensions.choice.c1.choice.rrcConnectionSetup_r8.radioResourceConfigDedicated.drb_ToReleaseList = NULL; rrcConnectionSetup->criticalExtensions.choice.c1.choice.rrcConnectionSetup_r8.radioResourceConfigDedicated.sps_Config = NULL; rrcConnectionSetup->criticalExtensions.choice.c1.choice.rrcConnectionSetup_r8.radioResourceConfigDedicated.physicalConfigDedicated = physicalConfigDedicated2; - rrcConnectionSetup->criticalExtensions.choice.c1.choice.rrcConnectionSetup_r8.radioResourceConfigDedicated.mac_MainConfig = NULL; -#ifdef CBA - betaOffset_CBA_Index = CALLOC(1,sizeof(long)); - cShift_CBA = CALLOC(1,sizeof(long)); - *betaOffset_CBA_Index=10; // need to be changed by Kaijie - *cShift_CBA=4; - physicalConfigDedicated2->pusch_CBAConfigDedicated_vlola->betaOffset_CBA_Index=betaOffset_CBA_Index; - physicalConfigDedicated2->pusch_CBAConfigDedicated_vlola->cShift_CBA=cShift_CBA; - rrcConnectionSetup->criticalExtensions.choice.c1.choice.rrcConnectionSetup_r8.radioResourceConfigDedicated.sps_CBA_ConfigList_vlola = NULL; -#endif + rrcConnectionSetup->criticalExtensions.choice.c1.choice.rrcConnectionSetup_r8.radioResourceConfigDedicated.mac_MainConfig = CALLOC(1,sizeof(struct LTE_RadioResourceConfigDedicated__mac_MainConfig)); + rrcConnectionSetup->criticalExtensions.choice.c1.choice.rrcConnectionSetup_r8.radioResourceConfigDedicated.mac_MainConfig->present = LTE_RadioResourceConfigDedicated__mac_MainConfig_PR_explicitValue; + + LTE_MAC_MainConfig_t *mac_MainConfig = &rrcConnectionSetup->criticalExtensions.choice.c1.choice.rrcConnectionSetup_r8.radioResourceConfigDedicated.mac_MainConfig->choice.explicitValue; + + mac_MainConfig->ul_SCH_Config = CALLOC(1, sizeof(*mac_MainConfig->ul_SCH_Config)); + + long *maxHARQ_Tx = CALLOC(1, sizeof(long)); + *maxHARQ_Tx = LTE_MAC_MainConfig__ul_SCH_Config__maxHARQ_Tx_n5; + long *periodicBSR_Timer = CALLOC(1, sizeof(long)); + *periodicBSR_Timer = LTE_PeriodicBSR_Timer_r12_sf64; + mac_MainConfig->ul_SCH_Config->maxHARQ_Tx = maxHARQ_Tx; + mac_MainConfig->ul_SCH_Config->periodicBSR_Timer = periodicBSR_Timer; + mac_MainConfig->ul_SCH_Config->retxBSR_Timer = LTE_RetxBSR_Timer_r12_sf320; + mac_MainConfig->ul_SCH_Config->ttiBundling = 0; // FALSE + mac_MainConfig->timeAlignmentTimerDedicated = LTE_TimeAlignmentTimer_infinity; + mac_MainConfig->drx_Config = NULL; + mac_MainConfig->phr_Config = CALLOC(1, sizeof(*mac_MainConfig->phr_Config)); + mac_MainConfig->phr_Config->present = LTE_MAC_MainConfig__phr_Config_PR_setup; + mac_MainConfig->phr_Config->choice.setup.periodicPHR_Timer = LTE_MAC_MainConfig__phr_Config__setup__periodicPHR_Timer_sf20; // sf20 = 20 subframes + mac_MainConfig->phr_Config->choice.setup.prohibitPHR_Timer = LTE_MAC_MainConfig__phr_Config__setup__prohibitPHR_Timer_sf20; // sf20 = 20 subframes + mac_MainConfig->phr_Config->choice.setup.dl_PathlossChange = LTE_MAC_MainConfig__phr_Config__setup__dl_PathlossChange_dB1; // Value dB1 =1 dB, dB3 = 3 dB + if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) { xer_fprint(stdout, &asn_DEF_LTE_DL_CCCH_Message, (void*)&dl_ccch_msg); } From 4fdccd3b4d6e7c9f8408dd6f81abe2e7aadc7ed1 Mon Sep 17 00:00:00 2001 From: Raphael Defosseux Date: Thu, 22 Nov 2018 14:28:06 +0100 Subject: [PATCH 171/233] CI: adding support for T tracing -- tracing is done w/ a single UE attach / detach -- traffic b/ EPC and eNB is captured by tshark Signed-off-by: Raphael Defosseux --- ci-scripts/active_net_interfaces.awk | 1 + ci-scripts/main.py | 64 ++++++++++++++++---- ci-scripts/xml_files/enb_usrp210_band7.xml | 13 ++++ ci-scripts/xml_files/enb_usrpb210_band40.xml | 15 ++++- 4 files changed, 81 insertions(+), 12 deletions(-) create mode 100644 ci-scripts/active_net_interfaces.awk diff --git a/ci-scripts/active_net_interfaces.awk b/ci-scripts/active_net_interfaces.awk new file mode 100644 index 0000000000..6d582c763b --- /dev/null +++ b/ci-scripts/active_net_interfaces.awk @@ -0,0 +1 @@ +/inet.*brd/{print "interfaceToUse="$NF"done"} diff --git a/ci-scripts/main.py b/ci-scripts/main.py index 0092234b95..91b97aac80 100644 --- a/ci-scripts/main.py +++ b/ci-scripts/main.py @@ -102,6 +102,7 @@ class SSHConnection(): self.iperf_args = '' self.iperf_packetloss_threshold = '' self.iperf_profile = '' + self.nbMaxUEtoAttach = -1 self.UEDevices = [] self.CatMDevices = [] self.UEIPAddresses = [] @@ -358,6 +359,18 @@ class SSHConnection(): self.CreateHtmlTestRow(self.Initialize_eNB_args, 'KO', pStatus) self.CreateHtmlFooter(False) sys.exit(1) + # If tracer options is on, running tshark on EPC side and capture traffic b/ EPC and eNB + result = re.search('T_stdout', str(self.Initialize_eNB_args)) + if result is not None: + self.open(self.EPCIPAddress, self.EPCUserName, self.EPCPassword) + self.command('ip addr show | awk -f /tmp/active_net_interfaces.awk | egrep -v "lo|tun"', '\$', 5) + result = re.search('interfaceToUse=(?P[a-zA-Z0-9\-\_]+)done', str(self.ssh.before)) + if result is not None: + eth_interface = result.group('eth_interface') + logging.debug('\u001B[1m Launching tshark on interface ' + eth_interface + '\u001B[0m') + self.command('echo ' + self.EPCPassword + ' | sudo -S rm -f /tmp/enb_' + SSH.testCase_id + '_s1log.pcap', '\$', 5) + self.command('echo $USER; nohup sudo tshark -f "host ' + self.eNBIPAddress +'" -i ' + eth_interface + ' -w /tmp/enb_' + SSH.testCase_id + '_s1log.pcap > /tmp/tshark.log 2>&1 &', self.EPCUserName, 5) + self.close() self.open(self.eNBIPAddress, self.eNBUserName, self.eNBPassword) self.command('cd ' + self.eNBSourceCodePath, '\$', 5) # Initialize_eNB_args usually start with -O and followed by the location in repository @@ -365,6 +378,14 @@ class SSHConnection(): extIdx = full_config_file.find('.conf') if (extIdx > 0): extra_options = full_config_file[extIdx + 5:] + # if tracer options is on, compiling and running T Tracer + result = re.search('T_stdout', str(extra_options)) + if result is not None: + logging.debug('\u001B[1m Compiling and launching T Tracer\u001B[0m') + self.command('cd common/utils/T/tracer', '\$', 5) + self.command('make', '\$', 10) + self.command('echo $USER; nohup ./record -d ../T_messages.txt -o ' + self.eNBSourceCodePath + '/cmake_targets/enb_' + SSH.testCase_id + '_record.raw -ON -off VCD -off HEAVY -off LEGACY_GROUP_TRACE -off LEGACY_GROUP_DEBUG > ' + self.eNBSourceCodePath + '/cmake_targets/enb_' + SSH.testCase_id + '_record.log 2>&1 &', self.eNBUserName, 5) + self.command('cd ' + self.eNBSourceCodePath, '\$', 5) full_config_file = full_config_file[:extIdx + 5] config_path, config_file = os.path.split(full_config_file) else: @@ -608,11 +629,14 @@ class SSHConnection(): multi_jobs = [] status_queue = SimpleQueue() lock = Lock() + nb_ue_to_connect = 0 for device_id in self.UEDevices: - p = Process(target = SSH.AttachUE_common, args = (device_id, status_queue, lock,)) - p.daemon = True - p.start() - multi_jobs.append(p) + if (self.nbMaxUEtoAttach == -1) or (nb_ue_to_connect < self.nbMaxUEtoAttach): + p = Process(target = SSH.AttachUE_common, args = (device_id, status_queue, lock,)) + p.daemon = True + p.start() + multi_jobs.append(p) + nb_ue_to_connect = nb_ue_to_connect + 1 for job in multi_jobs: job.join() @@ -1645,8 +1669,21 @@ class SSHConnection(): self.command('echo ' + self.eNBPassword + ' | sudo -S killall --signal SIGKILL lte-softmodem || true', '\$', 5) self.close() result = re.search('enb_', str(self.eNBLogFile)) + # If tracer options is on, stopping tshark on EPC side + result = re.search('T_stdout', str(self.Initialize_eNB_args)) + if result is not None: + self.open(self.EPCIPAddress, self.EPCUserName, self.EPCPassword) + logging.debug('\u001B[1m Stopping tshark \u001B[0m') + self.command('echo ' + self.EPCPassword + ' | sudo -S killall --signal SIGKILL tshark', '\$', 5) + time.sleep(1) + pcap_log_file = self.eNBLogFile.replace('.log', '_s1log.pcap') + self.command('echo ' + self.EPCPassword + ' | sudo -S chmod 666 /tmp/' + pcap_log_file, '\$', 5) + self.copyin(self.EPCIPAddress, self.EPCUserName, self.EPCPassword, '/tmp/' + pcap_log_file, '.') + self.copyout(self.eNBIPAddress, self.eNBUserName, self.eNBPassword, pcap_log_file, self.eNBSourceCodePath + '/cmake_targets/.') + self.close() if result is not None: self.copyin(self.eNBIPAddress, self.eNBUserName, self.eNBPassword, self.eNBSourceCodePath + '/cmake_targets/' + self.eNBLogFile, '.') + logging.debug('\u001B[1m Analyzing eNB logfile \u001B[0m') logStatus = self.AnalyzeLogFile_eNB() if (logStatus < 0): self.CreateHtmlTestRow('N/A', 'KO', logStatus) @@ -1672,11 +1709,8 @@ class SSHConnection(): self.command('cd scripts', '\$', 5) self.command('rm -f ./kill_hss.sh', '\$', 5) self.command('echo ' + self.EPCPassword + ' | sudo -S daemon --name=simulated_hss --stop', '\$', 5) - time.sleep(2) - self.command('ps -aux | egrep --color=never "hss_sim|simulated_hss" | grep -v grep | awk \'BEGIN{n=0}{pidId[n]=$2;n=n+1}END{print "kill -9 " pidId[0] " " pidId[1]}\' > ./kill_hss.sh', '\$', 5) - self.command('chmod 755 ./kill_hss.sh', '\$', 5) - self.command('echo ' + self.EPCPassword + ' | sudo -S ./kill_hss.sh', '\$', 5) - self.command('rm ./kill_hss.sh', '\$', 5) + time.sleep(1) + self.command('echo ' + self.EPCPassword + ' | sudo -S killall --signal SIGKILL hss_sim', '\$', 5) self.close() self.CreateHtmlTestRow('N/A', 'OK', ALL_PROCESSES_OK) @@ -1763,8 +1797,8 @@ class SSHConnection(): self.command('cd ' + self.eNBSourceCodePath, '\$', 5) self.command('cd cmake_targets', '\$', 5) self.command('echo ' + self.eNBPassword + ' | sudo -S rm -f enb.log.zip', '\$', 5) - self.command('echo ' + self.eNBPassword + ' | sudo -S zip enb.log.zip enb*.log core*', '\$', 60) - self.command('echo ' + self.eNBPassword + ' | sudo -S rm enb*.log core*', '\$', 5) + self.command('echo ' + self.eNBPassword + ' | sudo -S zip enb.log.zip enb*.log core* enb_*record.raw enb_*.pcap', '\$', 60) + self.command('echo ' + self.eNBPassword + ' | sudo -S rm enb*.log core* enb_*record.raw enb_*.pcap', '\$', 5) self.close() def LogCollectPing(self): @@ -2071,6 +2105,13 @@ def GetParametersFromXML(action): if (SSH.eNB_instance is None): SSH.eNB_instance = '0' + if action == 'Attach_UE': + nbMaxUEtoAttach = test.findtext('nbMaxUEtoAttach') + if (nbMaxUEtoAttach is None): + SSH.nbMaxUEtoAttach = -1 + else: + SSH.nbMaxUEtoAttach = int(nbMaxUEtoAttach) + if action == 'Ping': SSH.ping_args = test.findtext('ping_args') SSH.ping_packetloss_threshold = test.findtext('ping_packetloss_threshold') @@ -2248,6 +2289,7 @@ elif re.match('^TesteNB$', mode, re.IGNORECASE): sys.exit('Insufficient Parameter') SSH.copyout(SSH.EPCIPAddress, SSH.EPCUserName, SSH.EPCPassword, sys.path[0] + "/tcp_iperf_stats.awk", "/tmp") + SSH.copyout(SSH.EPCIPAddress, SSH.EPCUserName, SSH.EPCPassword, sys.path[0] + "/active_net_interfaces.awk", "/tmp") SSH.CreateHtmlHeader() #read test_case_list.xml file diff --git a/ci-scripts/xml_files/enb_usrp210_band7.xml b/ci-scripts/xml_files/enb_usrp210_band7.xml index c408dc7882..c85ceee81d 100644 --- a/ci-scripts/xml_files/enb_usrp210_band7.xml +++ b/ci-scripts/xml_files/enb_usrp210_band7.xml @@ -24,6 +24,7 @@ 010101 050101 060101 070101 040101 + 030100 040300 040401 040201 030201 030101 040301 040501 040603 040604 040605 040606 040607 040641 040642 040643 040644 040401 040201 030201 030111 040301 040511 040613 040614 040615 040616 040617 040651 040652 040653 040654 040401 040201 030201 030121 040301 040521 040623 040624 040625 040626 040627 040662 040661 040663 040664 040401 040201 030201 @@ -37,6 +38,12 @@ -w USRP -c --eNB + + Initialize_eNB + Initialize eNB (FDD/Band7/5MHz) with T Tracer on + -O ci-scripts/conf_files/enb.band7.tm1.25PRB.usrpb210.conf --T_stdout 0 + + Initialize_eNB Initialize eNB (FDD/Band7/5MHz) @@ -70,6 +77,12 @@ Terminate UE + + Attach_UE + Attach single UE + 1 + + Attach_UE Attach UE diff --git a/ci-scripts/xml_files/enb_usrpb210_band40.xml b/ci-scripts/xml_files/enb_usrpb210_band40.xml index 53a0dc9380..65492c4209 100644 --- a/ci-scripts/xml_files/enb_usrpb210_band40.xml +++ b/ci-scripts/xml_files/enb_usrpb210_band40.xml @@ -24,6 +24,7 @@ 010101 050101 060101 070101 040101 + 030100 040300 040401 040201 030201 030104 040301 040501 040602 040601 040603 040642 040641 040643 040401 040201 030201 030114 040301 040511 040612 040611 040613 040652 040651 040653 040401 040201 030201 050201 060201 070201 @@ -40,12 +41,18 @@ -w USRP -c --eNB + + Initialize_eNB + Initialize eNB (TDD/Band40/5MHz) with T Tracer on + -O ci-scripts/conf_files/enb.band40.tm1.25PRB.FairScheduler.usrpb210.conf --T_stdout 0 + + Initialize_eNB Initialize eNB (TDD/Band40/5MHz) -O ci-scripts/conf_files/enb.band40.tm1.25PRB.FairScheduler.usrpb210.conf - + Initialize_eNB Initialize eNB (TDD/Band40/10MHz/info) @@ -73,6 +80,12 @@ Terminate UE + + Attach_UE + Attach single UE + 1 + + Attach_UE Attach UE From 55732deb80ac341ef92b278aa04379001e94abac Mon Sep 17 00:00:00 2001 From: Raphael Defosseux Date: Thu, 22 Nov 2018 15:03:27 +0100 Subject: [PATCH 172/233] Astyling the common files Signed-off-by: Raphael Defosseux --- common/config/config_cmdline.c | 413 ++++++++------- common/config/config_load_configmodule.c | 477 +++++++++-------- common/config/config_load_configmodule.h | 25 +- common/config/config_paramdesc.h | 141 +++-- common/config/config_userapi.c | 604 ++++++++++++---------- common/config/config_userapi.h | 6 +- common/utils/LOG/log.c | 628 +++++++++++------------ common/utils/LOG/log.h | 344 +++++++------ common/utils/T/genids.c | 127 +++-- 9 files changed, 1426 insertions(+), 1339 deletions(-) diff --git a/common/config/config_cmdline.c b/common/config/config_cmdline.c index c28cf33758..7fca12540d 100644 --- a/common/config/config_cmdline.c +++ b/common/config/config_cmdline.c @@ -20,7 +20,7 @@ */ /*! \file common/config/cmdline/config_libconfig.c - * \brief configuration module, command line parsing implementation + * \brief configuration module, command line parsing implementation * \author Francois TABURET * \date 2017 * \version 0.1 @@ -39,223 +39,244 @@ #include "config_userapi.h" -int parse_stringlist(paramdef_t *cfgoptions, char *val) -{ -char *atoken; -char *tokctx; -char *tmpval=strdup(val); -int numelt=0; +int parse_stringlist(paramdef_t *cfgoptions, char *val) { + char *atoken; + char *tokctx; + char *tmpval=strdup(val); + int numelt=0; + cfgoptions->numelt=0; + atoken=strtok_r(tmpval, ",",&tokctx); - cfgoptions->numelt=0; + while(atoken != NULL) { + numelt++ ; + atoken=strtok_r(NULL, ",",&tokctx); + } - atoken=strtok_r(tmpval, ",",&tokctx); - while(atoken != NULL) { - numelt++ ; - atoken=strtok_r(NULL, ",",&tokctx); - } - free(tmpval); - config_check_valptr(cfgoptions,(char **)&(cfgoptions->strlistptr), sizeof(char *) * numelt); - cfgoptions->numelt=numelt; + free(tmpval); + config_check_valptr(cfgoptions,(char **)&(cfgoptions->strlistptr), sizeof(char *) * numelt); + cfgoptions->numelt=numelt; + atoken=strtok_r(val, ",",&tokctx); - atoken=strtok_r(val, ",",&tokctx); - for( int i=0; inumelt && atoken != NULL ; i++) { - config_check_valptr(cfgoptions,&(cfgoptions->strlistptr[i]),strlen(atoken)+1); - sprintf(cfgoptions->strlistptr[i],"%s",atoken); - printf_params("[LIBCONFIG] %s[%i]: %s\n", cfgoptions->optname,i,cfgoptions->strlistptr[i]); - atoken=strtok_r(NULL, ",",&tokctx); - } - return (cfgoptions->numelt > 0); -} - -int processoption(paramdef_t *cfgoptions, char *value) -{ -char *tmpval = value; -int optisset=0; -char defbool[2]="1"; + for( int i=0; inumelt && atoken != NULL ; i++) { + config_check_valptr(cfgoptions,&(cfgoptions->strlistptr[i]),strlen(atoken)+1); + sprintf(cfgoptions->strlistptr[i],"%s",atoken); + printf_params("[LIBCONFIG] %s[%i]: %s\n", cfgoptions->optname,i,cfgoptions->strlistptr[i]); + atoken=strtok_r(NULL, ",",&tokctx); + } - - if ( value == NULL) { - if( (cfgoptions->paramflags &PARAMFLAG_BOOL) == 0 ) { /* not a boolean, argument required */ - fprintf(stderr,"[CONFIG] command line, option %s requires an argument\n",cfgoptions->optname); - return 0; - } else { /* boolean value option without argument, set value to true*/ - tmpval = defbool; - } - } - switch(cfgoptions->type) - { - case TYPE_STRING: - if (cfgoptions->numelt == 0 ) { - config_check_valptr(cfgoptions, cfgoptions->strptr, strlen(tmpval)+1); - sprintf(*(cfgoptions->strptr), "%s",tmpval); - } else { - sprintf( (char *)(cfgoptions->strptr), "%s",tmpval); - } - printf_cmdl("[CONFIG] %s set to %s from command line\n", cfgoptions->optname, tmpval); - optisset=1; - break; - - case TYPE_STRINGLIST: - optisset=parse_stringlist(cfgoptions,tmpval); - break; - case TYPE_UINT32: - case TYPE_INT32: - case TYPE_UINT16: - case TYPE_INT16: - case TYPE_UINT8: - case TYPE_INT8: - config_check_valptr(cfgoptions, (char **)&(cfgoptions->iptr),sizeof(int32_t)); - config_assign_int(cfgoptions,cfgoptions->optname,(int32_t)strtol(tmpval,NULL,0)); - optisset=1; - break; - case TYPE_UINT64: - case TYPE_INT64: - config_check_valptr(cfgoptions, (char **)&(cfgoptions->i64ptr),sizeof(uint64_t)); - *(cfgoptions->i64ptr)=strtoll(tmpval,NULL,0); - printf_cmdl("[CONFIG] %s set to %lli from command line\n", cfgoptions->optname, (long long)*(cfgoptions->i64ptr)); - optisset=1; - break; - case TYPE_UINTARRAY: - case TYPE_INTARRAY: - - break; - case TYPE_DOUBLE: - config_check_valptr(cfgoptions, (char **)&(cfgoptions->dblptr),sizeof(double)); - *(cfgoptions->dblptr) = strtof(tmpval,NULL); - printf_cmdl("[CONFIG] %s set to %lf from command line\n", cfgoptions->optname, *(cfgoptions->dblptr)); - optisset=1; - break; - - case TYPE_IPV4ADDR: - - break; - - default: - fprintf(stderr,"[CONFIG] command line, %s type %i not supported\n",cfgoptions->optname, cfgoptions->type); - break; - } /* switch on param type */ - if (optisset == 1) { - cfgoptions->paramflags = cfgoptions->paramflags | PARAMFLAG_PARAMSET; - } - return optisset; + return (cfgoptions->numelt > 0); } -int config_check_cmdlineopt(char *prefix) -{ -int unknowndetected=0; -char testprefix[CONFIG_MAXOPTLENGTH]=""; -int finalcheck = 0; +int processoption(paramdef_t *cfgoptions, char *value) { + char *tmpval = value; + int optisset=0; + char defbool[2]="1"; - if (prefix != NULL) { - if (strcmp(prefix,CONFIG_CHECKALLSECTIONS) == 0) - finalcheck = 1; - else if (strlen(prefix) > 0) { - sprintf(testprefix,"--%s.",prefix); - } - } - - for (int i=1; iargc ; i++) { - if ( !finalcheck && strstr(config_get_if()->argv[i],testprefix) == NULL ) continue; - if ( !finalcheck && testprefix[0]==0 && index(config_get_if()->argv[i],'.') != NULL) continue; - if ( !finalcheck && config_get_if()->argv[i][0] == '-' && isdigit(config_get_if()->argv[i][1])) continue; - if ( (config_get_if()->argv_info[i] & CONFIG_CMDLINEOPT_PROCESSED) == 0 ) { - fprintf(stderr,"[CONFIG] unknown option: %s\n", - config_get_if()->argv[i] ); - unknowndetected++; - } + if ( value == NULL) { + if( (cfgoptions->paramflags &PARAMFLAG_BOOL) == 0 ) { /* not a boolean, argument required */ + fprintf(stderr,"[CONFIG] command line, option %s requires an argument\n",cfgoptions->optname); + return 0; + } else { /* boolean value option without argument, set value to true*/ + tmpval = defbool; } + } + + switch(cfgoptions->type) { + case TYPE_STRING: + if (cfgoptions->numelt == 0 ) { + config_check_valptr(cfgoptions, cfgoptions->strptr, strlen(tmpval)+1); + sprintf(*(cfgoptions->strptr), "%s",tmpval); + } else { + sprintf( (char *)(cfgoptions->strptr), "%s",tmpval); + } + + printf_cmdl("[CONFIG] %s set to %s from command line\n", cfgoptions->optname, tmpval); + optisset=1; + break; + + case TYPE_STRINGLIST: + optisset=parse_stringlist(cfgoptions,tmpval); + break; + + case TYPE_UINT32: + case TYPE_INT32: + case TYPE_UINT16: + case TYPE_INT16: + case TYPE_UINT8: + case TYPE_INT8: + config_check_valptr(cfgoptions, (char **)&(cfgoptions->iptr),sizeof(int32_t)); + config_assign_int(cfgoptions,cfgoptions->optname,(int32_t)strtol(tmpval,NULL,0)); + optisset=1; + break; + + case TYPE_UINT64: + case TYPE_INT64: + config_check_valptr(cfgoptions, (char **)&(cfgoptions->i64ptr),sizeof(uint64_t)); + *(cfgoptions->i64ptr)=strtoll(tmpval,NULL,0); + printf_cmdl("[CONFIG] %s set to %lli from command line\n", cfgoptions->optname, (long long)*(cfgoptions->i64ptr)); + optisset=1; + break; + + case TYPE_UINTARRAY: + case TYPE_INTARRAY: + break; + + case TYPE_DOUBLE: + config_check_valptr(cfgoptions, (char **)&(cfgoptions->dblptr),sizeof(double)); + *(cfgoptions->dblptr) = strtof(tmpval,NULL); + printf_cmdl("[CONFIG] %s set to %lf from command line\n", cfgoptions->optname, *(cfgoptions->dblptr)); + optisset=1; + break; + + case TYPE_IPV4ADDR: + break; + + default: + fprintf(stderr,"[CONFIG] command line, %s type %i not supported\n",cfgoptions->optname, cfgoptions->type); + break; + } /* switch on param type */ + + if (optisset == 1) { + cfgoptions->paramflags = cfgoptions->paramflags | PARAMFLAG_PARAMSET; + } + + return optisset; +} + +int config_check_cmdlineopt(char *prefix) { + int unknowndetected=0; + char testprefix[CONFIG_MAXOPTLENGTH]=""; + int finalcheck = 0; + + if (prefix != NULL) { + if (strcmp(prefix,CONFIG_CHECKALLSECTIONS) == 0) + finalcheck = 1; + else if (strlen(prefix) > 0) { + sprintf(testprefix,"--%s.",prefix); + } + } + + for (int i=1; iargc ; i++) { + if ( !finalcheck && strstr(config_get_if()->argv[i],testprefix) == NULL ) continue; + + if ( !finalcheck && testprefix[0]==0 && index(config_get_if()->argv[i],'.') != NULL) continue; + + if ( !finalcheck && config_get_if()->argv[i][0] == '-' && isdigit(config_get_if()->argv[i][1])) continue; + + if ( (config_get_if()->argv_info[i] & CONFIG_CMDLINEOPT_PROCESSED) == 0 ) { + fprintf(stderr,"[CONFIG] unknown option: %s\n", + config_get_if()->argv[i] ); + unknowndetected++; + } + } - printf_cmdl("[CONFIG] %i unknown option(s) in command line starting with %s (section %s)\n", unknowndetected,testprefix,((prefix==NULL)?"":prefix)); - return unknowndetected; + return unknowndetected; } /* parse_cmdline*/ -int config_process_cmdline(paramdef_t *cfgoptions,int numoptions, char *prefix) -{ +int config_process_cmdline(paramdef_t *cfgoptions,int numoptions, char *prefix) { int c = config_get_if()->argc; int i,j; char *pp; char cfgpath[CONFIG_MAXOPTLENGTH]; - j = 0; i = 0; - while (c > 0 ) { - char *oneargv = strdup(config_get_if()->argv[i]); /* we use strtok_r which modifies its string paramater, and we don't want argv to be modified */ - /* first check help options, either --help, -h or --help_
    */ - if (strncmp(oneargv, "-h",2) == 0 || strncmp(oneargv, "--help",6) == 0 ) { - char *tokctx; - pp=strtok_r(oneargv, "_",&tokctx); - config_get_if()->argv_info[i] |= CONFIG_CMDLINEOPT_PROCESSED; - if (pp == NULL || strcasecmp(pp,config_get_if()->argv[i] ) == 0 ) { - if( prefix == NULL) { - config_printhelp(cfgoptions,numoptions); - if ( ! ( CONFIG_ISFLAGSET(CONFIG_NOEXITONHELP))) - exit_fun("[CONFIG] Exiting after displaying help\n"); - } - } else { - pp=strtok_r(NULL, " ",&tokctx); - if ( prefix != NULL && pp != NULL && strncasecmp(prefix,pp,strlen(pp)) == 0 ) { - printf ("Help for %s section:\n",prefix); - config_printhelp(cfgoptions,numoptions); - if ( ! (CONFIG_ISFLAGSET(CONFIG_NOEXITONHELP))) { - fprintf(stderr,"[CONFIG] %s %i section %s:", __FILE__, __LINE__, prefix); - exit_fun(" Exiting after displaying help\n"); - } - } - } + + while (c > 0 ) { + char *oneargv = strdup(config_get_if()->argv[i]); /* we use strtok_r which modifies its string paramater, and we don't want argv to be modified */ + + /* first check help options, either --help, -h or --help_
    */ + if (strncmp(oneargv, "-h",2) == 0 || strncmp(oneargv, "--help",6) == 0 ) { + char *tokctx; + pp=strtok_r(oneargv, "_",&tokctx); + config_get_if()->argv_info[i] |= CONFIG_CMDLINEOPT_PROCESSED; + + if (pp == NULL || strcasecmp(pp,config_get_if()->argv[i] ) == 0 ) { + if( prefix == NULL) { + config_printhelp(cfgoptions,numoptions); + + if ( ! ( CONFIG_ISFLAGSET(CONFIG_NOEXITONHELP))) + exit_fun("[CONFIG] Exiting after displaying help\n"); + } + } else { + pp=strtok_r(NULL, " ",&tokctx); + + if ( prefix != NULL && pp != NULL && strncasecmp(prefix,pp,strlen(pp)) == 0 ) { + printf ("Help for %s section:\n",prefix); + config_printhelp(cfgoptions,numoptions); + + if ( ! (CONFIG_ISFLAGSET(CONFIG_NOEXITONHELP))) { + fprintf(stderr,"[CONFIG] %s %i section %s:", __FILE__, __LINE__, prefix); + exit_fun(" Exiting after displaying help\n"); + } + } + } + } + + /* now, check for non help options */ + if (oneargv[0] == '-') { + for(int n=0; n 2) && (strcmp(oneargv + 2,cfgpath ) == 0 )) ) { - char *valptr=NULL; - int ret; - config_get_if()->argv_info[i] |= CONFIG_CMDLINEOPT_PROCESSED; - if (c > 0) { - pp = config_get_if()->argv[i+1]; - if (pp != NULL ) { - ret = strlen(pp); - if (ret > 0 ) { - if (pp[0] != '-') - valptr=pp; - else if ( ret > 1 && pp[0] == '-' && isdigit(pp[1]) ) - valptr=pp; - } - } - } - j += processoption(&(cfgoptions[n]), valptr); - if ( valptr != NULL ) { - i++; - config_get_if()->argv_info[i] |= CONFIG_CMDLINEOPT_PROCESSED; - c--; - } - break; - } - } /* for n... */ - } /* if (oneargv[0] == '-') */ - free(oneargv); - i++; - c--; - } /* fin du while */ + if (prefix != NULL) { + sprintf(cfgpath,"%s.%s",prefix,cfgoptions[n].optname); + } else { + sprintf(cfgpath,"%s",cfgoptions[n].optname); + } + + if ( ((strlen(oneargv) == 2) && (strcmp(oneargv + 1,cfgpath) == 0)) || /* short option, one "-" */ + ((strlen(oneargv) > 2) && (strcmp(oneargv + 2,cfgpath ) == 0 )) ) { + char *valptr=NULL; + int ret; + config_get_if()->argv_info[i] |= CONFIG_CMDLINEOPT_PROCESSED; + + if (c > 0) { + pp = config_get_if()->argv[i+1]; + + if (pp != NULL ) { + ret = strlen(pp); + + if (ret > 0 ) { + if (pp[0] != '-') + valptr=pp; + else if ( ret > 1 && pp[0] == '-' && isdigit(pp[1]) ) + valptr=pp; + } + } + } + + j += processoption(&(cfgoptions[n]), valptr); + + if ( valptr != NULL ) { + i++; + config_get_if()->argv_info[i] |= CONFIG_CMDLINEOPT_PROCESSED; + c--; + } + + break; + } + } /* for n... */ + } /* if (oneargv[0] == '-') */ + + free(oneargv); + i++; + c--; + } /* fin du while */ + printf_cmdl("[CONFIG] %s %i options set from command line\n",((prefix == NULL) ? "(root)":prefix),j); + if ( !(CONFIG_ISFLAGSET( CONFIG_NOCHECKUNKOPT )) ) { - i=config_check_cmdlineopt(prefix); - if (i > 0) { - fprintf(stderr,"[CONFIG] %i unknown options for section %s detected in command line\n", - i,((prefix==NULL)?"\"root section\"":prefix)); - exit_fun(" Exiting after detecting errors in command line \n"); - } + i=config_check_cmdlineopt(prefix); + + if (i > 0) { + fprintf(stderr,"[CONFIG] %i unknown options for section %s detected in command line\n", + i,((prefix==NULL)?"\"root section\"":prefix)); + exit_fun(" Exiting after detecting errors in command line \n"); + } } - return j; + + return j; } /* parse_cmdline*/ diff --git a/common/config/config_load_configmodule.c b/common/config/config_load_configmodule.c index 15211aec8a..e20672aa02 100644 --- a/common/config/config_load_configmodule.c +++ b/common/config/config_load_configmodule.c @@ -20,7 +20,7 @@ */ /*! \file common/config/config_load_configmodule.c - * \brief configuration module, load the shared library implementing the configuration module + * \brief configuration module, load the shared library implementing the configuration module * \author Francois TABURET * \date 2017 * \version 0.1 @@ -42,293 +42,314 @@ #include "config_userapi.h" #define CONFIG_SHAREDLIBFORMAT "libparams_%s.so" -int load_config_sharedlib(configmodule_interface_t *cfgptr) -{ -void *lib_handle; -char fname[128]; -char libname[FILENAME_MAX]; -int st; +int load_config_sharedlib(configmodule_interface_t *cfgptr) { + void *lib_handle; + char fname[128]; + char libname[FILENAME_MAX]; + int st; + st=0; + sprintf(libname,CONFIG_SHAREDLIBFORMAT,cfgptr->cfgmode); + lib_handle = dlopen(libname,RTLD_NOW | RTLD_GLOBAL | RTLD_NODELETE); - st=0; - sprintf(libname,CONFIG_SHAREDLIBFORMAT,cfgptr->cfgmode); + if (!lib_handle) { + fprintf(stderr,"[CONFIG] %s %d Error calling dlopen(%s): %s\n",__FILE__, __LINE__, libname,dlerror()); + st = -1; + } else { + sprintf (fname,"config_%s_init",cfgptr->cfgmode); + cfgptr->init = dlsym(lib_handle,fname); - lib_handle = dlopen(libname,RTLD_NOW | RTLD_GLOBAL | RTLD_NODELETE); - if (!lib_handle) { - fprintf(stderr,"[CONFIG] %s %d Error calling dlopen(%s): %s\n",__FILE__, __LINE__, libname,dlerror()); + if (cfgptr->init == NULL ) { + printf("[CONFIG] %s %d no function %s for config mode %s\n", + __FILE__, __LINE__,fname, cfgptr->cfgmode); + } else { + st=cfgptr->init(cfgptr->cfgP,cfgptr->num_cfgP); + printf("[CONFIG] function %s returned %i\n", + fname, st); + } + + sprintf (fname,"config_%s_get",cfgptr->cfgmode); + cfgptr->get = dlsym(lib_handle,fname); + + if (cfgptr->get == NULL ) { + printf("[CONFIG] %s %d no function %s for config mode %s\n", + __FILE__, __LINE__,fname, cfgptr->cfgmode); st = -1; - } else { - sprintf (fname,"config_%s_init",cfgptr->cfgmode); - cfgptr->init = dlsym(lib_handle,fname); + } - if (cfgptr->init == NULL ) { - printf("[CONFIG] %s %d no function %s for config mode %s\n", - __FILE__, __LINE__,fname, cfgptr->cfgmode); - } else { - st=cfgptr->init(cfgptr->cfgP,cfgptr->num_cfgP); - printf("[CONFIG] function %s returned %i\n", - fname, st); - } + sprintf (fname,"config_%s_getlist",cfgptr->cfgmode); + cfgptr->getlist = dlsym(lib_handle,fname); - sprintf (fname,"config_%s_get",cfgptr->cfgmode); - cfgptr->get = dlsym(lib_handle,fname); - if (cfgptr->get == NULL ) { - printf("[CONFIG] %s %d no function %s for config mode %s\n", - __FILE__, __LINE__,fname, cfgptr->cfgmode); - st = -1; - } - - sprintf (fname,"config_%s_getlist",cfgptr->cfgmode); - cfgptr->getlist = dlsym(lib_handle,fname); - if (cfgptr->getlist == NULL ) { - printf("[CONFIG] %s %d no function %s for config mode %s\n", - __FILE__, __LINE__,fname, cfgptr->cfgmode); - st = -1; - } + if (cfgptr->getlist == NULL ) { + printf("[CONFIG] %s %d no function %s for config mode %s\n", + __FILE__, __LINE__,fname, cfgptr->cfgmode); + st = -1; + } - sprintf (fname,"config_%s_end",cfgptr->cfgmode); - cfgptr->end = dlsym(lib_handle,fname); - if (cfgptr->getlist == NULL ) { - printf("[CONFIG] %s %d no function %s for config mode %s\n", - __FILE__, __LINE__,fname, cfgptr->cfgmode); - } - } - - return st; + sprintf (fname,"config_%s_end",cfgptr->cfgmode); + cfgptr->end = dlsym(lib_handle,fname); + + if (cfgptr->getlist == NULL ) { + printf("[CONFIG] %s %d no function %s for config mode %s\n", + __FILE__, __LINE__,fname, cfgptr->cfgmode); + } + } + + return st; } /*-----------------------------------------------------------------------------------*/ /* from here: interface implementtion of the configuration module */ int nooptfunc(void) { - return 0; + return 0; }; -int config_cmdlineonly_getlist(paramlist_def_t *ParamList, - paramdef_t *params, int numparams, char *prefix) -{ - ParamList->numelt = 0; - return 0; +int config_cmdlineonly_getlist(paramlist_def_t *ParamList, + paramdef_t *params, int numparams, char *prefix) { + ParamList->numelt = 0; + return 0; } -int config_cmdlineonly_get(paramdef_t *cfgoptions,int numoptions, char *prefix ) -{ +int config_cmdlineonly_get(paramdef_t *cfgoptions,int numoptions, char *prefix ) { int defval; int fatalerror=0; int numdefvals=0; - - for(int i=0;i option, default cfgmode to libconfig - with one parameter, the path to the configuration file cfgmode must not be NULL */ - modeparams=cfgmode; - cfgmode=strdup(CONFIG_LIBCONFIGFILE); - } - cfgptr = calloc(sizeof(configmodule_interface_t),1); - cfgptr->argv_info = calloc(sizeof(int32_t), argc); - cfgptr->argv_info[0] |= CONFIG_CMDLINEOPT_PROCESSED; - if (OoptIdx >= 0) { - cfgptr->argv_info[OoptIdx] |= CONFIG_CMDLINEOPT_PROCESSED; - cfgptr->argv_info[OoptIdx+1] |= CONFIG_CMDLINEOPT_PROCESSED; - } + /* look for the OAI_CONFIGMODULE environement variable */ + if ( cfgparam == NULL ) { + cfgparam = getenv("OAI_CONFIGMODULE"); + } - cfgptr->rtflags = cfgptr->rtflags | tmpflags; - cfgptr->argc = argc; - cfgptr->argv = argv; - cfgptr->cfgmode=strdup(cfgmode); - cfgptr->num_cfgP=0; - atoken=strtok_r(modeparams,":",&strtokctx); - while ( cfgptr->num_cfgP< CONFIG_MAX_OOPT_PARAMS && atoken != NULL) { - /* look for debug level in the config parameters, it is commom to all config mode - and will be removed frome the parameter array passed to the shared module */ - char *aptr; - aptr=strcasestr(atoken,"dbgl"); - if (aptr != NULL) { - cfgptr->rtflags = cfgptr->rtflags | strtol(aptr+4,NULL,0); + /* default different for UE and softmodem because UE doesn't use config file*/ + /* and -O option is not mandatory for UE */ + /* phy simulators behave as UE */ + /* test of exec name would better be replaced by a parameter to the l */ + /* oad_configmodule function */ + if (cfgparam == NULL) { + tmpflags = tmpflags | CONFIG_NOOOPT; - } else { - cfgptr->cfgP[cfgptr->num_cfgP] = strdup(atoken); - cfgptr->num_cfgP++; - } - atoken = strtok_r(NULL,":",&strtokctx); - } + if ( initflags & CONFIG_ENABLECMDLINEONLY) { + cfgparam = CONFIG_CMDLINEONLY ":dbgl0" ; + } else { + cfgparam = CONFIG_CMDLINEONLY ":dbgl0" ; + cfgparam = CONFIG_LIBCONFIGFILE ":" DEFAULT_CFGFILENAME; + } + } - - printf("[CONFIG] get parameters from %s ",cfgmode); - for (i=0;inum_cfgP; i++) { - printf("%s ",cfgptr->cfgP[i]); - } - printf(", debug flags: 0x%08x\n",cfgptr->rtflags); + /* parse the config parameters to set the config source */ + i = sscanf(cfgparam,"%m[^':']:%ms",&cfgmode,&modeparams); - if (strstr(cfgparam,CONFIG_CMDLINEONLY) == NULL) { - i=load_config_sharedlib(cfgptr); - if (i == 0) { - printf("[CONFIG] config module %s loaded\n",cfgmode); - Config_Params[CONFIGPARAM_DEBUGFLAGS_IDX].uptr=&(cfgptr->rtflags); - config_get(Config_Params,CONFIG_PARAMLENGTH(Config_Params), CONFIG_SECTIONNAME ); - } else { - fprintf(stderr,"[CONFIG] %s %d config module \"%s\" couldn't be loaded\n", __FILE__, __LINE__,cfgmode); - cfgptr->rtflags = cfgptr->rtflags | CONFIG_HELP | CONFIG_ABORT; - } - } else { - cfgptr->init = (configmodule_initfunc_t)nooptfunc; - cfgptr->get = config_cmdlineonly_get; - cfgptr->getlist = config_cmdlineonly_getlist; - cfgptr->end = (configmodule_endfunc_t)nooptfunc; - } + if (i< 0) { + fprintf(stderr,"[CONFIG] %s, %d, sscanf error parsing config source %s: %s\n", __FILE__, __LINE__,cfgparam, strerror(errno)); + exit(-1) ; + } else if ( i == 1 ) { + /* -O argument doesn't contain ":" separator, assume -O option, default cfgmode to libconfig + with one parameter, the path to the configuration file cfgmode must not be NULL */ + modeparams=cfgmode; + cfgmode=strdup(CONFIG_LIBCONFIGFILE); + } - + cfgptr = calloc(sizeof(configmodule_interface_t),1); + cfgptr->argv_info = calloc(sizeof(int32_t), argc); + cfgptr->argv_info[0] |= CONFIG_CMDLINEOPT_PROCESSED; - if (modeparams != NULL) free(modeparams); - if (cfgmode != NULL) free(cfgmode); - if (CONFIG_ISFLAGSET(CONFIG_ABORT)) { - config_printhelp(Config_Params,CONFIG_PARAMLENGTH(Config_Params)); -// exit(-1); - } - return cfgptr; + if (OoptIdx >= 0) { + cfgptr->argv_info[OoptIdx] |= CONFIG_CMDLINEOPT_PROCESSED; + cfgptr->argv_info[OoptIdx+1] |= CONFIG_CMDLINEOPT_PROCESSED; + } + + cfgptr->rtflags = cfgptr->rtflags | tmpflags; + cfgptr->argc = argc; + cfgptr->argv = argv; + cfgptr->cfgmode=strdup(cfgmode); + cfgptr->num_cfgP=0; + atoken=strtok_r(modeparams,":",&strtokctx); + + while ( cfgptr->num_cfgP< CONFIG_MAX_OOPT_PARAMS && atoken != NULL) { + /* look for debug level in the config parameters, it is commom to all config mode + and will be removed frome the parameter array passed to the shared module */ + char *aptr; + aptr=strcasestr(atoken,"dbgl"); + + if (aptr != NULL) { + cfgptr->rtflags = cfgptr->rtflags | strtol(aptr+4,NULL,0); + } else { + cfgptr->cfgP[cfgptr->num_cfgP] = strdup(atoken); + cfgptr->num_cfgP++; + } + + atoken = strtok_r(NULL,":",&strtokctx); + } + + printf("[CONFIG] get parameters from %s ",cfgmode); + + for (i=0; inum_cfgP; i++) { + printf("%s ",cfgptr->cfgP[i]); + } + + printf(", debug flags: 0x%08x\n",cfgptr->rtflags); + + if (strstr(cfgparam,CONFIG_CMDLINEONLY) == NULL) { + i=load_config_sharedlib(cfgptr); + + if (i == 0) { + printf("[CONFIG] config module %s loaded\n",cfgmode); + Config_Params[CONFIGPARAM_DEBUGFLAGS_IDX].uptr=&(cfgptr->rtflags); + config_get(Config_Params,CONFIG_PARAMLENGTH(Config_Params), CONFIG_SECTIONNAME ); + } else { + fprintf(stderr,"[CONFIG] %s %d config module \"%s\" couldn't be loaded\n", __FILE__, __LINE__,cfgmode); + cfgptr->rtflags = cfgptr->rtflags | CONFIG_HELP | CONFIG_ABORT; + } + } else { + cfgptr->init = (configmodule_initfunc_t)nooptfunc; + cfgptr->get = config_cmdlineonly_get; + cfgptr->getlist = config_cmdlineonly_getlist; + cfgptr->end = (configmodule_endfunc_t)nooptfunc; + } + + if (modeparams != NULL) free(modeparams); + + if (cfgmode != NULL) free(cfgmode); + + if (CONFIG_ISFLAGSET(CONFIG_ABORT)) { + config_printhelp(Config_Params,CONFIG_PARAMLENGTH(Config_Params)); + // exit(-1); + } + + return cfgptr; } /* free memory allocated when reading parameters */ /* config module could be initialized again after this call */ -void end_configmodule(void) -{ +void end_configmodule(void) { if (cfgptr != NULL) { - if (cfgptr->end != NULL) { - printf ("[CONFIG] calling config module end function...\n"); - cfgptr->end(); - } + if (cfgptr->end != NULL) { + printf ("[CONFIG] calling config module end function...\n"); + cfgptr->end(); + } - printf ("[CONFIG] free %u config value pointers\n",cfgptr->numptrs); - for(int i=0; inumptrs ; i++) { - if (cfgptr->ptrs[i] != NULL) { - free(cfgptr->ptrs[i]); - cfgptr->ptrs[i]=NULL; - } + printf ("[CONFIG] free %u config value pointers\n",cfgptr->numptrs); + + for(int i=0; inumptrs ; i++) { + if (cfgptr->ptrs[i] != NULL) { + free(cfgptr->ptrs[i]); + cfgptr->ptrs[i]=NULL; } - cfgptr->numptrs=0; + } + + cfgptr->numptrs=0; } } /* free all memory used by config module */ /* should be called only at program exit */ -void free_configmodule(void) -{ +void free_configmodule(void) { if (cfgptr != NULL) { - end_configmodule(); - if( cfgptr->cfgmode != NULL) free(cfgptr->cfgmode); - printf ("[CONFIG] free %u config parameter pointers\n",cfgptr->num_cfgP); - for (int i=0; inum_cfgP; i++) { - if ( cfgptr->cfgP[i] != NULL) free(cfgptr->cfgP[i]); - } + end_configmodule(); + if( cfgptr->cfgmode != NULL) free(cfgptr->cfgmode); - free(cfgptr); - cfgptr=NULL; + printf ("[CONFIG] free %u config parameter pointers\n",cfgptr->num_cfgP); + + for (int i=0; inum_cfgP; i++) { + if ( cfgptr->cfgP[i] != NULL) free(cfgptr->cfgP[i]); + } + + free(cfgptr); + cfgptr=NULL; } } diff --git a/common/config/config_load_configmodule.h b/common/config/config_load_configmodule.h index d98e825095..2f5c055a00 100644 --- a/common/config/config_load_configmodule.h +++ b/common/config/config_load_configmodule.h @@ -20,8 +20,8 @@ */ /*! \file common/config/config_load_configmodule.h - * \brief: configuration module, include file to be used by the source code calling the - * configuration module initialization + * \brief: configuration module, include file to be used by the source code calling the + * configuration module initialization * \author Francois TABURET * \date 2017 * \version 0.1 @@ -31,7 +31,7 @@ * \warning */ #ifndef INCLUDE_CONFIG_LOADCONFIGMODULE_H -#define INCLUDE_CONFIG_LOADCONFIGMODULE_H +#define INCLUDE_CONFIG_LOADCONFIGMODULE_H #include @@ -61,8 +61,7 @@ typedef int(*configmodule_initfunc_t)(char *cfgP[],int numP); typedef int(*configmodule_getfunc_t)(paramdef_t *,int numparams, char *prefix); typedef int(*configmodule_getlistfunc_t)(paramlist_def_t *, paramdef_t *,int numparams, char *prefix); typedef void(*configmodule_endfunc_t)(void); -typedef struct configmodule_interface -{ +typedef struct configmodule_interface { int argc; char **argv; uint32_t *argv_info; @@ -75,7 +74,7 @@ typedef struct configmodule_interface configmodule_endfunc_t end; uint32_t numptrs; uint32_t rtflags; - char *ptrs[CONFIG_MAX_ALLOCATEDPTRS]; + char *ptrs[CONFIG_MAX_ALLOCATEDPTRS]; } configmodule_interface_t; #ifdef CONFIG_LOADCONFIG_MAIN @@ -85,17 +84,17 @@ static char config_helpstr [] = "\n lte-softmodem -O [config mode]<:dbgl[debugfl debugflags can also be defined in the config_libconfig section of the config file\n \ debugflags: mask, 1->print parameters, 2->print memory allocations debug messages\n \ 4->print command line processing debug messages\n "; - + #define CONFIG_SECTIONNAME "config" #define CONFIGPARAM_DEBUGFLAGS_IDX 0 static paramdef_t Config_Params[] = { -/*-----------------------------------------------------------------------------------------------------------------------*/ -/* config parameters for config module */ -/* optname helpstr paramflags XXXptr defXXXval type numelt */ -/*-----------------------------------------------------------------------------------------------------------------------*/ -{"debugflags", config_helpstr, 0, uptr:NULL, defintval:0, TYPE_MASK, 0}, + /*-----------------------------------------------------------------------------------------------------------------------*/ + /* config parameters for config module */ + /* optname helpstr paramflags XXXptr defXXXval type numelt */ + /*-----------------------------------------------------------------------------------------------------------------------*/ + {"debugflags", config_helpstr, 0, uptr:NULL, defintval:0, TYPE_MASK, 0}, }; #else @@ -104,7 +103,7 @@ extern configmodule_interface_t *cfgptr; #define printf_params(...) if ( (cfgptr->rtflags & (CONFIG_PRINTPARAMS)) != 0 ) { printf ( __VA_ARGS__ ); } -#define printf_ptrs(...) if ( (cfgptr->rtflags & (CONFIG_DEBUGPTR)) != 0 ) { printf ( __VA_ARGS__ ); } +#define printf_ptrs(...) if ( (cfgptr->rtflags & (CONFIG_DEBUGPTR)) != 0 ) { printf ( __VA_ARGS__ ); } #define printf_cmdl(...) if ( (cfgptr->rtflags & (CONFIG_DEBUGCMDLINE)) != 0 ) { printf ( __VA_ARGS__ ); } #define CONFIG_ENABLECMDLINEONLY (1<<1) diff --git a/common/config/config_paramdesc.h b/common/config/config_paramdesc.h index 60ab00a5ed..627c232f85 100644 --- a/common/config/config_paramdesc.h +++ b/common/config/config_paramdesc.h @@ -59,78 +59,77 @@ #define CONFIG_MAX_NUMCHECKVAL 20 typedef struct paramdef paramdef_t; typedef union checkedparam { - struct { - int (*f1)(paramdef_t *param); /* check an integer against a list of authorized values */ - int okintval[CONFIG_MAX_NUMCHECKVAL]; /* integer array, store possible values */ - int num_okintval; /* number of valid values in the checkingval array */ - } s1; - struct { - int (*f1a)(paramdef_t *param); /* check an integer against a list of authorized values and set param value */ - /* to the corresponding item in setintval array (mainly for RRC params) */ - int okintval[CONFIG_MAX_NUMCHECKVAL]; /* integer array, store possible values in config file */ - int setintval[CONFIG_MAX_NUMCHECKVAL]; /* integer array, values set in the paramdef structure */ - int num_okintval; /* number of valid values in the checkingval array */ - } s1a; - struct { - int (*f2)(paramdef_t *param); /* check an integer against an authorized range, defined by its min and max value */ - int okintrange[CONFIG_MAX_NUMCHECKVAL]; /* integer array, store min and max values */ - - } s2; - struct { - int (*f3)(paramdef_t *param); /* check a string against a list of authorized values */ - char *okstrval[CONFIG_MAX_NUMCHECKVAL]; /* string array, store possible values */ - int num_okstrval; /* number of valid values in the checkingval array */ - } s3; - struct { - int (*f3a)(paramdef_t *param); /* check a string against a list of authorized values and set param value */ - /* to the corresponding item in setintval array (mainly for RRC params) */ - char *okstrval[CONFIG_MAX_NUMCHECKVAL]; /* string array, store possible values */ - int setintval[CONFIG_MAX_NUMCHECKVAL]; /* integer array, values set in the paramdef structure */ - int num_okstrval; /* number of valid values in the checkingval array */ - } s3a; - struct { - int (*f4)(paramdef_t *param); /* generic check function, no arguments but the param description */ - - } s4; - struct { - void (*checkfunc)(void) ; - } s5; + struct { + int (*f1)(paramdef_t *param); /* check an integer against a list of authorized values */ + int okintval[CONFIG_MAX_NUMCHECKVAL]; /* integer array, store possible values */ + int num_okintval; /* number of valid values in the checkingval array */ + } s1; + struct { + int (*f1a)(paramdef_t *param); /* check an integer against a list of authorized values and set param value */ + /* to the corresponding item in setintval array (mainly for RRC params) */ + int okintval[CONFIG_MAX_NUMCHECKVAL]; /* integer array, store possible values in config file */ + int setintval[CONFIG_MAX_NUMCHECKVAL]; /* integer array, values set in the paramdef structure */ + int num_okintval; /* number of valid values in the checkingval array */ + } s1a; + struct { + int (*f2)(paramdef_t *param); /* check an integer against an authorized range, defined by its min and max value */ + int okintrange[CONFIG_MAX_NUMCHECKVAL]; /* integer array, store min and max values */ + + } s2; + struct { + int (*f3)(paramdef_t *param); /* check a string against a list of authorized values */ + char *okstrval[CONFIG_MAX_NUMCHECKVAL]; /* string array, store possible values */ + int num_okstrval; /* number of valid values in the checkingval array */ + } s3; + struct { + int (*f3a)(paramdef_t *param); /* check a string against a list of authorized values and set param value */ + /* to the corresponding item in setintval array (mainly for RRC params) */ + char *okstrval[CONFIG_MAX_NUMCHECKVAL]; /* string array, store possible values */ + int setintval[CONFIG_MAX_NUMCHECKVAL]; /* integer array, values set in the paramdef structure */ + int num_okstrval; /* number of valid values in the checkingval array */ + } s3a; + struct { + int (*f4)(paramdef_t *param); /* generic check function, no arguments but the param description */ + + } s4; + struct { + void (*checkfunc)(void) ; + } s5; } checkedparam_t; /* paramdef is used to describe a parameter, array of paramdef_t strustures is used as the main parameter in */ /* config apis used to retrieve parameters values */ -typedef struct paramdef -{ - char optname[MAX_OPTNAME_SIZE]; /* parameter name, can be used as long command line option */ - char *helpstr; /* help string */ - unsigned int paramflags; /* value is a "ored" combination of above PARAMFLAG_XXXX values */ - union { /* pointer to the parameter value, completed by the config module */ - char **strptr; - char **strlistptr; - uint8_t *u8ptr; - int8_t *i8ptr; - uint16_t *u16ptr; - int16_t *i16ptr; - uint32_t *uptr; - int32_t *iptr; - uint64_t *u64ptr; - int64_t *i64ptr; - double *dblptr; - void *voidptr; - } ; - union { /* default parameter value, to be used when PARAMFLAG_MANDATORY is not specified */ - char *defstrval; - char **defstrlistval; - uint32_t defuintval; - int defintval; - uint64_t defint64val; - int *defintarrayval; - double defdblval; - } ; - char type; /* parameter value type, as listed below as TYPE_XXXX macro */ - int numelt; /* number of elements in a list or array parameters or max size of string value */ - checkedparam_t *chkPptr; /* possible pointer to the structure containing the info used to check parameter values */ - int *processedvalue; /* used to store integer values computed from string original value */ +typedef struct paramdef { + char optname[MAX_OPTNAME_SIZE]; /* parameter name, can be used as long command line option */ + char *helpstr; /* help string */ + unsigned int paramflags; /* value is a "ored" combination of above PARAMFLAG_XXXX values */ + union { /* pointer to the parameter value, completed by the config module */ + char **strptr; + char **strlistptr; + uint8_t *u8ptr; + int8_t *i8ptr; + uint16_t *u16ptr; + int16_t *i16ptr; + uint32_t *uptr; + int32_t *iptr; + uint64_t *u64ptr; + int64_t *i64ptr; + double *dblptr; + void *voidptr; + } ; + union { /* default parameter value, to be used when PARAMFLAG_MANDATORY is not specified */ + char *defstrval; + char **defstrlistval; + uint32_t defuintval; + int defintval; + uint64_t defint64val; + int *defintarrayval; + double defdblval; + } ; + char type; /* parameter value type, as listed below as TYPE_XXXX macro */ + int numelt; /* number of elements in a list or array parameters or max size of string value */ + checkedparam_t *chkPptr; /* possible pointer to the structure containing the info used to check parameter values */ + int *processedvalue; /* used to store integer values computed from string original value */ } paramdef_t; #define TYPE_INT TYPE_INT32 @@ -160,9 +159,9 @@ typedef struct paramdef #define ANY_IPV4ADDR_STRING "0.0.0.0" typedef struct paramlist_def { - char listname[MAX_OPTNAME_SIZE]; - paramdef_t **paramarray; - int numelt ; + char listname[MAX_OPTNAME_SIZE]; + paramdef_t **paramarray; + int numelt ; } paramlist_def_t; /* macro helpers for module users */ diff --git a/common/config/config_userapi.c b/common/config/config_userapi.c index d6e4beeaf5..afbe1ae887 100644 --- a/common/config/config_userapi.c +++ b/common/config/config_userapi.c @@ -44,409 +44,449 @@ #include "config_userapi.h" -configmodule_interface_t *config_get_if(void) -{ - if (cfgptr == NULL) { - fprintf(stderr,"[CONFIG] %s %d config module not initialized\n",__FILE__, __LINE__); - exit(-1); - } - return cfgptr; -} - -char * config_check_valptr(paramdef_t *cfgoptions, char **ptr, int length) -{ - if (ptr == NULL ) { - ptr = malloc(sizeof(char *)); - if (ptr != NULL) { - *ptr=NULL; - cfgoptions->strptr=ptr; - if ( (cfgoptions->paramflags & PARAMFLAG_NOFREE) == 0) { - config_get_if()->ptrs[config_get_if()->numptrs] = (char *)ptr; - config_get_if()->numptrs++; - } - } else { - fprintf(stderr, "[CONFIG] %s %d option %s, cannot allocate pointer: %s \n", - __FILE__, __LINE__, cfgoptions->optname, strerror(errno)); - exit(-1); - } - } - printf_ptrs("[CONFIG] %s ptr: 0x%08lx requested size: %i\n",cfgoptions->optname,(uintptr_t)(ptr),length); - if(cfgoptions->numelt > 0 && PARAM_ISSCALAR(cfgoptions) ) { /* already allocated */ - if (*ptr != NULL) { - return *ptr; - } else { - fprintf(stderr,"[CONFIG] %s %d option %s, definition error: value pointer is NULL, declared as %i bytes allocated\n", - __FILE__, __LINE__,cfgoptions->optname, cfgoptions->numelt); - exit(-1); - } - } - - if (*ptr == NULL) { - *ptr = malloc(length); - if ( *ptr != NULL) { - memset(*ptr,0,length); - if ( (cfgoptions->paramflags & PARAMFLAG_NOFREE) == 0) { - config_get_if()->ptrs[config_get_if()->numptrs] = *ptr; - config_get_if()->numptrs++; - } - } else { - fprintf (stderr,"[CONFIG] %s %d malloc error\n",__FILE__, __LINE__); - exit(-1); - } - } - return *ptr; -} - -void config_assign_int(paramdef_t *cfgoptions, char *fullname, int val) -{ -int tmpval=val; - if ( ((cfgoptions->paramflags &PARAMFLAG_BOOL) != 0) && tmpval >0) { - tmpval =1; +configmodule_interface_t *config_get_if(void) { + if (cfgptr == NULL) { + fprintf(stderr,"[CONFIG] %s %d config module not initialized\n",__FILE__, __LINE__); + exit(-1); } + + return cfgptr; +} + +char *config_check_valptr(paramdef_t *cfgoptions, char **ptr, int length) { + if (ptr == NULL ) { + ptr = malloc(sizeof(char *)); + + if (ptr != NULL) { + *ptr=NULL; + cfgoptions->strptr=ptr; + + if ( (cfgoptions->paramflags & PARAMFLAG_NOFREE) == 0) { + config_get_if()->ptrs[config_get_if()->numptrs] = (char *)ptr; + config_get_if()->numptrs++; + } + } else { + fprintf(stderr, "[CONFIG] %s %d option %s, cannot allocate pointer: %s \n", + __FILE__, __LINE__, cfgoptions->optname, strerror(errno)); + exit(-1); + } + } + + printf_ptrs("[CONFIG] %s ptr: 0x%08lx requested size: %i\n",cfgoptions->optname,(uintptr_t)(ptr),length); + + if(cfgoptions->numelt > 0 && PARAM_ISSCALAR(cfgoptions) ) { /* already allocated */ + if (*ptr != NULL) { + return *ptr; + } else { + fprintf(stderr,"[CONFIG] %s %d option %s, definition error: value pointer is NULL, declared as %i bytes allocated\n", + __FILE__, __LINE__,cfgoptions->optname, cfgoptions->numelt); + exit(-1); + } + } + + if (*ptr == NULL) { + *ptr = malloc(length); + + if ( *ptr != NULL) { + memset(*ptr,0,length); + + if ( (cfgoptions->paramflags & PARAMFLAG_NOFREE) == 0) { + config_get_if()->ptrs[config_get_if()->numptrs] = *ptr; + config_get_if()->numptrs++; + } + } else { + fprintf (stderr,"[CONFIG] %s %d malloc error\n",__FILE__, __LINE__); + exit(-1); + } + } + + return *ptr; +} + +void config_assign_int(paramdef_t *cfgoptions, char *fullname, int val) { + int tmpval=val; + + if ( ((cfgoptions->paramflags &PARAMFLAG_BOOL) != 0) && tmpval >0) { + tmpval =1; + } + switch (cfgoptions->type) { - case TYPE_UINT8: - *(cfgoptions->u8ptr) = (uint8_t)tmpval; - printf_params("[CONFIG] %s: %u\n", fullname, (uint8_t)tmpval); - break; - case TYPE_INT8: - *(cfgoptions->i8ptr) = (int8_t)tmpval; - printf_params("[CONFIG] %s: %i\n", fullname, (int8_t)tmpval); - break; - case TYPE_UINT16: - *(cfgoptions->u16ptr) = (uint16_t)tmpval; - printf_params("[CONFIG] %s: %hu\n", fullname, (uint16_t)tmpval); - break; - case TYPE_INT16: - *(cfgoptions->i16ptr) = (int16_t)tmpval; - printf_params("[CONFIG] %s: %hi\n", fullname, (int16_t)tmpval); - break; - case TYPE_UINT32: - *(cfgoptions->uptr) = (uint32_t)tmpval; - printf_params("[CONFIG] %s: %u\n", fullname, (uint32_t)tmpval); - break; - case TYPE_MASK: - *(cfgoptions->uptr) = *(cfgoptions->uptr) | (uint32_t)tmpval; - printf_params("[CONFIG] %s: 0x%08x\n", fullname, (uint32_t)tmpval); - break; - case TYPE_INT32: - *(cfgoptions->iptr) = (int32_t)tmpval; - printf_params("[CONFIG] %s: %i\n", fullname, (int32_t)tmpval); - break; - default: - fprintf (stderr,"[CONFIG] %s %i type %i non integer parameter %s not assigned\n",__FILE__, __LINE__,cfgoptions->type,fullname); - break; + case TYPE_UINT8: + *(cfgoptions->u8ptr) = (uint8_t)tmpval; + printf_params("[CONFIG] %s: %u\n", fullname, (uint8_t)tmpval); + break; + + case TYPE_INT8: + *(cfgoptions->i8ptr) = (int8_t)tmpval; + printf_params("[CONFIG] %s: %i\n", fullname, (int8_t)tmpval); + break; + + case TYPE_UINT16: + *(cfgoptions->u16ptr) = (uint16_t)tmpval; + printf_params("[CONFIG] %s: %hu\n", fullname, (uint16_t)tmpval); + break; + + case TYPE_INT16: + *(cfgoptions->i16ptr) = (int16_t)tmpval; + printf_params("[CONFIG] %s: %hi\n", fullname, (int16_t)tmpval); + break; + + case TYPE_UINT32: + *(cfgoptions->uptr) = (uint32_t)tmpval; + printf_params("[CONFIG] %s: %u\n", fullname, (uint32_t)tmpval); + break; + + case TYPE_MASK: + *(cfgoptions->uptr) = *(cfgoptions->uptr) | (uint32_t)tmpval; + printf_params("[CONFIG] %s: 0x%08x\n", fullname, (uint32_t)tmpval); + break; + + case TYPE_INT32: + *(cfgoptions->iptr) = (int32_t)tmpval; + printf_params("[CONFIG] %s: %i\n", fullname, (int32_t)tmpval); + break; + + default: + fprintf (stderr,"[CONFIG] %s %i type %i non integer parameter %s not assigned\n",__FILE__, __LINE__,cfgoptions->type,fullname); + break; } } void config_assign_processedint(paramdef_t *cfgoption, int val) { - cfgoption->processedvalue = malloc(sizeof(int)); - if ( cfgoption->processedvalue != NULL) { - *(cfgoption->processedvalue) = val; - } else { - fprintf (stderr,"[CONFIG] %s %d malloc error\n",__FILE__, __LINE__); - exit(-1); - } + cfgoption->processedvalue = malloc(sizeof(int)); + + if ( cfgoption->processedvalue != NULL) { + *(cfgoption->processedvalue) = val; + } else { + fprintf (stderr,"[CONFIG] %s %d malloc error\n",__FILE__, __LINE__); + exit(-1); + } } int config_get_processedint(paramdef_t *cfgoption) { - int ret; - if ( cfgoption->processedvalue != NULL) { - ret=*(cfgoption->processedvalue); - free( cfgoption->processedvalue); - cfgoption->processedvalue=NULL; - printf_params("[CONFIG] %s: set from %s to %i\n",cfgoption->optname, *(cfgoption->strptr), ret); - } else { - fprintf (stderr,"[CONFIG] %s %d %s has no processed integer availablle\n",__FILE__, __LINE__, cfgoption->optname); - ret=0; - } -return ret; + int ret; + + if ( cfgoption->processedvalue != NULL) { + ret=*(cfgoption->processedvalue); + free( cfgoption->processedvalue); + cfgoption->processedvalue=NULL; + printf_params("[CONFIG] %s: set from %s to %i\n",cfgoption->optname, *(cfgoption->strptr), ret); + } else { + fprintf (stderr,"[CONFIG] %s %d %s has no processed integer availablle\n",__FILE__, __LINE__, cfgoption->optname); + ret=0; + } + + return ret; } -void config_printhelp(paramdef_t *params,int numparams) -{ - for (int i=0 ; is4.f4 != NULL) { - st += params[i].chkPptr->s4.f4(&(params[i])); - } - } - if (st != 0) { - fprintf(stderr,"[CONFIG] config_execcheck: section %s %i parameters with wrong value\n", prefix, -st); - if ( CONFIG_ISFLAGSET(CONFIG_NOABORTONCHKF) == 0) { - exit_fun("exit because configuration failed\n"); - } - } -return st; + for (int i=0 ; is4.f4 != NULL) { + st += params[i].chkPptr->s4.f4(&(params[i])); + } + } + + if (st != 0) { + fprintf(stderr,"[CONFIG] config_execcheck: section %s %i parameters with wrong value\n", prefix, -st); + + if ( CONFIG_ISFLAGSET(CONFIG_NOABORTONCHKF) == 0) { + exit_fun("exit because configuration failed\n"); + } + } + + return st; } -int config_get(paramdef_t *params,int numparams, char *prefix) -{ -int ret= -1; +int config_get(paramdef_t *params,int numparams, char *prefix) { + int ret= -1; if (CONFIG_ISFLAGSET(CONFIG_ABORT)) { fprintf(stderr,"[CONFIG] config_get, section %s skipped, config module not properly initialized\n",prefix); return ret; } + configmodule_interface_t *cfgif = config_get_if(); + if (cfgif != NULL) { ret = config_get_if()->get(params, numparams,prefix); + if (ret >= 0) { config_process_cmdline(params,numparams,prefix); config_execcheck(params,numparams,prefix); } + return ret; } + return ret; } -int config_getlist(paramlist_def_t *ParamList, paramdef_t *params, int numparams, char *prefix) -{ +int config_getlist(paramlist_def_t *ParamList, paramdef_t *params, int numparams, char *prefix) { if (CONFIG_ISFLAGSET(CONFIG_ABORT)) { fprintf(stderr,"[CONFIG] config_get skipped, config module not properly initialized\n"); return -1; } + if (!config_get_if()) return -1; const int ret = config_get_if()->getlist(ParamList, params, numparams, prefix); + if (ret >= 0 && params) { char *newprefix; + if (prefix) { int rc = asprintf(&newprefix, "%s.%s", prefix, ParamList->listname); + if (rc < 0) newprefix = NULL; } else { newprefix = ParamList->listname; } + char cfgpath[MAX_OPTNAME_SIZE*2 + 6]; /* prefix.listname.[listindex] */ + for (int i = 0; i < ParamList->numelt; ++i) { // TODO config_process_cmdline? sprintf(cfgpath, "%s.[%i]", newprefix, i); config_execcheck(ParamList->paramarray[i], numparams, cfgpath); } + if (prefix) free(newprefix); } + return ret; } -int config_isparamset(paramdef_t *params,int paramidx) -{ +int config_isparamset(paramdef_t *params,int paramidx) { if ((params[paramidx].paramflags & PARAMFLAG_PARAMSET) != 0) { - return 1; + return 1; } else { - return 0; + return 0; } } void print_intvalueerror(paramdef_t *param, char *fname, int *okval, int numokval) { - fprintf(stderr,"[CONFIG] %s: %s: %i invalid value, authorized values:\n ", - fname,param->optname, (int)*(param->uptr)); - for ( int i=0; ichkPptr->s1.num_okintval ; i++) { - if( *(param->uptr) == param->chkPptr->s1.okintval[i] ) { - return 0; - } - } - print_intvalueerror(param,"config_check_intval", param->chkPptr->s1.okintval,param->chkPptr->s1.num_okintval); - return -1; + fprintf(stderr,"[CONFIG] %s: %s: %i invalid value, authorized values:\n ", + fname,param->optname, (int)*(param->uptr)); + + for ( int i=0; ichkPptr->s1a.num_okintval ; i++) { - if (*(param->uptr) == param->chkPptr->s1a.okintval[i] ) { - printf_params("[CONFIG] %s: read value %i, set to %i\n",param->optname,*(param->uptr),param->chkPptr->s1a.setintval [i]); - *(param->uptr) = param->chkPptr->s1a.setintval [i]; - return 0; - } - } - print_intvalueerror(param,"config_check_modify_integer", param->chkPptr->s1a.okintval,param->chkPptr->s1a.num_okintval); +int config_check_intval(paramdef_t *param) { + if ( param == NULL ) { + fprintf(stderr,"[CONFIG] config_check_intval: NULL param argument\n"); return -1; + } + + for ( int i=0; ichkPptr->s1.num_okintval ; i++) { + if( *(param->uptr) == param->chkPptr->s1.okintval[i] ) { + return 0; + } + } + + print_intvalueerror(param,"config_check_intval", param->chkPptr->s1.okintval,param->chkPptr->s1.num_okintval); + return -1; } -int config_check_intrange(paramdef_t *param) -{ - if( *(param->iptr) >= param->chkPptr->s2.okintrange[0] && *(param->iptr) <= param->chkPptr->s2.okintrange[1] ) { - return 0; - } - fprintf(stderr,"[CONFIG] config_check_intrange: %s: %i invalid value, authorized range: %i %i\n", - param->optname, (int)*(param->uptr), param->chkPptr->s2.okintrange[0], param->chkPptr->s2.okintrange[1]); - return -1; +int config_check_modify_integer(paramdef_t *param) { + for (int i=0; i < param->chkPptr->s1a.num_okintval ; i++) { + if (*(param->uptr) == param->chkPptr->s1a.okintval[i] ) { + printf_params("[CONFIG] %s: read value %i, set to %i\n",param->optname,*(param->uptr),param->chkPptr->s1a.setintval [i]); + *(param->uptr) = param->chkPptr->s1a.setintval [i]; + return 0; + } + } + + print_intvalueerror(param,"config_check_modify_integer", param->chkPptr->s1a.okintval,param->chkPptr->s1a.num_okintval); + return -1; +} + +int config_check_intrange(paramdef_t *param) { + if( *(param->iptr) >= param->chkPptr->s2.okintrange[0] && *(param->iptr) <= param->chkPptr->s2.okintrange[1] ) { + return 0; + } + + fprintf(stderr,"[CONFIG] config_check_intrange: %s: %i invalid value, authorized range: %i %i\n", + param->optname, (int)*(param->uptr), param->chkPptr->s2.okintrange[0], param->chkPptr->s2.okintrange[1]); + return -1; } void print_strvalueerror(paramdef_t *param, char *fname, char **okval, int numokval) { - fprintf(stderr,"[CONFIG] %s: %s: %s invalid value, authorized values:\n ", - fname,param->optname, *(param->strptr)); - for ( int i=0; ioptname, *(param->strptr)); + + for ( int i=0; ichkPptr->s3.num_okstrval ; i++) { - if( strcasecmp(*(param->strptr),param->chkPptr->s3.okstrval[i] ) == 0) { - return 0; - } - } - print_strvalueerror(param, "config_check_strval", param->chkPptr->s3.okstrval, param->chkPptr->s3.num_okstrval); + +int config_check_strval(paramdef_t *param) { + if ( param == NULL ) { + fprintf(stderr,"[CONFIG] config_check_strval: NULL param argument\n"); return -1; + } + + for ( int i=0; ichkPptr->s3.num_okstrval ; i++) { + if( strcasecmp(*(param->strptr),param->chkPptr->s3.okstrval[i] ) == 0) { + return 0; + } + } + + print_strvalueerror(param, "config_check_strval", param->chkPptr->s3.okstrval, param->chkPptr->s3.num_okstrval); + return -1; } -int config_checkstr_assign_integer(paramdef_t *param) -{ +int config_checkstr_assign_integer(paramdef_t *param) { + for (int i=0; i < param->chkPptr->s3a.num_okstrval ; i++) { + if (strcasecmp(*(param->strptr),param->chkPptr->s3a.okstrval[i] ) == 0) { + config_assign_processedint(param, param->chkPptr->s3a.setintval[i]); + return 0; + } + } - - for (int i=0; i < param->chkPptr->s3a.num_okstrval ; i++) { - if (strcasecmp(*(param->strptr),param->chkPptr->s3a.okstrval[i] ) == 0) { - config_assign_processedint(param, param->chkPptr->s3a.setintval[i]); - return 0; - } - } - print_strvalueerror(param, "config_check_strval", param->chkPptr->s3a.okstrval, param->chkPptr->s3a.num_okstrval); - - return -1; + print_strvalueerror(param, "config_check_strval", param->chkPptr->s3a.okstrval, param->chkPptr->s3a.num_okstrval); + return -1; } -int config_setdefault_string(paramdef_t *cfgoptions, char *prefix) -{ +int config_setdefault_string(paramdef_t *cfgoptions, char *prefix) { int status = 0; + if( cfgoptions->defstrval != NULL) { - status=1; + status=1; - if (cfgoptions->numelt == 0 ) { - config_check_valptr(cfgoptions, (char **)(cfgoptions->strptr), sizeof(char *)); - config_check_valptr(cfgoptions, cfgoptions->strptr, strlen(cfgoptions->defstrval)+1); - sprintf(*(cfgoptions->strptr), "%s",cfgoptions->defstrval); - printf_params("[CONFIG] %s.%s set to default value \"%s\"\n", ((prefix == NULL) ? "" : prefix), cfgoptions->optname, *(cfgoptions->strptr)); - } else { - sprintf((char *)*(cfgoptions->strptr), "%s",cfgoptions->defstrval); - printf_params("[CONFIG] %s.%s set to default value \"%s\"\n", ((prefix == NULL) ? "" : prefix), cfgoptions->optname, (char *)*(cfgoptions->strptr)); - } + if (cfgoptions->numelt == 0 ) { + config_check_valptr(cfgoptions, (char **)(cfgoptions->strptr), sizeof(char *)); + config_check_valptr(cfgoptions, cfgoptions->strptr, strlen(cfgoptions->defstrval)+1); + sprintf(*(cfgoptions->strptr), "%s",cfgoptions->defstrval); + printf_params("[CONFIG] %s.%s set to default value \"%s\"\n", ((prefix == NULL) ? "" : prefix), cfgoptions->optname, *(cfgoptions->strptr)); + } else { + sprintf((char *)*(cfgoptions->strptr), "%s",cfgoptions->defstrval); + printf_params("[CONFIG] %s.%s set to default value \"%s\"\n", ((prefix == NULL) ? "" : prefix), cfgoptions->optname, (char *)*(cfgoptions->strptr)); + } } + return status; } -int config_setdefault_stringlist(paramdef_t *cfgoptions, char *prefix) -{ +int config_setdefault_stringlist(paramdef_t *cfgoptions, char *prefix) { int status = 0; + if( cfgoptions->defstrlistval != NULL) { - cfgoptions->strlistptr=cfgoptions->defstrlistval; - status=1; - for(int j=0; jnumelt; j++) - printf_params("[CONFIG] %s.%s[%i] set to default value %s\n", ((prefix == NULL) ? "" : prefix), cfgoptions->optname,j, cfgoptions->strlistptr[j]); + cfgoptions->strlistptr=cfgoptions->defstrlistval; + status=1; + + for(int j=0; jnumelt; j++) + printf_params("[CONFIG] %s.%s[%i] set to default value %s\n", ((prefix == NULL) ? "" : prefix), cfgoptions->optname,j, cfgoptions->strlistptr[j]); } + return status; } -int config_setdefault_int(paramdef_t *cfgoptions, char *prefix) -{ +int config_setdefault_int(paramdef_t *cfgoptions, char *prefix) { int status = 0; config_check_valptr(cfgoptions, (char **)(&(cfgoptions->iptr)),sizeof(int32_t)); - if( ((cfgoptions->paramflags & PARAMFLAG_MANDATORY) == 0)) { - config_assign_int(cfgoptions,cfgoptions->optname,cfgoptions->defintval); - status=1; - printf_params("[CONFIG] %s.%s set to default value\n", ((prefix == NULL) ? "" : prefix), cfgoptions->optname); - } - return status; -} -int config_setdefault_int64(paramdef_t *cfgoptions, char *prefix) -{ + if( ((cfgoptions->paramflags & PARAMFLAG_MANDATORY) == 0)) { + config_assign_int(cfgoptions,cfgoptions->optname,cfgoptions->defintval); + status=1; + printf_params("[CONFIG] %s.%s set to default value\n", ((prefix == NULL) ? "" : prefix), cfgoptions->optname); + } + + return status; +} + +int config_setdefault_int64(paramdef_t *cfgoptions, char *prefix) { int status = 0; config_check_valptr(cfgoptions, (char **)&(cfgoptions->i64ptr),sizeof(long long)); + if( ((cfgoptions->paramflags & PARAMFLAG_MANDATORY) == 0)) { - *(cfgoptions->u64ptr)=cfgoptions->defuintval; - status=1; - printf_params("[CONFIG] %s.%s set to default value %llu\n", ((prefix == NULL) ? "" : prefix), cfgoptions->optname, (long long unsigned)(*(cfgoptions->u64ptr))); + *(cfgoptions->u64ptr)=cfgoptions->defuintval; + status=1; + printf_params("[CONFIG] %s.%s set to default value %llu\n", ((prefix == NULL) ? "" : prefix), cfgoptions->optname, (long long unsigned)(*(cfgoptions->u64ptr))); } + return status; } -int config_setdefault_intlist(paramdef_t *cfgoptions, char *prefix) -{ - int status = 0; +int config_setdefault_intlist(paramdef_t *cfgoptions, char *prefix) { + int status = 0; + if( cfgoptions->defintarrayval != NULL) { - config_check_valptr(cfgoptions,(char **)&(cfgoptions->iptr), sizeof(int32_t*)); + config_check_valptr(cfgoptions,(char **)&(cfgoptions->iptr), sizeof(int32_t *)); cfgoptions->iptr=cfgoptions->defintarrayval; status=1; + for (int j=0; jnumelt ; j++) { - printf_params("[CONFIG] %s[%i] set to default value %i\n",cfgoptions->optname ,j,(int)cfgoptions->iptr[j]); + printf_params("[CONFIG] %s[%i] set to default value %i\n",cfgoptions->optname ,j,(int)cfgoptions->iptr[j]); } } + return status; } -int config_setdefault_double(paramdef_t *cfgoptions, char *prefix) -{ +int config_setdefault_double(paramdef_t *cfgoptions, char *prefix) { int status = 0; config_check_valptr(cfgoptions, (char **)&(cfgoptions->dblptr),sizeof(double)); - if( ((cfgoptions->paramflags & PARAMFLAG_MANDATORY) == 0)) { - *(cfgoptions->u64ptr)=cfgoptions->defdblval; - status=1; - printf_params("[CONFIG] %s set to default value %lf\n",cfgoptions->optname , *(cfgoptions->dblptr)); - } - return status; -} -int config_assign_ipv4addr(paramdef_t *cfgoptions, char *ipv4addr) -{ - config_check_valptr(cfgoptions,(char **)&(cfgoptions->uptr), sizeof(int)); - int rst=inet_pton(AF_INET, ipv4addr ,cfgoptions->uptr ); - if (rst == 1 && *(cfgoptions->uptr) > 0) { - printf_params("[CONFIG] %s: %s\n",cfgoptions->optname, ipv4addr); - return 1; - } else { - if ( strncmp(ipv4addr,ANY_IPV4ADDR_STRING,sizeof(ANY_IPV4ADDR_STRING)) == 0) { - printf_params("[CONFIG] %s:%s (INADDR_ANY) \n",cfgoptions->optname,ipv4addr); - *cfgoptions->uptr=INADDR_ANY; - return 1; - } else { - fprintf(stderr,"[CONFIG] %s not valid for %s \n", ipv4addr, cfgoptions->optname); - return -1; - } + if( ((cfgoptions->paramflags & PARAMFLAG_MANDATORY) == 0)) { + *(cfgoptions->u64ptr)=cfgoptions->defdblval; + status=1; + printf_params("[CONFIG] %s set to default value %lf\n",cfgoptions->optname , *(cfgoptions->dblptr)); } + + return status; +} + +int config_assign_ipv4addr(paramdef_t *cfgoptions, char *ipv4addr) { + config_check_valptr(cfgoptions,(char **)&(cfgoptions->uptr), sizeof(int)); + int rst=inet_pton(AF_INET, ipv4addr ,cfgoptions->uptr ); + + if (rst == 1 && *(cfgoptions->uptr) > 0) { + printf_params("[CONFIG] %s: %s\n",cfgoptions->optname, ipv4addr); + return 1; + } else { + if ( strncmp(ipv4addr,ANY_IPV4ADDR_STRING,sizeof(ANY_IPV4ADDR_STRING)) == 0) { + printf_params("[CONFIG] %s:%s (INADDR_ANY) \n",cfgoptions->optname,ipv4addr); + *cfgoptions->uptr=INADDR_ANY; + return 1; + } else { + fprintf(stderr,"[CONFIG] %s not valid for %s \n", ipv4addr, cfgoptions->optname); + return -1; + } + } + return 0; } -int config_setdefault_ipv4addr(paramdef_t *cfgoptions, char *prefix) -{ +int config_setdefault_ipv4addr(paramdef_t *cfgoptions, char *prefix) { int status = 0; - + if (cfgoptions->defstrval != NULL) { - status = config_assign_ipv4addr(cfgoptions, cfgoptions->defstrval); + status = config_assign_ipv4addr(cfgoptions, cfgoptions->defstrval); } + return status; -} +} diff --git a/common/config/config_userapi.h b/common/config/config_userapi.h index f4b592bafb..5542148343 100644 --- a/common/config/config_userapi.h +++ b/common/config/config_userapi.h @@ -20,7 +20,7 @@ */ /*! \file common/config/config_userapi.h - * \brief: configuration module, include file to be used by the source code calling the + * \brief: configuration module, include file to be used by the source code calling the * configuration module to access configuration parameters * \author Francois TABURET * \date 2017 @@ -31,7 +31,7 @@ * \warning */ #ifndef INCLUDE_CONFIG_USERAPI_H -#define INCLUDE_CONFIG_USERAPI_H +#define INCLUDE_CONFIG_USERAPI_H #include "config_load_configmodule.h" #ifdef __cplusplus @@ -48,7 +48,7 @@ extern "C" #define CONFIG_ISPARAMFLAGSET(P,F) ( !!(P.paramflags & F)) /* utility functions, to be used by configuration module and/or configuration libraries */ extern configmodule_interface_t *config_get_if(void); -extern char * config_check_valptr(paramdef_t *cfgoptions, char **ptr, int length) ; +extern char *config_check_valptr(paramdef_t *cfgoptions, char **ptr, int length) ; extern void config_printhelp(paramdef_t *,int numparams); extern int config_process_cmdline(paramdef_t *params,int numparams, char *prefix); extern void config_assign_processedint(paramdef_t *cfgoption, int val); diff --git a/common/utils/LOG/log.c b/common/utils/LOG/log.c index a65aa1e4a5..98f4b19f20 100644 --- a/common/utils/LOG/log.c +++ b/common/utils/LOG/log.c @@ -72,16 +72,14 @@ char *log_level_highlight_start[] = {LOG_RED, LOG_ORANGE, "", LOG_BLUE, LOG_CYBL char *log_level_highlight_end[] = {LOG_RESET,LOG_RESET,LOG_RESET, LOG_RESET,LOG_RESET}; /*!< \brief Optional end-format strings for highlighting */ -int write_file_matlab(const char *fname,const char *vname,void *data,int length,int dec,char format) -{ - +int write_file_matlab(const char *fname,const char *vname,void *data,int length,int dec,char format) { FILE *fp=NULL; int i; if (data == NULL) - return -1; - //printf("Writing %d elements of type %d to %s\n",length,format,fname); + return -1; + //printf("Writing %d elements of type %d to %s\n",length,format,fname); if (format == 10 || format ==11 || format == 12 || format == 13 || format == 14) { fp = fopen(fname,"a+"); @@ -89,8 +87,6 @@ int write_file_matlab(const char *fname,const char *vname,void *data,int length, fp = fopen(fname,"w+"); } - - if (fp== NULL) { printf("[OPENAIR][FILE OUTPUT] Cannot open file %s\n",fname); return(-1); @@ -99,121 +95,108 @@ int write_file_matlab(const char *fname,const char *vname,void *data,int length, if (format != 10 && format !=11 && format != 12 && format != 13 && format != 14) fprintf(fp,"%s = [",vname); - switch (format) { - case 0: // real 16-bit + case 0: // real 16-bit + for (i=0; i 0)) + fprintf(fp,"%d + j*(%d),",((short *)data)[i],((short *)data)[i+1]); + else if (i == 2*(length-1)) + fprintf(fp,"%d + j*(%d);",((short *)data)[i],((short *)data)[i+1]); + else if (i == 0) + fprintf(fp,"\n%d + j*(%d),",((short *)data)[i],((short *)data)[i+1]); + } - break; + break; - case 9: // real unsigned 8-bit - for (i=0; i 0)) + fprintf(fp,"%d,",((short *)data)[i]); + else if (i == (length-1)) + fprintf(fp,"%d;",((short *)data)[i]); + else if (i == 0) + fprintf(fp,"\n%d,",((short *)data)[i]); + } - break; - - - case 10 : // case eren 16 bit complex : - - for (i=0; i 0)) - fprintf(fp,"%d + j*(%d),",((short *)data)[i],((short *)data)[i+1]); - else if (i == 2*(length-1)) - fprintf(fp,"%d + j*(%d);",((short *)data)[i],((short *)data)[i+1]); - else if (i == 0) - fprintf(fp,"\n%d + j*(%d),",((short *)data)[i],((short *)data)[i+1]); - - - - } - - break; - - case 11 : //case eren 16 bit real for channel magnitudes: - for (i=0; i 0)) - fprintf(fp,"%d,",((short *)data)[i]); - else if (i == (length-1)) - fprintf(fp,"%d;",((short *)data)[i]); - else if (i == 0) - fprintf(fp,"\n%d,",((short *)data)[i]); - } - - printf("\n eren: length :%d",length); - break; - - case 12 : // case eren for log2_maxh real unsigned 8 bit - fprintf(fp,"%d \n",((unsigned char *)&data)[0]); - break; + printf("\n eren: length :%d",length); + break; + case 12 : // case eren for log2_maxh real unsigned 8 bit + fprintf(fp,"%d \n",((unsigned char *)&data)[0]); + break; } if (format != 10 && format !=11 && format !=12 && format != 13 && format != 15) { @@ -232,8 +215,6 @@ int write_file_matlab(const char *fname,const char *vname,void *data,int length, void log_getconfig(log_t *g_log) { char *gloglevel = NULL; int consolelog ; - - paramdef_t logparams_defaults[] = LOG_GLOBALPARAMS_DESC; paramdef_t logparams_level[MAX_LOG_PREDEF_COMPONENTS]; paramdef_t logparams_logfile[MAX_LOG_PREDEF_COMPONENTS]; @@ -241,131 +222,146 @@ void log_getconfig(log_t *g_log) { paramdef_t logparams_dump[sizeof(log_maskmap)/sizeof(mapping)]; CONFIG_SETRTFLAG(CONFIG_NOCHECKUNKOPT); int ret = config_get( logparams_defaults,sizeof(logparams_defaults)/sizeof(paramdef_t),CONFIG_STRING_LOG_PREFIX); - if (ret <0) { - fprintf(stderr,"[LOG] init aborted, configuration couldn't be performed"); - return; - } -/* set LOG display options (enable/disable color, thread name, level ) */ + if (ret <0) { + fprintf(stderr,"[LOG] init aborted, configuration couldn't be performed"); + return; + } + + /* set LOG display options (enable/disable color, thread name, level ) */ for(int i=0; iflag = g_log->flag | log_options[j].value; - break; - } else if (log_options[j+1].name == NULL){ - fprintf(stderr,"Unknown log option: %s\n",logparams_defaults[LOG_OPTIONS_IDX].strlistptr[i]); - exit(-1); - } - } - } - -/* build the parameter array for setting per component log level and infile options */ + for(int j=0; log_options[j].name != NULL ; j++) { + if (strcmp(logparams_defaults[LOG_OPTIONS_IDX].strlistptr[i],log_options[j].name) == 0) { + g_log->flag = g_log->flag | log_options[j].value; + break; + } else if (log_options[j+1].name == NULL) { + fprintf(stderr,"Unknown log option: %s\n",logparams_defaults[LOG_OPTIONS_IDX].strlistptr[i]); + exit(-1); + } + } + } + + /* build the parameter array for setting per component log level and infile options */ memset(logparams_level, 0, sizeof(paramdef_t)*MAX_LOG_PREDEF_COMPONENTS); memset(logparams_logfile, 0, sizeof(paramdef_t)*MAX_LOG_PREDEF_COMPONENTS); + for (int i=MIN_LOG_COMPONENTS; i < MAX_LOG_PREDEF_COMPONENTS; i++) { if(g_log->log_component[i].name == NULL) { - g_log->log_component[i].name = malloc(16); - sprintf((char *)g_log->log_component[i].name,"comp%i?",i); - logparams_logfile[i].paramflags = PARAMFLAG_DONOTREAD; - logparams_level[i].paramflags = PARAMFLAG_DONOTREAD; + g_log->log_component[i].name = malloc(16); + sprintf((char *)g_log->log_component[i].name,"comp%i?",i); + logparams_logfile[i].paramflags = PARAMFLAG_DONOTREAD; + logparams_level[i].paramflags = PARAMFLAG_DONOTREAD; } + sprintf(logparams_level[i].optname, LOG_CONFIG_LEVEL_FORMAT, g_log->log_component[i].name); sprintf(logparams_logfile[i].optname, LOG_CONFIG_LOGFILE_FORMAT, g_log->log_component[i].name); -/* workaround: all log options in existing configuration files use lower case component names - where component names include uppercase char in log.h.... */ - for (int j=0 ; jlog_component[i].level = map_str_to_int(log_level_names, *(logparams_level[i].strptr)); set_log(i, g_log->log_component[i].level); + if (*(logparams_logfile[i].uptr) == 1) - set_component_filelog(i); + set_component_filelog(i); } -/* build then read the debug and dump parameter array */ - for (int i=0;log_maskmap[i].name != NULL ; i++) { - sprintf(logparams_debug[i].optname, LOG_CONFIG_DEBUG_FORMAT, log_maskmap[i].name); - sprintf(logparams_dump[i].optname, LOG_CONFIG_DUMP_FORMAT, log_maskmap[i].name); - logparams_debug[i].defuintval = 0; - logparams_debug[i].type = TYPE_UINT; - logparams_debug[i].paramflags = PARAMFLAG_BOOL; - logparams_debug[i].uptr = NULL; - logparams_debug[i].chkPptr = NULL; - logparams_debug[i].numelt = 0; - logparams_dump[i].defuintval = 0; - logparams_dump[i].type = TYPE_UINT; - logparams_dump[i].paramflags = PARAMFLAG_BOOL; - logparams_dump[i].uptr = NULL; - logparams_dump[i].chkPptr = NULL; - logparams_dump[i].numelt = 0; + /* build then read the debug and dump parameter array */ + for (int i=0; log_maskmap[i].name != NULL ; i++) { + sprintf(logparams_debug[i].optname, LOG_CONFIG_DEBUG_FORMAT, log_maskmap[i].name); + sprintf(logparams_dump[i].optname, LOG_CONFIG_DUMP_FORMAT, log_maskmap[i].name); + logparams_debug[i].defuintval = 0; + logparams_debug[i].type = TYPE_UINT; + logparams_debug[i].paramflags = PARAMFLAG_BOOL; + logparams_debug[i].uptr = NULL; + logparams_debug[i].chkPptr = NULL; + logparams_debug[i].numelt = 0; + logparams_dump[i].defuintval = 0; + logparams_dump[i].type = TYPE_UINT; + logparams_dump[i].paramflags = PARAMFLAG_BOOL; + logparams_dump[i].uptr = NULL; + logparams_dump[i].chkPptr = NULL; + logparams_dump[i].numelt = 0; } + config_get( logparams_debug,(sizeof(log_maskmap)/sizeof(mapping)) - 1 ,CONFIG_STRING_LOG_PREFIX); CONFIG_CLEARRTFLAG(CONFIG_NOCHECKUNKOPT); config_get( logparams_dump,(sizeof(log_maskmap)/sizeof(mapping)) - 1 ,CONFIG_STRING_LOG_PREFIX); -/* set the debug mask according to the debug parameters values */ + + /* set the debug mask according to the debug parameters values */ for (int i=0; log_maskmap[i].name != NULL ; i++) { if (*(logparams_debug[i].uptr) ) - g_log->debug_mask = g_log->debug_mask | log_maskmap[i].value; + g_log->debug_mask = g_log->debug_mask | log_maskmap[i].value; + if (*(logparams_dump[i].uptr) ) - g_log->dump_mask = g_log->dump_mask | log_maskmap[i].value; - } -/* log globally enabled/disabled */ + g_log->dump_mask = g_log->dump_mask | log_maskmap[i].value; + } + + /* log globally enabled/disabled */ set_glog_onlinelog(consolelog); } -int register_log_component(char *name, char *fext, int compidx) -{ -int computed_compidx=compidx; +int register_log_component(char *name, char *fext, int compidx) { + int computed_compidx=compidx; if (strlen(fext) > 3) { - fext[3]=0; /* limit log file extension to 3 chars */ + fext[3]=0; /* limit log file extension to 3 chars */ } + if (compidx < 0) { /* this is not a pre-defined component */ - for (int i = MAX_LOG_PREDEF_COMPONENTS; i< MAX_LOG_COMPONENTS; i++) { - if (g_log->log_component[i].name == NULL) { - computed_compidx=i; - break; - } + for (int i = MAX_LOG_PREDEF_COMPONENTS; i< MAX_LOG_COMPONENTS; i++) { + if (g_log->log_component[i].name == NULL) { + computed_compidx=i; + break; } + } } + if (computed_compidx >= 0 && computed_compidx log_component[computed_compidx].name = strdup(name); - g_log->log_component[computed_compidx].stream = stdout; - g_log->log_component[computed_compidx].filelog = 0; - g_log->log_component[computed_compidx].filelog_name = malloc(strlen(name)+16);/* /tmp/.%s */ - sprintf(g_log->log_component[computed_compidx].filelog_name,"/tmp/%s.%s",name,fext); + g_log->log_component[computed_compidx].name = strdup(name); + g_log->log_component[computed_compidx].stream = stdout; + g_log->log_component[computed_compidx].filelog = 0; + g_log->log_component[computed_compidx].filelog_name = malloc(strlen(name)+16);/* /tmp/.%s */ + sprintf(g_log->log_component[computed_compidx].filelog_name,"/tmp/%s.%s",name,fext); } else { - fprintf(stderr,"{LOG} %s %d Couldn't register componemt %s\n",__FILE__,__LINE__,name); + fprintf(stderr,"{LOG} %s %d Couldn't register componemt %s\n",__FILE__,__LINE__,name); } -return computed_compidx; + + return computed_compidx; } -int isLogInitDone (void){ - if (g_log == NULL) - return 0; - if (!(g_log->flag & FLAG_INITIALIZED)) - return 0; - return 1; +int isLogInitDone (void) { + if (g_log == NULL) + return 0; + + if (!(g_log->flag & FLAG_INITIALIZED)) + return 0; + + return 1; } -int logInit (void) -{ +int logInit (void) { int i; g_log = calloc(1, sizeof(log_t)); @@ -373,10 +369,8 @@ int logInit (void) perror ("cannot allocated memory for log generation module \n"); exit(EXIT_FAILURE); } + memset(g_log,0,sizeof(log_t)); - - - register_log_component("PHY","log",PHY); register_log_component("MAC","log",MAC); register_log_component("OPT","log",OPT); @@ -392,144 +386,121 @@ int logInit (void) register_log_component("OTG_JITTER","dat",OTG_JITTER); register_log_component("OCG","",OCG); register_log_component("PERF","",PERF); - register_log_component("OIP","",OIP); - register_log_component("CLI","",CLI); - register_log_component("MSC","log",MSC); - register_log_component("OCM","log",OCM); - register_log_component("HW","",HW); - register_log_component("OSA","",OSA); - register_log_component("eRAL","",RAL_ENB); - register_log_component("mRAL","",RAL_UE); - register_log_component("ENB_APP","log",ENB_APP); - register_log_component("FLEXRAN_AGENT","log",FLEXRAN_AGENT); - register_log_component("TMR","",TMR); - register_log_component("USIM","txt",USIM); - register_log_component("SIM","txt",SIM); - + register_log_component("OIP","",OIP); + register_log_component("CLI","",CLI); + register_log_component("MSC","log",MSC); + register_log_component("OCM","log",OCM); + register_log_component("HW","",HW); + register_log_component("OSA","",OSA); + register_log_component("eRAL","",RAL_ENB); + register_log_component("mRAL","",RAL_UE); + register_log_component("ENB_APP","log",ENB_APP); + register_log_component("FLEXRAN_AGENT","log",FLEXRAN_AGENT); + register_log_component("TMR","",TMR); + register_log_component("USIM","txt",USIM); + register_log_component("SIM","txt",SIM); /* following log component are used for the localization*/ register_log_component("LOCALIZE","log",LOCALIZE); register_log_component("NAS","log",NAS); register_log_component("UDP","",UDP_); - - register_log_component("GTPV1U","",GTPU); - - register_log_component("S1AP","",S1AP); register_log_component("X2AP","",X2AP); - - register_log_component("SCTP","",SCTP); register_log_component("X2AP","",X2AP); register_log_component("LOADER","log",LOADER); register_log_component("ASN","log",ASN); - - for (int i=0 ; log_level_names[i].name != NULL ; i++) - g_log->level2string[i] = toupper(log_level_names[i].name[0]); // uppercased first letter of level name - - - - + g_log->level2string[i] = toupper(log_level_names[i].name[0]); // uppercased first letter of level name g_log->filelog_name = "/tmp/openair.log"; - log_getconfig(g_log); - - // set all unused component items to 0, they are for non predefined components for (i=MAX_LOG_PREDEF_COMPONENTS; i < MAX_LOG_COMPONENTS; i++) { - memset(&(g_log->log_component[i]),0,sizeof(log_component_t)); + memset(&(g_log->log_component[i]),0,sizeof(log_component_t)); } + g_log->flag = g_log->flag | FLAG_INITIALIZED; printf("log init done\n"); - return 0; } char *log_getthreadname(char *threadname, int bufsize) { + int rt = pthread_getname_np(pthread_self(), threadname,bufsize) ; -int rt = pthread_getname_np(pthread_self(), threadname,bufsize) ; - if (rt == 0) - { - return threadname; - } else { - return "thread?"; - } + if (rt == 0) { + return threadname; + } else { + return "thread?"; + } } static int log_header(char *log_buffer, int buffsize, int comp, int level,const char *format) { char threadname[PR_SET_NAME]; -return snprintf(log_buffer, buffsize , "%s%s[%s]%c %s %s%s", - log_level_highlight_end[level], - ( (g_log->flag & FLAG_NOCOLOR)?"":log_level_highlight_start[level]), - g_log->log_component[comp].name, - ( (g_log->flag & FLAG_LEVEL)?g_log->level2string[level]:' '), - ( (g_log->flag & FLAG_THREAD)?log_getthreadname(threadname,PR_SET_NAME+1):""), - format, - log_level_highlight_end[level]); + return snprintf(log_buffer, buffsize , "%s%s[%s]%c %s %s%s", + log_level_highlight_end[level], + ( (g_log->flag & FLAG_NOCOLOR)?"":log_level_highlight_start[level]), + g_log->log_component[comp].name, + ( (g_log->flag & FLAG_LEVEL)?g_log->level2string[level]:' '), + ( (g_log->flag & FLAG_THREAD)?log_getthreadname(threadname,PR_SET_NAME+1):""), + format, + log_level_highlight_end[level]); } -void logRecord_mt(const char *file, const char *func, int line, int comp, int level, const char* format, ... ) - { +void logRecord_mt(const char *file, const char *func, int line, int comp, int level, const char *format, ... ) { char log_buffer[MAX_LOG_TOTAL]; va_list args; - va_start(args, format); - - - - log_header(log_buffer,MAX_LOG_TOTAL ,comp, level,format); g_log->log_component[comp].vprint(g_log->log_component[comp].stream,log_buffer, args); va_end(args); - - } -void log_dump(int component, void *buffer, int buffsize,int datatype, const char* format, ... ) { -va_list args; -char *wbuf; +void log_dump(int component, void *buffer, int buffsize,int datatype, const char *format, ... ) { + va_list args; + char *wbuf; + switch(datatype) { + case LOG_DUMP_DOUBLE: + wbuf=malloc((buffsize * 10) + 64 + MAX_LOG_TOTAL); + break; - switch(datatype) { - case LOG_DUMP_DOUBLE: - wbuf=malloc((buffsize * 10) + 64 + MAX_LOG_TOTAL); - break; - case LOG_DUMP_CHAR: - default: - wbuf=malloc((buffsize * 3 ) + 64 + MAX_LOG_TOTAL); - break; + case LOG_DUMP_CHAR: + default: + wbuf=malloc((buffsize * 3 ) + 64 + MAX_LOG_TOTAL); + break; + } + + if (wbuf != NULL) { + va_start(args, format); + int pos=log_header(wbuf,MAX_LOG_TOTAL ,component, OAILOG_INFO,""); + int pos2=vsprintf(wbuf+pos,format, args); + pos=pos+pos2; + va_end(args); + + for (int i=0; ilog_component[component].print(g_log->log_component[component].stream,wbuf); free(wbuf); - } + } } -int set_log(int component, int level) -{ +int set_log(int component, int level) { /* Checking parameters */ DevCheck((component >= MIN_LOG_COMPONENTS) && (component < MAX_LOG_COMPONENTS), component, MIN_LOG_COMPONENTS, MAX_LOG_COMPONENTS); @@ -537,38 +508,34 @@ int set_log(int component, int level) OAILOG_ERR); if ( g_log->log_component[component].level != OAILOG_DISABLE ) - g_log->log_component[component].savedlevel = g_log->log_component[component].level; - g_log->log_component[component].level = level; + g_log->log_component[component].savedlevel = g_log->log_component[component].level; + g_log->log_component[component].level = level; return 0; } -void set_glog(int level) -{ +void set_glog(int level) { for (int c=0; c< MAX_LOG_COMPONENTS; c++ ) { - set_log(c, level); + set_log(c, level); } - } -void set_glog_onlinelog(int enable) -{ +void set_glog_onlinelog(int enable) { for (int c=0; c< MAX_LOG_COMPONENTS; c++ ) { - if ( enable ) { - g_log->log_component[c].level = g_log->log_component[c].savedlevel; - g_log->log_component[c].vprint = vfprintf; - g_log->log_component[c].print = fprintf; - g_log->log_component[c].stream = stdout; - } else { - g_log->log_component[c].level = OAILOG_DISABLE; - } - } + if ( enable ) { + g_log->log_component[c].level = g_log->log_component[c].savedlevel; + g_log->log_component[c].vprint = vfprintf; + g_log->log_component[c].print = fprintf; + g_log->log_component[c].stream = stdout; + } else { + g_log->log_component[c].level = OAILOG_DISABLE; + } + } } -void set_glog_filelog(int enable) -{ -static FILE *fptr; +void set_glog_filelog(int enable) { + static FILE *fptr; if ( enable ) { fptr = fopen(g_log->filelog_name,"w"); @@ -581,33 +548,35 @@ static FILE *fptr; } else { for (int c=0; c< MAX_LOG_COMPONENTS; c++ ) { g_log->log_component[c].filelog = 0; + if (fptr != NULL) { fclose(fptr); } + g_log->log_component[c].stream = stdout; - } - } + } + } } -void set_component_filelog(int comp) -{ - if (g_log->log_component[comp].stream == NULL || g_log->log_component[comp].stream == stdout) { - g_log->log_component[comp].stream = fopen(g_log->log_component[comp].filelog_name,"w"); - } - g_log->log_component[comp].vprint = vfprintf; - g_log->log_component[comp].print = fprintf; - g_log->log_component[comp].filelog = 1; +void set_component_filelog(int comp) { + if (g_log->log_component[comp].stream == NULL || g_log->log_component[comp].stream == stdout) { + g_log->log_component[comp].stream = fopen(g_log->log_component[comp].filelog_name,"w"); + } + + g_log->log_component[comp].vprint = vfprintf; + g_log->log_component[comp].print = fprintf; + g_log->log_component[comp].filelog = 1; } -void close_component_filelog(int comp) -{ - g_log->log_component[comp].filelog = 0; - if (g_log->log_component[comp].stream != NULL && g_log->log_component[comp].stream != stdout ) { - fclose(g_log->log_component[comp].stream); - g_log->log_component[comp].stream = stdout; - } - g_log->log_component[comp].vprint = vfprintf; - g_log->log_component[comp].print = fprintf; - +void close_component_filelog(int comp) { + g_log->log_component[comp].filelog = 0; + + if (g_log->log_component[comp].stream != NULL && g_log->log_component[comp].stream != stdout ) { + fclose(g_log->log_component[comp].stream); + g_log->log_component[comp].stream = stdout; + } + + g_log->log_component[comp].vprint = vfprintf; + g_log->log_component[comp].print = fprintf; } /* @@ -615,8 +584,7 @@ void close_component_filelog(int comp) * with string value NULL */ /* map a string to an int. Takes a mapping array and a string as arg */ -int map_str_to_int(mapping *map, const char *str) -{ +int map_str_to_int(mapping *map, const char *str) { while (1) { if (map->name == NULL) { return(-1); @@ -631,8 +599,7 @@ int map_str_to_int(mapping *map, const char *str) } /* map an int to a string. Takes a mapping array and a value */ -char *map_int_to_str(mapping *map, int val) -{ +char *map_int_to_str(mapping *map, int val) { while (1) { if (map->name == NULL) { return NULL; @@ -646,8 +613,7 @@ char *map_int_to_str(mapping *map, int val) } } -int is_newline( char *str, int size) -{ +int is_newline( char *str, int size) { int i; for ( i = 0; i < size; i++ ) { @@ -660,84 +626,65 @@ int is_newline( char *str, int size) return 0; } -void logClean (void) -{ +void logClean (void) { int i; if(isLogInitDone()) { LOG_UI(PHY,"\n"); + for (i=MIN_LOG_COMPONENTS; i < MAX_LOG_COMPONENTS; i++) { close_component_filelog(i); } } } - + #ifdef LOG_TEST -int main(int argc, char *argv[]) -{ - +int main(int argc, char *argv[]) { logInit(); - - test_log(); - return 1; } -int test_log(void) -{ +int test_log(void) { LOG_ENTER(MAC); // because the default level is DEBUG LOG_I(EMU, "1 Starting OAI logs version %s Build date: %s on %s\n", BUILD_VERSION, BUILD_DATE, BUILD_HOST); LOG_D(MAC, "1 debug MAC \n"); LOG_W(MAC, "1 warning MAC \n"); - set_log(EMU, OAILOG_INFO); set_log(MAC, OAILOG_WARNING); - LOG_I(EMU, "2 Starting OAI logs version %s Build date: %s on %s\n", BUILD_VERSION, BUILD_DATE, BUILD_HOST); LOG_E(MAC, "2 error MAC\n"); LOG_D(MAC, "2 debug MAC \n"); LOG_W(MAC, "2 warning MAC \n"); LOG_I(MAC, "2 info MAC \n"); - - set_log(MAC, OAILOG_NOTICE); - LOG_ENTER(MAC); LOG_I(EMU, "3 Starting OAI logs version %s Build date: %s on %s\n", BUILD_VERSION, BUILD_DATE, BUILD_HOST); LOG_D(MAC, "3 debug MAC \n"); LOG_W(MAC, "3 warning MAC \n"); LOG_I(MAC, "3 info MAC \n"); - set_log(MAC, LOG_DEBUG); set_log(EMU, LOG_DEBUG); - LOG_ENTER(MAC); LOG_I(EMU, "4 Starting OAI logs version %s Build date: %s on %s\n", BUILD_VERSION, BUILD_DATE, BUILD_HOST); LOG_D(MAC, "4 debug MAC \n"); LOG_W(MAC, "4 warning MAC \n"); LOG_I(MAC, "4 info MAC \n"); - - set_log(MAC, LOG_DEBUG); set_log(EMU, LOG_DEBUG); - LOG_I(LOG, "5 Starting OAI logs version %s Build date: %s on %s\n", BUILD_VERSION, BUILD_DATE, BUILD_HOST); LOG_D(MAC, "5 debug MAC \n"); LOG_W(MAC, "5 warning MAC \n"); LOG_I(MAC, "5 info MAC \n"); - - set_log(MAC, LOG_TRACE); set_log(EMU, LOG_TRACE); - LOG_ENTER(MAC); LOG_I(LOG, "6 Starting OAI logs version %s Build date: %s on %s\n", BUILD_VERSION, BUILD_DATE, BUILD_HOST); @@ -745,7 +692,6 @@ int test_log(void) LOG_W(MAC, "6 warning MAC \n"); LOG_I(MAC, "6 info MAC \n"); LOG_EXIT(MAC); - return 0; } #endif diff --git a/common/utils/LOG/log.h b/common/utils/LOG/log.h index 2a7a51a0a6..d0aa4a47c8 100644 --- a/common/utils/LOG/log.h +++ b/common/utils/LOG/log.h @@ -45,11 +45,11 @@ #include #include #ifndef __STDC_FORMAT_MACROS -#define __STDC_FORMAT_MACROS + #define __STDC_FORMAT_MACROS #endif #include #ifndef _GNU_SOURCE -#define _GNU_SOURCE + #define _GNU_SOURCE #endif #include #include "T.h" @@ -126,11 +126,11 @@ extern "C" { /** @defgroup macros to identify a debug entity * @ingroup each macro is a bit mask where the unique bit set identifies an entity to be debugged - * it allows to dynamically activate or not blocks of code. The LOG_MASKMAP_INIT macro + * it allows to dynamically activate or not blocks of code. The LOG_MASKMAP_INIT macro * is used to map a character string name to each debug bit, it allows to set or clear * the corresponding bit via the defined name, from the configuration or from the telnet * server. - * @brief + * @brief * @{*/ #define DEBUG_PRACH (1<<0) #define DEBUG_RU (1<<1) @@ -149,22 +149,22 @@ extern "C" { #define LOG_MASKMAP_INIT {\ - {"PRACH", DEBUG_PRACH},\ - {"RU", DEBUG_RU},\ - {"UE_PHYPROC", DEBUG_UE_PHYPROC},\ - {"LTEESTIM", DEBUG_LTEESTIM},\ - {"DLCELLSPEC", DEBUG_DLCELLSPEC},\ - {"ULSCH", DEBUG_ULSCH},\ - {"RRC", DEBUG_RRC},\ - {"PDCP", DEBUG_PDCP},\ - {"DFT", DEBUG_DFT},\ - {"ASN1", DEBUG_ASN1},\ - {"CTRLSOCKET", DEBUG_CTRLSOCKET},\ - {"SECURITY", DEBUG_SECURITY},\ - {"NAS", DEBUG_NAS},\ - {"UE_TIMING", UE_TIMING},\ - {NULL,-1}\ -} + {"PRACH", DEBUG_PRACH},\ + {"RU", DEBUG_RU},\ + {"UE_PHYPROC", DEBUG_UE_PHYPROC},\ + {"LTEESTIM", DEBUG_LTEESTIM},\ + {"DLCELLSPEC", DEBUG_DLCELLSPEC},\ + {"ULSCH", DEBUG_ULSCH},\ + {"RRC", DEBUG_RRC},\ + {"PDCP", DEBUG_PDCP},\ + {"DFT", DEBUG_DFT},\ + {"ASN1", DEBUG_ASN1},\ + {"CTRLSOCKET", DEBUG_CTRLSOCKET},\ + {"SECURITY", DEBUG_SECURITY},\ + {"NAS", DEBUG_NAS},\ + {"UE_TIMING", UE_TIMING},\ + {NULL,-1}\ + } @@ -177,46 +177,46 @@ extern "C" { typedef enum { - MIN_LOG_COMPONENTS = 0, - PHY = MIN_LOG_COMPONENTS, - MAC, - SIM, - OCG, - OMG, - OPT, - OTG, - OTG_LATENCY, - OTG_LATENCY_BG, - OTG_GP, - OTG_GP_BG, - OTG_JITTER, - RLC, - PDCP, - RRC, - NAS, - PERF, - OIP, - CLI, - MSC, - OCM, - UDP_, - GTPU, - SPGW, - S1AP, - SCTP, - HW, - OSA, - RAL_ENB, - RAL_UE, - ENB_APP, - FLEXRAN_AGENT, - TMR, - USIM, - LOCALIZE, - X2AP, - LOADER, - ASN, - MAX_LOG_PREDEF_COMPONENTS, + MIN_LOG_COMPONENTS = 0, + PHY = MIN_LOG_COMPONENTS, + MAC, + SIM, + OCG, + OMG, + OPT, + OTG, + OTG_LATENCY, + OTG_LATENCY_BG, + OTG_GP, + OTG_GP_BG, + OTG_JITTER, + RLC, + PDCP, + RRC, + NAS, + PERF, + OIP, + CLI, + MSC, + OCM, + UDP_, + GTPU, + SPGW, + S1AP, + SCTP, + HW, + OSA, + RAL_ENB, + RAL_UE, + ENB_APP, + FLEXRAN_AGENT, + TMR, + USIM, + LOCALIZE, + X2AP, + LOADER, + ASN, + MAX_LOG_PREDEF_COMPONENTS, } comp_name_t; @@ -225,42 +225,42 @@ comp_name_t; typedef struct { - char *name; /*!< \brief string name of item */ - int value; /*!< \brief integer value of mapping */ + char *name; /*!< \brief string name of item */ + int value; /*!< \brief integer value of mapping */ } mapping; typedef int(*log_vprint_func_t)(FILE *stream, const char *format, va_list ap ); typedef int(*log_print_func_t)(FILE *stream, const char *format, ... ); typedef struct { - const char *name; - int level; - int savedlevel; - int flag; - int filelog; - char *filelog_name; - FILE *stream; - log_vprint_func_t vprint; - log_print_func_t print; - /* SR: make the log buffer component relative */ - char log_buffer[MAX_LOG_TOTAL]; + const char *name; + int level; + int savedlevel; + int flag; + int filelog; + char *filelog_name; + FILE *stream; + log_vprint_func_t vprint; + log_print_func_t print; + /* SR: make the log buffer component relative */ + char log_buffer[MAX_LOG_TOTAL]; } log_component_t; typedef struct { - log_component_t log_component[MAX_LOG_COMPONENTS]; - char level2string[NUM_LOG_LEVEL]; - int flag; - char* filelog_name; - uint64_t debug_mask; - uint64_t dump_mask; + log_component_t log_component[MAX_LOG_COMPONENTS]; + char level2string[NUM_LOG_LEVEL]; + int flag; + char *filelog_name; + uint64_t debug_mask; + uint64_t dump_mask; } log_t; #if defined(ENABLE_ITTI) typedef enum log_instance_type_e { - LOG_INSTANCE_UNKNOWN, - LOG_INSTANCE_ENB, - LOG_INSTANCE_UE, + LOG_INSTANCE_UNKNOWN, + LOG_INSTANCE_ENB, + LOG_INSTANCE_UE, } log_instance_type_t; void log_set_instance_type (log_instance_type_t instance); @@ -271,9 +271,9 @@ void log_set_instance_type (log_instance_type_t instance); log_t *g_log; #else #ifdef __cplusplus - extern "C" { +extern "C" { #endif -extern log_t *g_log; + extern log_t *g_log; #ifdef __cplusplus } #endif @@ -284,7 +284,7 @@ extern log_t *g_log; int logInit (void); int isLogInitDone (void); void logRecord_mt(const char *file, const char *func, int line,int comp, int level, const char *format, ...) __attribute__ ((format (printf, 6, 7))); -void log_dump(int component, void *buffer, int buffsize,int datatype, const char* format, ... ); +void log_dump(int component, void *buffer, int buffsize,int datatype, const char *format, ... ); int set_log(int component, int level); void set_glog(int level); @@ -327,22 +327,22 @@ int32_t write_file_matlab(const char *fname, const char *vname, void *data, int #define LOG_CONFIG_DUMP_FORMAT "%s_dump" #define LOG_CONFIG_HELP_OPTIONS " list of comma separated options to enable log module behavior. Available options: \n"\ - " nocolor: disable color usage in log messages\n"\ - " level: add log level indication in log messages\n"\ - " thread: add threads names in log messages\n" - + " nocolor: disable color usage in log messages\n"\ + " level: add log level indication in log messages\n"\ + " thread: add threads names in log messages\n" + + - /*------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ -/* LOG globalconfiguration parameters */ -/* optname help paramflags XXXptr defXXXval type numelt */ +/* LOG globalconfiguration parameters */ +/* optname help paramflags XXXptr defXXXval type numelt */ /*------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ #define LOG_GLOBALPARAMS_DESC { \ -{LOG_CONFIG_STRING_GLOBAL_LOG_LEVEL, "Default log level for all componemts\n", 0, strptr:(char **)&gloglevel, defstrval:log_level_names[2].name, TYPE_STRING, 0}, \ -{LOG_CONFIG_STRING_GLOBAL_LOG_ONLINE, "Default console output option, for all components\n", 0, iptr:&(consolelog), defintval:1, TYPE_INT, 0}, \ -{LOG_CONFIG_STRING_GLOBAL_LOG_OPTIONS, LOG_CONFIG_HELP_OPTIONS, 0, strlistptr:NULL, defstrlistval:NULL, TYPE_STRINGLIST,0} \ -} + {LOG_CONFIG_STRING_GLOBAL_LOG_LEVEL, "Default log level for all componemts\n", 0, strptr:(char **)&gloglevel, defstrval:log_level_names[2].name, TYPE_STRING, 0}, \ + {LOG_CONFIG_STRING_GLOBAL_LOG_ONLINE, "Default console output option, for all components\n", 0, iptr:&(consolelog), defintval:1, TYPE_INT, 0}, \ + {LOG_CONFIG_STRING_GLOBAL_LOG_OPTIONS, LOG_CONFIG_HELP_OPTIONS, 0, strlistptr:NULL, defstrlistval:NULL, TYPE_STRINGLIST,0} \ + } #define LOG_OPTIONS_IDX 2 /*----------------------------------------------------------------------------------*/ @@ -354,23 +354,23 @@ int32_t write_file_matlab(const char *fname, const char *vname, void *data, int #define LOG_DUMP_DOUBLE 1 // debugging macros #define LOG_F LOG_I /* because LOG_F was originaly to dump a message or buffer but is also used as a regular level...., to dump use LOG_DUMPMSG */ -# if T_TRACER - /* per component, level dependant macros */ -# define LOG_E(c, x...) do { if (T_stdout) { if( g_log->log_component[c].level >= OAILOG_ERR ) logRecord_mt(__FILE__, __FUNCTION__, __LINE__,c, OAILOG_ERR, x) ;} else { T(T_LEGACY_ ## c ## _ERROR, T_PRINTF(x)) ;}} while (0) -# define LOG_W(c, x...) do { if (T_stdout) { if( g_log->log_component[c].level >= OAILOG_WARNING) logRecord_mt(__FILE__, __FUNCTION__, __LINE__,c, OAILOG_WARNING, x) ;} else { T(T_LEGACY_ ## c ## _WARNING, T_PRINTF(x)) ;}} while (0) -# define LOG_I(c, x...) do { if (T_stdout) { if( g_log->log_component[c].level >= OAILOG_INFO ) logRecord_mt(__FILE__, __FUNCTION__, __LINE__,c, OAILOG_INFO, x) ;} else { T(T_LEGACY_ ## c ## _INFO, T_PRINTF(x)) ;}} while (0) -# define LOG_D(c, x...) do { if (T_stdout) { if( g_log->log_component[c].level >= OAILOG_DEBUG ) logRecord_mt(__FILE__, __FUNCTION__, __LINE__,c, OAILOG_DEBUG, x) ;} else { T(T_LEGACY_ ## c ## _DEBUG, T_PRINTF(x)) ;}} while (0) -# define LOG_T(c, x...) do { if (T_stdout) { if( g_log->log_component[c].level >= OAILOG_TRACE ) logRecord_mt(__FILE__, __FUNCTION__, __LINE__,c, OAILOG_TRACE, x) ;} else { T(T_LEGACY_ ## c ## _TRACE, T_PRINTF(x)) ;}} while (0) - /* macro used to dump a buffer or a message as in openair2/RRC/LTE/RRC_eNB.c, replaces LOG_F macro */ +# if T_TRACER +/* per component, level dependant macros */ +# define LOG_E(c, x...) do { if (T_stdout) { if( g_log->log_component[c].level >= OAILOG_ERR ) logRecord_mt(__FILE__, __FUNCTION__, __LINE__,c, OAILOG_ERR, x) ;} else { T(T_LEGACY_ ## c ## _ERROR, T_PRINTF(x)) ;}} while (0) +# define LOG_W(c, x...) do { if (T_stdout) { if( g_log->log_component[c].level >= OAILOG_WARNING) logRecord_mt(__FILE__, __FUNCTION__, __LINE__,c, OAILOG_WARNING, x) ;} else { T(T_LEGACY_ ## c ## _WARNING, T_PRINTF(x)) ;}} while (0) +# define LOG_I(c, x...) do { if (T_stdout) { if( g_log->log_component[c].level >= OAILOG_INFO ) logRecord_mt(__FILE__, __FUNCTION__, __LINE__,c, OAILOG_INFO, x) ;} else { T(T_LEGACY_ ## c ## _INFO, T_PRINTF(x)) ;}} while (0) +# define LOG_D(c, x...) do { if (T_stdout) { if( g_log->log_component[c].level >= OAILOG_DEBUG ) logRecord_mt(__FILE__, __FUNCTION__, __LINE__,c, OAILOG_DEBUG, x) ;} else { T(T_LEGACY_ ## c ## _DEBUG, T_PRINTF(x)) ;}} while (0) +# define LOG_T(c, x...) do { if (T_stdout) { if( g_log->log_component[c].level >= OAILOG_TRACE ) logRecord_mt(__FILE__, __FUNCTION__, __LINE__,c, OAILOG_TRACE, x) ;} else { T(T_LEGACY_ ## c ## _TRACE, T_PRINTF(x)) ;}} while (0) +/* macro used to dump a buffer or a message as in openair2/RRC/LTE/RRC_eNB.c, replaces LOG_F macro */ # define LOG_DUMPMSG(c, f, b, s, x...) do { if(g_log->dump_mask & f) log_dump(c, b, s, LOG_DUMP_CHAR, x) ;} while (0) /* */ # define nfapi_log(FILE, FNC, LN, COMP, LVL, F...) do { if (T_stdout) { logRecord_mt(__FILE__, __FUNCTION__, __LINE__,COMP, LVL, F) ;}} while (0) /* */ - /* bitmask dependant macros, to isolate debugging code */ +/* bitmask dependant macros, to isolate debugging code */ # define LOG_DEBUGFLAG(D) (g_log->debug_mask & D) - /* bitmask dependant macros, to generate debug file such as matlab file or message dump */ +/* bitmask dependant macros, to generate debug file such as matlab file or message dump */ # define LOG_DUMPFLAG(D) (g_log->dump_mask & D) # define LOG_M(file, vector, data, len, dec, format) do { write_file_matlab(file, vector, data, len, dec, format);} while(0)/* */ - /* define variable only used in LOG macro's */ +/* define variable only used in LOG macro's */ # define LOG_VAR(A,B) A B # else /* T_TRACER: remove all debugging and tracing messages, except errors */ # define LOG_I(c, x...) /* */ @@ -380,15 +380,15 @@ int32_t write_file_matlab(const char *fname, const char *vname, void *data, int # define LOG_T(c, x...) /* */ # define LOG_DUMPMSG(c, b, s, x...) /* */ -# define nfapi_log(FILE, FNC, LN, COMP, LVL, FMT...) +# define nfapi_log(FILE, FNC, LN, COMP, LVL, FMT...) # define LOG_DEBUGFLAG(D) ( 0 ) -# define LOG_DUMPFLAG(D) ( 0 ) -# define LOG_M(file, vector, data, len, dec, format) +# define LOG_DUMPFLAG(D) ( 0 ) +# define LOG_M(file, vector, data, len, dec, format) # define LOG_VAR(A,B) # endif /* T_TRACER */ /* avoid warnings for variables only used in LOG macro's but set outside debug section */ -#define GCC_NOTUSED __attribute__((unused)) -#define LOG_USEDINLOG_VAR(A,B) GCC_NOTUSED A B +#define GCC_NOTUSED __attribute__((unused)) +#define LOG_USEDINLOG_VAR(A,B) GCC_NOTUSED A B /* unfiltered macros, usefull for simulators or messages at init time, before log is configured */ #define LOG_UM(file, vector, data, len, dec, format) do { write_file_matlab(file, vector, data, len, dec, format);} while(0) @@ -420,78 +420,82 @@ static __inline__ uint64_t rdtsc(void) { extern double cpuf; -static inline uint64_t checkTCPU(int timeout, char * file, int line) { - static uint64_t __thread lastCPUTime=0; - static uint64_t __thread last=0; - uint64_t cur=rdtsc(); - struct timespec CPUt; - clock_gettime(CLOCK_THREAD_CPUTIME_ID, &CPUt); - uint64_t CPUTime=CPUt.tv_sec*1000*1000+CPUt.tv_nsec/1000; - double microCycles=(double)(cpuf*1000); - int duration=(int)((cur-last)/microCycles); - if ( last!=0 && duration > timeout ) { - //struct timespec ts; - //clock_gettime(CLOCK_MONOTONIC, &ts); - printf("%s:%d lte-ue delay %d (exceed %d), CPU for this period: %lld\n", file, line, - duration, timeout, (long long)CPUTime-lastCPUTime ); - } - last=cur; - lastCPUTime=CPUTime; - return cur; +static inline uint64_t checkTCPU(int timeout, char *file, int line) { + static uint64_t __thread lastCPUTime=0; + static uint64_t __thread last=0; + uint64_t cur=rdtsc(); + struct timespec CPUt; + clock_gettime(CLOCK_THREAD_CPUTIME_ID, &CPUt); + uint64_t CPUTime=CPUt.tv_sec*1000*1000+CPUt.tv_nsec/1000; + double microCycles=(double)(cpuf*1000); + int duration=(int)((cur-last)/microCycles); + + if ( last!=0 && duration > timeout ) { + //struct timespec ts; + //clock_gettime(CLOCK_MONOTONIC, &ts); + printf("%s:%d lte-ue delay %d (exceed %d), CPU for this period: %lld\n", file, line, + duration, timeout, (long long)CPUTime-lastCPUTime ); + } + + last=cur; + lastCPUTime=CPUTime; + return cur; } -static inline unsigned long long checkT(int timeout, char * file, int line) { - static unsigned long long __thread last=0; - unsigned long long cur=rdtsc(); - int microCycles=(int)(cpuf*1000); - int duration=(int)((cur-last)/microCycles); - if ( last!=0 && duration > timeout ) - printf("%s:%d lte-ue delay %d (exceed %d)\n", file, line, - duration, timeout); - last=cur; - return cur; +static inline unsigned long long checkT(int timeout, char *file, int line) { + static unsigned long long __thread last=0; + unsigned long long cur=rdtsc(); + int microCycles=(int)(cpuf*1000); + int duration=(int)((cur-last)/microCycles); + + if ( last!=0 && duration > timeout ) + printf("%s:%d lte-ue delay %d (exceed %d)\n", file, line, + duration, timeout); + + last=cur; + return cur; } typedef struct m { - uint64_t iterations; - uint64_t sum; - uint64_t maxArray[11]; + uint64_t iterations; + uint64_t sum; + uint64_t maxArray[11]; } Meas; -static inline void printMeas(char * txt, Meas *M, int period) { - if (M->iterations%period == 0 ) { - char txt2[512]; - sprintf(txt2,"%s avg=%" PRIu64 " iterations=%" PRIu64 " max=%" - PRIu64 ":%" PRIu64 ":%" PRIu64 ":%" PRIu64 ":%" PRIu64 ":%" PRIu64 ":%" PRIu64 ":%" PRIu64 ":%" PRIu64 ":%" PRIu64 "\n", - txt, - M->sum/M->iterations, - M->iterations, - M->maxArray[1],M->maxArray[2], M->maxArray[3],M->maxArray[4], M->maxArray[5], - M->maxArray[6],M->maxArray[7], M->maxArray[8],M->maxArray[9],M->maxArray[10]); +static inline void printMeas(char *txt, Meas *M, int period) { + if (M->iterations%period == 0 ) { + char txt2[512]; + sprintf(txt2,"%s avg=%" PRIu64 " iterations=%" PRIu64 " max=%" + PRIu64 ":%" PRIu64 ":%" PRIu64 ":%" PRIu64 ":%" PRIu64 ":%" PRIu64 ":%" PRIu64 ":%" PRIu64 ":%" PRIu64 ":%" PRIu64 "\n", + txt, + M->sum/M->iterations, + M->iterations, + M->maxArray[1],M->maxArray[2], M->maxArray[3],M->maxArray[4], M->maxArray[5], + M->maxArray[6],M->maxArray[7], M->maxArray[8],M->maxArray[9],M->maxArray[10]); #if DISABLE_LOG_X - printf("%s",txt2); + printf("%s",txt2); #else - LOG_W(PHY, "%s",txt2); + LOG_W(PHY, "%s",txt2); #endif - } + } } -static inline int cmpint(const void* a, const void* b) { - uint64_t* aa=(uint64_t*)a; - uint64_t* bb=(uint64_t*)b; - return (int)(*aa-*bb); +static inline int cmpint(const void *a, const void *b) { + uint64_t *aa=(uint64_t *)a; + uint64_t *bb=(uint64_t *)b; + return (int)(*aa-*bb); } -static inline void updateTimes(uint64_t start, Meas *M, int period, char * txt) { - if (start!=0) { - uint64_t end=rdtsc(); - long long diff=(end-start)/(cpuf*1000); - M->maxArray[0]=diff; - M->sum+=diff; - M->iterations++; - qsort(M->maxArray, 11, sizeof(uint64_t), cmpint); - printMeas(txt,M,period); - } +static inline void updateTimes(uint64_t start, Meas *M, int period, char *txt) { + if (start!=0) { + uint64_t end=rdtsc(); + long long diff=(end-start)/(cpuf*1000); + M->maxArray[0]=diff; + M->sum+=diff; + M->iterations++; + qsort(M->maxArray, 11, sizeof(uint64_t), cmpint); + printMeas(txt,M,period); + } } #define check(a) do { checkT(a,__FILE__,__LINE__); } while (0) diff --git a/common/utils/T/genids.c b/common/utils/T/genids.c index 112fe9de5a..a130988262 100644 --- a/common/utils/T/genids.c +++ b/common/utils/T/genids.c @@ -8,27 +8,35 @@ char **unique_ids; int unique_ids_size; int unique_ids_maxsize; -int cmp(const void *p1, const void *p2) -{ - return strcmp(*(char * const *)p1, *(char * const *)p2); +int cmp(const void *p1, const void *p2) { + return strcmp(*(char *const *)p1, *(char *const *)p2); } /* return 1 if s was not already known, 0 if it was */ -int new_unique_id(char *s, char *input_file) -{ +int new_unique_id(char *s, char *input_file) { if (unique_ids_size) - if (bsearch(&s, unique_ids, unique_ids_size, sizeof(char *), cmp) != NULL) { - printf("error: ID %s is not unique in %s\n", s, input_file); - return 0; - } + if (bsearch(&s, unique_ids, unique_ids_size, sizeof(char *), cmp) != NULL) { + printf("error: ID %s is not unique in %s\n", s, input_file); + return 0; + } + if (unique_ids_size == unique_ids_maxsize) { unique_ids_maxsize += 256; unique_ids = realloc(unique_ids, unique_ids_maxsize * sizeof(char *)); - if (unique_ids == NULL) { printf("error: out of memory\n"); abort(); } + + if (unique_ids == NULL) { + printf("error: out of memory\n"); + abort(); + } } + unique_ids[unique_ids_size] = strdup(s); - if (unique_ids[unique_ids_size] == NULL) - { printf("error: out of memory\n"); abort(); } + + if (unique_ids[unique_ids_size] == NULL) { + printf("error: out of memory\n"); + abort(); + } + unique_ids_size++; qsort(unique_ids, unique_ids_size, sizeof(char *), cmp); return 1; @@ -38,14 +46,17 @@ char *bufname; int bufname_size; int bufname_maxsize; -void putname(int c) -{ +void putname(int c) { if (bufname_size == bufname_maxsize) { bufname_maxsize += 256; bufname = realloc(bufname, bufname_maxsize); - if (bufname == NULL) - { printf("error: memory allocation error\n"); exit(1); } + + if (bufname == NULL) { + printf("error: memory allocation error\n"); + exit(1); + } } + bufname[bufname_size] = c; bufname_size++; } @@ -54,42 +65,54 @@ char *bufvalue; int bufvalue_size; int bufvalue_maxsize; -void putvalue(int c) -{ +void putvalue(int c) { if (bufvalue_size == bufvalue_maxsize) { bufvalue_maxsize += 256; bufvalue = realloc(bufvalue, bufvalue_maxsize); - if (bufvalue == NULL) - { printf("error: memory allocation error\n"); exit(1); } + + if (bufvalue == NULL) { + printf("error: memory allocation error\n"); + exit(1); + } } + bufvalue[bufvalue_size] = c; bufvalue_size++; } -void smash_spaces(FILE *f) -{ +void smash_spaces(FILE *f) { int c; + while (1) { c = fgetc(f); + if (isspace(c)) continue; + if (c == ' ') continue; + if (c == '\t') continue; + if (c == '\n') continue; + if (c == 10 || c == 13) continue; + if (c == '#') { while (1) { c = fgetc(f); + if (c == '\n' || c == EOF) break; } + continue; } + break; } + if (c != EOF) ungetc(c, f); } -void get_line(FILE *f, char **name, char **value) -{ +void get_line(FILE *f, char **name, char **value) { int c; bufname_size = 0; bufvalue_size = 0; @@ -97,23 +120,39 @@ void get_line(FILE *f, char **name, char **value) *value = NULL; smash_spaces(f); c = fgetc(f); - while (!(c == '=' || isspace(c) || c == EOF)) { putname(c); c = fgetc(f); } + + while (!(c == '=' || isspace(c) || c == EOF)) { + putname(c); + c = fgetc(f); + } + if (c == EOF) return; + putname(0); + while (!(c == EOF || c == '=')) c = fgetc(f); + if (c == EOF) return; + smash_spaces(f); c = fgetc(f); - while (!(c == 10 || c == 13 || c == EOF)) { putvalue(c); c = fgetc(f); } + + while (!(c == 10 || c == 13 || c == EOF)) { + putvalue(c); + c = fgetc(f); + } + putvalue(0); + if (bufname_size <= 1) return; + if (bufvalue_size <= 1) return; + *name = bufname; *value = bufvalue; } -int main(int n, char **v) -{ +int main(int n, char **v) { FILE *in; FILE *out; char *name; @@ -121,36 +160,54 @@ int main(int n, char **v) char *in_name; char *out_name; - if (n != 3) { printf("error: gimme \n"); exit(1); } + if (n != 3) { + printf("error: gimme \n"); + exit(1); + } n = 0; - in_name = v[1]; out_name = v[2]; + in = fopen(in_name, "r"); - in = fopen(in_name, "r"); if (in == NULL) { perror(in_name); exit(1); } - out = fopen(out_name, "w"); if (out == NULL) { perror(out_name); exit(1); } + if (in == NULL) { + perror(in_name); + exit(1); + } + + out = fopen(out_name, "w"); + + if (out == NULL) { + perror(out_name); + exit(1); + } fprintf(out, "/* generated file, do not edit by hand */\n\n"); while (1) { get_line(in, &name, &value); + if (name == NULL) break; + if (isspace(value[strlen(value)-1])) { printf("error: bad value '%s' (no space at the end please!)\n", value); unlink(out_name); exit(1); } + if (!strcmp(name, "ID")) { - if (!new_unique_id(value, in_name)) { unlink(out_name); exit(1); } + if (!new_unique_id(value, in_name)) { + unlink(out_name); + exit(1); + } + fprintf(out, "#define T_%s T_ID(%d)\n", value, n); n++; } } - fprintf(out, "#define T_NUMBER_OF_IDS %d\n", n); + fprintf(out, "#define T_NUMBER_OF_IDS %d\n", n); fclose(in); fclose(out); - return 0; } From 5bf45e014a01a8d27a88703f1436858dfb7510fa Mon Sep 17 00:00:00 2001 From: Raymond Knopp Date: Sun, 25 Nov 2018 18:34:48 +0100 Subject: [PATCH 173/233] addition of testing procedures for format 1A transmission in dlsim (nb RB > 2 or 3 which is used for TBS calculation). bugfix in UE receiver (leftover nb_antennas_tx => nb_antenna_ports_eNB) --- openair1/PHY/LTE_TRANSPORT/dlsch_scrambling.c | 1 - openair1/PHY/LTE_UE_TRANSPORT/dci_tools_ue.c | 11 +++- .../PHY/LTE_UE_TRANSPORT/dlsch_decoding.c | 1 - .../PHY/LTE_UE_TRANSPORT/dlsch_demodulation.c | 2 +- .../LTE_UE_TRANSPORT/dlsch_llr_computation.c | 18 +++---- openair1/SIMULATION/LTE_PHY/dlsim.c | 52 +++++++++---------- 6 files changed, 45 insertions(+), 40 deletions(-) diff --git a/openair1/PHY/LTE_TRANSPORT/dlsch_scrambling.c b/openair1/PHY/LTE_TRANSPORT/dlsch_scrambling.c index 1a83508cee..20ab151f50 100644 --- a/openair1/PHY/LTE_TRANSPORT/dlsch_scrambling.c +++ b/openair1/PHY/LTE_TRANSPORT/dlsch_scrambling.c @@ -169,7 +169,6 @@ void dlsch_scrambling(LTE_DL_FRAME_PARMS *frame_parms, - s = lte_gold_generic(&x1, &x2, 0); e += 32; } diff --git a/openair1/PHY/LTE_UE_TRANSPORT/dci_tools_ue.c b/openair1/PHY/LTE_UE_TRANSPORT/dci_tools_ue.c index 76176d346e..0f77f69f41 100644 --- a/openair1/PHY/LTE_UE_TRANSPORT/dci_tools_ue.c +++ b/openair1/PHY/LTE_UE_TRANSPORT/dci_tools_ue.c @@ -51,7 +51,14 @@ #include "transport_proto_ue.h" #include "../LTE_TRANSPORT/transport_common_proto.h" #include "SCHED/sched_common.h" - + +/* +#undef LOG_D +#define LOG_D(A,B...) printf(B) +#undef LOG_I +#define LOG_I(A,B...) printf(B) +*/ + extern uint16_t beta_cqi[16]; extern uint16_t beta_ri[16]; extern uint16_t beta_ack[16]; @@ -1274,7 +1281,7 @@ void compute_llr_offset(LTE_DL_FRAME_PARMS *frame_parms, symbol_mod = (symbol >= (7-frame_parms->Ncp))? (symbol-(7-frame_parms->Ncp)) : symbol; if((symbol_mod == 0) || symbol_mod == (4-frame_parms->Ncp)) { - if (frame_parms->nb_antennas_tx == 2) + if (frame_parms->nb_antenna_ports_eNB == 2) crs_re = 4; else crs_re = 2; diff --git a/openair1/PHY/LTE_UE_TRANSPORT/dlsch_decoding.c b/openair1/PHY/LTE_UE_TRANSPORT/dlsch_decoding.c index afbd19329d..3c88b1aa5b 100644 --- a/openair1/PHY/LTE_UE_TRANSPORT/dlsch_decoding.c +++ b/openair1/PHY/LTE_UE_TRANSPORT/dlsch_decoding.c @@ -40,7 +40,6 @@ //#define DEBUG_DLSCH_DECODING #define UE_DEBUG_TRACE 1 - void free_ue_dlsch(LTE_UE_DLSCH_t *dlsch) { diff --git a/openair1/PHY/LTE_UE_TRANSPORT/dlsch_demodulation.c b/openair1/PHY/LTE_UE_TRANSPORT/dlsch_demodulation.c index e8f20c85de..11146d0144 100644 --- a/openair1/PHY/LTE_UE_TRANSPORT/dlsch_demodulation.c +++ b/openair1/PHY/LTE_UE_TRANSPORT/dlsch_demodulation.c @@ -4335,7 +4335,7 @@ void dlsch_channel_aver_band(int **dl_ch_estimates_ext, else nre=12; - for (aatx=0; aatxnb_antennas_tx; aatx++){ + for (aatx=0; aatxnb_antenna_ports_eNB; aatx++){ for (aarx=0; aarxnb_antennas_rx; aarx++) { dl_ch128=(__m128i *)&dl_ch_estimates_ext[aatx*frame_parms->nb_antennas_rx + aarx][symbol*frame_parms->N_RB_DL*12]; avg128D = _mm_setzero_si128(); diff --git a/openair1/PHY/LTE_UE_TRANSPORT/dlsch_llr_computation.c b/openair1/PHY/LTE_UE_TRANSPORT/dlsch_llr_computation.c index ea3f100504..55407d8e2d 100644 --- a/openair1/PHY/LTE_UE_TRANSPORT/dlsch_llr_computation.c +++ b/openair1/PHY/LTE_UE_TRANSPORT/dlsch_llr_computation.c @@ -672,15 +672,15 @@ int dlsch_qpsk_llr(LTE_DL_FRAME_PARMS *frame_parms, len = (nb_rb*12) - pbch_pss_sss_adjust; } - - /* - LOG_I(PHY,"dlsch_qpsk_llr: [symb %d / FirstSym %d / Length %d]: @LLR Buff %x, @LLR Buff(symb) %x \n", - symbol, - first_symbol_flag, - len, - dlsch_llr, - llr32); - */ + + LOG_D(PHY,"[p %d : symb %d / FirstSym %d / Length %d]: @LLR Buff %p, @LLR Buff(symb) %p \n", + frame_parms->nb_antenna_ports_eNB, + symbol, + first_symbol_flag, + len, + dlsch_llr, + llr32); + qpsk_llr((short *)rxF, (short *)llr32, diff --git a/openair1/SIMULATION/LTE_PHY/dlsim.c b/openair1/SIMULATION/LTE_PHY/dlsim.c index 0f4655eb2c..0043e0a029 100644 --- a/openair1/SIMULATION/LTE_PHY/dlsim.c +++ b/openair1/SIMULATION/LTE_PHY/dlsim.c @@ -372,6 +372,7 @@ fill_dlsch_config(nfapi_dl_config_request_body_t * dl_req, dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.transmission_mode = transmission_mode; dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.num_bf_prb_per_subband = num_bf_prb_per_subband; dl_config_pdu->dlsch_pdu.dlsch_pdu_rel8.num_bf_vector = num_bf_vector; + dl_config_pdu->dlsch_pdu.dlsch_pdu_rel13.initial_transmission_sf_io = 0xFFFF; dl_req->number_pdu++; } @@ -402,6 +403,7 @@ void fill_DCI(PHY_VARS_eNB *eNB, nfapi_dl_config_request_body_t *dl_req=&sched_resp->DL_req->dl_config_request_body; nfapi_dl_config_request_pdu_t *dl_config_pdu; nfapi_tx_request_body_t *TX_req=&sched_resp->TX_req->tx_request_body; + int NB_RB4TBS = common_flag == 0 ? NB_RB : (2+TPC); dl_req->number_dci=0; dl_req->number_pdu=0; @@ -414,26 +416,24 @@ void fill_DCI(PHY_VARS_eNB *eNB, case 2: case 7: - if (common_flag == 0) { - dl_config_pdu = &dl_req->dl_config_pdu_list[dl_req->number_pdu]; memset((void *) dl_config_pdu, 0, sizeof(nfapi_dl_config_request_pdu_t)); dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE; dl_config_pdu->pdu_size = (uint8_t) (2 + sizeof(nfapi_dl_config_dci_dl_pdu)); - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.dci_format = NFAPI_DL_DCI_FORMAT_1; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.dci_format = (common_flag == 0) ? NFAPI_DL_DCI_FORMAT_1 : NFAPI_DL_DCI_FORMAT_1A; dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level = 4; dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tl.tag = NFAPI_DL_CONFIG_REQUEST_DCI_DL_PDU_REL8_TAG; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti = n_rnti+k; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti_type = 1; // CRNTI : see Table 4-10 from SCF082 - nFAPI specifications + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti = (common_flag == 0) ? n_rnti+k : SI_RNTI; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti_type = (common_flag ==0 ) ? 1: 2; // CRNTI : see Table 4-10 from SCF082 - nFAPI specifications dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.transmission_power = 6000; // equal to RS power dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.harq_process = 0; dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tpc = TPC; // dont adjust power when retransmitting - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.new_data_indicator_1 = ndi; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.new_data_indicator_1 = (common_flag == 0) ? ndi : 0; dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.mcs_1 = mcs1; dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.redundancy_version_1 = rv; - dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.resource_block_coding = DLSCH_RB_ALLOC; + dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.resource_block_coding = (common_flag == 0) ? DLSCH_RB_ALLOC : computeRIV(eNB->frame_parms.N_RB_DL,0,NB_RB); //deactivate second codeword dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.mcs_2 = 0; dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.redundancy_version_2 = 1; @@ -445,11 +445,12 @@ void fill_DCI(PHY_VARS_eNB *eNB, dl_req->number_pdu++; dl_req->tl.tag = NFAPI_DL_CONFIG_REQUEST_BODY_TAG; + AssertFatal(TPC>=0 && TPC<2, "TPC should be 0 or 1\n"); fill_dlsch_config(dl_req, - get_TBS_DL(mcs1,NB_RB), + get_TBS_DL(mcs1,NB_RB4TBS), (retrans > 0) ? -1 : 0, /* retransmission, no pdu_index */ - n_rnti, + (common_flag == 0) ? n_rnti : SI_RNTI, 0, // type 0 allocation from 7.1.6 in 36.213 0, // virtual_resource_block_assignment_flag, unused here DLSCH_RB_ALLOC, // resource_block_coding, @@ -472,13 +473,10 @@ void fill_DCI(PHY_VARS_eNB *eNB, ); fill_tx_req(TX_req, (frame * 10) + subframe, - get_TBS_DL(mcs1,NB_RB), + get_TBS_DL(mcs1,NB_RB4TBS), 0, input_buffer[k]); - } - else { - - } + break; @@ -589,8 +587,7 @@ int main(int argc, char **argv) int eNB_id = 0; unsigned char round; unsigned char i_mod = 2; - unsigned short NB_RB; - + int NB_RB; SCM_t channel_model=Rayleigh1; // unsigned char *input_data,*decoded_output; @@ -1000,30 +997,33 @@ int main(int argc, char **argv) // alternatively you can disable ITTI completely in CMakeLists.txt //itti_init(TASK_MAX, THREAD_MAX, MESSAGES_ID_MAX, tasks_info, messages_info, messages_definition_xml, NULL); - if (common_flag == 0) { switch (N_RB_DL) { case 6: if (rballocset==0) DLSCH_RB_ALLOC = 0x3f; num_pdcch_symbols = 3; break; - + case 25: if (rballocset==0) DLSCH_RB_ALLOC = 0x1fff; break; - + case 50: if (rballocset==0) DLSCH_RB_ALLOC = 0x1ffff; break; - + case 100: if (rballocset==0) DLSCH_RB_ALLOC = 0x1ffffff; break; } - - NB_RB=conv_nprb(0,DLSCH_RB_ALLOC,N_RB_DL); - } else - NB_RB = 4; + + NB_RB = conv_nprb(0,DLSCH_RB_ALLOC,N_RB_DL); + } + else { + if (rballocset==0) NB_RB = 8; + else NB_RB = DLSCH_RB_ALLOC; + AssertFatal(NB_RB <= N_RB_DL,"illegal NB_RB %d\n",NB_RB); + } if (xforms==1) { fl_initialize (&argc, argv, NULL, 0, 0); @@ -1524,7 +1524,7 @@ int main(int argc, char **argv) // Simulate HARQ procedures!!! memset(CCE_table,0,800*sizeof(int)); - if (common_flag == 0) { + if (/*common_flag == 0*/ 1) { num_dci=0; num_common_dci=0; @@ -1656,7 +1656,7 @@ int main(int argc, char **argv) if (generate_ue_dlsch_params_from_dci(proc->frame_rx, proc->subframe_rx, (void *)&dci_alloc[0].dci_pdu, - n_rnti, + common_flag == 0 ? n_rnti : SI_RNTI, dci_alloc[0].format, UE->pdcch_vars[UE->current_thread_id[proc->subframe_rx]][eNB_id], UE->pdsch_vars[UE->current_thread_id[proc->subframe_rx]][eNB_id], From 131986282ac0774cd332ae5f5b1102fca19a0113 Mon Sep 17 00:00:00 2001 From: nepes Date: Sun, 25 Nov 2018 21:22:02 +0100 Subject: [PATCH 174/233] removed some logging in UE and tested TM2 reception on Band 20 cells. --- openair1/PHY/LTE_UE_TRANSPORT/dlsch_decoding.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/openair1/PHY/LTE_UE_TRANSPORT/dlsch_decoding.c b/openair1/PHY/LTE_UE_TRANSPORT/dlsch_decoding.c index 3c88b1aa5b..1b4ca3ed2f 100644 --- a/openair1/PHY/LTE_UE_TRANSPORT/dlsch_decoding.c +++ b/openair1/PHY/LTE_UE_TRANSPORT/dlsch_decoding.c @@ -38,7 +38,7 @@ #include "common/utils/LOG/vcd_signal_dumper.h" #include "PHY/LTE_UE_TRANSPORT/transport_proto_ue.h" //#define DEBUG_DLSCH_DECODING -#define UE_DEBUG_TRACE 1 +//#define UE_DEBUG_TRACE 1 void free_ue_dlsch(LTE_UE_DLSCH_t *dlsch) { @@ -625,7 +625,7 @@ decoder_if_t *tc; if (err_flag == 1) { #if UE_DEBUG_TRACE - LOG_I(PHY,"[UE %d] DLSCH: Setting NAK for SFN/SF %d/%d (pid %d, status %d, round %d, TBS %d, mcs %d) Kr %d r %d harq_process->round %d\n", + LOG_D(PHY,"[UE %d] DLSCH: Setting NAK for SFN/SF %d/%d (pid %d, status %d, round %d, TBS %d, mcs %d) Kr %d r %d harq_process->round %d\n", phy_vars_ue->Mod_id, frame, subframe, harq_pid,harq_process->status, harq_process->round,harq_process->TBS,harq_process->mcs,Kr,r,harq_process->round); #endif dlsch->harq_ack[subframe].ack = 0; @@ -649,7 +649,7 @@ decoder_if_t *tc; return((1+dlsch->max_turbo_iterations)); } else { #if UE_DEBUG_TRACE - LOG_I(PHY,"[UE %d] DLSCH: Setting ACK for subframe %d TBS %d mcs %d nb_rb %d\n", + LOG_D(PHY,"[UE %d] DLSCH: Setting ACK for subframe %d TBS %d mcs %d nb_rb %d\n", phy_vars_ue->Mod_id,subframe,harq_process->TBS,harq_process->mcs,harq_process->nb_rb); #endif From 814b967cced0e0c7337394930c7f42c27ea1bb82 Mon Sep 17 00:00:00 2001 From: Raphael Defosseux Date: Mon, 26 Nov 2018 15:19:01 +0100 Subject: [PATCH 175/233] CI: more T tracer during run -- RAW record file is parsed and replayed -- Replayed log file is parsed instead of normal eNB file during terminate Signed-off-by: Raphael Defosseux --- ci-scripts/main.py | 94 +++++++++++++++++++++++++++++++++------------- 1 file changed, 67 insertions(+), 27 deletions(-) diff --git a/ci-scripts/main.py b/ci-scripts/main.py index 91b97aac80..eb1f0bfd22 100644 --- a/ci-scripts/main.py +++ b/ci-scripts/main.py @@ -414,11 +414,26 @@ class SSHConnection(): while (doLoop): loopCounter = loopCounter - 1 if (loopCounter == 0): + # In case of T tracer recording, we may need to kill it + result = re.search('T_stdout', str(self.Initialize_eNB_args)) + if result is not None: + self.command('killall --signal SIGKILL record', '\$', 5) + self.close() doLoop = False logging.error('\u001B[1;37;41m eNB logging system did not show got sync! \u001B[0m') self.CreateHtmlTestRow('-O ' + config_file + extra_options, 'KO', ALL_PROCESSES_OK) self.CreateHtmlFooter(False) - self.close() + # In case of T tracer recording, we need to kill tshark on EPC side + result = re.search('T_stdout', str(self.Initialize_eNB_args)) + if result is not None: + self.open(self.EPCIPAddress, self.EPCUserName, self.EPCPassword) + logging.debug('\u001B[1m Stopping tshark \u001B[0m') + self.command('echo ' + self.EPCPassword + ' | sudo -S killall --signal SIGKILL tshark', '\$', 5) + self.close() + time.sleep(1) + pcap_log_file = 'enb_' + SSH.testCase_id + '_s1log.pcap' + self.copyin(self.EPCIPAddress, self.EPCUserName, self.EPCPassword, '/tmp/' + pcap_log_file, '.') + self.copyout(self.eNBIPAddress, self.eNBUserName, self.eNBPassword, pcap_log_file, self.eNBSourceCodePath + '/cmake_targets/.') sys.exit(1) else: self.command('stdbuf -o0 cat enb_' + SSH.testCase_id + '.log | egrep --color=never -i "wait|sync"', '\$', 4) @@ -661,6 +676,10 @@ class SSHConnection(): html_queue.put(html_cell) if (attach_status): self.CreateHtmlTestRowQueue('N/A', 'OK', len(self.UEDevices), html_queue) + result = re.search('T_stdout', str(self.Initialize_eNB_args)) + if result is not None: + logging.debug('Waiting 5 seconds to fill up record file') + time.sleep(5) else: self.CreateHtmlTestRowQueue('N/A', 'KO', len(self.UEDevices), html_queue) self.AutoTerminateUEandeNB() @@ -696,6 +715,10 @@ class SSHConnection(): for job in multi_jobs: job.join() self.CreateHtmlTestRow('N/A', 'OK', ALL_PROCESSES_OK) + result = re.search('T_stdout', str(self.Initialize_eNB_args)) + if result is not None: + logging.debug('Waiting 5 seconds to fill up record file') + time.sleep(5) def RebootUE_common(self, device_id): try: @@ -1462,7 +1485,7 @@ class SSHConnection(): fileCheck = re.search('enb_', str(self.eNBLogFile)) if fileCheck is not None: self.copyin(self.eNBIPAddress, self.eNBUserName, self.eNBPassword, self.eNBSourceCodePath + '/cmake_targets/' + self.eNBLogFile, '.') - logStatus = self.AnalyzeLogFile_eNB() + logStatus = self.AnalyzeLogFile_eNB(self.eNBLogFile) if logStatus < 0: result = logStatus return result @@ -1533,10 +1556,10 @@ class SSHConnection(): except: os.kill(os.getppid(),signal.SIGUSR1) - def AnalyzeLogFile_eNB(self): - if (not os.path.isfile('./' + SSH.eNBLogFile)): + def AnalyzeLogFile_eNB(self, eNBlogFile): + if (not os.path.isfile('./' + eNBlogFile)): return -1 - enb_log_file = open('./' + SSH.eNBLogFile, 'r') + enb_log_file = open('./' + eNBlogFile, 'r') foundAssertion = False msgAssertion = '' msgLine = 0 @@ -1569,28 +1592,28 @@ class SSHConnection(): if foundAssertion and (msgLine < 3): msgLine += 1 msgAssertion += str(line) - result = re.search('Generating RRCConnectionSetup', str(line)) + result = re.search('Generating LTE_RRCConnectionSetup', str(line)) if result is not None: rrcSetupRequest += 1 - result = re.search('RRCConnectionSetupComplete from UE', str(line)) + result = re.search('LTE_RRCConnectionSetupComplete from UE', str(line)) if result is not None: rrcSetupComplete += 1 - result = re.search('Generate RRCConnectionRelease', str(line)) + result = re.search('Generate LTE_RRCConnectionRelease', str(line)) if result is not None: rrcReleaseRequest += 1 - result = re.search('Generate RRCConnectionReconfiguration', str(line)) + result = re.search('Generate LTE_RRCConnectionReconfiguration', str(line)) if result is not None: rrcReconfigRequest += 1 - result = re.search('RRCConnectionReconfigurationComplete from UE rnti', str(line)) + result = re.search('LTE_RRCConnectionReconfigurationComplete from UE rnti', str(line)) if result is not None: rrcReconfigComplete += 1 - result = re.search('RRCConnectionReestablishmentRequest', str(line)) + result = re.search('LTE_RRCConnectionReestablishmentRequest', str(line)) if result is not None: rrcReestablishRequest += 1 - result = re.search('RRCConnectionReestablishmentComplete', str(line)) + result = re.search('LTE_RRCConnectionReestablishmentComplete', str(line)) if result is not None: rrcReestablishComplete += 1 - result = re.search('RRCConnectionReestablishmentReject', str(line)) + result = re.search('LTE_RRCConnectionReestablishmentReject', str(line)) if result is not None: rrcReestablishReject += 1 result = re.search('uci->stat', str(line)) @@ -1668,7 +1691,6 @@ class SSHConnection(): if result is not None: self.command('echo ' + self.eNBPassword + ' | sudo -S killall --signal SIGKILL lte-softmodem || true', '\$', 5) self.close() - result = re.search('enb_', str(self.eNBLogFile)) # If tracer options is on, stopping tshark on EPC side result = re.search('T_stdout', str(self.Initialize_eNB_args)) if result is not None: @@ -1681,19 +1703,37 @@ class SSHConnection(): self.copyin(self.EPCIPAddress, self.EPCUserName, self.EPCPassword, '/tmp/' + pcap_log_file, '.') self.copyout(self.eNBIPAddress, self.eNBUserName, self.eNBPassword, pcap_log_file, self.eNBSourceCodePath + '/cmake_targets/.') self.close() - if result is not None: - self.copyin(self.eNBIPAddress, self.eNBUserName, self.eNBPassword, self.eNBSourceCodePath + '/cmake_targets/' + self.eNBLogFile, '.') - logging.debug('\u001B[1m Analyzing eNB logfile \u001B[0m') - logStatus = self.AnalyzeLogFile_eNB() - if (logStatus < 0): - self.CreateHtmlTestRow('N/A', 'KO', logStatus) - self.CreateHtmlFooter(False) - sys.exit(1) - else: - self.CreateHtmlTestRow('N/A', 'OK', ALL_PROCESSES_OK) + logging.debug('\u001B[1m Replaying RAW record file\u001B[0m') + self.open(self.eNBIPAddress, self.eNBUserName, self.eNBPassword) + self.command('cd ' + self.eNBSourceCodePath + '/common/utils/T/tracer/', '\$', 5) + raw_record_file = self.eNBLogFile.replace('.log', '_record.raw') + replay_log_file = self.eNBLogFile.replace('.log', '_replay.log') + extracted_txt_file = self.eNBLogFile.replace('.log', '_extracted_messages.txt') + extracted_log_file = self.eNBLogFile.replace('.log', '_extracted_messages.log') + self.command('./extract_config -i ' + self.eNBSourceCodePath + '/cmake_targets/' + raw_record_file + ' > ' + self.eNBSourceCodePath + '/cmake_targets/' + extracted_txt_file, '\$', 5) + self.command('echo $USER; nohup ./replay -i ' + self.eNBSourceCodePath + '/cmake_targets/' + raw_record_file + ' > ' + self.eNBSourceCodePath + '/cmake_targets/' + replay_log_file + ' 2>&1 &', self.eNBUserName, 5) + self.command('./textlog -d ' + self.eNBSourceCodePath + '/cmake_targets/' + extracted_txt_file + ' -no-gui -ON -full > ' + self.eNBSourceCodePath + '/cmake_targets/' + extracted_log_file, '\$', 5) + self.close() + self.copyin(self.eNBIPAddress, self.eNBUserName, self.eNBPassword, self.eNBSourceCodePath + '/cmake_targets/' + extracted_log_file, '.') + logging.debug('\u001B[1m Analyzing eNB replay logfile \u001B[0m') + logStatus = self.AnalyzeLogFile_eNB(extracted_log_file) + self.CreateHtmlTestRow('N/A', 'OK', ALL_PROCESSES_OK) self.eNBLogFile = '' else: - self.CreateHtmlTestRow('N/A', 'OK', ALL_PROCESSES_OK) + result = re.search('enb_', str(self.eNBLogFile)) + if result is not None: + self.copyin(self.eNBIPAddress, self.eNBUserName, self.eNBPassword, self.eNBSourceCodePath + '/cmake_targets/' + self.eNBLogFile, '.') + logging.debug('\u001B[1m Analyzing eNB logfile \u001B[0m') + logStatus = self.AnalyzeLogFile_eNB(self.eNBLogFile) + if (logStatus < 0): + self.CreateHtmlTestRow('N/A', 'KO', logStatus) + self.CreateHtmlFooter(False) + sys.exit(1) + else: + self.CreateHtmlTestRow('N/A', 'OK', ALL_PROCESSES_OK) + self.eNBLogFile = '' + else: + self.CreateHtmlTestRow('N/A', 'OK', ALL_PROCESSES_OK) def TerminateHSS(self): self.open(self.EPCIPAddress, self.EPCUserName, self.EPCPassword) @@ -1797,8 +1837,8 @@ class SSHConnection(): self.command('cd ' + self.eNBSourceCodePath, '\$', 5) self.command('cd cmake_targets', '\$', 5) self.command('echo ' + self.eNBPassword + ' | sudo -S rm -f enb.log.zip', '\$', 5) - self.command('echo ' + self.eNBPassword + ' | sudo -S zip enb.log.zip enb*.log core* enb_*record.raw enb_*.pcap', '\$', 60) - self.command('echo ' + self.eNBPassword + ' | sudo -S rm enb*.log core* enb_*record.raw enb_*.pcap', '\$', 5) + self.command('echo ' + self.eNBPassword + ' | sudo -S zip enb.log.zip enb*.log core* enb_*record.raw enb_*.pcap enb_*txt', '\$', 60) + self.command('echo ' + self.eNBPassword + ' | sudo -S rm enb*.log core* enb_*record.raw enb_*.pcap enb_*txt', '\$', 5) self.close() def LogCollectPing(self): From fb5201ba97646486b5069b4b3de49a235003b9fc Mon Sep 17 00:00:00 2001 From: Raymond Knopp Date: Mon, 26 Nov 2018 21:02:41 +0100 Subject: [PATCH 176/233] initialization of dfts for RU. moved init_dfts out from lte_init_top into lte_init_RU() and lte_init_ue_signal() --- openair1/PHY/INIT/init_top.c | 3 --- openair1/PHY/INIT/lte_init_ru.c | 1 + openair1/PHY/INIT/lte_init_ue.c | 1 + openair2/LAYER2/MAC/eNB_scheduler_primitives.c | 3 +-- openair2/LAYER2/MAC/mac.h | 5 ++--- 5 files changed, 5 insertions(+), 8 deletions(-) diff --git a/openair1/PHY/INIT/init_top.c b/openair1/PHY/INIT/init_top.c index 1bb36bd2e5..5f1b764335 100644 --- a/openair1/PHY/INIT/init_top.c +++ b/openair1/PHY/INIT/init_top.c @@ -59,11 +59,9 @@ void generate_qpsk_table(void) { } } -void init_7_5KHz(void); void init_lte_top(LTE_DL_FRAME_PARMS *frame_parms) { ccodelte_init(); ccodelte_init_inv(); - init_dfts(); phy_generate_viterbi_tables_lte(); load_codinglib(); lte_sync_time_init(frame_parms); @@ -76,7 +74,6 @@ void init_lte_top(LTE_DL_FRAME_PARMS *frame_parms) { init_unscrambling_lut(); init_scrambling_lut(); //set_taus_seed(1328); -// init_7_5KHz(); init_sss(); } diff --git a/openair1/PHY/INIT/lte_init_ru.c b/openair1/PHY/INIT/lte_init_ru.c index e2f6259447..c4cd3600c0 100644 --- a/openair1/PHY/INIT/lte_init_ru.c +++ b/openair1/PHY/INIT/lte_init_ru.c @@ -67,6 +67,7 @@ int phy_init_RU(RU_t *ru) { } if (ru->function != NGFI_RRU_IF5) { // we need to do RX/TX RU processing + init_dfts(); init_7_5KHz(); LOG_I(PHY,"nb_tx %d\n",ru->nb_tx); ru->common.rxdata_7_5kHz = (int32_t**)malloc16(ru->nb_rx*sizeof(int32_t*) ); diff --git a/openair1/PHY/INIT/lte_init_ue.c b/openair1/PHY/INIT/lte_init_ue.c index 31c37e4669..838590079b 100644 --- a/openair1/PHY/INIT/lte_init_ue.c +++ b/openair1/PHY/INIT/lte_init_ue.c @@ -665,6 +665,7 @@ int init_lte_ue_signal(PHY_VARS_UE *ue, init_frame_parms(&ue->frame_parms,1); init_lte_top(&ue->frame_parms); init_7_5KHz(); + init_dfts(); init_ul_hopping(&ue->frame_parms); diff --git a/openair2/LAYER2/MAC/eNB_scheduler_primitives.c b/openair2/LAYER2/MAC/eNB_scheduler_primitives.c index b43c34fe14..06e7a7f4b2 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_primitives.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_primitives.c @@ -2272,8 +2272,7 @@ uint8_t get_tmode(module_id_t module_idP, int CC_idP, int UE_idP) eNB_MAC_INST *eNB = RC.mac[module_idP]; COMMON_channels_t *cc = &eNB->common_channels[CC_idP]; - struct LTE_PhysicalConfigDedicated *physicalConfigDedicated = - eNB->UE_list.physicalConfigDedicated[CC_idP][UE_idP]; + LTE_PhysicalConfigDedicated_t *physicalConfigDedicated = eNB->UE_list.physicalConfigDedicated[CC_idP][UE_idP]; if (physicalConfigDedicated == NULL) { // RRCConnectionSetup not received by UE yet AssertFatal(cc->p_eNB <= 2, "p_eNB is %d, should be <2\n", diff --git a/openair2/LAYER2/MAC/mac.h b/openair2/LAYER2/MAC/mac.h index 0625a327eb..7785abd16f 100644 --- a/openair2/LAYER2/MAC/mac.h +++ b/openair2/LAYER2/MAC/mac.h @@ -1,4 +1,4 @@ -/* + /* * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. @@ -1070,8 +1070,7 @@ typedef struct { /*! \brief UE list used by eNB to order UEs/CC for scheduling*/ typedef struct { /// Dedicated information for UEs - struct PhysicalConfigDedicated - *physicalConfigDedicated[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB]; + LTE_PhysicalConfigDedicated_t *physicalConfigDedicated[NFAPI_CC_MAX][MAX_MOBILES_PER_ENB]; /// DLSCH pdu DLSCH_PDU DLSCH_pdu[NFAPI_CC_MAX][2][MAX_MOBILES_PER_ENB]; /// DCI template and MAC connection parameters for UEs From 4d934dacfbcfb2ca753d876f05e15937e6586964 Mon Sep 17 00:00:00 2001 From: Raymond Knopp Date: Tue, 27 Nov 2018 11:26:20 +0100 Subject: [PATCH 177/233] initializations of dfts for UE (bad order in call to init_dfts from lte_init_ue_signal() ) --- openair1/PHY/INIT/init_top.c | 2 -- openair1/PHY/INIT/lte_init_ue.c | 4 ++-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/openair1/PHY/INIT/init_top.c b/openair1/PHY/INIT/init_top.c index 5f1b764335..698f34833d 100644 --- a/openair1/PHY/INIT/init_top.c +++ b/openair1/PHY/INIT/init_top.c @@ -64,7 +64,6 @@ void init_lte_top(LTE_DL_FRAME_PARMS *frame_parms) { ccodelte_init_inv(); phy_generate_viterbi_tables_lte(); load_codinglib(); - lte_sync_time_init(frame_parms); generate_ul_ref_sigs(); generate_ul_ref_sigs_rx(); generate_64qam_table(); @@ -79,7 +78,6 @@ void init_lte_top(LTE_DL_FRAME_PARMS *frame_parms) { void free_lte_top(void) { free_codinglib(); - lte_sync_time_free(); /* free_ul_ref_sigs() is called in phy_free_lte_eNB() */ } diff --git a/openair1/PHY/INIT/lte_init_ue.c b/openair1/PHY/INIT/lte_init_ue.c index 838590079b..2edbd611c2 100644 --- a/openair1/PHY/INIT/lte_init_ue.c +++ b/openair1/PHY/INIT/lte_init_ue.c @@ -661,11 +661,11 @@ int init_lte_ue_signal(PHY_VARS_UE *ue, - + ini_dfts(); init_frame_parms(&ue->frame_parms,1); + lte_sync_time_init(frame_parms); init_lte_top(&ue->frame_parms); init_7_5KHz(); - init_dfts(); init_ul_hopping(&ue->frame_parms); From c7e611ead147161490f5f78db51c32a15de7902a Mon Sep 17 00:00:00 2001 From: Raymond Knopp Date: Tue, 27 Nov 2018 12:26:51 +0100 Subject: [PATCH 178/233] compilation ok. --- openair1/PHY/INIT/lte_init_ue.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openair1/PHY/INIT/lte_init_ue.c b/openair1/PHY/INIT/lte_init_ue.c index 2edbd611c2..f82fd4a1ba 100644 --- a/openair1/PHY/INIT/lte_init_ue.c +++ b/openair1/PHY/INIT/lte_init_ue.c @@ -661,9 +661,9 @@ int init_lte_ue_signal(PHY_VARS_UE *ue, - ini_dfts(); + init_dfts(); init_frame_parms(&ue->frame_parms,1); - lte_sync_time_init(frame_parms); + lte_sync_time_init(&ue->frame_parms); init_lte_top(&ue->frame_parms); init_7_5KHz(); init_ul_hopping(&ue->frame_parms); From 15314aebff0a8253a618a8bdcb74643b1684529d Mon Sep 17 00:00:00 2001 From: Raphael Defosseux Date: Tue, 27 Nov 2018 15:45:36 +0100 Subject: [PATCH 179/233] CI: after fix, adding 10/20MHz testing to IF4p5 scenarios Signed-off-by: Raphael Defosseux --- ci-scripts/main.py | 19 ++++++++++++++++++- ci-scripts/xml_files/if4p5_usrp210_band40.xml | 8 +++----- ci-scripts/xml_files/if4p5_usrp210_band7.xml | 7 ++----- 3 files changed, 23 insertions(+), 11 deletions(-) diff --git a/ci-scripts/main.py b/ci-scripts/main.py index f617d6f40a..5ce0dc5af5 100644 --- a/ci-scripts/main.py +++ b/ci-scripts/main.py @@ -396,7 +396,7 @@ class SSHConnection(): self.close() sys.exit(1) else: - self.command('stdbuf -o0 cat enb_' + SSH.testCase_id + '.log | egrep --color=never -i "wait|sync"', '\$', 4) + self.command('stdbuf -o0 cat enb_' + SSH.testCase_id + '.log | egrep --text --color=never -i "wait|sync"', '\$', 4) if rruCheck: result = re.search('wait RUs', str(self.ssh.before)) else: @@ -1406,6 +1406,8 @@ class SSHConnection(): rrcReestablishRequest = 0 rrcReestablishComplete = 0 rrcReestablishReject = 0 + rlcDiscardBuffer = 0 + rachCanceledProcedure = 0 uciStatMsgCount = 0 pdcpFailure = 0 ulschFailure = 0 @@ -1458,6 +1460,12 @@ class SSHConnection(): result = re.search('ULSCH in error in round', str(line)) if result is not None: ulschFailure += 1 + result = re.search('BAD all_segments_received', str(line)) + if result is not None: + rlcDiscardBuffer += 1 + result = re.search('Canceled RA procedure for UE rnti', str(line)) + if result is not None: + rachCanceledProcedure += 1 enb_log_file.close() self.htmleNBFailureMsg = '' if uciStatMsgCount > 0: @@ -1500,6 +1508,10 @@ class SSHConnection(): rrcMsg = ' -- ' + str(rrcReestablishReject) + ' were rejected' logging.debug('\u001B[1;30;43m ' + rrcMsg + ' \u001B[0m') self.htmleNBFailureMsg += rrcMsg + '\n' + if rachCanceledProcedure > 0: + rachMsg = 'eNB cancelled ' + str(rachCanceledProcedure) + ' RA procedure(s)' + logging.debug('\u001B[1;30;43m ' + rachMsg + ' \u001B[0m') + self.htmleNBFailureMsg += rachMsg + '\n' if foundSegFault: logging.debug('\u001B[1;37;41m eNB ended with a Segmentation Fault! \u001B[0m') return ENB_PROCESS_SEG_FAULT @@ -1510,6 +1522,11 @@ class SSHConnection(): if foundRealTimeIssue: logging.debug('\u001B[1;37;41m eNB faced real time issues! \u001B[0m') return ENB_PROCESS_REALTIME_ISSUE + if rlcDiscardBuffer > 0: + rlcMsg = 'eNB RLC discarded ' + str(rlcDiscardBuffer) + ' buffer(s)' + logging.debug('\u001B[1;37;41m ' + rlcMsg + ' \u001B[0m') + self.htmleNBFailureMsg += rlcMsg + '\n' + return ENB_PROCESS_REALTIME_ISSUE return 0 def TerminateeNB(self): diff --git a/ci-scripts/xml_files/if4p5_usrp210_band40.xml b/ci-scripts/xml_files/if4p5_usrp210_band40.xml index b7877009fd..ac5d9ef5ba 100644 --- a/ci-scripts/xml_files/if4p5_usrp210_band40.xml +++ b/ci-scripts/xml_files/if4p5_usrp210_band40.xml @@ -21,17 +21,15 @@ --> - - + 010101 050101 060101 070101 040101 - 030104 030105 040301 040501 040602 040401 040201 030201 030202 + 030104 030105 040301 040501 040602 040642 040401 040201 030201 030202 + 030114 030115 040301 040511 040612 040652 040401 040201 030201 030202 050201 060201 070201 diff --git a/ci-scripts/xml_files/if4p5_usrp210_band7.xml b/ci-scripts/xml_files/if4p5_usrp210_band7.xml index 9ca3a113bf..a582754229 100644 --- a/ci-scripts/xml_files/if4p5_usrp210_band7.xml +++ b/ci-scripts/xml_files/if4p5_usrp210_band7.xml @@ -21,17 +21,14 @@ --> - 010101 050101 060101 070101 040101 030101 030102 040301 040501 040604 040642 040401 040201 030201 030202 - 050201 060201 070201 - - + 050201 060201 070201 + From 5d0fe4cea75e709a024653b9616c969a079f2d29 Mon Sep 17 00:00:00 2001 From: Raphael Defosseux Date: Wed, 28 Nov 2018 20:31:24 +0100 Subject: [PATCH 180/233] Fixing some compilation errors/warnings Signed-off-by: Raphael Defosseux --- openair2/RRC/LTE/MESSAGES/asn1_msg.c | 2 +- targets/RT/USER/lte-softmodem-common.c | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/openair2/RRC/LTE/MESSAGES/asn1_msg.c b/openair2/RRC/LTE/MESSAGES/asn1_msg.c index 3e8a30c3a4..6d831741c2 100644 --- a/openair2/RRC/LTE/MESSAGES/asn1_msg.c +++ b/openair2/RRC/LTE/MESSAGES/asn1_msg.c @@ -2350,7 +2350,7 @@ do_RRCConnectionReestablishment( return -1; } - LOG_D(RRC,"RRCConnectionReestablishment Encoded %zd bits (%zd bytes)\n", + LOG_D(RRC,"RRCConnectionReestablishment Encoded %u bits (%u bytes)\n", (uint32_t)enc_rval.encoded, (uint32_t)(enc_rval.encoded+7)/8); return((enc_rval.encoded+7)/8); } diff --git a/targets/RT/USER/lte-softmodem-common.c b/targets/RT/USER/lte-softmodem-common.c index 4eb0d3e888..c934084a43 100644 --- a/targets/RT/USER/lte-softmodem-common.c +++ b/targets/RT/USER/lte-softmodem-common.c @@ -49,6 +49,7 @@ softmodem_params_t* get_softmodem_params(void) { return &softmodem_params; } +#if 0 void set_parallel_conf(char *parallel_conf) { if(strcmp(parallel_conf,"PARALLEL_SINGLE_THREAD")==0) softmodem_params.thread_struct.parallel_conf = PARALLEL_SINGLE_THREAD; @@ -70,6 +71,7 @@ WORKER_CONF_t get_thread_worker_conf(void) { return softmodem_params.thread_struct.worker_conf; } +#endif void get_common_options(void) { char *parallel_config=NULL; From e7f0701aa7640ac717e48d3573506a0dc4a8204c Mon Sep 17 00:00:00 2001 From: Wang Tsu-Han Date: Thu, 29 Nov 2018 16:03:07 +0100 Subject: [PATCH 181/233] fixes for getting config by command line --- openair2/ENB_APP/enb_config.c | 32 +++++++++++++++----------- targets/RT/USER/lte-softmodem-common.c | 4 ++-- 2 files changed, 21 insertions(+), 15 deletions(-) diff --git a/openair2/ENB_APP/enb_config.c b/openair2/ENB_APP/enb_config.c index 9cbfb8741e..71adb2b811 100644 --- a/openair2/ENB_APP/enb_config.c +++ b/openair2/ENB_APP/enb_config.c @@ -67,6 +67,8 @@ extern PARALLEL_CONF_t get_thread_parallel_conf(void); extern WORKER_CONF_t get_thread_worker_conf(void); extern uint32_t to_earfcn_DL(int eutra_bandP, uint32_t dl_CarrierFreq, uint32_t bw); extern uint32_t to_earfcn_UL(int eutra_bandP, uint32_t ul_CarrierFreq, uint32_t bw); +extern char *parallel_config; +extern char *worker_config; void RCconfig_flexran() { uint16_t i; @@ -2494,29 +2496,33 @@ int RCconfig_X2(MessageDef *msg_p, uint32_t i) { int RCconfig_parallel(void) { char *parallel_conf = NULL; char *worker_conf = NULL; + paramdef_t ThreadParams[] = THREAD_CONF_DESC; paramlist_def_t THREADParamList = {THREAD_CONFIG_STRING_THREAD_STRUCT,NULL,0}; config_getlist( &THREADParamList,NULL,0,NULL); - if(THREADParamList.numelt>0) { - config_getlist( &THREADParamList,ThreadParams,sizeof(ThreadParams)/sizeof(paramdef_t),NULL); - parallel_conf = strdup(*(THREADParamList.paramarray[0][THREAD_PARALLEL_IDX].strptr)); - } else { - parallel_conf = strdup("PARALLEL_RU_L1_TRX_SPLIT"); + if(parallel_config == NULL){ + if(THREADParamList.numelt>0) { + config_getlist( &THREADParamList,ThreadParams,sizeof(ThreadParams)/sizeof(paramdef_t),NULL); + parallel_conf = strdup(*(THREADParamList.paramarray[0][THREAD_PARALLEL_IDX].strptr)); + } else { + parallel_conf = strdup("PARALLEL_RU_L1_TRX_SPLIT"); + } + set_parallel_conf(parallel_conf); } - if(THREADParamList.numelt>0) { - config_getlist( &THREADParamList,ThreadParams,sizeof(ThreadParams)/sizeof(paramdef_t),NULL); - worker_conf = strdup(*(THREADParamList.paramarray[0][THREAD_WORKER_IDX].strptr)); - } else { - worker_conf = strdup("WORKER_ENABLE"); + if(worker_config == NULL){ + if(THREADParamList.numelt>0) { + config_getlist( &THREADParamList,ThreadParams,sizeof(ThreadParams)/sizeof(paramdef_t),NULL); + worker_conf = strdup(*(THREADParamList.paramarray[0][THREAD_WORKER_IDX].strptr)); + } else { + worker_conf = strdup("WORKER_ENABLE"); + } + set_worker_conf(worker_conf); } - set_parallel_conf(parallel_conf); - set_worker_conf(worker_conf); - return 0; } diff --git a/targets/RT/USER/lte-softmodem-common.c b/targets/RT/USER/lte-softmodem-common.c index 94a5dd0a6b..7e1235b310 100644 --- a/targets/RT/USER/lte-softmodem-common.c +++ b/targets/RT/USER/lte-softmodem-common.c @@ -35,6 +35,8 @@ #include "common/config/config_userapi.h" #include "common/utils/load_module_shlib.h" static softmodem_params_t softmodem_params; +char *parallel_config=NULL; +char *worker_config=NULL; uint64_t get_softmodem_optmask(void) { return softmodem_params.optmask; @@ -51,8 +53,6 @@ softmodem_params_t* get_softmodem_params(void) { void get_common_options(void) { -char *parallel_config=NULL; -char *worker_config=NULL; uint32_t online_log_messages; From f88a43ca60f1dc63bba663f4cad20aaee0ff3b00 Mon Sep 17 00:00:00 2001 From: Wang Tsu-Han Date: Thu, 29 Nov 2018 16:03:07 +0100 Subject: [PATCH 182/233] fixes for getting config by command line --- openair2/ENB_APP/enb_config.c | 32 +++++++++++++++----------- targets/RT/USER/lte-softmodem-common.c | 4 ++-- 2 files changed, 21 insertions(+), 15 deletions(-) diff --git a/openair2/ENB_APP/enb_config.c b/openair2/ENB_APP/enb_config.c index cb6b76b540..faee587fa9 100644 --- a/openair2/ENB_APP/enb_config.c +++ b/openair2/ENB_APP/enb_config.c @@ -69,6 +69,8 @@ extern PARALLEL_CONF_t get_thread_parallel_conf(void); extern WORKER_CONF_t get_thread_worker_conf(void); extern uint32_t to_earfcn_DL(int eutra_bandP, uint32_t dl_CarrierFreq, uint32_t bw); extern uint32_t to_earfcn_UL(int eutra_bandP, uint32_t ul_CarrierFreq, uint32_t bw); +extern char *parallel_config; +extern char *worker_config; void RCconfig_flexran() { uint16_t i; @@ -2672,29 +2674,33 @@ int RCconfig_X2(MessageDef *msg_p, uint32_t i) { int RCconfig_parallel(void) { char *parallel_conf = NULL; char *worker_conf = NULL; + paramdef_t ThreadParams[] = THREAD_CONF_DESC; paramlist_def_t THREADParamList = {THREAD_CONFIG_STRING_THREAD_STRUCT,NULL,0}; config_getlist( &THREADParamList,NULL,0,NULL); - if(THREADParamList.numelt>0) { - config_getlist( &THREADParamList,ThreadParams,sizeof(ThreadParams)/sizeof(paramdef_t),NULL); - parallel_conf = strdup(*(THREADParamList.paramarray[0][THREAD_PARALLEL_IDX].strptr)); - } else { - parallel_conf = strdup("PARALLEL_RU_L1_TRX_SPLIT"); + if(parallel_config == NULL){ + if(THREADParamList.numelt>0) { + config_getlist( &THREADParamList,ThreadParams,sizeof(ThreadParams)/sizeof(paramdef_t),NULL); + parallel_conf = strdup(*(THREADParamList.paramarray[0][THREAD_PARALLEL_IDX].strptr)); + } else { + parallel_conf = strdup("PARALLEL_RU_L1_TRX_SPLIT"); + } + set_parallel_conf(parallel_conf); } - if(THREADParamList.numelt>0) { - config_getlist( &THREADParamList,ThreadParams,sizeof(ThreadParams)/sizeof(paramdef_t),NULL); - worker_conf = strdup(*(THREADParamList.paramarray[0][THREAD_WORKER_IDX].strptr)); - } else { - worker_conf = strdup("WORKER_ENABLE"); + if(worker_config == NULL){ + if(THREADParamList.numelt>0) { + config_getlist( &THREADParamList,ThreadParams,sizeof(ThreadParams)/sizeof(paramdef_t),NULL); + worker_conf = strdup(*(THREADParamList.paramarray[0][THREAD_WORKER_IDX].strptr)); + } else { + worker_conf = strdup("WORKER_ENABLE"); + } + set_worker_conf(worker_conf); } - set_parallel_conf(parallel_conf); - set_worker_conf(worker_conf); - return 0; } diff --git a/targets/RT/USER/lte-softmodem-common.c b/targets/RT/USER/lte-softmodem-common.c index c934084a43..5e5c432b13 100644 --- a/targets/RT/USER/lte-softmodem-common.c +++ b/targets/RT/USER/lte-softmodem-common.c @@ -35,6 +35,8 @@ #include "common/config/config_userapi.h" #include "common/utils/load_module_shlib.h" static softmodem_params_t softmodem_params; +char *parallel_config=NULL; +char *worker_config=NULL; uint64_t get_softmodem_optmask(void) { return softmodem_params.optmask; @@ -74,8 +76,6 @@ WORKER_CONF_t get_thread_worker_conf(void) #endif void get_common_options(void) { -char *parallel_config=NULL; -char *worker_config=NULL; uint32_t online_log_messages; From 84d66914f07e725b2c37b624f558c94eae9fc530 Mon Sep 17 00:00:00 2001 From: Raphael Defosseux Date: Thu, 29 Nov 2018 21:47:15 +0100 Subject: [PATCH 183/233] Removed dead code Signed-off-by: Raphael Defosseux --- openair1/PHY/INIT/lte_init_ue.c | 1 + targets/RT/USER/lte-softmodem-common.c | 23 ----------------------- 2 files changed, 1 insertion(+), 23 deletions(-) diff --git a/openair1/PHY/INIT/lte_init_ue.c b/openair1/PHY/INIT/lte_init_ue.c index f82fd4a1ba..1361c41087 100644 --- a/openair1/PHY/INIT/lte_init_ue.c +++ b/openair1/PHY/INIT/lte_init_ue.c @@ -30,6 +30,7 @@ #include "common/utils/LOG/vcd_signal_dumper.h" #include "assertions.h" #include +#include "PHY/LTE_ESTIMATION/lte_estimation.h" #include "PHY/LTE_TRANSPORT/transport_common_proto.h" #include "PHY/LTE_UE_TRANSPORT/transport_proto_ue.h" #include "PHY/LTE_REFSIG/lte_refsig.h" diff --git a/targets/RT/USER/lte-softmodem-common.c b/targets/RT/USER/lte-softmodem-common.c index 5e5c432b13..7e1235b310 100644 --- a/targets/RT/USER/lte-softmodem-common.c +++ b/targets/RT/USER/lte-softmodem-common.c @@ -51,29 +51,6 @@ softmodem_params_t* get_softmodem_params(void) { return &softmodem_params; } -#if 0 -void set_parallel_conf(char *parallel_conf) -{ - if(strcmp(parallel_conf,"PARALLEL_SINGLE_THREAD")==0) softmodem_params.thread_struct.parallel_conf = PARALLEL_SINGLE_THREAD; - else if(strcmp(parallel_conf,"PARALLEL_RU_L1_SPLIT")==0) softmodem_params.thread_struct.parallel_conf = PARALLEL_RU_L1_SPLIT; - else if(strcmp(parallel_conf,"PARALLEL_RU_L1_TRX_SPLIT")==0) softmodem_params.thread_struct.parallel_conf = PARALLEL_RU_L1_TRX_SPLIT; - printf("[CONFIG] parallel conf is set to %d\n",softmodem_params.thread_struct.parallel_conf); -} -void set_worker_conf(char *worker_conf) -{ - if(strcmp(worker_conf,"WORKER_DISABLE")==0) softmodem_params.thread_struct.worker_conf = WORKER_DISABLE; - else if(strcmp(worker_conf,"WORKER_ENABLE")==0) softmodem_params.thread_struct.worker_conf = WORKER_ENABLE; - printf("[CONFIG] worker conf is set to %d\n",softmodem_params.thread_struct.worker_conf); -} -PARALLEL_CONF_t get_thread_parallel_conf(void) -{ - return softmodem_params.thread_struct.parallel_conf; -} -WORKER_CONF_t get_thread_worker_conf(void) -{ - return softmodem_params.thread_struct.worker_conf; -} -#endif void get_common_options(void) { From 41343e7119be7adc0e84c4ff95faa256004ad5f0 Mon Sep 17 00:00:00 2001 From: Raphael Defosseux Date: Mon, 3 Dec 2018 16:00:34 +0100 Subject: [PATCH 184/233] CI: initial testing on FlexRan integration -- Connection w/ basic simulator Signed-off-by: Raphael Defosseux --- ci-scripts/Jenkinsfile-gitlab | 31 ++++- ci-scripts/buildOnVM.sh | 24 +++- ci-scripts/conf_files/lte-fdd-basic-sim.conf | 4 +- ci-scripts/conf_files/lte-tdd-basic-sim.conf | 4 +- ci-scripts/oai-ci-vm-tool | 18 +++ ci-scripts/reportTestLocally.sh | 23 +++ ci-scripts/runTestOnVM.sh | 139 ++++++++++++++++++- ci-scripts/waitBuildOnVM.sh | 8 ++ 8 files changed, 238 insertions(+), 13 deletions(-) diff --git a/ci-scripts/Jenkinsfile-gitlab b/ci-scripts/Jenkinsfile-gitlab index 423e07be92..cf769bfcfe 100644 --- a/ci-scripts/Jenkinsfile-gitlab +++ b/ci-scripts/Jenkinsfile-gitlab @@ -31,6 +31,7 @@ def sendSocialMediaMessage(pipeChannel, pipeColor, pipeMessage) { } def doRedHatBuild = false +def doFlexranCtrlTest = false pipeline { agent { @@ -69,6 +70,12 @@ pipeline { } else { doRedHatBuild = false } + if (params.FlexRanRtcGitLabRepository_Credentials != null) { + doFlexranCtrlTest = True + } + if (fileExists("flexran")) { + sh "rm -Rf flexran > /dev/null 2>&1" + } } } } @@ -103,6 +110,18 @@ pipeline { // For the moment, there is no fail criteria. Just a notification of number of files that do not follow sh "./ci-scripts/checkCodingFormattingRules.sh" } + if (doFlexranCtrlTest) { + sh "mkdir flexran" + dir ('flexran') { + withCredentials([ + [$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.FlexRanRtcGitLabRepository_Credentials}", usernameVariable: 'git_username', passwordVariable: 'git_password'] + ]) { + sh "git clone https://${git_username}:${git_password}@gitlab.eurecom.fr/flexran/flexran-rtc.git . > ../git_clone.log 2>&1" + } + sh "sed -i -e 's#add-apt-repository.*cleishm.*neo4j#add-apt-repository ppa:cleishm/neo4j -y#' -e 's#libneo4j-client-dev#libneo4j-client-dev -y#' tools/install_dependencies" + sh "zip -r -qq flexran.zip ." + } + } } } post { @@ -288,12 +307,22 @@ pipeline { stage ("Test basic simulator") { steps { gitlabCommitStatus(name: "Test basic-sim") { - timeout (time: 20, unit: 'MINUTES') { + timeout (time: 30, unit: 'MINUTES') { sh "./ci-scripts/oai-ci-vm-tool test --workspace $WORKSPACE --variant basic-sim --job-name ${JOB_NAME} --build-id ${BUILD_ID}" } } } } + stage ("Build Flexran Controller") { + when { + expression {doFlexranCtrlTest} + } + steps { + timeout (time: 20, unit: 'MINUTES') { + sh "./ci-scripts/oai-ci-vm-tool test --workspace $WORKSPACE --variant flexran-rtc --job-name ${JOB_NAME} --build-id ${BUILD_ID} --keep-alive" + } + } + } stage ("Test FDD - Band 7 - B210") { steps { script { diff --git a/ci-scripts/buildOnVM.sh b/ci-scripts/buildOnVM.sh index aed449f180..1787d27886 100755 --- a/ci-scripts/buildOnVM.sh +++ b/ci-scripts/buildOnVM.sh @@ -106,7 +106,12 @@ function build_on_vm { echo "############################################################" echo "Copying GIT repo into VM ($VM_NAME)" echo "############################################################" - scp -o StrictHostKeyChecking=no $JENKINS_WKSP/localZip.zip ubuntu@$VM_IP_ADDR:/home/ubuntu + if [[ "$VM_NAME" == *"-flexran-rtc"* ]] + then + scp -o StrictHostKeyChecking=no $JENKINS_WKSP/flexran/flexran.zip ubuntu@$VM_IP_ADDR:/home/ubuntu/localZip.zip + else + scp -o StrictHostKeyChecking=no $JENKINS_WKSP/localZip.zip ubuntu@$VM_IP_ADDR:/home/ubuntu + fi scp -o StrictHostKeyChecking=no /etc/apt/apt.conf.d/01proxy ubuntu@$VM_IP_ADDR:/home/ubuntu echo "############################################################" @@ -126,7 +131,22 @@ function build_on_vm { echo "sudo apt-get update > zip-install.txt 2>&1" >> $VM_CMDS echo "sudo apt-get --yes install zip daemon cppcheck >> zip-install.txt 2>&1" >> $VM_CMDS fi - else + fi + if [[ "$VM_NAME" == *"-flexran-rtc"* ]] + then + if [ $DAEMON -eq 0 ] + then + echo "echo \"sudo apt-get --yes --quiet install zip curl jq \"" >> $VM_CMDS + echo "sudo apt-get update > zip-install.txt 2>&1" >> $VM_CMDS + echo "sudo apt-get --yes install zip curl jq >> zip-install.txt 2>&1" >> $VM_CMDS + else + echo "echo \"sudo apt-get --yes --quiet install zip daemon curl jq \"" >> $VM_CMDS + echo "sudo apt-get update > zip-install.txt 2>&1" >> $VM_CMDS + echo "sudo apt-get --yes install zip daemon curl jq >> zip-install.txt 2>&1" >> $VM_CMDS + fi + fi + if [[ "$VM_NAME" != *"-cppcheck"* ]] && [[ "$VM_NAME" != *"-flexran-rtc"* ]] + then if [ $DAEMON -eq 0 ] then echo "echo \"sudo apt-get --yes --quiet install zip subversion libboost-dev \"" >> $VM_CMDS diff --git a/ci-scripts/conf_files/lte-fdd-basic-sim.conf b/ci-scripts/conf_files/lte-fdd-basic-sim.conf index 1d1395cf6d..594e3299db 100644 --- a/ci-scripts/conf_files/lte-fdd-basic-sim.conf +++ b/ci-scripts/conf_files/lte-fdd-basic-sim.conf @@ -237,8 +237,8 @@ THREAD_STRUCT = ( NETWORK_CONTROLLER : { FLEXRAN_ENABLED = "no"; - FLEXRAN_INTERFACE_NAME = "lo"; - FLEXRAN_IPV4_ADDRESS = "127.0.0.1"; + FLEXRAN_INTERFACE_NAME = "ens3"; + FLEXRAN_IPV4_ADDRESS = "CI_FLEXRAN_CTL_IP_ADDR"; FLEXRAN_PORT = 2210; FLEXRAN_CACHE = "/mnt/oai_agent_cache"; FLEXRAN_AWAIT_RECONF = "no"; diff --git a/ci-scripts/conf_files/lte-tdd-basic-sim.conf b/ci-scripts/conf_files/lte-tdd-basic-sim.conf index 32a84fd206..da330d2379 100644 --- a/ci-scripts/conf_files/lte-tdd-basic-sim.conf +++ b/ci-scripts/conf_files/lte-tdd-basic-sim.conf @@ -217,8 +217,8 @@ THREAD_STRUCT = ( NETWORK_CONTROLLER : { FLEXRAN_ENABLED = "no"; - FLEXRAN_INTERFACE_NAME = "lo"; - FLEXRAN_IPV4_ADDRESS = "127.0.0.1"; + FLEXRAN_INTERFACE_NAME = "ens3"; + FLEXRAN_IPV4_ADDRESS = "CI_FLEXRAN_CTL_IP_ADDR"; FLEXRAN_PORT = 2210; FLEXRAN_CACHE = "/mnt/oai_agent_cache"; FLEXRAN_AWAIT_RECONF = "no"; diff --git a/ci-scripts/oai-ci-vm-tool b/ci-scripts/oai-ci-vm-tool index cfa18ece2e..8bf7853d0c 100755 --- a/ci-scripts/oai-ci-vm-tool +++ b/ci-scripts/oai-ci-vm-tool @@ -40,6 +40,7 @@ function variant_usage { echo " --variant cppcheck OR -v4" echo " --variant enb-ethernet OR -v7" echo " --variant ue-ethernet OR -v8" + echo " --variant flexran-rtc OR -v10" } MY_DIR=$(dirname $(readlink -f $0)) @@ -284,6 +285,15 @@ case $key in NBARGS=$[$NBARGS+256] shift ;; + -v10) + VM_NAME=ci-flexran-rtc + ARCHIVES_LOC=flexran + LOG_PATTERN=.Rel14.txt + NB_PATTERN_FILES=1 + BUILD_OPTIONS="cmake . && make -j2" + NBARGS=$[$NBARGS+256] + shift + ;; --variant) variant="$2" case $variant in @@ -340,6 +350,14 @@ case $key in BUILD_OPTIONS="--UE -t ETHERNET --noS1" NBARGS=$[$NBARGS+256] ;; + flexran-rtc) + VM_NAME=ci-flexran-rtc + ARCHIVES_LOC=flexran + LOG_PATTERN=.Rel14.txt + NB_PATTERN_FILES=1 + BUILD_OPTIONS="cmake . && make -j2" + NBARGS=$[$NBARGS+256] + ;; *) echo "" echo "Syntax Error: Invalid Variant option -> $variant" diff --git a/ci-scripts/reportTestLocally.sh b/ci-scripts/reportTestLocally.sh index 7bbf52ca2b..372b949aa8 100755 --- a/ci-scripts/reportTestLocally.sh +++ b/ci-scripts/reportTestLocally.sh @@ -362,6 +362,29 @@ function report_test { echo " " >> ./test_simulator_results.html fi + if [ -e $JENKINS_WKSP/flexran/flexran_build_complete.txt ] + then + echo "

    Basic Simulator + FlexRan Controller Check

    " >> ./test_simulator_results.html + echo " " >> ./test_simulator_results.html + echo " " >> ./test_simulator_results.html + echo " " >> ./test_simulator_results.html + echo " " >> ./test_simulator_results.html + echo " " >> ./test_simulator_results.html + + FLEXRAN_QUERIES=`ls $ARCHIVES_LOC/flexran_ctl_query_*log` + for QUERY in $FLEXRAN_QUERIES + do + echo " " >> ./test_simulator_results.html + NAME=`echo $QUERY | sed -e "s#$ARCHIVES_LOC/##"` + echo " " >> ./test_simulator_results.html + echo " " >> ./test_simulator_results.html + echo " " >> ./test_simulator_results.html + done + echo "
    Log File NameJSON Query Response
    $NAME
    " >> ./test_simulator_results.html
    +            egrep -v "LOG_NAME|\-\-\-\-\-" $QUERY >> ./test_simulator_results.html
    +            echo "        
    " >> ./test_simulator_results.html + fi + ARCHIVES_LOC=archives/phy_sim/test if [ -d $ARCHIVES_LOC ] then diff --git a/ci-scripts/runTestOnVM.sh b/ci-scripts/runTestOnVM.sh index 527fe48edb..40ea22d853 100755 --- a/ci-scripts/runTestOnVM.sh +++ b/ci-scripts/runTestOnVM.sh @@ -61,6 +61,7 @@ function start_basic_sim_enb { local LOC_LOG_FILE=$4 local LOC_NB_RBS=$5 local LOC_CONF_FILE=$6 + local LOC_FLEXRAN_CTL_IP_ADRR=$7 echo "cd /home/ubuntu/tmp" > $1 echo "echo \"sudo apt-get --yes --quiet install daemon \"" >> $1 echo "sudo apt-get --yes install daemon >> /home/ubuntu/tmp/cmake_targets/log/daemon-install.txt 2>&1" >> $1 @@ -71,6 +72,12 @@ function start_basic_sim_enb { echo "cd ci-scripts/conf_files/" >> $1 echo "cp $LOC_CONF_FILE ci-$LOC_CONF_FILE" >> $1 echo "sed -i -e 's#N_RB_DL.*=.*;#N_RB_DL = $LOC_NB_RBS;#' -e 's#CI_MME_IP_ADDR#$LOC_EPC_IP_ADDR#' -e 's#CI_ENB_IP_ADDR#$LOC_VM_IP_ADDR#' ci-$LOC_CONF_FILE" >> $1 + if [[ $LOC_FLEXRAN_CTL_IP_ADRR =~ .*none.* ]] + then + echo "sed -i -e 's#CI_FLEXRAN_CTL_IP_ADDR#127.0.0.1#' ci-$LOC_CONF_FILE" >> $1 + else + echo "sed -i -e 's#FLEXRAN_ENABLED = .*no.*;#FLEXRAN_ENABLED = \"yes\";#' -e 's#CI_FLEXRAN_CTL_IP_ADDR#$LOC_FLEXRAN_CTL_IP_ADRR#' ci-$LOC_CONF_FILE" >> $1 + fi echo "echo \"grep N_RB_DL ci-$LOC_CONF_FILE\"" >> $1 echo "grep N_RB_DL ci-$LOC_CONF_FILE | sed -e 's#N_RB_DL.*=#N_RB_DL =#'" >> $1 echo "echo \"cd /home/ubuntu/tmp/cmake_targets/basic_simulator/enb/\"" >> $1 @@ -286,6 +293,35 @@ function terminate_ltebox_epc { rm $1 } +function start_flexran_ctrl { + echo "cd /home/ubuntu/tmp" > $1 + echo "if [ -f cmake_targets/log/flexran_ctl_run.log ]; then rm -f cmake_targets/log/flexran_ctl_run.log cmake_targets/log/flexran_ctl_query*.log; fi" >> $1 + echo "echo \" sudo build/rt_controller -c log_config/basic_log\"" >> $1 + echo "nohup sudo build/rt_controller -c log_config/basic_log > cmake_targets/log/flexran_ctl_run.log 2>&1 &" >> $1 + ssh -o StrictHostKeyChecking=no ubuntu@$2 < $1 + rm $1 + sleep 10 +} + +function stop_flexran_ctrl { + echo "echo \"sudo killall --signal SIGKILL rt_controller\"" > $1 + echo "sudo killall --signal SIGKILL rt_controller" > $1 + ssh -o StrictHostKeyChecking=no ubuntu@$2 < $1 + rm $1 + sleep 2 +} + +function query_flexran_ctrl_status { + local LOC_MESSAGE=$3 + echo "cd /home/ubuntu/tmp" > $1 + echo "echo \"------------------------------------------------------------\" > cmake_targets/log/flexran_ctl_query_${LOC_MESSAGE}.log" >> $1 + echo "echo \"LOG_NAME: $LOC_MESSAGE\" >> cmake_targets/log/flexran_ctl_query_${LOC_MESSAGE}.log" >> $1 + echo "echo \"------------------------------------------------------------\" >> cmake_targets/log/flexran_ctl_query_${LOC_MESSAGE}.log" >> $1 + echo "curl http://localhost:9999/stats | jq '.' | tee -a cmake_targets/log/flexran_ctl_query_${LOC_MESSAGE}.log" >> $1 + ssh -o StrictHostKeyChecking=no ubuntu@$2 < $1 + rm $1 +} + function run_test_on_vm { echo "############################################################" echo "OAI CI VM script" @@ -564,7 +600,7 @@ function run_test_on_vm { echo "Starting the eNB in FDD-5MHz mode" echo "############################################################" CURRENT_ENB_LOG_FILE=fdd_05MHz_enb.log - start_basic_sim_enb $VM_CMDS $VM_IP_ADDR $EPC_VM_IP_ADDR $CURRENT_ENB_LOG_FILE 25 lte-fdd-basic-sim.conf + start_basic_sim_enb $VM_CMDS $VM_IP_ADDR $EPC_VM_IP_ADDR $CURRENT_ENB_LOG_FILE 25 lte-fdd-basic-sim.conf none echo "############################################################" echo "Starting the UE in FDD-5MHz mode" @@ -622,7 +658,7 @@ function run_test_on_vm { echo "Starting the eNB in FDD-10MHz mode" echo "############################################################" CURRENT_ENB_LOG_FILE=fdd_10MHz_enb.log - start_basic_sim_enb $VM_CMDS $VM_IP_ADDR $EPC_VM_IP_ADDR $CURRENT_ENB_LOG_FILE 50 lte-fdd-basic-sim.conf + start_basic_sim_enb $VM_CMDS $VM_IP_ADDR $EPC_VM_IP_ADDR $CURRENT_ENB_LOG_FILE 50 lte-fdd-basic-sim.conf none echo "############################################################" echo "Starting the UE in FDD-10MHz mode" @@ -680,7 +716,7 @@ function run_test_on_vm { echo "Starting the eNB in FDD-20MHz mode" echo "############################################################" CURRENT_ENB_LOG_FILE=fdd_20MHz_enb.log - start_basic_sim_enb $VM_CMDS $VM_IP_ADDR $EPC_VM_IP_ADDR $CURRENT_ENB_LOG_FILE 100 lte-fdd-basic-sim.conf + start_basic_sim_enb $VM_CMDS $VM_IP_ADDR $EPC_VM_IP_ADDR $CURRENT_ENB_LOG_FILE 100 lte-fdd-basic-sim.conf none echo "############################################################" echo "Starting the UE in FDD-20MHz mode" @@ -725,11 +761,97 @@ function run_test_on_vm { recover_core_dump $VM_CMDS $VM_IP_ADDR $ARCHIVES_LOC/$CURRENT_ENB_LOG_FILE $ARCHIVES_LOC sleep 10 + if [ -d $JENKINS_WKSP/flexran ] + then + echo "############################################################" + echo "Flexran testing is possible" + echo "############################################################" + local j="0" + while [ $j -lt 20 ] + do + if [ -e $JENKINS_WKSP/flexran/flexran_build_complete.txt ] + then + echo "Found an proper flexran controller vm build" + j="100" + else + j=$[$j+1] + sleep 30 + fi + done + if [ $j -lt 50 ] + then + echo "ERROR: compiling flexran controller on vm went wrong" + terminate_ltebox_epc $EPC_VM_CMDS $EPC_VM_IP_ADDR + exit -1 + fi + FLEXRAN_CTL_VM_NAME=`echo $VM_NAME | sed -e "s#basic-sim#flexran-rtc#"` + FLEXRAN_CTL_VM_CMDS=`echo $VM_CMDS | sed -e "s#cmds#flexran-rtc-cmds#"` + IS_FLEXRAN_VM_ALIVE=`uvt-kvm list | grep -c $FLEXRAN_CTL_VM_NAME` + if [ $IS_FLEXRAN_VM_ALIVE -eq 0 ] + then + echo "ERROR: Flexran Ctl VM is not alive" + terminate_ltebox_epc $EPC_VM_CMDS $EPC_VM_IP_ADDR + exit -1 + fi + uvt-kvm wait $FLEXRAN_CTL_VM_NAME --insecure + FLEXRAN_CTL_VM_IP_ADDR=`uvt-kvm ip $FLEXRAN_CTL_VM_NAME` + + echo "$FLEXRAN_CTL_VM_NAME has for IP addr = $FLEXRAN_CTL_VM_IP_ADDR" + echo "FLEXRAN_CTL_VM_CMDS = $FLEXRAN_CTL_VM_CMDS" + echo "############################################################" + echo "Starting the FLEXRAN CONTROLLER" + echo "############################################################" + start_flexran_ctrl $FLEXRAN_CTL_VM_CMDS $FLEXRAN_CTL_VM_IP_ADDR + query_flexran_ctrl_status $FLEXRAN_CTL_VM_CMDS $FLEXRAN_CTL_VM_IP_ADDR 01_no_enb_connected + + echo "############################################################" + echo "Starting the eNB in FDD-5MHz mode with Flexran ON" + echo "############################################################" + CURRENT_ENB_LOG_FILE=fdd_05fMHz_enb.log + start_basic_sim_enb $VM_CMDS $VM_IP_ADDR $EPC_VM_IP_ADDR $CURRENT_ENB_LOG_FILE 25 lte-fdd-basic-sim.conf $FLEXRAN_CTL_VM_IP_ADDR + query_flexran_ctrl_status $FLEXRAN_CTL_VM_CMDS $FLEXRAN_CTL_VM_IP_ADDR 02_enb_connected + + echo "############################################################" + echo "Starting the UE in FDD-5MHz mode" + echo "############################################################" + CURRENT_UE_LOG_FILE=fdd_05fMHz_ue.log + start_basic_sim_ue $VM_CMDS $VM_IP_ADDR $CURRENT_UE_LOG_FILE 25 2680 + if [ $UE_SYNC -eq 0 ] + then + echo "Problem w/ eNB and UE not syncing" + terminate_enb_ue_basic_sim $VM_CMDS $VM_IP_ADDR + scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_ENB_LOG_FILE $ARCHIVES_LOC + scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_UE_LOG_FILE $ARCHIVES_LOC + recover_core_dump $VM_CMDS $VM_IP_ADDR $ARCHIVES_LOC/$CURRENT_ENB_LOG_FILE $ARCHIVES_LOC + terminate_ltebox_epc $EPC_VM_CMDS $EPC_VM_IP_ADDR + stop_flexran_ctrl $FLEXRAN_CTL_VM_CMDS $FLEXRAN_CTL_VM_IP_ADDR + exit -1 + fi + query_flexran_ctrl_status $FLEXRAN_CTL_VM_CMDS $FLEXRAN_CTL_VM_IP_ADDR 03_enb_ue_connected + get_ue_ip_addr $VM_CMDS $VM_IP_ADDR + + sleep 30 + echo "############################################################" + echo "Terminate enb/ue simulators" + echo "############################################################" + terminate_enb_ue_basic_sim $VM_CMDS $VM_IP_ADDR + scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_ENB_LOG_FILE $ARCHIVES_LOC + scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_UE_LOG_FILE $ARCHIVES_LOC + recover_core_dump $VM_CMDS $VM_IP_ADDR $ARCHIVES_LOC/$CURRENT_ENB_LOG_FILE $ARCHIVES_LOC + sleep 10 + + echo "############################################################" + echo "Stopping the FLEXRAN CONTROLLER" + echo "############################################################" + stop_flexran_ctrl $FLEXRAN_CTL_VM_CMDS $FLEXRAN_CTL_VM_IP_ADDR + scp -o StrictHostKeyChecking=no ubuntu@$FLEXRAN_CTL_VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/flexran_ctl_*.log $ARCHIVES_LOC + fi + echo "############################################################" echo "Starting the eNB in TDD-5MHz mode" echo "############################################################" CURRENT_ENB_LOG_FILE=tdd_05MHz_enb.log - start_basic_sim_enb $VM_CMDS $VM_IP_ADDR $EPC_VM_IP_ADDR $CURRENT_ENB_LOG_FILE 25 lte-tdd-basic-sim.conf + start_basic_sim_enb $VM_CMDS $VM_IP_ADDR $EPC_VM_IP_ADDR $CURRENT_ENB_LOG_FILE 25 lte-tdd-basic-sim.conf none echo "############################################################" echo "Starting the UE in TDD-5MHz mode" @@ -779,7 +901,7 @@ function run_test_on_vm { echo "Starting the eNB in TDD-10MHz mode" echo "############################################################" CURRENT_ENB_LOG_FILE=tdd_10MHz_enb.log - start_basic_sim_enb $VM_CMDS $VM_IP_ADDR $EPC_VM_IP_ADDR $CURRENT_ENB_LOG_FILE 50 lte-tdd-basic-sim.conf + start_basic_sim_enb $VM_CMDS $VM_IP_ADDR $EPC_VM_IP_ADDR $CURRENT_ENB_LOG_FILE 50 lte-tdd-basic-sim.conf none echo "############################################################" echo "Starting the UE in TDD-10MHz mode" @@ -828,7 +950,7 @@ function run_test_on_vm { echo "Starting the eNB in TDD-20MHz mode" echo "############################################################" CURRENT_ENB_LOG_FILE=tdd_20MHz_enb.log - start_basic_sim_enb $VM_CMDS $VM_IP_ADDR $EPC_VM_IP_ADDR $CURRENT_ENB_LOG_FILE 100 lte-tdd-basic-sim.conf + start_basic_sim_enb $VM_CMDS $VM_IP_ADDR $EPC_VM_IP_ADDR $CURRENT_ENB_LOG_FILE 100 lte-tdd-basic-sim.conf none echo "############################################################" echo "Starting the UE in TDD-20MHz mode" @@ -891,6 +1013,11 @@ function run_test_on_vm { ssh-keygen -R $VM_IP_ADDR uvt-kvm destroy $EPC_VM_NAME ssh-keygen -R $EPC_VM_IP_ADDR + if [ -e $JENKINS_WKSP/flexran/flexran_build_complete.txt ] + then + uvt-kvm destroy $FLEXRAN_CTL_VM_NAME + ssh-keygen -R $FLEXRAN_CTL_VM_IP_ADDR + fi fi echo "############################################################" diff --git a/ci-scripts/waitBuildOnVM.sh b/ci-scripts/waitBuildOnVM.sh index bee11f2820..e39e03702f 100755 --- a/ci-scripts/waitBuildOnVM.sh +++ b/ci-scripts/waitBuildOnVM.sh @@ -167,4 +167,12 @@ function check_on_vm_build { if [ $NB_PATTERN_FILES -ne $NB_FOUND_FILES ]; then STATUS=-1; fi + # If we were building the FlexRan Controller, flag-touch for basic-simulator to continue + if [[ "$VM_NAME" == *"-flexran-rtc"* ]] + then + if [[ $STATUS -eq 0 ]] + then + touch $JENKINS_WKSP/flexran/flexran_build_complete.txt + fi + fi } From b474d4a7f3d653de7cae88186ee04ad7995b18ba Mon Sep 17 00:00:00 2001 From: Raphael Defosseux Date: Mon, 3 Dec 2018 16:09:36 +0100 Subject: [PATCH 185/233] CI: typo Signed-off-by: Raphael Defosseux --- ci-scripts/Jenkinsfile-gitlab | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-scripts/Jenkinsfile-gitlab b/ci-scripts/Jenkinsfile-gitlab index cf769bfcfe..dba36b73d6 100644 --- a/ci-scripts/Jenkinsfile-gitlab +++ b/ci-scripts/Jenkinsfile-gitlab @@ -71,7 +71,7 @@ pipeline { doRedHatBuild = false } if (params.FlexRanRtcGitLabRepository_Credentials != null) { - doFlexranCtrlTest = True + doFlexranCtrlTest = true } if (fileExists("flexran")) { sh "rm -Rf flexran > /dev/null 2>&1" From e6ef20e1f95635222128dda3ff4be6bbb9bc92bc Mon Sep 17 00:00:00 2001 From: Raphael Defosseux Date: Mon, 3 Dec 2018 16:25:02 +0100 Subject: [PATCH 186/233] CI: missing building code for flexran controller Signed-off-by: Raphael Defosseux --- ci-scripts/buildOnVM.sh | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/ci-scripts/buildOnVM.sh b/ci-scripts/buildOnVM.sh index 1787d27886..f9fb3b776f 100755 --- a/ci-scripts/buildOnVM.sh +++ b/ci-scripts/buildOnVM.sh @@ -176,7 +176,19 @@ function build_on_vm { echo "chmod 775 ./my-vm-build.sh " >> $VM_CMDS echo "sudo -E daemon --inherit --unsafe --name=build_daemon --chdir=/home/ubuntu/tmp -O /home/ubuntu/tmp/cmake_targets/log/cppcheck_build.txt -E /home/ubuntu/tmp/cmake_targets/log/cppcheck.xml ./my-vm-build.sh" >> $VM_CMDS fi - else + fi + if [[ "$VM_NAME" == *"-flexran-rtc"* ]] + then + echo "mkdir -p cmake_targets/log" >> $VM_CMDS + echo "chmod 777 cmake_targets/log" >> $VM_CMDS + echo "cp /home/ubuntu/zip-install.txt cmake_targets/log" >> $VM_CMDS + echo "echo \"./tools/install_dependencies \"" >> $VM_CMDS + echo "./tools/install_dependencies > cmake_targets/log/install-build.txt 2>&1" >> $VM_CMDS + echo "echo \"$BUILD_OPTIONS \"" >> $VM_CMDS + echo "$BUILD_OPTIONS > cmake_targets/log/rt_controller.Rel14.txt 2>&1" >> $VM_CMDS + fi + if [[ "$VM_NAME" != *"-cppcheck"* ]] && [[ "$VM_NAME" != *"-flexran-rtc"* ]] + then echo "echo \"source oaienv\"" >> $VM_CMDS echo "source oaienv" >> $VM_CMDS echo "cd cmake_targets/" >> $VM_CMDS From a36c1e4c62795dfa1b331989fff3db9307a72b5d Mon Sep 17 00:00:00 2001 From: Raphael Defosseux Date: Mon, 3 Dec 2018 18:43:32 +0100 Subject: [PATCH 187/233] CI: building not testing the flexran controller VM Signed-off-by: Raphael Defosseux --- ci-scripts/Jenkinsfile-gitlab | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-scripts/Jenkinsfile-gitlab b/ci-scripts/Jenkinsfile-gitlab index dba36b73d6..b4b9ceb565 100644 --- a/ci-scripts/Jenkinsfile-gitlab +++ b/ci-scripts/Jenkinsfile-gitlab @@ -319,7 +319,7 @@ pipeline { } steps { timeout (time: 20, unit: 'MINUTES') { - sh "./ci-scripts/oai-ci-vm-tool test --workspace $WORKSPACE --variant flexran-rtc --job-name ${JOB_NAME} --build-id ${BUILD_ID} --keep-alive" + sh "./ci-scripts/oai-ci-vm-tool build --workspace $WORKSPACE --variant flexran-rtc --job-name ${JOB_NAME} --build-id ${BUILD_ID} --keep-alive" } } } From 81a4d5d3be62f4dc04e890d61bf71ee7d4b84f66 Mon Sep 17 00:00:00 2001 From: Raphael Defosseux Date: Mon, 3 Dec 2018 20:28:01 +0100 Subject: [PATCH 188/233] CI: syntax error Signed-off-by: Raphael Defosseux --- ci-scripts/Jenkinsfile-gitlab | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-scripts/Jenkinsfile-gitlab b/ci-scripts/Jenkinsfile-gitlab index b4b9ceb565..0d9f37ed24 100644 --- a/ci-scripts/Jenkinsfile-gitlab +++ b/ci-scripts/Jenkinsfile-gitlab @@ -319,7 +319,7 @@ pipeline { } steps { timeout (time: 20, unit: 'MINUTES') { - sh "./ci-scripts/oai-ci-vm-tool build --workspace $WORKSPACE --variant flexran-rtc --job-name ${JOB_NAME} --build-id ${BUILD_ID} --keep-alive" + sh "./ci-scripts/oai-ci-vm-tool build --workspace $WORKSPACE --variant flexran-rtc --job-name ${JOB_NAME} --build-id ${BUILD_ID} --keep-vm-alive" } } } From 5012faa1058ad1ce300a837595c499bb6ff11ab0 Mon Sep 17 00:00:00 2001 From: Raphael Defosseux Date: Tue, 4 Dec 2018 16:11:02 +0100 Subject: [PATCH 189/233] CI: HTML reporting improvements with bootstrap usage Signed-off-by: Raphael Defosseux --- ci-scripts/buildOnRH.sh | 8 ++- ci-scripts/main.py | 22 ++++--- ci-scripts/reportBuildLocally.sh | 106 +++++++++++++++++++++++-------- ci-scripts/reportTestLocally.sh | 59 ++++++++++++++++- ci-scripts/runTestOnVM.sh | 22 +++++++ ci-scripts/waitBuildOnVM.sh | 13 +++- 6 files changed, 191 insertions(+), 39 deletions(-) diff --git a/ci-scripts/buildOnRH.sh b/ci-scripts/buildOnRH.sh index ce5b24dc49..bb57cde165 100755 --- a/ci-scripts/buildOnRH.sh +++ b/ci-scripts/buildOnRH.sh @@ -198,12 +198,18 @@ do fi done -if [ $NB_PATTERN_FILES -ne $NB_FOUND_FILES ]; then STATUS=-1; fi +if [ $NB_PATTERN_FILES -ne $NB_FOUND_FILES ] +then + echo "Expecting $NB_PATTERN_FILES log files and found $NB_FOUND_FILES" + STATUS=-1 +fi if [ $STATUS -eq 0 ] then + echo "BUILD_OK" > $ARCHIVES_LOC/build_final_status.log echo "STATUS seems OK" else + echo "BUILD_KO" > $ARCHIVES_LOC/build_final_status.log echo "STATUS failed?" fi exit $STATUS diff --git a/ci-scripts/main.py b/ci-scripts/main.py index 8d5ca76b78..51af244530 100644 --- a/ci-scripts/main.py +++ b/ci-scripts/main.py @@ -670,9 +670,9 @@ class SSHConnection(): device_id = status_queue.get() message = status_queue.get() if (count < 0): - html_cell = "
    UE (" + device_id + ")\n" + message + "
    " + html_cell = '
    UE (' + device_id + ')\n' + message + '
    ' else: - html_cell = "
    UE (" + device_id + ")\n" + message + ' in ' + str(count + 2) + ' seconds
    ' + html_cell = '
    UE (' + device_id + ')\n' + message + ' in ' + str(count + 2) + ' seconds
    ' html_queue.put(html_cell) if (attach_status): self.CreateHtmlTestRowQueue('N/A', 'OK', len(self.UEDevices), html_queue) @@ -955,7 +955,7 @@ class SSHConnection(): device_id = status_queue.get() ip_addr = status_queue.get() message = status_queue.get() - html_cell = "
    UE (" + device_id + ")\nIP Address  : " + ip_addr + "\n" + message + "
    " + html_cell = '
    UE (' + device_id + ')\nIP Address  : ' + ip_addr + '\n' + message + '
    ' html_queue.put(html_cell) if (ping_status): self.CreateHtmlTestRowQueue(self.ping_args, 'OK', len(self.UEDevices), html_queue) @@ -1438,7 +1438,7 @@ class SSHConnection(): device_id = status_queue.get() ip_addr = status_queue.get() message = status_queue.get() - html_cell = "
    UE (" + device_id + ")\nIP Address  : " + ip_addr + "\n" + message + "
    " + html_cell = '
    UE (' + device_id + ')\nIP Address  : ' + ip_addr + '\n' + message + '
    ' html_queue.put(html_cell) if (iperf_noperf and iperf_status): self.CreateHtmlTestRowQueue(self.iperf_args, 'PERF NOT MET', len(self.UEDevices), html_queue) @@ -1923,9 +1923,13 @@ class SSHConnection(): self.htmlFile.write('\n') self.htmlFile.write('\n') self.htmlFile.write('\n') + self.htmlFile.write(' \n') + self.htmlFile.write(' \n') + self.htmlFile.write(' \n') + self.htmlFile.write(' \n') self.htmlFile.write(' Test Results for TEMPLATE_JOB_NAME job build #TEMPLATE_BUILD_ID\n') self.htmlFile.write('\n') - self.htmlFile.write('\n') + self.htmlFile.write('
    \n') self.htmlFile.write(' \n') self.htmlFile.write(' \n') self.htmlFile.write(' \n') self.htmlFile.write(' \n') self.htmlFile.write('
    \n') @@ -2016,7 +2020,8 @@ class SSHConnection(): self.htmlFile.write(' FAIL
    \n') - self.htmlFile.write('\n') + self.htmlFile.write('
    End of Test Report -- Copyright 2018 OpenAirInterface. All Rights Reserved.
    \n') + self.htmlFile.write('
    \n') self.htmlFile.write('\n') self.htmlFile.close() self.htmlFooterCreated = False @@ -2061,7 +2066,8 @@ class SSHConnection(): result = re.search('showed|Reestablishment', self.htmleNBFailureMsg) if result is not None: cellBgColor = 'orange' - self.htmlFile.write('
    ' + self.htmleNBFailureMsg + '
    \n') + self.htmlFile.write('
    ' + self.htmleNBFailureMsg + '
    \n') self.htmleNBFailureMsg = '' else: i = 0 @@ -2089,7 +2095,7 @@ class SSHConnection(): if (i < ue_status): if (not ue_queue.empty()): if (addOrangeBK): - self.htmlFile.write(' ' + str(ue_queue.get()) + '\n') + self.htmlFile.write(' ' + str(ue_queue.get()).replace('white', 'orange') + '\n') else: self.htmlFile.write(' ' + str(ue_queue.get()) + '\n') else: diff --git a/ci-scripts/reportBuildLocally.sh b/ci-scripts/reportBuildLocally.sh index 1b97841e69..c42ecef00b 100755 --- a/ci-scripts/reportBuildLocally.sh +++ b/ci-scripts/reportBuildLocally.sh @@ -141,6 +141,23 @@ function details_table { function summary_table_header { echo "

    $1

    " >> ./build_results.html + if [ -f $2/build_final_status.log ] + then + if [ `grep -c BUILD_OK $2/build_final_status.log` -eq 1 ] + then + echo "
    " >> ./build_results.html + echo " BUILD was SUCCESSFUL " >> ./build_results.html + echo "
    " >> ./build_results.html + else + echo "
    " >> ./build_results.html + echo " BUILD was a FAILURE! " >> ./build_results.html + echo "
    " >> ./build_results.html + fi + else + echo "
    " >> ./build_results.html + echo " COULD NOT DETERMINE BUILD FINAL STATUS! " >> ./build_results.html + echo "
    " >> ./build_results.html + fi echo " " >> ./build_results.html echo " " >> ./build_results.html echo " " >> ./build_results.html @@ -198,7 +215,28 @@ function summary_table_footer { } function sca_summary_table_header { - echo "

    $1

    " >> ./build_results.html + echo "

    $2

    " >> ./build_results.html + NB_ERRORS=`egrep -c "severity=\"error\"" $1` + NB_WARNINGS=`egrep -c "severity=\"warning\"" $1` + if [ $NB_ERRORS -eq 0 ] && [ $NB_WARNINGS -eq 0 ] + then + echo "
    " >> ./build_results.html + echo " CPPCHECK found NO error and NO warning " >> ./build_results.html + echo "
    " >> ./build_results.html + else + if [ $NB_ERRORS -eq 0 ] + then + echo "
    " >> ./build_results.html + echo " CPPCHECK found NO error and $NB_WARNINGS warnings " >> ./build_results.html + echo "
    " >> ./build_results.html + else + echo "
    " >> ./build_results.html + echo " CPPCHECK found $NB_ERRORS errors and $NB_WARNINGS warnings " >> ./build_results.html + echo "
    " >> ./build_results.html + fi + fi + echo " " >> ./build_results.html + echo "
    " >> ./build_results.html echo "
    Element
    " >> ./build_results.html echo " " >> ./build_results.html echo " " >> ./build_results.html @@ -263,6 +301,7 @@ function sca_summary_table_footer { echo "
    Error / Warning Type
    " >> ./build_results.html echo "

    Full details in zipped artifact (cppcheck/cppcheck.xml)

    " >> ./build_results.html echo "

    Graphical Interface tool : cppcheck-gui -l cppcheck/cppcheck.xml

    " >> ./build_results.html + echo " " >> ./build_results.html } function report_build { @@ -276,10 +315,14 @@ function report_build { echo "" > ./build_results.html echo "" >> ./build_results.html echo "" >> ./build_results.html + echo " " >> ./build_results.html + echo " " >> ./build_results.html + echo " " >> ./build_results.html + echo " " >> ./build_results.html echo " Build Results for $JOB_NAME job build #$BUILD_ID" >> ./build_results.html echo " " >> ./build_results.html echo "" >> ./build_results.html - echo "" >> ./build_results.html + echo "
    " >> ./build_results.html echo " " >> ./build_results.html echo " " >> ./build_results.html echo " " >> ./build_results.html; fi - if [ $MR_TRIG -eq 1 ]; then echo " " >> ./build_results.html; fi - echo " " >> ./build_results.html - if [ -f ./oai_rules_result_list.txt ] - then - awk '{print " "}' ./oai_rules_result_list.txt >> ./build_results.html - fi - echo "
    " >> ./build_results.html @@ -344,33 +387,38 @@ function report_build { if [ -f ./oai_rules_result.txt ] then echo "

    OAI Coding / Formatting Guidelines Check

    " >> ./build_results.html - echo " " >> ./build_results.html - echo " " >> ./build_results.html - echo " " >> ./build_results.html NB_FILES=`cat ./oai_rules_result.txt` if [ $NB_FILES = "0" ] then - if [ $PU_TRIG -eq 1 ]; then echo " " >> ./build_results.html; fi - if [ $MR_TRIG -eq 1 ]; then echo " " >> ./build_results.html; fi - echo " " >> ./build_results.html - echo "
    Result:All files in repository follow OAI rules. All modified files in Merge-Request follow OAI rules.
    " >> ./build_results.html + echo "
    " >> ./build_results.html + if [ $PU_TRIG -eq 1 ]; then echo " All files in repository follow OAI rules. " >> ./build_results.html; fi + if [ $MR_TRIG -eq 1 ]; then echo " All modified files in Merge-Request follow OAI rules. " >> ./build_results.html; fi + echo "
    " >> ./build_results.html else - if [ $PU_TRIG -eq 1 ]; then echo "
    $NB_FILES files in repository DO NOT follow OAI rules. $NB_FILES modified files in Merge-Request DO NOT follow OAI rules.
    "$1"
    " >> ./build_results.html + echo "
    " >> ./build_results.html + if [ $PU_TRIG -eq 1 ]; then echo " $NB_FILES files in repository DO NOT follow OAI rules. " >> ./build_results.html; fi + if [ $MR_TRIG -eq 1 ]; then echo " $NB_FILES modified files in Merge-Request DO NOT follow OAI rules. " >> ./build_results.html; fi + echo "
    " >> ./build_results.html + fi + if [ -f ./oai_rules_result_list.txt ] + then + echo " " >> ./build_results.html + echo "
    " >> ./build_results.html echo "

    Please apply the following command to this(ese) file(s):

    " >> ./build_results.html echo "

    astyle --options=ci-scripts/astyle-options.txt filename(s)

    " >> ./build_results.html + echo " " >> ./build_results.html + echo " " >> ./build_results.html + echo " " >> ./build_results.html + echo " " >> ./build_results.html + awk '{print " "}' ./oai_rules_result_list.txt >> ./build_results.html + echo "
    Filename
    "$1"
    " >> ./build_results.html + echo "
    " >> ./build_results.html fi fi echo "

    Ubuntu 16.04 LTS -- Summary

    " >> ./build_results.html - sca_summary_table_header "OAI Static Code Analysis with CPPCHECK" + sca_summary_table_header ./archives/cppcheck/cppcheck.xml "OAI Static Code Analysis with CPPCHECK" sca_summary_table_row ./archives/cppcheck/cppcheck.xml "Uninitialized variable" uninitvar sca_summary_table_row ./archives/cppcheck/cppcheck.xml "Uninitialized struct member" uninitStructMember sca_summary_table_row ./archives/cppcheck/cppcheck.xml "Memory leak" memleak @@ -382,20 +430,20 @@ function report_build { sca_summary_table_row ./archives/cppcheck/cppcheck.xml "Expression depends on order of evaluation of side effects" unknownEvaluationOrder sca_summary_table_footer ./archives/cppcheck/cppcheck.xml - summary_table_header "OAI Build eNB -- USRP option" + summary_table_header "OAI Build eNB -- USRP option" ./archives/enb_usrp summary_table_row "LTE SoftModem - Release 14" ./archives/enb_usrp/lte-softmodem.Rel14.txt "Built target lte-softmodem" ./enb_usrp_row1.html summary_table_row "Coding - Release 14" ./archives/enb_usrp/coding.Rel14.txt "Built target coding" ./enb_usrp_row2.html summary_table_row "OAI USRP device if - Release 14" ./archives/enb_usrp/oai_usrpdevif.Rel14.txt "Built target oai_usrpdevif" ./enb_usrp_row3.html summary_table_row "Parameters Lib Config - Release 14" ./archives/enb_usrp/params_libconfig.Rel14.txt "Built target params_libconfig" ./enb_usrp_row4.html summary_table_footer - summary_table_header "OAI Build basic simulator option" + summary_table_header "OAI Build basic simulator option" ./archives/basic_sim summary_table_row "Basic Simulator eNb - Release 14" ./archives/basic_sim/basic_simulator_enb.txt "Built target lte-softmodem" ./basic_sim_row1.html summary_table_row "Basic Simulator UE - Release 14" ./archives/basic_sim/basic_simulator_ue.txt "Built target lte-uesoftmodem" ./basic_sim_row2.html summary_table_row "Conf 2 UE data - Release 14" ./archives/basic_sim/conf2uedata.Rel14.txt "Built target conf2uedata" ./basic_sim_row3.html summary_table_footer - summary_table_header "OAI Build Physical simulators option" + summary_table_header "OAI Build Physical simulators option" ./archives/phy_sim summary_table_row "DL Simulator - Release 14" ./archives/phy_sim/dlsim.Rel14.txt "Built target dlsim" ./phy_sim_row1.html summary_table_row "UL Simulator - Release 14" ./archives/phy_sim/ulsim.Rel14.txt "Built target ulsim" ./phy_sim_row2.html summary_table_row "Coding - Release 14" ./archives/phy_sim/coding.Rel14.txt "Built target coding" ./phy_sim_row3.html @@ -404,7 +452,7 @@ function report_build { if [ -f archives/gnb_usrp/nr-softmodem.Rel14.txt ] then - summary_table_header "OAI Build gNB -- USRP option" + summary_table_header "OAI Build gNB -- USRP option" ./archives/gnb_usrp summary_table_row "LTE SoftModem - Release 14" ./archives/gnb_usrp/nr-softmodem.Rel14.txt "Built target nr-softmodem" ./gnb_usrp_row1.html summary_table_row "Coding - Release 14" ./archives/gnb_usrp/coding.Rel14.txt "Built target coding" ./gnb_usrp_row2.html summary_table_row "OAI USRP device if - Release 14" ./archives/gnb_usrp/oai_usrpdevif.Rel14.txt "Built target oai_usrpdevif" ./gnb_usrp_row3.html @@ -414,7 +462,7 @@ function report_build { if [ -f archives/nrue_usrp/nr-uesoftmodem.Rel14.txt ] then - summary_table_header "OAI Build 5G NR UE -- USRP option" + summary_table_header "OAI Build 5G NR UE -- USRP option" ./archives/nrue_usrp summary_table_row "UE SoftModem - Release 14" ./archives/nrue_usrp/nr-uesoftmodem.Rel14.txt "Built target nr-uesoftmodem" ./nrue_usrp_row1.html summary_table_row "Coding - Release 14" ./archives/nrue_usrp/coding.Rel14.txt "Built target coding" ./nrue_usrp_row2.html summary_table_row "OAI USRP device if - Release 14" ./archives/nrue_usrp/oai_usrpdevif.Rel14.txt "Built target oai_usrpdevif" ./nrue_usrp_row3.html @@ -422,7 +470,7 @@ function report_build { summary_table_footer fi - summary_table_header "OAI Build eNB -- ETHERNET transport option" + summary_table_header "OAI Build eNB -- ETHERNET transport option" ./archives/enb_eth summary_table_row "LTE SoftModem w/o S1 - Release 14" ./archives/enb_eth/lte-softmodem-nos1.Rel14.txt "Built target lte-softmodem" ./enb_eth_row1.html summary_table_row "Coding - Release 14" ./archives/enb_eth/coding.Rel14.txt "Built target coding" ./enb_eth_row2.html summary_table_row "OAI ETHERNET transport - Release 14" ./archives/enb_eth/oai_eth_transpro.Rel14.txt "Built target oai_eth_transpro" ./enb_eth_row3.html @@ -431,7 +479,7 @@ function report_build { summary_table_row "NAS Mesh - Release 14" ./archives/enb_eth/nasmesh.Rel14.txt "Built target nasmesh" ./enb_eth_row6.html summary_table_footer - summary_table_header "OAI Build UE -- ETHERNET transport option" + summary_table_header "OAI Build UE -- ETHERNET transport option" ./archives/ue_eth summary_table_row "LTE UE SoftModem w/o S1 - Release 14" ./archives/ue_eth/lte-uesoftmodem-nos1.Rel14.txt "Built target lte-uesoftmodem" ./ue_eth_row1.html summary_table_row "Coding - Release 14" ./archives/ue_eth/coding.Rel14.txt "Built target coding" ./ue_eth_row2.html summary_table_row "OAI ETHERNET transport - Release 14" ./archives/ue_eth/oai_eth_transpro.Rel14.txt "Built target oai_eth_transpro" ./ue_eth_row3.html @@ -444,7 +492,7 @@ function report_build { then echo "

    Red Hat (CentOS Linux release 7.4.1708) -- Summary

    " >> ./build_results.html - summary_table_header "Red Hat -- OAI Build eNB -- USRP option" + summary_table_header "Red Hat -- OAI Build eNB -- USRP option" ./archives/red_hat summary_table_row "LTE SoftModem - Release 14" ./archives/red_hat/lte-softmodem.Rel14.txt "Built target lte-softmodem" ./enb_usrp_rh_row1.html summary_table_row "Coding - Release 14" ./archives/red_hat/coding.Rel14.txt "Built target coding" ./enb_usrp_rh_row2.html summary_table_row "OAI USRP device if - Release 14" ./archives/red_hat/oai_usrpdevif.Rel14.txt "Built target oai_usrpdevif" ./enb_usrp_rh_row3.html @@ -453,6 +501,8 @@ function report_build { fi echo "

    Details

    " >> ./build_results.html + echo " " >> ./build_results.html + echo "
    " >> ./build_results.html for DETAILS_TABLE in `ls ./enb_usrp_row*.html` do @@ -492,6 +542,8 @@ function report_build { fi rm -f ./*_row*.html - echo "" >> ./build_results.html + echo "
    " >> ./build_results.html + echo "
    End of Build Report -- Copyright 2018 OpenAirInterface. All Rights Reserved.
    " >> ./build_results.html + echo "
    " >> ./build_results.html echo "" >> ./build_results.html } diff --git a/ci-scripts/reportTestLocally.sh b/ci-scripts/reportTestLocally.sh index 372b949aa8..25dce87e46 100755 --- a/ci-scripts/reportTestLocally.sh +++ b/ci-scripts/reportTestLocally.sh @@ -92,10 +92,14 @@ function report_test { echo "" > ./test_simulator_results.html echo "" >> ./test_simulator_results.html echo "" >> ./test_simulator_results.html + echo " " >> ./test_simulator_results.html + echo " " >> ./test_simulator_results.html + echo " " >> ./test_simulator_results.html + echo " " >> ./test_simulator_results.html echo " Simulator Results for $JOB_NAME job build #$BUILD_ID" >> ./test_simulator_results.html echo " " >> ./test_simulator_results.html echo "" >> ./test_simulator_results.html - echo "" >> ./test_simulator_results.html + echo "
    " >> ./test_simulator_results.html echo " " >> ./test_simulator_results.html echo " " >> ./test_simulator_results.html echo " \n') self.htmlFile.write(' \n') self.htmlFile.write('
    " >> ./test_simulator_results.html @@ -162,6 +166,26 @@ function report_test { then echo "

    Basic Simulator Check

    " >> ./test_simulator_results.html + if [ -f $ARCHIVES_LOC/test_final_status.log ] + then + if [ `grep -c TEST_OK $ARCHIVES_LOC/test_final_status.log` -eq 1 ] + then + echo "
    " >> ./test_simulator_results.html + echo " TEST was SUCCESSFUL " >> ./test_simulator_results.html + echo "
    " >> ./test_simulator_results.html + else + echo "
    " >> ./test_simulator_results.html + echo " TEST was a FAILURE! " >> ./test_simulator_results.html + echo "
    " >> ./test_simulator_results.html + fi + else + echo "
    " >> ./test_simulator_results.html + echo " COULD NOT DETERMINE TEST FINAL STATUS! " >> ./test_simulator_results.html + echo "
    " >> ./test_simulator_results.html + fi + + echo " " >> ./test_simulator_results.html + echo "
    " >> ./test_simulator_results.html echo " " >> ./test_simulator_results.html echo " " >> ./test_simulator_results.html echo " " >> ./test_simulator_results.html @@ -360,11 +384,17 @@ function report_test { done echo "
    Log File Name
    " >> ./test_simulator_results.html + echo "
    " >> ./test_simulator_results.html fi if [ -e $JENKINS_WKSP/flexran/flexran_build_complete.txt ] then echo "

    Basic Simulator + FlexRan Controller Check

    " >> ./test_simulator_results.html + echo "
    " >> ./test_simulator_results.html + echo " TEST was SUCCESSFUL " >> ./test_simulator_results.html + echo "
    " >> ./test_simulator_results.html + echo " " >> ./test_simulator_results.html + echo "
    " >> ./test_simulator_results.html echo " " >> ./test_simulator_results.html echo " " >> ./test_simulator_results.html echo " " >> ./test_simulator_results.html @@ -383,6 +413,7 @@ function report_test { echo " " >> ./test_simulator_results.html done echo "
    Log File Name
    " >> ./test_simulator_results.html + echo "
    " >> ./test_simulator_results.html fi ARCHIVES_LOC=archives/phy_sim/test @@ -390,6 +421,24 @@ function report_test { then echo "

    Physical Simulators Check

    " >> ./test_simulator_results.html + if [ -f $ARCHIVES_LOC/test_final_status.log ] + then + if [ `grep -c TEST_OK $ARCHIVES_LOC/test_final_status.log` -eq 1 ] + then + echo "
    " >> ./test_simulator_results.html + echo " TEST was SUCCESSFUL " >> ./test_simulator_results.html + echo "
    " >> ./test_simulator_results.html + else + echo "
    " >> ./test_simulator_results.html + echo " TEST was a FAILURE! " >> ./test_simulator_results.html + echo "
    " >> ./test_simulator_results.html + fi + else + echo "
    " >> ./test_simulator_results.html + echo " COULD NOT DETERMINE TEST FINAL STATUS! " >> ./test_simulator_results.html + echo "
    " >> ./test_simulator_results.html + fi + echo " " >> ./test_simulator_results.html echo " " >> ./test_simulator_results.html echo " " >> ./test_simulator_results.html @@ -422,6 +471,10 @@ function report_test { done echo "
    Log File Name
    " >> ./test_simulator_results.html + echo "
    " >> ./test_simulator_results.html + + echo " " >> ./test_simulator_results.html + echo "
    " >> ./test_simulator_results.html echo "

    Details

    " >> ./test_simulator_results.html for XML_FILE in $XML_TESTS @@ -472,6 +525,8 @@ function report_test { done fi - echo "" >> ./test_simulator_results.html + echo "
    " >> ./test_simulator_results.html + echo "
    End of Test Report -- Copyright 2018 OpenAirInterface. All Rights Reserved.
    " >> ./test_simulator_results.html + echo "" >> ./test_simulator_results.html echo "" >> ./test_simulator_results.html } diff --git a/ci-scripts/runTestOnVM.sh b/ci-scripts/runTestOnVM.sh index 40ea22d853..3878d2e36f 100755 --- a/ci-scripts/runTestOnVM.sh +++ b/ci-scripts/runTestOnVM.sh @@ -441,6 +441,12 @@ function run_test_on_vm { if [ $NB_RUNS -eq 0 ]; then STATUS=-1; fi if [ $NB_FAILURES -ne 0 ]; then STATUS=-1; fi + if [ $STATUS -eq 0 ] + then + echo "TEST_OK" > $ARCHIVES_LOC/test_final_status.log + else + echo "TEST_KO" > $ARCHIVES_LOC/test_final_status.log + fi fi if [[ "$RUN_OPTIONS" == "complex" ]] && [[ $VM_NAME =~ .*-basic-sim.* ]] @@ -580,6 +586,7 @@ function run_test_on_vm { if [ $i -lt 50 ] then echo "Problem w/ starting ltebox EPC" + echo "TEST_KO" > $ARCHIVES_LOC/test_final_status.log exit -1 fi fi @@ -615,6 +622,7 @@ function run_test_on_vm { scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_UE_LOG_FILE $ARCHIVES_LOC recover_core_dump $VM_CMDS $VM_IP_ADDR $ARCHIVES_LOC/$CURRENT_ENB_LOG_FILE $ARCHIVES_LOC terminate_ltebox_epc $EPC_VM_CMDS $EPC_VM_IP_ADDR + echo "TEST_KO" > $ARCHIVES_LOC/test_final_status.log exit -1 fi get_ue_ip_addr $VM_CMDS $VM_IP_ADDR @@ -673,6 +681,7 @@ function run_test_on_vm { scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_UE_LOG_FILE $ARCHIVES_LOC recover_core_dump $VM_CMDS $VM_IP_ADDR $ARCHIVES_LOC/$CURRENT_ENB_LOG_FILE $ARCHIVES_LOC terminate_ltebox_epc $EPC_VM_CMDS $EPC_VM_IP_ADDR + echo "TEST_KO" > $ARCHIVES_LOC/test_final_status.log exit -1 fi get_ue_ip_addr $VM_CMDS $VM_IP_ADDR @@ -731,6 +740,7 @@ function run_test_on_vm { scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_UE_LOG_FILE $ARCHIVES_LOC recover_core_dump $VM_CMDS $VM_IP_ADDR $ARCHIVES_LOC/$CURRENT_ENB_LOG_FILE $ARCHIVES_LOC terminate_ltebox_epc $EPC_VM_CMDS $EPC_VM_IP_ADDR + echo "TEST_KO" > $ARCHIVES_LOC/test_final_status.log exit -1 fi get_ue_ip_addr $VM_CMDS $VM_IP_ADDR @@ -782,6 +792,7 @@ function run_test_on_vm { then echo "ERROR: compiling flexran controller on vm went wrong" terminate_ltebox_epc $EPC_VM_CMDS $EPC_VM_IP_ADDR + echo "TEST_KO" > $ARCHIVES_LOC/test_final_status.log exit -1 fi FLEXRAN_CTL_VM_NAME=`echo $VM_NAME | sed -e "s#basic-sim#flexran-rtc#"` @@ -791,6 +802,7 @@ function run_test_on_vm { then echo "ERROR: Flexran Ctl VM is not alive" terminate_ltebox_epc $EPC_VM_CMDS $EPC_VM_IP_ADDR + echo "TEST_KO" > $ARCHIVES_LOC/test_final_status.log exit -1 fi uvt-kvm wait $FLEXRAN_CTL_VM_NAME --insecure @@ -825,6 +837,7 @@ function run_test_on_vm { recover_core_dump $VM_CMDS $VM_IP_ADDR $ARCHIVES_LOC/$CURRENT_ENB_LOG_FILE $ARCHIVES_LOC terminate_ltebox_epc $EPC_VM_CMDS $EPC_VM_IP_ADDR stop_flexran_ctrl $FLEXRAN_CTL_VM_CMDS $FLEXRAN_CTL_VM_IP_ADDR + echo "TEST_KO" > $ARCHIVES_LOC/test_final_status.log exit -1 fi query_flexran_ctrl_status $FLEXRAN_CTL_VM_CMDS $FLEXRAN_CTL_VM_IP_ADDR 03_enb_ue_connected @@ -866,6 +879,7 @@ function run_test_on_vm { scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_UE_LOG_FILE $ARCHIVES_LOC recover_core_dump $VM_CMDS $VM_IP_ADDR $ARCHIVES_LOC/$CURRENT_ENB_LOG_FILE $ARCHIVES_LOC terminate_ltebox_epc $EPC_VM_CMDS $EPC_VM_IP_ADDR + echo "TEST_KO" > $ARCHIVES_LOC/test_final_status.log exit -1 fi get_ue_ip_addr $VM_CMDS $VM_IP_ADDR @@ -916,6 +930,7 @@ function run_test_on_vm { scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_UE_LOG_FILE $ARCHIVES_LOC recover_core_dump $VM_CMDS $VM_IP_ADDR $ARCHIVES_LOC/$CURRENT_ENB_LOG_FILE $ARCHIVES_LOC terminate_ltebox_epc $EPC_VM_CMDS $EPC_VM_IP_ADDR + echo "TEST_KO" > $ARCHIVES_LOC/test_final_status.log exit -1 fi get_ue_ip_addr $VM_CMDS $VM_IP_ADDR @@ -965,6 +980,7 @@ function run_test_on_vm { scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_UE_LOG_FILE $ARCHIVES_LOC recover_core_dump $VM_CMDS $VM_IP_ADDR $ARCHIVES_LOC/$CURRENT_ENB_LOG_FILE $ARCHIVES_LOC terminate_ltebox_epc $EPC_VM_CMDS $EPC_VM_IP_ADDR + echo "TEST_KO" > $ARCHIVES_LOC/test_final_status.log exit -1 fi get_ue_ip_addr $VM_CMDS $VM_IP_ADDR @@ -1027,5 +1043,11 @@ function run_test_on_vm { if [ $PING_STATUS -ne 0 ]; then STATUS=-1; fi if [ $IPERF_STATUS -ne 0 ]; then STATUS=-1; fi + if [ $STATUS -eq 0 ] + then + echo "TEST_OK" > $ARCHIVES_LOC/test_final_status.log + else + echo "TEST_KO" > $ARCHIVES_LOC/test_final_status.log + fi fi } diff --git a/ci-scripts/waitBuildOnVM.sh b/ci-scripts/waitBuildOnVM.sh index e39e03702f..21a2f7a9e1 100755 --- a/ci-scripts/waitBuildOnVM.sh +++ b/ci-scripts/waitBuildOnVM.sh @@ -165,7 +165,11 @@ function check_on_vm_build { fi done - if [ $NB_PATTERN_FILES -ne $NB_FOUND_FILES ]; then STATUS=-1; fi + if [ $NB_PATTERN_FILES -ne $NB_FOUND_FILES ] + then + echo "Expecting $NB_PATTERN_FILES log files and found $NB_FOUND_FILES" + STATUS=-1 + fi # If we were building the FlexRan Controller, flag-touch for basic-simulator to continue if [[ "$VM_NAME" == *"-flexran-rtc"* ]] @@ -175,4 +179,11 @@ function check_on_vm_build { touch $JENKINS_WKSP/flexran/flexran_build_complete.txt fi fi + + if [[ $STATUS -eq 0 ]] + then + echo "BUILD_OK" > $ARCHIVES_LOC/build_final_status.log + else + echo "BUILD_KO" > $ARCHIVES_LOC/build_final_status.log + fi } From b805cfc62862a1509645ad9cb16a53c5e6d7fa60 Mon Sep 17 00:00:00 2001 From: Raphael Defosseux Date: Tue, 4 Dec 2018 19:47:44 +0100 Subject: [PATCH 190/233] CI: HTML report improvements -- typos correction Signed-off-by: Raphael Defosseux --- ci-scripts/main.py | 5 +++-- ci-scripts/reportBuildLocally.sh | 1 + ci-scripts/reportTestLocally.sh | 3 ++- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/ci-scripts/main.py b/ci-scripts/main.py index 51af244530..c32eb8d286 100644 --- a/ci-scripts/main.py +++ b/ci-scripts/main.py @@ -1438,7 +1438,7 @@ class SSHConnection(): device_id = status_queue.get() ip_addr = status_queue.get() message = status_queue.get() - html_cell = '
    UE (' + device_id + ')\nIP Address  : ' + ip_addr + '\n' + message + '
    ' + html_cell = '
    UE (' + device_id + ')\nIP Address  : ' + ip_addr + '\n' + message + '
    ' html_queue.put(html_cell) if (iperf_noperf and iperf_status): self.CreateHtmlTestRowQueue(self.iperf_args, 'PERF NOT MET', len(self.UEDevices), html_queue) @@ -2020,7 +2020,8 @@ class SSHConnection(): self.htmlFile.write('
    FAIL
    \n') - self.htmlFile.write('
    End of Test Report -- Copyright 2018 OpenAirInterface. All Rights Reserved.
    \n') + self.htmlFile.write('

    \n') + self.htmlFile.write('
    End of Test Report -- Copyright 2018 OpenAirInterface. All Rights Reserved.
    \n') self.htmlFile.write('
    \n') self.htmlFile.write('\n') self.htmlFile.close() diff --git a/ci-scripts/reportBuildLocally.sh b/ci-scripts/reportBuildLocally.sh index c42ecef00b..634eac3adc 100755 --- a/ci-scripts/reportBuildLocally.sh +++ b/ci-scripts/reportBuildLocally.sh @@ -543,6 +543,7 @@ function report_build { rm -f ./*_row*.html echo " " >> ./build_results.html + echo "

    " >> ./build_results.html echo "
    End of Build Report -- Copyright 2018 OpenAirInterface. All Rights Reserved.
    " >> ./build_results.html echo "" >> ./build_results.html echo "" >> ./build_results.html diff --git a/ci-scripts/reportTestLocally.sh b/ci-scripts/reportTestLocally.sh index 25dce87e46..c6fef123d7 100755 --- a/ci-scripts/reportTestLocally.sh +++ b/ci-scripts/reportTestLocally.sh @@ -525,7 +525,8 @@ function report_test { done fi - echo "" >> ./test_simulator_results.html + echo " " >> ./test_simulator_results.html + echo "

    " >> ./test_simulator_results.html echo "
    End of Test Report -- Copyright 2018 OpenAirInterface. All Rights Reserved.
    " >> ./test_simulator_results.html echo "" >> ./test_simulator_results.html echo "" >> ./test_simulator_results.html From 5832204fe13935a2d94c7ed6379e736d8cf982f8 Mon Sep 17 00:00:00 2001 From: Clayton Shepard Date: Wed, 5 Dec 2018 02:21:03 -0600 Subject: [PATCH 191/233] Added Iris hardware support. Signed-off-by: Rahman Doost --- cmake_targets/CMakeLists.txt | 18 + cmake_targets/build_oai | 26 +- cmake_targets/tools/build_helper | 68 ++ targets/ARCH/COMMON/common_lib.c | 5 +- targets/ARCH/COMMON/common_lib.h | 2 + targets/ARCH/IRIS/USERSPACE/LIB/Makefile.inc | 4 + targets/ARCH/IRIS/USERSPACE/LIB/iris_lib.cpp | 847 ++++++++++++++++++ .../CONF/enb.band38.tm1.25PRB.iris030.conf | 264 ++++++ .../CONF/enb.band7.tm1.25PRB.iris030.conf | 264 ++++++ targets/RT/USER/lte-ru.c | 4 +- 10 files changed, 1496 insertions(+), 6 deletions(-) create mode 100644 targets/ARCH/IRIS/USERSPACE/LIB/Makefile.inc create mode 100644 targets/ARCH/IRIS/USERSPACE/LIB/iris_lib.cpp create mode 100644 targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band38.tm1.25PRB.iris030.conf create mode 100644 targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.25PRB.iris030.conf diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt index f205e3f5fa..8e4d1afe3d 100644 --- a/cmake_targets/CMakeLists.txt +++ b/cmake_targets/CMakeLists.txt @@ -551,6 +551,15 @@ set(TPLIB_ETHERNET_SOURCE ) add_library(oai_eth_transpro MODULE ${TPLIB_ETHERNET_SOURCE} ) +include_directories("${OPENAIR_TARGETS}/ARCH/IRIS/USERSPACE/LIB/") +set(option_HWIRISLIB_lib "-l SoapySDR") +set(HWLIB_IRIS_SOURCE + ${OPENAIR_TARGETS}/ARCH/IRIS/USERSPACE/LIB/iris_lib.cpp + ) +add_library(oai_irisdevif MODULE ${HWLIB_IRIS_SOURCE}) +target_include_directories(oai_irisdevif PRIVATE /usr/local/lib/SoapySDR/modules0.6/) +target_link_libraries(oai_irisdevif SoapySDR) + include_directories("${OPENAIR_TARGETS}/ARCH/mobipass/") set(TPLIB_MOBIPASS_SOURCE ${OPENAIR_TARGETS}/ARCH/mobipass/interface.c @@ -1787,6 +1796,15 @@ include_directories(${CRYPTO_INCLUDE_DIRS}) if (${RF_BOARD} STREQUAL "OAI_USRP") find_package(Boost REQUIRED) include_directories(${LIBBOOST_INCLUDE_DIR}) + +elseif (${RF_BOARD} STREQUAL "OAI_IRIS") + include_directories("${OPENAIR_TARGETS}/ARCH/IRIS/USERSPACE/LIB/") + include_directories("/usr/local/include/") + set(HW_SOURCE ${HW_SOURCE} + ${OPENAIR_TARGETS}/ARCH/IRIS/USERSPACE/LIB/iris_lib.cpp) + LINK_DIRECTORIES("/usr/local/lib") + set(option_HW_lib "-lSoapySDR -rdynamic -ldl") + endif (${RF_BOARD} STREQUAL "OAI_USRP") pkg_search_module(OPENPGM openpgm-5.1 openpgm-5.2) diff --git a/cmake_targets/build_oai b/cmake_targets/build_oai index 3954827c09..5cd1cc2631 100755 --- a/cmake_targets/build_oai +++ b/cmake_targets/build_oai @@ -107,7 +107,7 @@ Options Rel8 limits the implementation to 3GPP Release 8 version Rel10 limits the implementation to 3GPP Release 10 version -w | --hardware - EXMIMO, USRP, BLADERF, ETHERNET, LMSSDR, None (Default) + EXMIMO, USRP, BLADERF, ETHERNET, LMSSDR, IRIS, None (Default) Adds this RF board support (in external packages installation and in compilation) -t | --transport protocol ETHERNET , None @@ -231,7 +231,7 @@ function main() { -w | --hardware) HW="$2" #"${i#*=}" # Use OAI_USRP as the key word USRP is used inside UHD driver - if [ "$HW" != "BLADERF" -a "$HW" != "USRP" -a "$HW" != "LMSSDR" -a "$HW" != "None" -a "$HW" != "EXMIMO" ] ; then + if [ "$HW" != "BLADERF" -a "$HW" != "USRP" -a "$HW" != "LMSSDR" -a "$HW" != "None" -a "$HW" != "EXMIMO" -a "$HW" != "IRIS" ] ; then echo_fatal "Unknown HW type $HW will exit..." else if [ "$HW" == "USRP" ] ; then @@ -243,6 +243,9 @@ function main() { if [ "$HW" == "LMSSDR" ] ; then HW="OAI_LMSSDR" fi + if [ "$HW" == "IRIS" ] ; then + HW="OAI_IRIS" + fi echo_info "Setting hardware to: $HW" fi shift 2;; @@ -414,7 +417,9 @@ function main() { DEADLINE_SCHEDULER_FLAG_USER="False" elif [ "$HW" = "OAI_BLADERF" ] ; then DEADLINE_SCHEDULER_FLAG_USER="False" - elif [ "$HW" = "OAI_LMSSDR" ] ; then + elif [ "$HW" = "OAI_LMSSDR" ] ; then + DEADLINE_SCHEDULER_FLAG_USER="False" + elif [ "$HW" = "OAI_IRIS" ] ; then DEADLINE_SCHEDULER_FLAG_USER="False" elif [ "$HW" = "None" ] ; then DEADLINE_SCHEDULER_FLAG_USER="False" @@ -484,6 +489,13 @@ function main() { flash_firmware_bladerf fi fi + if [ "$HW" == "OAI_IRIS" ] ; then + echo_info "installing packages for IRIS support" + check_install_soapy + #if [ ! "$DISABLE_HARDWARE_DEPENDENCY" == "True" ]; then + # flash_firmware_iris + #fi + fi echo_info "installing protobuf/protobuf-c for flexran agent support" install_protobuf_from_source install_protobuf_c_from_source @@ -756,6 +768,14 @@ function main() { ln -sf liboai_lmssdrdevif.so liboai_device.so ln -sf $dbin/liboai_lmssdrdevif.so.$REL $dbin/liboai_device.so echo_info "liboai_device.so is linked to LMSSDR device library" + elif [ "$HW" == "OAI_IRIS" ] ; then + compilations \ + $build_dir oai_irisdevif \ + liboai_irisdevif.so $dbin/liboai_irisdevif.so.$REL + + ln -s liboai_irisdevif.so liboai_device.so + ln -s $dbin/liboai_irisdevif.so.$REL $dbin/liboai_device.so + echo_info "liboai_device.so is linked to IRIS device library" else echo_info "liboai_device.so is not linked to any device library" fi diff --git a/cmake_targets/tools/build_helper b/cmake_targets/tools/build_helper index 551fc13593..658844531e 100755 --- a/cmake_targets/tools/build_helper +++ b/cmake_targets/tools/build_helper @@ -379,6 +379,74 @@ check_install_lmssdr_driver(){ } +install_soapy_from_source(){ + soapy_install_log=$OPENAIR_DIR/cmake_targets/log/soapy_install_log.txt + echo_info "\nInstalling Soapy EcoSystem from source. The log file for Soapy installation is here: $soapy_install_log " + ( + cd /tmp + echo "Downloading SoapySDR" + rm -rf /tmp/soapysdr + git clone https://github.com/pothosware/SoapySDR.git + cd soapysdr + #git checkout tags/release_003_010_001_001 + mkdir -p build + cd build + $CMAKE ../ + echo "Compiling SoapySDR" + make -j`nproc` + $SUDO make install + $SUDO ldconfig + cd /tmp + echo "Downloading SoapyRemote" + rm -rf /tmp/soapyremote + git clone https://github.com/pothosware/SoapyRemote.git + cd soapyremote + #git checkout tags/release_003_010_001_001 + mkdir -p build + cd build + cmake ../ + echo "Compiling SoapyRemote" + make -j`nproc` + $SUDO make install + $SUDO ldconfig + ) >& $soapy_install_log +} + +install_soapy_iris_from_source(){ + iris_install_log=$OPENAIR_DIR/cmake_targets/log/iris_install_log.txt + echo_info "\nInstalling Iris driver from source. The log file for Iris driver installation is here: $iris_install_log " + ( + cd /tmp + echo "Downloading SoapyIris" + rm -rf /tmp/sklk-soapyiris + git clone https://github.com/skylarkwireless/sklk-soapyiris.git + cd sklk-soapyiris + mkdir -p build + cd build + cmake ../ + echo "Compiling SoapyIris" + make -j`nproc` + $SUDO make install + $SUDO ldconfig + ) >& $iris_install_log +} + +check_install_soapy () { + #if [[ "$OS_DISTRO" == "ubuntu" ]]; then + #first we remove old installation + $SUDO apt-get remove -y soapysdr soapysdr-server libsoapysdr-dev python-soapysdr python3-soapysdr soapysdr-module-remote || true + $SUDO add-apt-repository -y ppa:myriadrf/drivers + $SUDO apt-get update + $SUDO apt-get install -y soapysdr soapysdr-server libsoapysdr-dev python-soapysdr python3-soapysdr soapysdr-module-remote + + #elif [[ "$OS_BASEDISTRO" == "fedora" ]]; then + # $SUDO $INSTALLER -y install software-properties-common python3-software-properties python-software-properties subversion git python3 python-numpy python3-numpy cmake swig python-dev + # install_soapy_from_source + #fi + install_soapy_iris_from_source + +} + check_install_additional_tools (){ $SUDO $INSTALLER update -y if [[ "$OS_DISTRO" == "ubuntu" ]]; then diff --git a/targets/ARCH/COMMON/common_lib.c b/targets/ARCH/COMMON/common_lib.c index d25826e82e..b62eb9d2df 100644 --- a/targets/ARCH/COMMON/common_lib.c +++ b/targets/ARCH/COMMON/common_lib.c @@ -48,7 +48,7 @@ int set_device(openair0_device *device) { case USRP_B200_DEV: printf("[%s] has loaded USRP B200 device.\n",((device->host_type == RAU_HOST) ? "RAU": "RRU")); break; -case USRP_X300_DEV: + case USRP_X300_DEV: printf("[%s] has loaded USRP X300 device.\n",((device->host_type == RAU_HOST) ? "RAU": "RRU")); break; case BLADERF_DEV: @@ -57,6 +57,9 @@ case USRP_X300_DEV: case LMSSDR_DEV: printf("[%s] has loaded LMSSDR device.\n",((device->host_type == RAU_HOST) ? "RAU": "RRU")); break; + case IRIS_DEV: + printf("[%s] has loaded Iris device.\n",((device->host_type == RAU_HOST) ? "RAU": "RRU")); + break; case NONE_DEV: printf("[%s] has not loaded a HW device.\n",((device->host_type == RAU_HOST) ? "RAU": "RRU")); break; diff --git a/targets/ARCH/COMMON/common_lib.h b/targets/ARCH/COMMON/common_lib.h index 0ef3cd233f..084ef9fcd9 100644 --- a/targets/ARCH/COMMON/common_lib.h +++ b/targets/ARCH/COMMON/common_lib.h @@ -95,6 +95,8 @@ typedef enum { BLADERF_DEV, /*!\brief device is LMSSDR (SoDeRa)*/ LMSSDR_DEV, + /*!\brief device is Iris */ + IRIS_DEV, /*!\brief device is NONE*/ NONE_DEV, MAX_RF_DEV_TYPE diff --git a/targets/ARCH/IRIS/USERSPACE/LIB/Makefile.inc b/targets/ARCH/IRIS/USERSPACE/LIB/Makefile.inc new file mode 100644 index 0000000000..79d0a5b7a8 --- /dev/null +++ b/targets/ARCH/IRIS/USERSPACE/LIB/Makefile.inc @@ -0,0 +1,4 @@ +IRIS_OBJ += $(OPENAIR_TARGETS)/ARCH/IRIS/USERSPACE/LIB/iris_lib.o +IRIS_FILE_OBJ += $(OPENAIR_TARGETS)/ARCH/IRIS/USERSPACE/LIB/iris_lib.cpp +IRIS_CFLAGS += -I$(OPENAIR_TARGETS)/ARCH/COMMON -I$(OPENAIR_TARGETS)/ARCH/IRIS/USERSPACE/LIB/ -I$(OPENAIR_TARGETS)/COMMON + diff --git a/targets/ARCH/IRIS/USERSPACE/LIB/iris_lib.cpp b/targets/ARCH/IRIS/USERSPACE/LIB/iris_lib.cpp new file mode 100644 index 0000000000..3133742cd4 --- /dev/null +++ b/targets/ARCH/IRIS/USERSPACE/LIB/iris_lib.cpp @@ -0,0 +1,847 @@ + +/** iris_lib.cpp + * + * \author: Rahman Doost-Mohammady : doost@rice.edu + */ + +#include +#include +#include +#include +#include +#include +#include +//#include +#include +#include +#include +#include +#include +#include +#include "common/utils/LOG/log_extern.h" +#include "common_lib.h" +#include + +#ifdef __SSE4_1__ +# include +#endif + +#ifdef __AVX2__ +# include +#endif + +#define SAMPLE_RATE_DOWN 1 + +/*! \brief Iris Configuration */ +typedef struct { + + // -------------------------------- + // variables for Iris configuration + // -------------------------------- + //! Iris device pointer + std::vector iris; + int device_num; + int rx_num_channels; + int tx_num_channels; + //create a send streamer and a receive streamer + //! Iris TX Stream + std::vector txStream; + //! Iris RX Stream + std::vector rxStream; + + //! Sampling rate + double sample_rate; + + //! time offset between transmiter timestamp and receiver timestamp; + double tdiff; + + //! TX forward samples. + int tx_forward_nsamps; //166 for 20Mhz + + + // -------------------------------- + // Debug and output control + // -------------------------------- + //! Number of underflows + int num_underflows; + //! Number of overflows + int num_overflows; + + //! Number of sequential errors + int num_seq_errors; + //! tx count + int64_t tx_count; + //! rx count + int64_t rx_count; + //! timestamp of RX packet + openair0_timestamp rx_timestamp; + +} iris_state_t; + +/*! \brief Called to start the Iris lime transceiver. Return 0 if OK, < 0 if error + @param device pointer to the device structure specific to the RF hardware target +*/ +static int trx_iris_start(openair0_device *device) { + iris_state_t *s = (iris_state_t *) device->priv; + + long long timeNs = s->iris[0]->getHardwareTime("") + 500000; + int flags = 0; + //flags |= SOAPY_SDR_HAS_TIME; + int r; + for (r = 0; r < s->device_num; r++) { + int ret = s->iris[r]->activateStream(s->rxStream[r], flags, timeNs, 0); + int ret2 = s->iris[r]->activateStream(s->txStream[r]); + if (ret < 0 | ret2 < 0) + return -1; + } + return 0; +} + +/*! \brief Stop Iris + * \param card refers to the hardware index to use + */ +int trx_iris_stop(openair0_device *device) { + iris_state_t *s = (iris_state_t *) device->priv; + int r; + for (r = 0; r < s->device_num; r++) { + s->iris[r]->deactivateStream(s->txStream[r]); + s->iris[r]->deactivateStream(s->rxStream[r]); + } + return (0); +} + +/*! \brief Terminate operation of the Iris lime transceiver -- free all associated resources + * \param device the hardware to use + */ +static void trx_iris_end(openair0_device *device) { + LOG_I(HW, "Closing Iris device.\n"); + trx_iris_stop(device); + iris_state_t *s = (iris_state_t *) device->priv; + int r; + for (r = 0; r < s->device_num; r++) { + s->iris[r]->closeStream(s->txStream[r]); + s->iris[r]->closeStream(s->rxStream[r]); + SoapySDR::Device::unmake(s->iris[r]); + } +} + +/*! \brief Called to send samples to the Iris RF target + @param device pointer to the device structure specific to the RF hardware target + @param timestamp The timestamp at whicch the first sample MUST be sent + @param buff Buffer which holds the samples + @param nsamps number of samples to be sent + @param antenna_id index of the antenna if the device has multiple anteannas + @param flags flags must be set to TRUE if timestamp parameter needs to be applied +*/ + + +static int +trx_iris_write(openair0_device *device, openair0_timestamp timestamp, void **buff, int nsamps, int cc, int flags) { + using namespace std::chrono; + static long long int loop = 0; + static long time_min = 0, time_max = 0, time_avg = 0; + struct timespec tp_start, tp_end; + long time_diff; + + int ret = 0, ret_i = 0; + int flag = 0; + + iris_state_t *s = (iris_state_t *) device->priv; + int nsamps2; // aligned to upper 32 or 16 byte boundary +#if defined(__x86_64) || defined(__i386__) +#ifdef __AVX2__ + nsamps2 = (nsamps+7)>>3; + __m256i buff_tx[2][nsamps2]; +#else + nsamps2 = (nsamps+3)>>2; + __m128i buff_tx[2][nsamps2]; +#endif +#endif + + // bring RX data into 12 LSBs for softmodem RX + for (int i=0; iiris[0]->getHardwareTime(""); + return nsamps; + } + + if (flags == 2 || flags == 1) { // start of burst + + } else if (flags == 3 | flags == 4) { + flag |= SOAPY_SDR_END_BURST; + } + + + long long timeNs = SoapySDR::ticksToTimeNs(timestamp, s->sample_rate / SAMPLE_RATE_DOWN); + uint32_t *samps[2]; //= (uint32_t **)buff; + int r; + int m = s->tx_num_channels; + for (r = 0; r < s->device_num; r++) { + int samples_sent = 0; + samps[0] = (uint32_t *) buff_tx[m * r]; + + if (cc % 2 == 0) + samps[1] = (uint32_t *) buff_tx[m * r + 1]; //cws: it seems another thread can clobber these, so we need to save them locally. +#ifdef IRIS_DEBUG + int i; + for (i = 200; i < 216; i++) + printf("%d, ",((int16_t)(samps[0][i]>>16))>>4); + printf("\n"); + //printf("\nHardware time before write: %lld, tx_time_stamp: %lld\n", s->iris[0]->getHardwareTime(""), timeNs); +#endif + ret = s->iris[r]->writeStream(s->txStream[r], (void **) samps, (size_t)(nsamps), flag, timeNs, 1000000); + + if (ret < 0) + printf("Unable to write stream!\n"); + else + samples_sent = ret; + + + if (samples_sent != nsamps) + printf("[xmit] tx samples %d != %d\n", samples_sent, nsamps); + + } + + return nsamps; +} + +/*! \brief Receive samples from hardware. + * Read \ref nsamps samples from each channel to buffers. buff[0] is the array for + * the first channel. *ptimestamp is the time at which the first sample + * was received. + * \param device the hardware to use + * \param[out] ptimestamp the time at which the first sample was received. + * \param[out] buff An array of pointers to buffers for received samples. The buffers must be large enough to hold the number of samples \ref nsamps. + * \param nsamps Number of samples. One sample is 2 byte I + 2 byte Q => 4 byte. + * \param antenna_id Index of antenna for which to receive samples + * \returns the number of sample read +*/ +static int trx_iris_read(openair0_device *device, openair0_timestamp *ptimestamp, void **buff, int nsamps, int cc) { + int ret = 0; + static long long nextTime; + static bool nextTimeValid = false; + iris_state_t *s = (iris_state_t *) device->priv; + bool time_set = false; + long long timeNs = 0; + int flags; + int samples_received; + uint32_t *samps[2]; //= (uint32_t **)buff; + + int r; + int m = s->rx_num_channels; + int nsamps2; // aligned to upper 32 or 16 byte boundary +#if defined(__x86_64) || defined(__i386__) +#ifdef __AVX2__ + nsamps2 = (nsamps+7)>>3; + __m256i buff_tmp[2][nsamps2]; +#else + nsamps2 = (nsamps+3)>>2; + __m128i buff_tmp[2][nsamps2]; +#endif +#endif + + for (r = 0; r < s->device_num; r++) { + flags = 0; + samples_received = 0; + samps[0] = (uint32_t *) buff_tmp[m * r]; + if (cc % 2 == 0) + samps[1] = (uint32_t *) buff_tmp[m * r + 1]; + + flags = 0; + ret = s->iris[r]->readStream(s->rxStream[r], (void **) samps, (size_t)(nsamps), flags, + timeNs, 1000000); + if (ret < 0) { + if (ret == SOAPY_SDR_TIME_ERROR) + printf("[recv] Time Error in tx stream!\n"); + else if (ret == SOAPY_SDR_OVERFLOW | (flags & SOAPY_SDR_END_ABRUPT)) + printf("[recv] Overflow occured!\n"); + else if (ret == SOAPY_SDR_TIMEOUT) + printf("[recv] Timeout occured!\n"); + else if (ret == SOAPY_SDR_STREAM_ERROR) + printf("[recv] Stream (tx) error occured!\n"); + else if (ret == SOAPY_SDR_CORRUPTION) + printf("[recv] Bad packet occured!\n"); + break; + } else + samples_received = ret; + + + if (r == 0) { + if (samples_received == ret) // first batch + { + if (flags & SOAPY_SDR_HAS_TIME) { + s->rx_timestamp = SoapySDR::timeNsToTicks(timeNs, s->sample_rate / SAMPLE_RATE_DOWN); + *ptimestamp = s->rx_timestamp; + nextTime = timeNs; + nextTimeValid = true; + time_set = true; + //printf("1) time set %llu \n", *ptimestamp); + } + } + } + + if (r == 0) { + if (samples_received == nsamps) { + + if (flags & SOAPY_SDR_HAS_TIME) { + s->rx_timestamp = SoapySDR::timeNsToTicks(nextTime, s->sample_rate / SAMPLE_RATE_DOWN); + *ptimestamp = s->rx_timestamp; + nextTime = timeNs; + nextTimeValid = true; + time_set = true; + } + } else if (samples_received < nsamps) + printf("[recv] received %d samples out of %d\n", samples_received, nsamps); + + s->rx_count += samples_received; + + if (s->sample_rate != 0 && nextTimeValid) { + if (!time_set) { + s->rx_timestamp = SoapySDR::timeNsToTicks(nextTime, s->sample_rate / SAMPLE_RATE_DOWN); + *ptimestamp = s->rx_timestamp; + //printf("2) time set %llu, nextTime will be %llu \n", *ptimestamp, nextTime); + } + nextTime += SoapySDR::ticksToTimeNs(samples_received, s->sample_rate / SAMPLE_RATE_DOWN); + } + } + + // bring RX data into 12 LSBs for softmodem RX + for (int i=0; ipriv; + return SoapySDR::timeNsToTicks(s->iris[0]->getHardwareTime(""), s->sample_rate); +} + +/*! \brief Compares two variables within precision + * \param a first variable + * \param b second variable +*/ +static bool is_equal(double a, double b) { + return std::fabs(a - b) < std::numeric_limits::epsilon(); +} + +void *set_freq_thread(void *arg) { + + openair0_device *device = (openair0_device *) arg; + iris_state_t *s = (iris_state_t *) device->priv; + int r, i; + printf("Setting Iris TX Freq %f, RX Freq %f\n", device->openair0_cfg[0].tx_freq[0], + device->openair0_cfg[0].rx_freq[0]); + // add check for the number of channels in the cfg + for (r = 0; r < s->device_num; r++) { + for (i = 0; i < s->iris[r]->getNumChannels(SOAPY_SDR_RX); i++) { + if (i < s->rx_num_channels) + s->iris[r]->setFrequency(SOAPY_SDR_RX, i, "RF", device->openair0_cfg[0].rx_freq[i]); + } + for (i = 0; i < s->iris[r]->getNumChannels(SOAPY_SDR_TX); i++) { + if (i < s->tx_num_channels) + s->iris[r]->setFrequency(SOAPY_SDR_TX, i, "RF", device->openair0_cfg[0].tx_freq[i]); + } + } +} + +/*! \brief Set frequencies (TX/RX) + * \param device the hardware to use + * \param openair0_cfg RF frontend parameters set by application + * \param dummy dummy variable not used + * \returns 0 in success + */ +int trx_iris_set_freq(openair0_device *device, openair0_config_t *openair0_cfg, int dont_block) { + iris_state_t *s = (iris_state_t *) device->priv; + pthread_t f_thread; + if (dont_block) + pthread_create(&f_thread, NULL, set_freq_thread, (void *) device); + else { + int r, i; + for (r = 0; r < s->device_num; r++) { + printf("Setting Iris TX Freq %f, RX Freq %f\n", openair0_cfg[0].tx_freq[0], openair0_cfg[0].rx_freq[0]); + for (i = 0; i < s->iris[r]->getNumChannels(SOAPY_SDR_RX); i++) { + if (i < s->rx_num_channels) { + s->iris[r]->setFrequency(SOAPY_SDR_RX, i, "RF", openair0_cfg[0].rx_freq[i]); + } + } + for (i = 0; i < s->iris[r]->getNumChannels(SOAPY_SDR_TX); i++) { + if (i < s->tx_num_channels) { + s->iris[r]->setFrequency(SOAPY_SDR_TX, i, "RF", openair0_cfg[0].tx_freq[i]); + } + } + } + } + return (0); +} + + +/*! \brief Set Gains (TX/RX) + * \param device the hardware to use + * \param openair0_cfg RF frontend parameters set by application + * \returns 0 in success + */ +int trx_iris_set_gains(openair0_device *device, + openair0_config_t *openair0_cfg) { + iris_state_t *s = (iris_state_t *) device->priv; + int r; + for (r = 0; r < s->device_num; r++) { + s->iris[r]->setGain(SOAPY_SDR_RX, 0, openair0_cfg[0].rx_gain[0]); + s->iris[r]->setGain(SOAPY_SDR_TX, 0, openair0_cfg[0].tx_gain[0]); + s->iris[r]->setGain(SOAPY_SDR_RX, 1, openair0_cfg[0].rx_gain[1]); + s->iris[r]->setGain(SOAPY_SDR_TX, 1, openair0_cfg[0].tx_gain[1]); + } + return (0); +} + +/*! \brief Iris RX calibration table */ +rx_gain_calib_table_t calib_table_iris[] = { + {3500000000.0, 83}, + {2660000000.0, 83}, + {2580000000.0, 83}, + {2300000000.0, 83}, + {1880000000.0, 83}, + {816000000.0, 83}, + {-1, 0}}; + + +/*! \brief Set RX gain offset + * \param openair0_cfg RF frontend parameters set by application + * \param chain_index RF chain to apply settings to + * \returns 0 in success + */ +void set_rx_gain_offset(openair0_config_t *openair0_cfg, int chain_index, int bw_gain_adjust) { + + int i = 0; + // loop through calibration table to find best adjustment factor for RX frequency + double min_diff = 6e9, diff, gain_adj = 0.0; + if (bw_gain_adjust == 1) { + switch ((int) openair0_cfg[0].sample_rate) { + case 30720000: + break; + case 23040000: + gain_adj = 1.25; + break; + case 15360000: + gain_adj = 3.0; + break; + case 7680000: + gain_adj = 6.0; + break; + case 3840000: + gain_adj = 9.0; + break; + case 1920000: + gain_adj = 12.0; + break; + default: + printf("unknown sampling rate %d\n", (int) openair0_cfg[0].sample_rate); + exit(-1); + break; + } + } + + while (openair0_cfg->rx_gain_calib_table[i].freq > 0) { + diff = fabs(openair0_cfg->rx_freq[chain_index] - openair0_cfg->rx_gain_calib_table[i].freq); + printf("cal %d: freq %f, offset %f, diff %f\n", + i, + openair0_cfg->rx_gain_calib_table[i].freq, + openair0_cfg->rx_gain_calib_table[i].offset, diff); + if (min_diff > diff) { + min_diff = diff; + openair0_cfg->rx_gain_offset[chain_index] = openair0_cfg->rx_gain_calib_table[i].offset + gain_adj; + } + i++; + } + +} + +/*! \brief print the Iris statistics +* \param device the hardware to use +* \returns 0 on success +*/ +int trx_iris_get_stats(openair0_device *device) { + + return (0); + +} + +/*! \brief Reset the Iris statistics +* \param device the hardware to use +* \returns 0 on success +*/ +int trx_iris_reset_stats(openair0_device *device) { + + return (0); + +} + + +extern "C" { +/*! \brief Initialize Openair Iris target. It returns 0 if OK +* \param device the hardware to use +* \param openair0_cfg RF frontend parameters set by application +*/ +int device_init(openair0_device *device, openair0_config_t *openair0_cfg) { + + size_t i, r, card; + int bw_gain_adjust = 0; + openair0_cfg[0].rx_gain_calib_table = calib_table_iris; + iris_state_t *s = (iris_state_t *) malloc(sizeof(iris_state_t)); + memset(s, 0, sizeof(iris_state_t)); + + std::string devFE("DEV"); + std::string cbrsFE("CBRS"); + std::string wireFormat("WIRE"); + + // Initialize Iris device + device->openair0_cfg = openair0_cfg; + SoapySDR::Kwargs args; + args["driver"] = "iris"; + char *iris_addrs = device->openair0_cfg[0].sdr_addrs; + if (iris_addrs == NULL) + { + s->iris.push_back(SoapySDR::Device::make(args)); + } + else + { + char *serial = strtok(iris_addrs, ","); + while (serial != NULL) { + LOG_I(HW, "Attempting to open Iris device %s\n", serial); + args["serial"] = serial; + s->iris.push_back(SoapySDR::Device::make(args)); + serial = strtok(NULL, ","); + } + } + + s->device_num = s->iris.size(); + device->type = IRIS_DEV; + + + switch ((int) openair0_cfg[0].sample_rate) { + case 30720000: + //openair0_cfg[0].samples_per_packet = 1024; + openair0_cfg[0].tx_sample_advance = 115; + openair0_cfg[0].tx_bw = 20e6; + openair0_cfg[0].rx_bw = 20e6; + break; + case 23040000: + //openair0_cfg[0].samples_per_packet = 1024; + openair0_cfg[0].tx_sample_advance = 113; + openair0_cfg[0].tx_bw = 15e6; + openair0_cfg[0].rx_bw = 15e6; + break; + case 15360000: + //openair0_cfg[0].samples_per_packet = 1024; + openair0_cfg[0].tx_sample_advance = 60; + openair0_cfg[0].tx_bw = 10e6; + openair0_cfg[0].rx_bw = 10e6; + break; + case 7680000: + //openair0_cfg[0].samples_per_packet = 1024; + openair0_cfg[0].tx_sample_advance = 30; + openair0_cfg[0].tx_bw = 5e6; + openair0_cfg[0].rx_bw = 5e6; + break; + case 1920000: + //openair0_cfg[0].samples_per_packet = 1024; + openair0_cfg[0].tx_sample_advance = 20; + openair0_cfg[0].tx_bw = 1.4e6; + openair0_cfg[0].rx_bw = 1.4e6; + break; + default: + printf("Error: unknown sampling rate %f\n", openair0_cfg[0].sample_rate); + exit(-1); + break; + } + + printf("tx_sample_advance %d\n", openair0_cfg[0].tx_sample_advance); + s->rx_num_channels = openair0_cfg[0].rx_num_channels; + s->tx_num_channels = openair0_cfg[0].tx_num_channels; + if ((s->rx_num_channels == 1 || s->rx_num_channels == 2) && (s->tx_num_channels == 1 || s->tx_num_channels == 2)) + printf("Enabling %d rx and %d tx channel(s) on each device...\n", s->rx_num_channels, s->tx_num_channels); + else { + printf("Invalid rx or tx number of channels (%d, %d)\n", s->rx_num_channels, s->tx_num_channels); + exit(-1); + } + + for (r = 0; r < s->device_num; r++) { + switch ((int) openair0_cfg[0].sample_rate) { + case 1920000: + s->iris[r]->setMasterClockRate(256 * openair0_cfg[0].sample_rate); + break; + case 3840000: + s->iris[r]->setMasterClockRate(128 * openair0_cfg[0].sample_rate); + break; + case 7680000: + s->iris[r]->setMasterClockRate(64 * openair0_cfg[0].sample_rate); + break; + case 15360000: + s->iris[r]->setMasterClockRate(32 * openair0_cfg[0].sample_rate); + break; + case 30720000: + s->iris[r]->setMasterClockRate(16 * openair0_cfg[0].sample_rate); + break; + default: + printf("Error: unknown sampling rate %f\n", openair0_cfg[0].sample_rate); + exit(-1); + break; + } + // display Iris settings + printf("Actual master clock: %fMHz...\n", (s->iris[r]->getMasterClockRate() / 1e6)); + + /* Setting TX/RX BW after streamers are created due to iris calibration issue */ + for (i = 0; i < s->tx_num_channels; i++) { + if (i < s->iris[r]->getNumChannels(SOAPY_SDR_TX)) { + if (s->iris[r]->getHardwareInfo()["frontend"].compare(devFE) != 0) + s->iris[r]->setBandwidth(SOAPY_SDR_TX, i, 30e6); + else + s->iris[r]->setBandwidth(SOAPY_SDR_TX, i, openair0_cfg[0].tx_bw); + + printf("Setting tx bandwidth on channel %lu/%lu: BW %f (readback %f)\n", i, + s->iris[r]->getNumChannels(SOAPY_SDR_TX), openair0_cfg[0].tx_bw / 1e6, + s->iris[r]->getBandwidth(SOAPY_SDR_TX, i) / 1e6); + } + } + for (i = 0; i < s->rx_num_channels; i++) { + if (i < s->iris[r]->getNumChannels(SOAPY_SDR_RX)) { + if (s->iris[r]->getHardwareInfo()["frontend"].compare(devFE) != 0) + s->iris[r]->setBandwidth(SOAPY_SDR_TX, i, 30e6); + else + s->iris[r]->setBandwidth(SOAPY_SDR_RX, i, openair0_cfg[0].rx_bw); + printf("Setting rx bandwidth on channel %lu/%lu : BW %f (readback %f)\n", i, + s->iris[r]->getNumChannels(SOAPY_SDR_RX), openair0_cfg[0].rx_bw / 1e6, + s->iris[r]->getBandwidth(SOAPY_SDR_RX, i) / 1e6); + } + } + + for (i = 0; i < s->iris[r]->getNumChannels(SOAPY_SDR_RX); i++) { + if (i < s->rx_num_channels) { + s->iris[r]->setSampleRate(SOAPY_SDR_RX, i, openair0_cfg[0].sample_rate / SAMPLE_RATE_DOWN); + s->iris[r]->setFrequency(SOAPY_SDR_RX, i, "RF", openair0_cfg[0].rx_freq[i]); + + set_rx_gain_offset(&openair0_cfg[0], i, bw_gain_adjust); + //s->iris[r]->setGain(SOAPY_SDR_RX, i, openair0_cfg[0].rx_gain[i] - openair0_cfg[0].rx_gain_offset[i]); + if (s->iris[r]->getHardwareInfo()["frontend"].compare(devFE) != 0) { + s->iris[r]->setGain(SOAPY_SDR_RX, i, "LNA", openair0_cfg[0].rx_gain[i] - openair0_cfg[0].rx_gain_offset[i]); + //s->iris[r]->setGain(SOAPY_SDR_RX, i, "LNA", 0); + s->iris[r]->setGain(SOAPY_SDR_RX, i, "LNA1", 30); + s->iris[r]->setGain(SOAPY_SDR_RX, i, "LNA2", 17); + s->iris[r]->setGain(SOAPY_SDR_RX, i, "TIA", 0); + s->iris[r]->setGain(SOAPY_SDR_RX, i, "PGA", 0); + s->iris[r]->setGain(SOAPY_SDR_RX, i, "ATTN", 0); + } else { + s->iris[r]->setGain(SOAPY_SDR_RX, i, "LNA", openair0_cfg[0].rx_gain[i] - openair0_cfg[0].rx_gain_offset[i]); // [0,30] + s->iris[r]->setGain(SOAPY_SDR_RX, i, "TIA", 0); // [0,12,6] + s->iris[r]->setGain(SOAPY_SDR_RX, i, "PGA", 0); // [-12,19,1] + //s->iris[r]->setGain(SOAPY_SDR_RX, i, 50); // [-12,19,1] + + } + + s->iris[r]->setDCOffsetMode(SOAPY_SDR_RX, i, true); // move somewhere else + } + } + for (i = 0; i < s->iris[r]->getNumChannels(SOAPY_SDR_TX); i++) { + if (i < s->tx_num_channels) { + s->iris[r]->setSampleRate(SOAPY_SDR_TX, i, openair0_cfg[0].sample_rate / SAMPLE_RATE_DOWN); + s->iris[r]->setFrequency(SOAPY_SDR_TX, i, "RF", openair0_cfg[0].tx_freq[i]); + + if (s->iris[r]->getHardwareInfo()["frontend"].compare(devFE) == 0) { + //s->iris[r]->setGain(SOAPY_SDR_TX, i, "PAD", openair0_cfg[0].tx_gain[i]); + s->iris[r]->setGain(SOAPY_SDR_TX, i, "PAD", 52); + s->iris[r]->setGain(SOAPY_SDR_TX, i, "IAMP", 12); + //s->iris[r]->writeSetting("TX_ENABLE_DELAY", "0"); + //s->iris[r]->writeSetting("TX_DISABLE_DELAY", "100"); + } else { + s->iris[r]->setGain(SOAPY_SDR_TX, i, "ATTN", 0); // [-18, 0, 6] dB + s->iris[r]->setGain(SOAPY_SDR_TX, i, "IAMP", 9); // [-12, 12, 1] dB + s->iris[r]->setGain(SOAPY_SDR_TX, i, "PAD", 52); //openair0_cfg[0].tx_gain[i]); + //s->iris[r]->setGain(SOAPY_SDR_TX, i, "PAD", 35); // [0, 52, 1] dB + s->iris[r]->setGain(SOAPY_SDR_TX, i, "PA1", 9); // 17 ??? dB + s->iris[r]->setGain(SOAPY_SDR_TX, i, "PA2", 0); // [0, 17, 17] dB + s->iris[r]->setGain(SOAPY_SDR_TX, i, "PA3", 20); // 33 ??? dB + s->iris[r]->writeSetting("TX_ENABLE_DELAY", "0"); + s->iris[r]->writeSetting("TX_DISABLE_DELAY", "100"); + } + +// if (openair0_cfg[0].duplex_mode == 0) { +// printf("\nFDD: Enable TX antenna override\n"); +// s->iris[r]->writeSetting(SOAPY_SDR_TX, i, "TX_ENB_OVERRIDE", +// "true"); // From Josh: forces tx switching to be on always transmit regardless of bursts +// } + } + } + + + for (i = 0; i < s->iris[r]->getNumChannels(SOAPY_SDR_RX); i++) { + if (i < s->rx_num_channels) { + + //if (s->iris[r]->getHardwareInfo()["frontend"].compare(devFE) != 0) { + // printf("\nUsing SKLK calibration...\n"); + // s->iris[r]->writeSetting(SOAPY_SDR_RX, i, "CALIBRATE", "SKLK"); + //} else { + // s->iris[r]->writeSetting(SOAPY_SDR_RX, i, "CALIBRATE", ""); + // printf("\nUsing LMS calibration...\n"); + + //} + } + + } + + for (i = 0; i < s->iris[r]->getNumChannels(SOAPY_SDR_TX); i++) { + if (i < s->tx_num_channels) { + + if (s->iris[r]->getHardwareInfo()["frontend"].compare(devFE) != 0) { + printf("\nUsing SKLK calibration...\n"); + s->iris[r]->writeSetting(SOAPY_SDR_TX, i, "CALIBRATE", "SKLK"); + + } else { + printf("\nUsing LMS calibration...\n"); + s->iris[r]->writeSetting(SOAPY_SDR_TX, i, "CALIBRATE", ""); + } + } + + } + + if (s->iris[r]->getHardwareInfo()["frontend"].compare(devFE) == 0) { + for (i = 0; i < s->iris[r]->getNumChannels(SOAPY_SDR_RX); i++) { + if (openair0_cfg[0].duplex_mode == 0) { + printf("\nFDD: Setting receive antenna to %s\n", s->iris[r]->listAntennas(SOAPY_SDR_RX, i)[1].c_str()); + if (i < s->rx_num_channels) + s->iris[r]->setAntenna(SOAPY_SDR_RX, i, "RX"); + } else { + printf("\nTDD: Setting receive antenna to %s\n", s->iris[r]->listAntennas(SOAPY_SDR_RX, i)[0].c_str()); + if (i < s->rx_num_channels) + s->iris[r]->setAntenna(SOAPY_SDR_RX, i, "TRX"); + } + } + } + + + //s->iris[r]->writeSetting("TX_SW_DELAY", std::to_string( + // -openair0_cfg[0].tx_sample_advance)); //should offset switching to compensate for RF path (Lime) delay -- this will eventually be automated + + // create tx & rx streamer + //const SoapySDR::Kwargs &arg = SoapySDR::Kwargs(); + std::map rxStreamArgs; + rxStreamArgs["WIRE"] = SOAPY_SDR_CS16; + + std::vector channels; + for (i = 0; i < s->rx_num_channels; i++) + if (i < s->iris[r]->getNumChannels(SOAPY_SDR_RX)) + channels.push_back(i); + s->rxStream.push_back(s->iris[r]->setupStream(SOAPY_SDR_RX, SOAPY_SDR_CS16, channels));//, rxStreamArgs)); + + std::vector tx_channels = {}; + for (i = 0; i < s->tx_num_channels; i++) + if (i < s->iris[r]->getNumChannels(SOAPY_SDR_TX)) + tx_channels.push_back(i); + s->txStream.push_back(s->iris[r]->setupStream(SOAPY_SDR_TX, SOAPY_SDR_CS16, tx_channels)); //, arg)); + //s->iris[r]->setHardwareTime(0, ""); + + std::cout << "Front end detected: " << s->iris[r]->getHardwareInfo()["frontend"] << "\n"; + for (i = 0; i < s->rx_num_channels; i++) { + if (i < s->iris[r]->getNumChannels(SOAPY_SDR_RX)) { + printf("RX Channel %lu\n", i); + printf("Actual RX sample rate: %fMSps...\n", (s->iris[r]->getSampleRate(SOAPY_SDR_RX, i) / 1e6)); + printf("Actual RX frequency: %fGHz...\n", (s->iris[r]->getFrequency(SOAPY_SDR_RX, i) / 1e9)); + printf("Actual RX gain: %f...\n", (s->iris[r]->getGain(SOAPY_SDR_RX, i))); + printf("Actual RX LNA gain: %f...\n", (s->iris[r]->getGain(SOAPY_SDR_RX, i, "LNA"))); + printf("Actual RX PGA gain: %f...\n", (s->iris[r]->getGain(SOAPY_SDR_RX, i, "PGA"))); + printf("Actual RX TIA gain: %f...\n", (s->iris[r]->getGain(SOAPY_SDR_RX, i, "TIA"))); + if (s->iris[r]->getHardwareInfo()["frontend"].compare(devFE) != 0) { + printf("Actual RX LNA1 gain: %f...\n", (s->iris[r]->getGain(SOAPY_SDR_RX, i, "LNA1"))); + printf("Actual RX LNA2 gain: %f...\n", (s->iris[r]->getGain(SOAPY_SDR_RX, i, "LNA2"))); + } + printf("Actual RX bandwidth: %fM...\n", (s->iris[r]->getBandwidth(SOAPY_SDR_RX, i) / 1e6)); + printf("Actual RX antenna: %s...\n", (s->iris[r]->getAntenna(SOAPY_SDR_RX, i).c_str())); + } + } + + for (i = 0; i < s->tx_num_channels; i++) { + if (i < s->iris[r]->getNumChannels(SOAPY_SDR_TX)) { + printf("TX Channel %lu\n", i); + printf("Actual TX sample rate: %fMSps...\n", (s->iris[r]->getSampleRate(SOAPY_SDR_TX, i) / 1e6)); + printf("Actual TX frequency: %fGHz...\n", (s->iris[r]->getFrequency(SOAPY_SDR_TX, i) / 1e9)); + printf("Actual TX gain: %f...\n", (s->iris[r]->getGain(SOAPY_SDR_TX, i))); + printf("Actual TX PAD gain: %f...\n", (s->iris[r]->getGain(SOAPY_SDR_TX, i, "PAD"))); + printf("Actual TX IAMP gain: %f...\n", (s->iris[r]->getGain(SOAPY_SDR_TX, i, "IAMP"))); + if (s->iris[r]->getHardwareInfo()["frontend"].compare(devFE) != 0) { + printf("Actual TX PA1 gain: %f...\n", (s->iris[r]->getGain(SOAPY_SDR_TX, i, "PA1"))); + printf("Actual TX PA2 gain: %f...\n", (s->iris[r]->getGain(SOAPY_SDR_TX, i, "PA2"))); + printf("Actual TX PA3 gain: %f...\n", (s->iris[r]->getGain(SOAPY_SDR_TX, i, "PA3"))); + } + printf("Actual TX bandwidth: %fM...\n", (s->iris[r]->getBandwidth(SOAPY_SDR_TX, i) / 1e6)); + printf("Actual TX antenna: %s...\n", (s->iris[r]->getAntenna(SOAPY_SDR_TX, i).c_str())); + } + } + } + s->iris[0]->writeSetting("SYNC_DELAYS", ""); + for (r = 0; r < s->device_num; r++) + s->iris[r]->setHardwareTime(0, "TRIGGER"); + s->iris[0]->writeSetting("TRIGGER_GEN", ""); + for (r = 0; r < s->device_num; r++) + printf("Device timestamp: %f...\n", (s->iris[r]->getHardwareTime("TRIGGER") / 1e9)); + + device->priv = s; + device->trx_start_func = trx_iris_start; + device->trx_write_func = trx_iris_write; + device->trx_read_func = trx_iris_read; + device->trx_get_stats_func = trx_iris_get_stats; + device->trx_reset_stats_func = trx_iris_reset_stats; + device->trx_end_func = trx_iris_end; + device->trx_stop_func = trx_iris_stop; + device->trx_set_freq_func = trx_iris_set_freq; + device->trx_set_gains_func = trx_iris_set_gains; + device->openair0_cfg = openair0_cfg; + + s->sample_rate = openair0_cfg[0].sample_rate; + // TODO: + // init tx_forward_nsamps based iris_time_offset ex + if (is_equal(s->sample_rate, (double) 30.72e6)) + s->tx_forward_nsamps = 176; + if (is_equal(s->sample_rate, (double) 15.36e6)) + s->tx_forward_nsamps = 90; + if (is_equal(s->sample_rate, (double) 7.68e6)) + s->tx_forward_nsamps = 50; + + LOG_I(HW, "Finished initializing %d Iris device(s).\n", s->device_num); + fflush(stdout); + return 0; +} +} +/*@}*/ + + + + + diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band38.tm1.25PRB.iris030.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band38.tm1.25PRB.iris030.conf new file mode 100644 index 0000000000..77993457ab --- /dev/null +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band38.tm1.25PRB.iris030.conf @@ -0,0 +1,264 @@ +Active_eNBs = ( "eNB_Eurecom_LTEBox"); +# Asn1_verbosity, choice in: none, info, annoying +Asn1_verbosity = "none"; + +eNBs = +( + { + ////////// Identification parameters: + eNB_ID = 0xe00; + + cell_type = "CELL_MACRO_ENB"; + + eNB_name = "eNB_Eurecom_LTEBox"; + + // Tracking area code, 0x0000 and 0xfffe are reserved values + tracking_area_code = 1; + + plmn_list = ( { mcc = 208; mnc = 92; mnc_length = 2; } ); + + tr_s_preference = "local_mac" + + ////////// Physical parameters: + + component_carriers = ( + { + node_function = "eNodeB_3GPP"; + node_timing = "synch_to_ext_device"; + node_synch_ref = 0; + frame_type = "TDD"; + tdd_config = 3; + tdd_config_s = 0; + prefix_type = "NORMAL"; + eutra_band = 38; + downlink_frequency = 2580000000L; + uplink_frequency_offset = 0; + Nid_cell = 10; + N_RB_DL = 25; + Nid_cell_mbsfn = 0; + nb_antenna_ports = 1; + nb_antennas_tx = 1; + nb_antennas_rx = 1; + tx_gain = 52; # [~50 for DEV-FE, ~30 for CBRS-FE] + rx_gain = 115; # [115 for DEV-FE, 90 for CBRS-FE] + pbch_repetition = "FALSE"; + prach_root = 0; + prach_config_index = 0; + prach_high_speed = "DISABLE"; + prach_zero_correlation = 1; + prach_freq_offset = 2; + pucch_delta_shift = 1; + pucch_nRB_CQI = 1; + pucch_nCS_AN = 0; + pucch_n1_AN = 32; + pdsch_referenceSignalPower = -30; + pdsch_p_b = 0; + pusch_n_SB = 1; + pusch_enable64QAM = "DISABLE"; + pusch_hoppingMode = "interSubFrame"; + pusch_hoppingOffset = 0; + pusch_groupHoppingEnabled = "ENABLE"; + pusch_groupAssignment = 0; + pusch_sequenceHoppingEnabled = "DISABLE"; + pusch_nDMRS1 = 1; + phich_duration = "NORMAL"; + phich_resource = "ONESIXTH"; + srs_enable = "DISABLE"; + /* srs_BandwidthConfig =; + srs_SubframeConfig =; + srs_ackNackST =; + srs_MaxUpPts =;*/ + + pusch_p0_Nominal = -70; + pusch_alpha = "AL1"; + pucch_p0_Nominal = -96; + msg3_delta_Preamble = 6; + pucch_deltaF_Format1 = "deltaF2"; + pucch_deltaF_Format1b = "deltaF3"; + pucch_deltaF_Format2 = "deltaF0"; + pucch_deltaF_Format2a = "deltaF0"; + pucch_deltaF_Format2b = "deltaF0"; + + rach_numberOfRA_Preambles = 64; + rach_preamblesGroupAConfig = "DISABLE"; + /* + rach_sizeOfRA_PreamblesGroupA = ; + rach_messageSizeGroupA = ; + rach_messagePowerOffsetGroupB = ; + */ + rach_powerRampingStep = 4; + rach_preambleInitialReceivedTargetPower = -96; + rach_preambleTransMax = 10; + rach_raResponseWindowSize = 10; + rach_macContentionResolutionTimer = 48; + rach_maxHARQ_Msg3Tx = 4; + + pcch_default_PagingCycle = 128; + pcch_nB = "oneT"; + bcch_modificationPeriodCoeff = 2; + ue_TimersAndConstants_t300 = 1000; + ue_TimersAndConstants_t301 = 1000; + ue_TimersAndConstants_t310 = 1000; + ue_TimersAndConstants_t311 = 10000; + ue_TimersAndConstants_n310 = 20; + ue_TimersAndConstants_n311 = 1; + ue_TransmissionMode = 1; + + //Parameters for SIB18 + rxPool_sc_CP_Len = "normal"; + rxPool_sc_Period = "sf40"; + rxPool_data_CP_Len = "normal"; + rxPool_ResourceConfig_prb_Num = 20; + rxPool_ResourceConfig_prb_Start = 5; + rxPool_ResourceConfig_prb_End = 44; + rxPool_ResourceConfig_offsetIndicator_present = "prSmall"; + rxPool_ResourceConfig_offsetIndicator_choice = 0; + rxPool_ResourceConfig_subframeBitmap_present = "prBs40"; + rxPool_ResourceConfig_subframeBitmap_choice_bs_buf = "00000000000000000000"; + rxPool_ResourceConfig_subframeBitmap_choice_bs_size = 5; + rxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused = 0; +/* rxPool_dataHoppingConfig_hoppingParameter = 0; + rxPool_dataHoppingConfig_numSubbands = "ns1"; + rxPool_dataHoppingConfig_rbOffset = 0; + rxPool_commTxResourceUC-ReqAllowed = "TRUE"; +*/ + // Parameters for SIB19 + discRxPool_cp_Len = "normal" + discRxPool_discPeriod = "rf32" + discRxPool_numRetx = 1; + discRxPool_numRepetition = 2; + discRxPool_ResourceConfig_prb_Num = 5; + discRxPool_ResourceConfig_prb_Start = 3; + discRxPool_ResourceConfig_prb_End = 21; + discRxPool_ResourceConfig_offsetIndicator_present = "prSmall"; + discRxPool_ResourceConfig_offsetIndicator_choice = 0; + discRxPool_ResourceConfig_subframeBitmap_present = "prBs40"; + discRxPool_ResourceConfig_subframeBitmap_choice_bs_buf = "f0ffffffff"; + discRxPool_ResourceConfig_subframeBitmap_choice_bs_size = 5; + discRxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused = 0; + + } + ); + + srb1_parameters : + { + # timer_poll_retransmit = (ms) [5, 10, 15, 20,... 250, 300, 350, ... 500] + timer_poll_retransmit = 80; + + # timer_reordering = (ms) [0,5, ... 100, 110, 120, ... ,200] + timer_reordering = 35; + + # timer_reordering = (ms) [0,5, ... 250, 300, 350, ... ,500] + timer_status_prohibit = 0; + + # poll_pdu = [4, 8, 16, 32 , 64, 128, 256, infinity(>10000)] + poll_pdu = 4; + + # poll_byte = (kB) [25,50,75,100,125,250,375,500,750,1000,1250,1500,2000,3000,infinity(>10000)] + poll_byte = 99999; + + # max_retx_threshold = [1, 2, 3, 4 , 6, 8, 16, 32] + max_retx_threshold = 4; + } + + # ------- SCTP definitions + SCTP : + { + # Number of streams to use in input/output + SCTP_INSTREAMS = 2; + SCTP_OUTSTREAMS = 2; + }; + + + ////////// MME parameters: + mme_ip_address = ( { ipv4 = "127.0.0.20"; + ipv6 = "fe80::d65d:dfff:fe1d:f4d4"; + active = "yes"; + preference = "ipv4"; + } + ); + + NETWORK_INTERFACES : + { + ENB_INTERFACE_NAME_FOR_S1_MME = "eno1"; + ENB_IPV4_ADDRESS_FOR_S1_MME = "127.0.0.10/8"; + ENB_INTERFACE_NAME_FOR_S1U = "enp5s0"; + ENB_IPV4_ADDRESS_FOR_S1U = "127.0.0.10/8"; + ENB_PORT_FOR_S1U = 2152; # Spec 2152 + + ENB_IPV4_ADDRESS_FOR_X2C = "127.0.0.10/8"; + ENB_PORT_FOR_X2C = 36422; # Spec 36422 + }; + } +); + +MACRLCs = ( + { + num_cc = 1; + tr_s_preference = "local_L1"; + tr_n_preference = "local_RRC"; + phy_test_mode = 0; + puSch10xSnr = 200; + puCch10xSnr = 200; + } +); + +L1s = ( + { + num_cc = 1; + tr_n_preference = "local_mac"; + } +); + +RUs = ( + { + local_rf = "yes" + nb_tx = 1 + nb_rx = 1 + att_tx = 0 + att_rx = 0; + bands = [7]; + max_pdschReferenceSignalPower = -27; + max_rxgain = 125; + eNB_instances = [0]; + #sdr_addrs = "RF3C000025"; + } +); + +NETWORK_CONTROLLER : +{ + FLEXRAN_ENABLED = "no"; + FLEXRAN_INTERFACE_NAME = "lo"; + FLEXRAN_IPV4_ADDRESS = "127.0.0.1"; + FLEXRAN_PORT = 2210; + FLEXRAN_CACHE = "/mnt/oai_agent_cache"; + FLEXRAN_AWAIT_RECONF = "no"; +}; + +THREAD_STRUCT = ( + { + #three config for level of parallelism "PARALLEL_SINGLE_THREAD", "PARALLEL_RU_L1_SPLIT", or "PARALLEL_RU_L1_TRX_SPLIT" + parallel_config = "PARALLEL_RU_L1_TRX_SPLIT"; + #two option for worker "WORKER_DISABLE" or "WORKER_ENABLE" + worker_config = "WORKER_ENABLE"; + } +); + + log_config : + { + global_log_level ="info"; + global_log_verbosity ="medium"; + hw_log_level ="info"; + hw_log_verbosity ="medium"; + phy_log_level ="info"; + phy_log_verbosity ="medium"; + mac_log_level ="info"; + mac_log_verbosity ="high"; + rlc_log_level ="info"; + rlc_log_verbosity ="medium"; + pdcp_log_level ="info"; + pdcp_log_verbosity ="medium"; + rrc_log_level ="info"; + rrc_log_verbosity ="medium"; + }; + diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.25PRB.iris030.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.25PRB.iris030.conf new file mode 100644 index 0000000000..ca85c6538f --- /dev/null +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.25PRB.iris030.conf @@ -0,0 +1,264 @@ +Active_eNBs = ( "eNB_Eurecom_LTEBox"); +# Asn1_verbosity, choice in: none, info, annoying +Asn1_verbosity = "none"; + +eNBs = +( + { + ////////// Identification parameters: + eNB_ID = 0xe00; + + cell_type = "CELL_MACRO_ENB"; + + eNB_name = "eNB_Eurecom_LTEBox"; + + // Tracking area code, 0x0000 and 0xfffe are reserved values + tracking_area_code = 1; + + plmn_list = ( { mcc = 208; mnc = 92; mnc_length = 2; } ); + + tr_s_preference = "local_mac" + + ////////// Physical parameters: + + component_carriers = ( + { + node_function = "eNodeB_3GPP"; + node_timing = "synch_to_ext_device"; + node_synch_ref = 0; + frame_type = "FDD"; + tdd_config = 3; + tdd_config_s = 0; + prefix_type = "NORMAL"; + eutra_band = 7; + downlink_frequency = 2660000000L; + uplink_frequency_offset = -120000000; + Nid_cell = 10; + N_RB_DL = 25; + Nid_cell_mbsfn = 0; + nb_antenna_ports = 1; + nb_antennas_tx = 1; + nb_antennas_rx = 1; + tx_gain = 52; # [~50 for DEV-FE, ~30 for CBRS-FE] + rx_gain = 115; # [115 for DEV-FE, 90 for CBRS-FE] + pbch_repetition = "FALSE"; + prach_root = 0; + prach_config_index = 0; + prach_high_speed = "DISABLE"; + prach_zero_correlation = 1; + prach_freq_offset = 2; + pucch_delta_shift = 1; + pucch_nRB_CQI = 1; + pucch_nCS_AN = 0; + pucch_n1_AN = 32; + pdsch_referenceSignalPower = -30; + pdsch_p_b = 0; + pusch_n_SB = 1; + pusch_enable64QAM = "DISABLE"; + pusch_hoppingMode = "interSubFrame"; + pusch_hoppingOffset = 0; + pusch_groupHoppingEnabled = "ENABLE"; + pusch_groupAssignment = 0; + pusch_sequenceHoppingEnabled = "DISABLE"; + pusch_nDMRS1 = 1; + phich_duration = "NORMAL"; + phich_resource = "ONESIXTH"; + srs_enable = "DISABLE"; + /* srs_BandwidthConfig =; + srs_SubframeConfig =; + srs_ackNackST =; + srs_MaxUpPts =;*/ + + pusch_p0_Nominal = -70; + pusch_alpha = "AL1"; + pucch_p0_Nominal = -96; + msg3_delta_Preamble = 6; + pucch_deltaF_Format1 = "deltaF2"; + pucch_deltaF_Format1b = "deltaF3"; + pucch_deltaF_Format2 = "deltaF0"; + pucch_deltaF_Format2a = "deltaF0"; + pucch_deltaF_Format2b = "deltaF0"; + + rach_numberOfRA_Preambles = 64; + rach_preamblesGroupAConfig = "DISABLE"; + /* + rach_sizeOfRA_PreamblesGroupA = ; + rach_messageSizeGroupA = ; + rach_messagePowerOffsetGroupB = ; + */ + rach_powerRampingStep = 4; + rach_preambleInitialReceivedTargetPower = -96; + rach_preambleTransMax = 10; + rach_raResponseWindowSize = 10; + rach_macContentionResolutionTimer = 48; + rach_maxHARQ_Msg3Tx = 4; + + pcch_default_PagingCycle = 128; + pcch_nB = "oneT"; + bcch_modificationPeriodCoeff = 2; + ue_TimersAndConstants_t300 = 1000; + ue_TimersAndConstants_t301 = 1000; + ue_TimersAndConstants_t310 = 1000; + ue_TimersAndConstants_t311 = 10000; + ue_TimersAndConstants_n310 = 20; + ue_TimersAndConstants_n311 = 1; + ue_TransmissionMode = 1; + + //Parameters for SIB18 + rxPool_sc_CP_Len = "normal"; + rxPool_sc_Period = "sf40"; + rxPool_data_CP_Len = "normal"; + rxPool_ResourceConfig_prb_Num = 20; + rxPool_ResourceConfig_prb_Start = 5; + rxPool_ResourceConfig_prb_End = 44; + rxPool_ResourceConfig_offsetIndicator_present = "prSmall"; + rxPool_ResourceConfig_offsetIndicator_choice = 0; + rxPool_ResourceConfig_subframeBitmap_present = "prBs40"; + rxPool_ResourceConfig_subframeBitmap_choice_bs_buf = "00000000000000000000"; + rxPool_ResourceConfig_subframeBitmap_choice_bs_size = 5; + rxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused = 0; +/* rxPool_dataHoppingConfig_hoppingParameter = 0; + rxPool_dataHoppingConfig_numSubbands = "ns1"; + rxPool_dataHoppingConfig_rbOffset = 0; + rxPool_commTxResourceUC-ReqAllowed = "TRUE"; +*/ + // Parameters for SIB19 + discRxPool_cp_Len = "normal" + discRxPool_discPeriod = "rf32" + discRxPool_numRetx = 1; + discRxPool_numRepetition = 2; + discRxPool_ResourceConfig_prb_Num = 5; + discRxPool_ResourceConfig_prb_Start = 3; + discRxPool_ResourceConfig_prb_End = 21; + discRxPool_ResourceConfig_offsetIndicator_present = "prSmall"; + discRxPool_ResourceConfig_offsetIndicator_choice = 0; + discRxPool_ResourceConfig_subframeBitmap_present = "prBs40"; + discRxPool_ResourceConfig_subframeBitmap_choice_bs_buf = "f0ffffffff"; + discRxPool_ResourceConfig_subframeBitmap_choice_bs_size = 5; + discRxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused = 0; + + } + ); + + srb1_parameters : + { + # timer_poll_retransmit = (ms) [5, 10, 15, 20,... 250, 300, 350, ... 500] + timer_poll_retransmit = 80; + + # timer_reordering = (ms) [0,5, ... 100, 110, 120, ... ,200] + timer_reordering = 35; + + # timer_reordering = (ms) [0,5, ... 250, 300, 350, ... ,500] + timer_status_prohibit = 0; + + # poll_pdu = [4, 8, 16, 32 , 64, 128, 256, infinity(>10000)] + poll_pdu = 4; + + # poll_byte = (kB) [25,50,75,100,125,250,375,500,750,1000,1250,1500,2000,3000,infinity(>10000)] + poll_byte = 99999; + + # max_retx_threshold = [1, 2, 3, 4 , 6, 8, 16, 32] + max_retx_threshold = 4; + } + + # ------- SCTP definitions + SCTP : + { + # Number of streams to use in input/output + SCTP_INSTREAMS = 2; + SCTP_OUTSTREAMS = 2; + }; + + + ////////// MME parameters: + mme_ip_address = ( { ipv4 = "127.0.0.20"; + ipv6 = "fe80::d65d:dfff:fe1d:f4d4"; + active = "yes"; + preference = "ipv4"; + } + ); + + NETWORK_INTERFACES : + { + ENB_INTERFACE_NAME_FOR_S1_MME = "lo"; + ENB_IPV4_ADDRESS_FOR_S1_MME = "127.0.0.10/8"; + ENB_INTERFACE_NAME_FOR_S1U = "lo"; + ENB_IPV4_ADDRESS_FOR_S1U = "127.0.0.10/8"; + ENB_PORT_FOR_S1U = 2152; # Spec 2152 + + ENB_IPV4_ADDRESS_FOR_X2C = "127.0.0.10/8"; + ENB_PORT_FOR_X2C = 36422; # Spec 36422 + }; + } +); + +MACRLCs = ( + { + num_cc = 1; + tr_s_preference = "local_L1"; + tr_n_preference = "local_RRC"; + phy_test_mode = 0; + puSch10xSnr = 200; + puCch10xSnr = 200; + } +); + +L1s = ( + { + num_cc = 1; + tr_n_preference = "local_mac"; + } +); + +RUs = ( + { + local_rf = "yes" + nb_tx = 1 + nb_rx = 1 + att_tx = 0 + att_rx = 0; + bands = [7]; + max_pdschReferenceSignalPower = -27; + max_rxgain = 125; + eNB_instances = [0]; + sdr_addrs = "RF3E000028"; + } +); + +NETWORK_CONTROLLER : +{ + FLEXRAN_ENABLED = "no"; + FLEXRAN_INTERFACE_NAME = "lo"; + FLEXRAN_IPV4_ADDRESS = "127.0.0.1"; + FLEXRAN_PORT = 2210; + FLEXRAN_CACHE = "/mnt/oai_agent_cache"; + FLEXRAN_AWAIT_RECONF = "no"; +}; + +THREAD_STRUCT = ( + { + #three config for level of parallelism "PARALLEL_SINGLE_THREAD", "PARALLEL_RU_L1_SPLIT", or "PARALLEL_RU_L1_TRX_SPLIT" + parallel_config = "PARALLEL_RU_L1_TRX_SPLIT"; + #two option for worker "WORKER_DISABLE" or "WORKER_ENABLE" + worker_config = "WORKER_ENABLE"; + } +); + + log_config : + { + global_log_level ="info"; + global_log_verbosity ="medium"; + hw_log_level ="info"; + hw_log_verbosity ="medium"; + phy_log_level ="info"; + phy_log_verbosity ="medium"; + mac_log_level ="info"; + mac_log_verbosity ="high"; + rlc_log_level ="info"; + rlc_log_verbosity ="medium"; + pdcp_log_level ="info"; + pdcp_log_verbosity ="medium"; + rrc_log_level ="info"; + rrc_log_verbosity ="medium"; + }; + diff --git a/targets/RT/USER/lte-ru.c b/targets/RT/USER/lte-ru.c index 4a0d2d5266..614b29bc8e 100644 --- a/targets/RT/USER/lte-ru.c +++ b/targets/RT/USER/lte-ru.c @@ -761,9 +761,9 @@ void rx_rf(RU_t *ru,int *frame,int *subframe) { proc->timestamp_rx = ts-ru->ts_offset; // AssertFatal(rxs == fp->samples_per_tti, -// "rx_rf: Asked for %d samples, got %d from USRP\n",fp->samples_per_tti,rxs); +// "rx_rf: Asked for %d samples, got %d from SDR\n",fp->samples_per_tti,rxs); if(rxs != fp->samples_per_tti){ - LOG_E(PHY,"rx_rf: Asked for %d samples, got %d from USRP\n",fp->samples_per_tti,rxs); + LOG_E(PHY,"rx_rf: Asked for %d samples, got %d from SDR\n",fp->samples_per_tti,rxs); late_control=STATE_BURST_TERMINATE; } From 5dc5f6bc79763a0ec6df28aee8e55b64324601d9 Mon Sep 17 00:00:00 2001 From: Raphael Defosseux Date: Mon, 10 Dec 2018 14:49:48 +0100 Subject: [PATCH 192/233] CI: missing OSA banners Signed-off-by: Raphael Defosseux --- ci-scripts/active_net_interfaces.awk | 20 ++++++++++++++++++++ ci-scripts/doGitLabMerge.sh | 20 ++++++++++++++++++++ ci-scripts/tcp_iperf_stats.awk | 20 ++++++++++++++++++++ 3 files changed, 60 insertions(+) diff --git a/ci-scripts/active_net_interfaces.awk b/ci-scripts/active_net_interfaces.awk index 6d582c763b..6d1174c1cc 100644 --- a/ci-scripts/active_net_interfaces.awk +++ b/ci-scripts/active_net_interfaces.awk @@ -1 +1,21 @@ +#/* +# * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more +# * contributor license agreements. See the NOTICE file distributed with +# * this work for additional information regarding copyright ownership. +# * The OpenAirInterface Software Alliance licenses this file to You under +# * the OAI Public License, Version 1.1 (the "License"); you may not use this file +# * except in compliance with the License. +# * You may obtain a copy of the License at +# * +# * http://www.openairinterface.org/?page_id=698 +# * +# * Unless required by applicable law or agreed to in writing, software +# * distributed under the License is distributed on an "AS IS" BASIS, +# * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# * See the License for the specific language governing permissions and +# * limitations under the License. +# *------------------------------------------------------------------------------- +# * For more information about the OpenAirInterface (OAI) Software Alliance: +# * contact@openairinterface.org +# */ /inet.*brd/{print "interfaceToUse="$NF"done"} diff --git a/ci-scripts/doGitLabMerge.sh b/ci-scripts/doGitLabMerge.sh index dfe2f02b55..852b6407ea 100755 --- a/ci-scripts/doGitLabMerge.sh +++ b/ci-scripts/doGitLabMerge.sh @@ -1,4 +1,24 @@ #!/bin/bash +#/* +# * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more +# * contributor license agreements. See the NOTICE file distributed with +# * this work for additional information regarding copyright ownership. +# * The OpenAirInterface Software Alliance licenses this file to You under +# * the OAI Public License, Version 1.1 (the "License"); you may not use this file +# * except in compliance with the License. +# * You may obtain a copy of the License at +# * +# * http://www.openairinterface.org/?page_id=698 +# * +# * Unless required by applicable law or agreed to in writing, software +# * distributed under the License is distributed on an "AS IS" BASIS, +# * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# * See the License for the specific language governing permissions and +# * limitations under the License. +# *------------------------------------------------------------------------------- +# * For more information about the OpenAirInterface (OAI) Software Alliance: +# * contact@openairinterface.org +# */ function usage { echo "OAI GitLab merge request applying script" diff --git a/ci-scripts/tcp_iperf_stats.awk b/ci-scripts/tcp_iperf_stats.awk index e5c64b6283..3a00e4555f 100644 --- a/ci-scripts/tcp_iperf_stats.awk +++ b/ci-scripts/tcp_iperf_stats.awk @@ -1,3 +1,23 @@ +#/* +# * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more +# * contributor license agreements. See the NOTICE file distributed with +# * this work for additional information regarding copyright ownership. +# * The OpenAirInterface Software Alliance licenses this file to You under +# * the OAI Public License, Version 1.1 (the "License"); you may not use this file +# * except in compliance with the License. +# * You may obtain a copy of the License at +# * +# * http://www.openairinterface.org/?page_id=698 +# * +# * Unless required by applicable law or agreed to in writing, software +# * distributed under the License is distributed on an "AS IS" BASIS, +# * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# * See the License for the specific language governing permissions and +# * limitations under the License. +# *------------------------------------------------------------------------------- +# * For more information about the OpenAirInterface (OAI) Software Alliance: +# * contact@openairinterface.org +# */ BEGIN{max=0;min=10000} { if ($0 ~/Mbits/) { From 1b659b936cf3e224e8838d95b872f9e8a3119ca2 Mon Sep 17 00:00:00 2001 From: Laurent Date: Wed, 12 Dec 2018 14:21:00 +0100 Subject: [PATCH 193/233] fix issue 379 --- cmake_targets/CMakeLists.txt | 111 +++++++++++++++++------------------ 1 file changed, 54 insertions(+), 57 deletions(-) diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt index 8d9a5d263d..c9d6c07291 100644 --- a/cmake_targets/CMakeLists.txt +++ b/cmake_targets/CMakeLists.txt @@ -260,17 +260,17 @@ add_boolean_option(ENABLE_ITTI True "ITTI is internal messaging, should remain e set (OCP_ITTI ${OPENAIR_DIR}/common/utils/ocp_itti) if (${ENABLE_ITTI}) add_library(ITTI - # add .h files if depend on (this one is generated) ${OCP_ITTI}/intertask_interface.cpp ${OPENAIR_DIR}/common/utils/backtrace.c ${OPENAIR_DIR}/common/utils/memory_pools.c ) +add_dependencies(ITTI rrc_flag) set(ITTI_LIB ITTI) set(GTPU_need_ITTI ${OPENAIR3_DIR}/GTPV1-U/gtpv1u_eNB.c) endif (${ENABLE_ITTI}) ############################# -# ASN.1 grammar C code generation & dependancies +# ASN.1 grammar C code generation & dependencies ################################ # A difficulty: asn1c generates C code of a un-predictable list of files # so, generate the c from asn1c once at cmake run time @@ -278,8 +278,6 @@ endif (${ENABLE_ITTI}) # (so creating new asn.1 objects instead of modifying the object attributes) # New C code source file, cmake must be re-run (instead of re-running make only) ############# -# set(asn1c_call "${OPENAIR_CMAKE}/tools/generate_asn1") -# set(fix_asn1c_call "${OPENAIR_CMAKE}/tools/fix_asn1") set(asn1_generated_dir ${OPENAIR_BIN_DIR}) set(protoc_call "${OPENAIR_CMAKE}/tools/generate_protobuf") @@ -317,32 +315,27 @@ elseif (${RRC_ASN1_VERSION} STREQUAL "Rel15") endif (${RRC_ASN1_VERSION} STREQUAL "Rel8") add_definitions(-DLTE_RRC_VERSION=${LTE_RRC_VERSION}) set (RRC_FULL_DIR ${asn1_generated_dir}/RRC_${RRC_ASN1_VERSION}) -message("calling ASN1C_PREFIX=LTE_ asn1c -pdu=all -fcompound-names -gen-PER -no-gen-OER -no-gen-example -D ${RRC_FULL_DIR} ${RRC_GRAMMAR}") -execute_process(COMMAND mkdir -p ${RRC_FULL_DIR} - COMMAND env "ASN1C_PREFIX=LTE_" asn1c -pdu=all -fcompound-names -gen-PER -no-gen-OER -no-gen-example -D ${RRC_FULL_DIR} ${RRC_GRAMMAR} + +# Warning: if you modify ASN.1 source file to generate new C files, cmake should be re-run instead of make +execute_process(COMMAND ${OPENAIR_CMAKE}/tools/make_asn1c_includes.sh "${RRC_FULL_DIR}" "${RRC_GRAMMAR}" "LTE_" RESULT_VARIABLE ret) if (NOT ${ret} STREQUAL 0) message(FATAL_ERROR "${ret}: error") endif (NOT ${ret} STREQUAL 0) - file(GLOB rrc_source ${RRC_FULL_DIR}/*.c) -file(GLOB rrc_h ${RRC_FULL_DIR}/*.h) -set(rrc_h ${rrc_h} ${RRC_FULL_DIR}/asn_constant.h) -set_source_files_properties(${rrc_source} PROPERTIES COMPILE_FLAGS -w) # suppress warnings from generated code -add_library(RRC_LIB ${rrc_h} ${rrc_source} - ${OPENAIR2_DIR}/RRC/LTE/MESSAGES/asn1_msg.c - ${OPENAIR2_DIR}/RRC/LTE/MESSAGES/asn1_msg_NB_IoT.c) -include_directories ("${RRC_FULL_DIR}") - -# add the command to generate the source code -# Warning: if you modify ASN.1 source file to generate new C files, cmake should be re-run instead of make -add_custom_command ( - OUTPUT ${RRC_FULL_DIR}/asn_constant.h - COMMAND mkdir -p ${RRC_FULL_DIR} - COMMAND env "ASN1C_PREFIX=LTE_" asn1c -pdu=all -fcompound-names -gen-PER -no-gen-OER -no-gen-example -D ${RRC_FULL_DIR} ${RRC_GRAMMAR} +add_custom_target ( + rrc_flag ALL + ${OPENAIR_CMAKE}/tools/make_asn1c_includes.sh "${RRC_FULL_DIR}" "${RRC_GRAMMAR}" "LTE_" DEPENDS ${RRC_GRAMMAR} ) +set_source_files_properties(${rrc_source} PROPERTIES COMPILE_FLAGS -w) # suppress warnings from generated code +add_library(RRC_LIB ${rrc_source} + ${OPENAIR2_DIR}/RRC/LTE/MESSAGES/asn1_msg.c + ${OPENAIR2_DIR}/RRC/LTE/MESSAGES/asn1_msg_NB_IoT.c) +add_dependencies(RRC_LIB rrc_flag) +include_directories ("${RRC_FULL_DIR}") + # S1AP # Same limitation as described in RRC: unknown generated file list # so we generate it at cmake time @@ -378,28 +371,26 @@ endif(${S1AP_RELEASE} STREQUAL "R8") add_definitions(-DS1AP_VERSION=${S1AP_VERSION}) set(S1AP_ASN_DIR ${S1AP_DIR}/MESSAGES/ASN1/${S1AP_RELEASE}) set(S1AP_C_DIR ${asn1_generated_dir}/S1AP_${S1AP_RELEASE}) -message("calling ASN1C_PREFIX=S1AP_ asn1c -pdu=all -fcompound-names -fno-include-deps -gen-PER -no-gen-OER -no-gen-example -D ${S1AP_C_DIR} ${S1AP_ASN_DIR}/${S1AP_ASN_FILES}") -execute_process(COMMAND mkdir -p ${S1AP_C_DIR} - COMMAND env "ASN1C_PREFIX=S1AP_" asn1c -pdu=all -fcompound-names -fno-include-deps -gen-PER -no-gen-OER -no-gen-example -D ${S1AP_C_DIR} ${S1AP_ASN_DIR}/${S1AP_ASN_FILES} + +# Warning: if you modify ASN.1 source file to generate new C files, cmake should be re-run instead of make +execute_process(COMMAND ${OPENAIR_CMAKE}/tools/make_asn1c_includes.sh "${S1AP_C_DIR}" "${S1AP_ASN_DIR}/${S1AP_ASN_FILES}" "S1AP_" -fno-include-deps RESULT_VARIABLE ret) if (NOT ${ret} STREQUAL 0) message(FATAL_ERROR "${ret}: error") endif (NOT ${ret} STREQUAL 0) file(GLOB S1AP_source ${S1AP_C_DIR}/*.c) -file(GLOB s1ap_h ${S1AP_C_DIR}/*.h) -set(s1ap_h ${s1ap_h}) - -add_custom_command ( - OUTPUT ${S1AP_C_DIR}/S1AP_asn_constant.h - COMMAND mkdir -p ${S1AP_C_DIR} - COMMAND env "ASN1C_PREFIX=S1AP_" asn1c -pdu=all -fcompound-names -fno-include-deps -gen-PER -no-gen-OER -no-gen-example -D ${S1AP_C_DIR} ${S1AP_ASN_DIR}/${S1AP_ASN_FILES} - DEPENDS ${S1AP_ASN_DIR}/${S1AP_ASN_FILES} +add_custom_target ( + s1ap_flag ALL + ${OPENAIR_CMAKE}/tools/make_asn1c_includes.sh "${S1AP_C_DIR}" "${S1AP_ASN_DIR}/${S1AP_ASN_FILES}" "S1AP_" -fno-include-deps + DEPENDS "${S1AP_ASN_DIR}/${S1AP_ASN_FILES}" ) + add_library(S1AP_LIB ${S1AP_source} ${S1AP_DIR}/s1ap_common.c ) +add_dependencies(S1AP_LIB rrc_flag s1ap_flag) include_directories ("${S1AP_C_DIR}") include_directories ("${S1AP_DIR}") @@ -418,6 +409,7 @@ add_library(S1AP_ENB ${S1AP_DIR}/s1ap_eNB_trace.c ${S1AP_DIR}/s1ap_eNB_ue_context.c ) +add_dependencies(S1AP_ENB rrc_flag s1ap_flag) #X2AP # Same limitation as described in RRC/S1AP: unknown generated file list @@ -445,22 +437,19 @@ endif(${X2AP_RELEASE} STREQUAL "R8") add_definitions(-DX2AP_VERSION=${X2AP_VERSION}) set(X2AP_ASN_DIR ${X2AP_DIR}/MESSAGES/ASN1/${X2AP_RELEASE}) set(X2AP_C_DIR ${asn1_generated_dir}/X2AP_${X2AP_RELEASE}) -message("calling ASN1C_PREFIX=X2AP_ asn1c -pdu=all -fcompound-names -fno-include-deps -gen-PER -no-gen-OER -no-gen-example -D ${X2AP_C_DIR} ${X2AP_ASN_DIR}/${X2AP_ASN_FILES}") -execute_process(COMMAND mkdir -p ${X2AP_C_DIR} - COMMAND env "ASN1C_PREFIX=X2AP_" asn1c -pdu=all -fcompound-names -fno-include-deps -gen-PER -no-gen-OER -no-gen-example -D ${X2AP_C_DIR} ${X2AP_ASN_DIR}/${X2AP_ASN_FILES} + +# Warning: if you modify ASN.1 source file to generate new C files, cmake should be re-run instead of make +execute_process(COMMAND ${OPENAIR_CMAKE}/tools/make_asn1c_includes.sh "${X2AP_C_DIR}" "${X2AP_ASN_DIR}/${X2AP_ASN_FILES}" "X2AP_" -fno-include-deps RESULT_VARIABLE ret) if (NOT ${ret} STREQUAL 0) message(FATAL_ERROR "${ret}: error") endif (NOT ${ret} STREQUAL 0) + file(GLOB X2AP_source ${X2AP_C_DIR}/*.c) -file(GLOB x2ap_h ${X2AP_C_DIR}/*.h) -set(x2ap_h ${x2ap_h}) - -add_custom_command ( - OUTPUT ${X2AP_C_DIR}/X2AP_asn_constant.h - COMMAND mkdir -p ${X2AP_C_DIR} - COMMAND env "ASN1C_PREFIX=X2AP_" asn1c -pdu=all -fcompound-names -fno-include-deps -gen-PER -no-gen-OER -no-gen-example -D ${X2AP_C_DIR} ${X2AP_ASN_DIR}/${X2AP_ASN_FILES} +add_custom_target ( + x2_flag ALL + COMMAND ${OPENAIR_CMAKE}/tools/make_asn1c_includes.sh "${X2AP_C_DIR}" "${X2AP_ASN_DIR}/${X2AP_ASN_FILES}" "X2AP_" -fno-include-deps DEPENDS ${X2AP_ASN_DIR}/${X2AP_ASN_FILES} ) @@ -468,6 +457,7 @@ add_library(X2AP_LIB ${X2AP_source} ${X2AP_DIR}/x2ap_common.c ) +add_dependencies(X2AP_LIB rrc_flag x2_flag) include_directories ("${X2AP_C_DIR}") include_directories ("${X2AP_DIR}") @@ -481,6 +471,7 @@ add_library(X2AP_ENB ${X2AP_DIR}/x2ap_eNB_management_procedures.c ${X2AP_DIR}/x2ap_eNB_generate_messages.c ) +add_dependencies(X2AP_ENB rrc_flag x2_flag) # Hardware dependant options ################################### @@ -872,6 +863,7 @@ add_library(FLEXRAN_AGENT ${OPENAIR2_DIR}/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_internal.c ${OPENAIR2_DIR}/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_slice_verification.c ) +add_dependencies(FLEXRAN_AGENT rrc_flag) set(FLEXRAN_AGENT_LIB FLEXRAN_AGENT) #include_directories(${OPENAIR2_DIR}/ENB_APP) @@ -937,6 +929,7 @@ set(UTIL_SRC # ${OPENAIR2_DIR}/UTIL/OTG/otg_rx.c ) add_library(UTIL ${UTIL_SRC}) +add_dependencies(UTIL rrc_flag) #set(OMG_SUMO_SRC # ${OPENAIR2_DIR}/UTIL/OMG/client_traci_OMG.c @@ -976,12 +969,14 @@ set(SCHED_SRC ${OPENAIR1_DIR}/SCHED/phy_procedures_lte_common.c ) add_library(SCHED_LIB ${SCHED_SRC}) +add_dependencies(SCHED_LIB rrc_flag) set(SCHED_SRC_RU ${OPENAIR1_DIR}/SCHED/ru_procedures.c ${OPENAIR1_DIR}/SCHED/prach_procedures.c ) add_library(SCHED_RU_LIB ${SCHED_SRC_RU}) +add_dependencies(SCHED_RU_LIB rrc_flag) set(SCHED_SRC_UE ${OPENAIR1_DIR}/SCHED_UE/phy_procedures_lte_ue.c @@ -991,6 +986,7 @@ set(SCHED_SRC_UE ${OPENAIR1_DIR}/SCHED_UE/srs_pc.c ) add_library(SCHED_UE_LIB ${SCHED_SRC_UE}) +add_dependencies(SCHED_UE_LIB rrc_flag) # nFAPI ################################# @@ -1042,6 +1038,7 @@ set(NFAPI_USER_SRC ${NFAPI_USER_DIR}/nfapi_vnf.c ) add_library(NFAPI_USER_LIB ${NFAPI_USER_SRC}) +add_dependencies(NFAPI_USER_LIB rrc_flag) include_directories(${NFAPI_USER_DIR}) # Layer 1 @@ -1060,9 +1057,6 @@ set(PHY_TURBOIF add_library(coding MODULE ${PHY_TURBOSRC} ) set(PHY_SRC_COMMON - # depend on code generation from asn1c - ${RRC_FULL_DIR}/asn_constant.h - # actual source ${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/dci_tools_common.c ${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/lte_mcs.c # ${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/slss.c @@ -1113,7 +1107,6 @@ set(PHY_SRC_COMMON ) set(PHY_SRC - # actual source ${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/pss.c ${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/sss.c ${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/sss_gen.c @@ -1141,7 +1134,6 @@ set(PHY_SRC ) set(PHY_SRC_RU - # actual source ${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/if4_tools.c ${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/if5_tools.c ${OPENAIR1_DIR}/PHY/MODULATION/slot_fep_ul.c @@ -1155,7 +1147,6 @@ set(PHY_SRC_RU ) set(PHY_SRC_UE - # actual source ${OPENAIR1_DIR}/PHY/LTE_UE_TRANSPORT/sss_ue.c ${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/sss_gen.c ${OPENAIR1_DIR}/PHY/LTE_UE_TRANSPORT/dlsch_demodulation.c @@ -1204,9 +1195,13 @@ if (${COMPILATION_AVX2} STREQUAL "True") endif () add_library(PHY_COMMON ${PHY_SRC_COMMON}) +add_dependencies(PHY_COMMON rrc_flag) add_library(PHY ${PHY_SRC}) +add_dependencies(PHY rrc_flag) add_library(PHY_UE ${PHY_SRC_UE}) +add_dependencies(PHY_UE rrc_flag) add_library(PHY_RU ${PHY_SRC_RU}) +add_dependencies(PHY_RU rrc_flag) #Library for mex functions #########################3 @@ -1376,11 +1371,13 @@ add_library(L2 ${MAC_SRC} ${ENB_APP_SRC}) # ${OPENAIR2_DIR}/RRC/L2_INTERFACE/openair_rrc_L2_interface.c) +add_dependencies(L2 rrc_flag s1ap_flag x2_flag) add_library(L2_UE ${L2_SRC_UE} ${MAC_SRC_UE} ) +add_dependencies(L2_UE rrc_flag s1ap_flag x2_flag) include_directories(${NFAPI_USER_DIR}) @@ -1406,6 +1403,7 @@ set (GTPV1U_SRC ${GTPV1U_DIR}/gtpv1u_teid_pool.c ) add_library(GTPV1U ${GTPV1U_SRC}) +add_dependencies(GTPV1U rrc_flag) set(SCTP_SRC ${OPENAIR3_DIR}/SCTP/sctp_common.c @@ -1413,8 +1411,10 @@ set(SCTP_SRC ${OPENAIR3_DIR}/SCTP/sctp_eNB_itti_messaging.c ) add_library(SCTP_CLIENT ${SCTP_SRC}) +add_dependencies(SCTP_CLIENT rrc_flag) add_library(UDP ${OPENAIR3_DIR}/UDP/udp_eNB_task.c) +add_dependencies(UDP rrc_flag) set(NAS_SRC ${OPENAIR3_DIR}/NAS/) @@ -1663,6 +1663,7 @@ if(NAS_UE) ${libnas_ue_esm_OBJS} ${libnas_ue_esm_sap_OBJS} ) + add_dependencies(LIB_NAS_UE rrc_flag) set(NAS_UE_LIB LIB_NAS_UE) include_directories(${NAS_SRC}UE) @@ -1920,8 +1921,6 @@ add_definitions(-DASN1_MINIMUM_VERSION=924) ################################################### add_executable(lte-softmodem - ${rrc_h} - ${s1ap_h} ${OPENAIR_TARGETS}/RT/USER/rt_wrapper.c ${OPENAIR_TARGETS}/RT/USER/lte-enb.c ${OPENAIR_TARGETS}/RT/USER/lte-ru.c @@ -1944,6 +1943,7 @@ add_executable(lte-softmodem ${CONFIG_SOURCES} ${SHLIB_LOADER_SOURCES} ) +add_dependencies(lte-softmodem rrc_flag s1ap_flag x2_flag) target_link_libraries (lte-softmodem -Wl,--start-group @@ -1960,8 +1960,6 @@ target_link_libraries (lte-softmodem ${T_LIB}) # lte-softmodem-nos1 is both eNB and UE implementation ################################################### add_executable(lte-softmodem-nos1 - ${rrc_h} - ${s1ap_h} ${OPENAIR_TARGETS}/RT/USER/rt_wrapper.c ${OPENAIR_TARGETS}/RT/USER/lte-enb.c ${OPENAIR_TARGETS}/RT/USER/lte-ru.c @@ -1983,6 +1981,7 @@ add_executable(lte-softmodem-nos1 ${CONFIG_SOURCES} ${SHLIB_LOADER_SOURCES} ) +add_dependencies(lte-softmodem-nos1 rrc_flag s1ap_flag x2_flag) target_link_libraries (lte-softmodem-nos1 -Wl,--start-group RRC_LIB SECU_CN SECU_OSA UTIL HASHTABLE SCHED_LIB SCHED_RU_LIB PHY_COMMON PHY PHY_RU LFDS L2 ${RAL_LIB} ${ITTI_LIB} @@ -1999,8 +1998,6 @@ target_link_libraries (lte-softmodem-nos1 ${T_LIB}) ####################################### add_executable(lte-uesoftmodem - ${rrc_h} - ${s1ap_h} ${OPENAIR_TARGETS}/RT/USER/rt_wrapper.c ${OPENAIR_TARGETS}/RT/USER/lte-ue.c ${OPENAIR_TARGETS}/RT/USER/lte-uesoftmodem.c @@ -2023,6 +2020,7 @@ add_executable(lte-uesoftmodem ${SHLIB_LOADER_SOURCES} ) +add_dependencies(lte-uesoftmodem rrc_flag s1ap_flag x2_flag) target_link_libraries (lte-uesoftmodem -Wl,--start-group RRC_LIB S1AP_LIB S1AP_ENB X2AP_LIB X2AP_ENB GTPV1U SECU_CN SECU_OSA UTIL HASHTABLE SCTP_CLIENT UDP SCHED_RU_LIB SCHED_UE_LIB PHY_COMMON PHY_UE PHY_RU LFDS L2_UE SIMU @@ -2038,8 +2036,6 @@ target_link_libraries (lte-uesoftmodem ${T_LIB}) # lte-uesoftmodem-nos1 is UE implementation ################################################### add_executable(lte-uesoftmodem-nos1 - ${rrc_h} - ${s1ap_h} ${OPENAIR_TARGETS}/RT/USER/rt_wrapper.c ${OPENAIR_TARGETS}/RT/USER/lte-ue.c ${OPENAIR_TARGETS}/RT/USER/lte-uesoftmodem.c @@ -2063,6 +2059,7 @@ add_executable(lte-uesoftmodem-nos1 ${SHLIB_LOADER_SOURCES} ) +add_dependencies(lte-uesoftmodem-nos1 rrc_flag s1ap_flag x2_flag) target_link_libraries (lte-uesoftmodem-nos1 -Wl,--start-group RRC_LIB SECU_CN SECU_OSA UTIL HASHTABLE SCHED_RU_LIB SCHED_UE_LIB PHY_COMMON PHY_UE PHY_RU LFDS L2_UE SIMU ${RAL_LIB} ${ITTI_LIB} From 89229ac59a9a8b620ec971c6d045e893074476bd Mon Sep 17 00:00:00 2001 From: Laurent Date: Wed, 12 Dec 2018 14:49:54 +0100 Subject: [PATCH 194/233] fix issue 379 --- cmake_targets/tools/make_asn1c_includes.sh | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100755 cmake_targets/tools/make_asn1c_includes.sh diff --git a/cmake_targets/tools/make_asn1c_includes.sh b/cmake_targets/tools/make_asn1c_includes.sh new file mode 100755 index 0000000000..bd4254c938 --- /dev/null +++ b/cmake_targets/tools/make_asn1c_includes.sh @@ -0,0 +1,15 @@ +#!/bin/bash +GENERATED_FULL_DIR=$1 +shift +ASN1_SOURCE_DIR=$1 +shift +export ASN1C_PREFIX=$1 +shift +options=$* +done_flag="$GENERATED_FULL_DIR"/done +if [ "$done_flag" -ot $ASN1_SOURCE_DIR ] ; then + rm -f "$GENERATED_FULL_DIR"/${ASN1C_PREFIX}*.c "$GENERATED_FULL_DIR"/${ASN1C_PREFIX}*.h + mkdir -p "$GENERATED_FULL_DIR" + asn1c -pdu=all -fcompound-names -gen-PER -no-gen-OER -no-gen-example $options -D $GENERATED_FULL_DIR $ASN1_SOURCE_DIR |& egrep -v "^Copied|^Compiled" | sort -u +fi +touch $done_flag From 70711c346959b9a132573e6e27366c3bd84e7322 Mon Sep 17 00:00:00 2001 From: Raphael Defosseux Date: Thu, 13 Dec 2018 10:02:02 +0100 Subject: [PATCH 195/233] CI: adding support for multiple XML scenario files Signed-off-by: Raphael Defosseux --- ci-scripts/Jenkinsfile-tmp-ran | 36 ++-- ci-scripts/main.py | 306 ++++++++++++++++++++----------- ci-scripts/reportBuildLocally.sh | 21 ++- ci-scripts/reportTestLocally.sh | 19 +- 4 files changed, 243 insertions(+), 139 deletions(-) diff --git a/ci-scripts/Jenkinsfile-tmp-ran b/ci-scripts/Jenkinsfile-tmp-ran index 938110b458..fc01233bfb 100644 --- a/ci-scripts/Jenkinsfile-tmp-ran +++ b/ci-scripts/Jenkinsfile-tmp-ran @@ -27,6 +27,8 @@ def pythonExecutor = params.pythonExecutor // Location of the test XML file to be run def testXMLFile = params.pythonTestXmlFile +def mainPythonAllXmlFiles = "" +def buildStageStatus = true // Name of the test stage def testStageName = params.pipelineTestStageName @@ -108,8 +110,14 @@ pipeline { if (params.pythonTestXmlFile == null) { // picking default testXMLFile = 'xml_files/enb_usrpB210_band7_50PRB.xml' + echo "Test XML file(default): ${testXMLFile}" + mainPythonAllXmlFiles += "--XMLTestFile=" + testXMLFile + " " } else { - echo "Test XML file : ${testXMLFile}" + String[] myXmlTestSuite = testXMLFile.split("\\r?\\n") + for (xmlFile in myXmlTestSuite) { + mainPythonAllXmlFiles += "--XMLTestFile=" + xmlFile + " " + echo "Test XML file : ${xmlFile}" + } } // If not present picking a default Stage Name if (params.pipelineTestStageName == null) { @@ -194,17 +202,23 @@ pipeline { steps { script { dir ('ci-scripts') { - try { - echo "\u2705 \u001B[32m${testStageName}\u001B[0m" - withCredentials([ - [$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.eNB_Credentials}", usernameVariable: 'eNB_Username', passwordVariable: 'eNB_Password'], - [$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.EPC_Credentials}", usernameVariable: 'EPC_Username', passwordVariable: 'EPC_Password'], - [$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.ADB_Credentials}", usernameVariable: 'ADB_Username', passwordVariable: 'ADB_Password'] - ]) { - sh "python3 main.py --mode=TesteNB --eNBIPAddress=${params.eNB_IPAddress} --eNBRepository=${eNB_Repository} --eNBBranch=${eNB_Branch} --eNBCommitID=${eNB_CommitID} --eNB_AllowMerge=${eNB_AllowMergeRequestProcess} --eNBTargetBranch=${eNB_TargetBranch} --eNBUserName=${eNB_Username} --eNBPassword=${eNB_Password} --eNBSourceCodePath=${params.eNB_SourceCodePath} --EPCIPAddress=${params.EPC_IPAddress} --EPCType=${params.EPC_Type} --EPCUserName=${EPC_Username} --EPCPassword=${EPC_Password} --EPCSourceCodePath=${params.EPC_SourceCodePath} --ADBIPAddress=${params.ADB_IPAddress} --ADBUserName=${ADB_Username} --ADBPassword=${ADB_Password} --XMLTestFile=${testXMLFile}" + echo "\u2705 \u001B[32m${testStageName}\u001B[0m" + withCredentials([ + [$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.eNB_Credentials}", usernameVariable: 'eNB_Username', passwordVariable: 'eNB_Password'], + [$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.EPC_Credentials}", usernameVariable: 'EPC_Username', passwordVariable: 'EPC_Password'], + [$class: 'UsernamePasswordMultiBinding', credentialsId: "${params.ADB_Credentials}", usernameVariable: 'ADB_Username', passwordVariable: 'ADB_Password'] + ]) { + sh "python3 main.py --mode=InitiateHtml --eNBRepository=${eNB_Repository} --eNBBranch=${eNB_Branch} --eNBCommitID=${eNB_CommitID} --eNB_AllowMerge=${eNB_AllowMergeRequestProcess} --eNBTargetBranch=${eNB_TargetBranch} --ADBIPAddress=${params.ADB_IPAddress} --ADBUserName=${ADB_Username} --ADBPassword=${ADB_Password} ${mainPythonAllXmlFiles}" + String[] myXmlTestSuite = testXMLFile.split("\\r?\\n") + for (xmlFile in myXmlTestSuite) { + try { + sh "python3 main.py --mode=TesteNB --eNBIPAddress=${params.eNB_IPAddress} --eNBRepository=${eNB_Repository} --eNBBranch=${eNB_Branch} --eNBCommitID=${eNB_CommitID} --eNB_AllowMerge=${eNB_AllowMergeRequestProcess} --eNBTargetBranch=${eNB_TargetBranch} --eNBUserName=${eNB_Username} --eNBPassword=${eNB_Password} --eNBSourceCodePath=${params.eNB_SourceCodePath} --EPCIPAddress=${params.EPC_IPAddress} --EPCType=${params.EPC_Type} --EPCUserName=${EPC_Username} --EPCPassword=${EPC_Password} --EPCSourceCodePath=${params.EPC_SourceCodePath} --ADBIPAddress=${params.ADB_IPAddress} --ADBUserName=${ADB_Username} --ADBPassword=${ADB_Password} --XMLTestFile=${xmlFile}" + } catch (Exception e) { + currentBuild.result = 'FAILURE' + buildStageStatus = false + } } - } catch (Exception e) { - currentBuild.result = 'FAILURE' + sh "python3 main.py --mode=FinalizeHtml --finalStatus=${buildStageStatus}" } } } diff --git a/ci-scripts/main.py b/ci-scripts/main.py index c32eb8d286..849e50b076 100644 --- a/ci-scripts/main.py +++ b/ci-scripts/main.py @@ -91,7 +91,8 @@ class SSHConnection(): self.ADBUserName = '' self.ADBPassword = '' self.testCase_id = '' - self.testXMLfile = '' + self.testXMLfiles = [] + self.nbTestXMLfiles = 0 self.desc = '' self.Build_eNB_args = '' self.Initialize_eNB_args = '' @@ -112,6 +113,11 @@ class SSHConnection(): self.htmlUEConnected = 0 self.htmleNBFailureMsg = '' self.picocom_closure = False + self.idle_sleep_time = 0 + self.htmlTabRefs = [] + self.htmlTabNames = [] + self.htmlTabIcons = [] + self.finalStatus = False def open(self, ipaddress, username, password): count = 0 @@ -282,9 +288,9 @@ class SSHConnection(): self.command('chmod 777 log', '\$', 5) # no need to remove in log (git clean did the trick) self.command('stdbuf -o0 ./build_oai ' + self.Build_eNB_args + ' 2>&1 | stdbuf -o0 tee -a compile_oai_enb.log', 'Bypassing the Tests', 600) - self.command('mkdir -p build_log_' + SSH.testCase_id, '\$', 5) - self.command('mv log/* ' + 'build_log_' + SSH.testCase_id, '\$', 5) - self.command('mv compile_oai_enb.log ' + 'build_log_' + SSH.testCase_id, '\$', 5) + self.command('mkdir -p build_log_' + self.testCase_id, '\$', 5) + self.command('mv log/* ' + 'build_log_' + self.testCase_id, '\$', 5) + self.command('mv compile_oai_enb.log ' + 'build_log_' + self.testCase_id, '\$', 5) # Workaround to run with develop-nr self.command('if [ -e ran_build ]; then cp -rf ran_build lte_build_oai; fi', '\$', 30) self.close() @@ -300,7 +306,7 @@ class SSHConnection(): self.command('cd ' + self.EPCSourceCodePath, '\$', 5) self.command('source oaienv', '\$', 5) self.command('cd scripts', '\$', 5) - self.command('echo ' + self.EPCPassword + ' | sudo -S ./run_hss 2>&1 | stdbuf -o0 awk \'{ print strftime("[%Y/%m/%d %H:%M:%S] ",systime()) $0 }\' | stdbuf -o0 tee -a hss_' + SSH.testCase_id + '.log &', 'Core state: 2 -> 3', 35) + self.command('echo ' + self.EPCPassword + ' | sudo -S ./run_hss 2>&1 | stdbuf -o0 awk \'{ print strftime("[%Y/%m/%d %H:%M:%S] ",systime()) $0 }\' | stdbuf -o0 tee -a hss_' + self.testCase_id + '.log &', 'Core state: 2 -> 3', 35) else: logging.debug('Using the ltebox simulated HSS') self.command('if [ -d ' + self.EPCSourceCodePath + '/scripts ]; then echo ' + self.eNBPassword + ' | sudo -S rm -Rf ' + self.EPCSourceCodePath + '/scripts ; fi', '\$', 5) @@ -326,7 +332,7 @@ class SSHConnection(): logging.debug('\u001B[1;37;41m Hostname Not Found! \u001B[0m') sys.exit(1) host_name = result.group('host_name') - self.command('echo ' + self.EPCPassword + ' | sudo -S ./run_mme 2>&1 | stdbuf -o0 tee -a mme_' + SSH.testCase_id + '.log &', 'MME app initialization complete', 100) + self.command('echo ' + self.EPCPassword + ' | sudo -S ./run_mme 2>&1 | stdbuf -o0 tee -a mme_' + self.testCase_id + '.log &', 'MME app initialization complete', 100) else: self.command('cd /opt/ltebox/tools', '\$', 5) self.command('echo ' + self.EPCPassword + ' | sudo -S ./start_mme', '\$', 5) @@ -342,7 +348,7 @@ class SSHConnection(): self.command('cd ' + self.EPCSourceCodePath, '\$', 5) self.command('source oaienv', '\$', 5) self.command('cd scripts', '\$', 5) - self.command('echo ' + self.EPCPassword + ' | sudo -S ./run_spgw 2>&1 | stdbuf -o0 tee -a spgw_' + SSH.testCase_id + '.log &', 'Initializing SPGW-APP task interface: DONE', 30) + self.command('echo ' + self.EPCPassword + ' | sudo -S ./run_spgw 2>&1 | stdbuf -o0 tee -a spgw_' + self.testCase_id + '.log &', 'Initializing SPGW-APP task interface: DONE', 30) else: self.command('cd /opt/ltebox/tools', '\$', 5) self.command('echo ' + self.EPCPassword + ' | sudo -S ./start_xGw', '\$', 5) @@ -357,7 +363,7 @@ class SSHConnection(): pStatus = self.CheckProcessExist(initialize_eNB_flag) if (pStatus < 0): self.CreateHtmlTestRow(self.Initialize_eNB_args, 'KO', pStatus) - self.CreateHtmlFooter(False) + self.CreateHtmlTabFooter(False) sys.exit(1) # If tracer options is on, running tshark on EPC side and capture traffic b/ EPC and eNB result = re.search('T_stdout', str(self.Initialize_eNB_args)) @@ -368,8 +374,8 @@ class SSHConnection(): if result is not None: eth_interface = result.group('eth_interface') logging.debug('\u001B[1m Launching tshark on interface ' + eth_interface + '\u001B[0m') - self.command('echo ' + self.EPCPassword + ' | sudo -S rm -f /tmp/enb_' + SSH.testCase_id + '_s1log.pcap', '\$', 5) - self.command('echo $USER; nohup sudo tshark -f "host ' + self.eNBIPAddress +'" -i ' + eth_interface + ' -w /tmp/enb_' + SSH.testCase_id + '_s1log.pcap > /tmp/tshark.log 2>&1 &', self.EPCUserName, 5) + self.command('echo ' + self.EPCPassword + ' | sudo -S rm -f /tmp/enb_' + self.testCase_id + '_s1log.pcap', '\$', 5) + self.command('echo $USER; nohup sudo tshark -f "host ' + self.eNBIPAddress +'" -i ' + eth_interface + ' -w /tmp/enb_' + self.testCase_id + '_s1log.pcap > /tmp/tshark.log 2>&1 &', self.EPCUserName, 5) self.close() self.open(self.eNBIPAddress, self.eNBUserName, self.eNBPassword) self.command('cd ' + self.eNBSourceCodePath, '\$', 5) @@ -384,7 +390,7 @@ class SSHConnection(): logging.debug('\u001B[1m Compiling and launching T Tracer\u001B[0m') self.command('cd common/utils/T/tracer', '\$', 5) self.command('make', '\$', 10) - self.command('echo $USER; nohup ./record -d ../T_messages.txt -o ' + self.eNBSourceCodePath + '/cmake_targets/enb_' + SSH.testCase_id + '_record.raw -ON -off VCD -off HEAVY -off LEGACY_GROUP_TRACE -off LEGACY_GROUP_DEBUG > ' + self.eNBSourceCodePath + '/cmake_targets/enb_' + SSH.testCase_id + '_record.log 2>&1 &', self.eNBUserName, 5) + self.command('echo $USER; nohup ./record -d ../T_messages.txt -o ' + self.eNBSourceCodePath + '/cmake_targets/enb_' + self.testCase_id + '_record.raw -ON -off VCD -off HEAVY -off LEGACY_GROUP_TRACE -off LEGACY_GROUP_DEBUG > ' + self.eNBSourceCodePath + '/cmake_targets/enb_' + self.testCase_id + '_record.log 2>&1 &', self.eNBUserName, 5) self.command('cd ' + self.eNBSourceCodePath, '\$', 5) full_config_file = full_config_file[:extIdx + 5] config_path, config_file = os.path.split(full_config_file) @@ -402,12 +408,12 @@ class SSHConnection(): # Launch eNB with the modified config file self.command('source oaienv', '\$', 5) self.command('cd cmake_targets', '\$', 5) - self.command('echo "ulimit -c unlimited && ./lte_build_oai/build/lte-softmodem -O ' + self.eNBSourceCodePath + '/' + ci_full_config_file + extra_options + '" > ./my-lte-softmodem-run' + str(SSH.eNB_instance) + '.sh ', '\$', 5) - self.command('chmod 775 ./my-lte-softmodem-run' + str(SSH.eNB_instance) + '.sh ', '\$', 5) - self.command('echo ' + self.eNBPassword + ' | sudo -S rm -Rf enb_' + SSH.testCase_id + '.log', '\$', 5) - self.command('echo ' + self.eNBPassword + ' | sudo -S -E daemon --inherit --unsafe --name=enb' + str(SSH.eNB_instance) + '_daemon --chdir=' + self.eNBSourceCodePath + '/cmake_targets -o ' + self.eNBSourceCodePath + '/cmake_targets/enb_' + SSH.testCase_id + '.log ./my-lte-softmodem-run' + str(SSH.eNB_instance) + '.sh', '\$', 5) + self.command('echo "ulimit -c unlimited && ./lte_build_oai/build/lte-softmodem -O ' + self.eNBSourceCodePath + '/' + ci_full_config_file + extra_options + '" > ./my-lte-softmodem-run' + str(self.eNB_instance) + '.sh ', '\$', 5) + self.command('chmod 775 ./my-lte-softmodem-run' + str(self.eNB_instance) + '.sh ', '\$', 5) + self.command('echo ' + self.eNBPassword + ' | sudo -S rm -Rf enb_' + self.testCase_id + '.log', '\$', 5) + self.command('echo ' + self.eNBPassword + ' | sudo -S -E daemon --inherit --unsafe --name=enb' + str(self.eNB_instance) + '_daemon --chdir=' + self.eNBSourceCodePath + '/cmake_targets -o ' + self.eNBSourceCodePath + '/cmake_targets/enb_' + self.testCase_id + '.log ./my-lte-softmodem-run' + str(self.eNB_instance) + '.sh', '\$', 5) if not rruCheck: - self.eNBLogFile = 'enb_' + SSH.testCase_id + '.log' + self.eNBLogFile = 'enb_' + self.testCase_id + '.log' time.sleep(6) doLoop = True loopCounter = 10 @@ -422,7 +428,7 @@ class SSHConnection(): doLoop = False logging.error('\u001B[1;37;41m eNB logging system did not show got sync! \u001B[0m') self.CreateHtmlTestRow('-O ' + config_file + extra_options, 'KO', ALL_PROCESSES_OK) - self.CreateHtmlFooter(False) + self.CreateHtmlTabFooter(False) # In case of T tracer recording, we need to kill tshark on EPC side result = re.search('T_stdout', str(self.Initialize_eNB_args)) if result is not None: @@ -431,12 +437,12 @@ class SSHConnection(): self.command('echo ' + self.EPCPassword + ' | sudo -S killall --signal SIGKILL tshark', '\$', 5) self.close() time.sleep(1) - pcap_log_file = 'enb_' + SSH.testCase_id + '_s1log.pcap' + pcap_log_file = 'enb_' + self.testCase_id + '_s1log.pcap' self.copyin(self.EPCIPAddress, self.EPCUserName, self.EPCPassword, '/tmp/' + pcap_log_file, '.') self.copyout(self.eNBIPAddress, self.eNBUserName, self.eNBPassword, pcap_log_file, self.eNBSourceCodePath + '/cmake_targets/.') sys.exit(1) else: - self.command('stdbuf -o0 cat enb_' + SSH.testCase_id + '.log | egrep --text --color=never -i "wait|sync"', '\$', 4) + self.command('stdbuf -o0 cat enb_' + self.testCase_id + '.log | egrep --text --color=never -i "wait|sync"', '\$', 4) if rruCheck: result = re.search('wait RUs', str(self.ssh.before)) else: @@ -472,7 +478,7 @@ class SSHConnection(): sys.exit('Insufficient Parameter') multi_jobs = [] for device_id in self.UEDevices: - p = Process(target = SSH.InitializeUE_common, args = (device_id,)) + p = Process(target = self.InitializeUE_common, args = (device_id,)) p.daemon = True p.start() multi_jobs.append(p) @@ -639,7 +645,7 @@ class SSHConnection(): if (pStatus < 0): self.CreateHtmlTestRow('N/A', 'KO', pStatus) self.AutoTerminateUEandeNB() - self.CreateHtmlFooter(False) + self.CreateHtmlTabFooter(False) sys.exit(1) multi_jobs = [] status_queue = SimpleQueue() @@ -647,7 +653,7 @@ class SSHConnection(): nb_ue_to_connect = 0 for device_id in self.UEDevices: if (self.nbMaxUEtoAttach == -1) or (nb_ue_to_connect < self.nbMaxUEtoAttach): - p = Process(target = SSH.AttachUE_common, args = (device_id, status_queue, lock,)) + p = Process(target = self.AttachUE_common, args = (device_id, status_queue, lock,)) p.daemon = True p.start() multi_jobs.append(p) @@ -657,7 +663,7 @@ class SSHConnection(): if (status_queue.empty()): self.CreateHtmlTestRow('N/A', 'KO', ALL_PROCESSES_OK) - self.CreateHtmlFooter(False) + self.CreateHtmlTabFooter(False) self.AutoTerminateUEandeNB() sys.exit(1) else: @@ -683,7 +689,7 @@ class SSHConnection(): else: self.CreateHtmlTestRowQueue('N/A', 'KO', len(self.UEDevices), html_queue) self.AutoTerminateUEandeNB() - self.CreateHtmlFooter(False) + self.CreateHtmlTabFooter(False) sys.exit(1) def DetachUE_common(self, device_id): @@ -704,11 +710,11 @@ class SSHConnection(): if (pStatus < 0): self.CreateHtmlTestRow('N/A', 'KO', pStatus) self.AutoTerminateUEandeNB() - self.CreateHtmlFooter(False) + self.CreateHtmlTabFooter(False) sys.exit(1) multi_jobs = [] for device_id in self.UEDevices: - p = Process(target = SSH.DetachUE_common, args = (device_id,)) + p = Process(target = self.DetachUE_common, args = (device_id,)) p.daemon = True p.start() multi_jobs.append(p) @@ -767,11 +773,11 @@ class SSHConnection(): pStatus = self.CheckProcessExist(initialize_eNB_flag) if (pStatus < 0): self.CreateHtmlTestRow('N/A', 'KO', pStatus) - self.CreateHtmlFooter(False) + self.CreateHtmlTabFooter(False) sys.exit(1) multi_jobs = [] for device_id in self.UEDevices: - p = Process(target = SSH.RebootUE_common, args = (device_id,)) + p = Process(target = self.RebootUE_common, args = (device_id,)) p.daemon = True p.start() multi_jobs.append(p) @@ -851,7 +857,7 @@ class SSHConnection(): self.command('cd ' + self.EPCSourceCodePath, '\$', 5) self.command('cd scripts', '\$', 5) ping_time = re.findall("-c (\d+)",str(self.ping_args)) - ping_status = self.command('stdbuf -o0 ping ' + self.ping_args + ' ' + UE_IPAddress + ' 2>&1 | stdbuf -o0 tee -a ping_' + SSH.testCase_id + '_' + device_id + '.log', '\$', int(ping_time[0])*1.5) + ping_status = self.command('stdbuf -o0 ping ' + self.ping_args + ' ' + UE_IPAddress + ' 2>&1 | stdbuf -o0 tee -a ping_' + self.testCase_id + '_' + device_id + '.log', '\$', int(ping_time[0])*1.5) # TIMEOUT CASE if ping_status < 0: message = 'Ping with UE (' + str(UE_IPAddress) + ') crashed due to TIMEOUT!' @@ -919,12 +925,12 @@ class SSHConnection(): pStatus = self.CheckProcessExist(initialize_eNB_flag) if (pStatus < 0): self.CreateHtmlTestRow(self.ping_args, 'KO', pStatus) - self.CreateHtmlFooter(False) + self.CreateHtmlTabFooter(False) sys.exit(1) ueIpStatus = self.GetAllUEIPAddresses() if (ueIpStatus < 0): self.CreateHtmlTestRow(self.ping_args, 'KO', UE_IP_ADDRESS_ISSUE) - self.CreateHtmlFooter(False) + self.CreateHtmlTabFooter(False) sys.exit(1) multi_jobs = [] i = 0 @@ -932,7 +938,7 @@ class SSHConnection(): status_queue = SimpleQueue() for UE_IPAddress in self.UEIPAddresses: device_id = self.UEDevices[i] - p = Process(target = SSH.Ping_common, args = (lock,UE_IPAddress,device_id,status_queue,)) + p = Process(target = self.Ping_common, args = (lock,UE_IPAddress,device_id,status_queue,)) p.daemon = True p.start() multi_jobs.append(p) @@ -943,7 +949,7 @@ class SSHConnection(): if (status_queue.empty()): self.CreateHtmlTestRow(self.ping_args, 'KO', ALL_PROCESSES_OK) self.AutoTerminateUEandeNB() - self.CreateHtmlFooter(False) + self.CreateHtmlTabFooter(False) sys.exit(1) else: ping_status = True @@ -962,7 +968,7 @@ class SSHConnection(): else: self.CreateHtmlTestRowQueue(self.ping_args, 'KO', len(self.UEDevices), html_queue) self.AutoTerminateUEandeNB() - self.CreateHtmlFooter(False) + self.CreateHtmlTabFooter(False) sys.exit(1) def Iperf_ComputeTime(self): @@ -978,11 +984,11 @@ class SSHConnection(): logging.debug('\u001B[1;37;41m Iperf bandwidth Not Found! \u001B[0m') sys.exit(1) iperf_bandwidth = result.group('iperf_bandwidth') - if SSH.iperf_profile == 'balanced': + if self.iperf_profile == 'balanced': iperf_bandwidth_new = float(iperf_bandwidth)/ue_num - if SSH.iperf_profile == 'single-ue': + if self.iperf_profile == 'single-ue': iperf_bandwidth_new = float(iperf_bandwidth) - if SSH.iperf_profile == 'unbalanced': + if self.iperf_profile == 'unbalanced': # residual is 2% of max bw residualBW = float(iperf_bandwidth) / 50 if idx == 0: @@ -998,7 +1004,7 @@ class SSHConnection(): return result def Iperf_analyzeV2TCPOutput(self, lock, UE_IPAddress, device_id, statusQueue, iperf_real_options): - self.command('awk -f /tmp/tcp_iperf_stats.awk /tmp/CI-eNB/scripts/iperf_' + SSH.testCase_id + '_' + device_id + '.log', '\$', 5) + self.command('awk -f /tmp/tcp_iperf_stats.awk /tmp/CI-eNB/scripts/iperf_' + self.testCase_id + '_' + device_id + '.log', '\$', 5) result = re.search('Avg Bitrate : (?P[0-9\.]+ Mbits\/sec) Max Bitrate : (?P[0-9\.]+ Mbits\/sec) Min Bitrate : (?P[0-9\.]+ Mbits\/sec)', str(self.ssh.before)) if result is not None: avgbitrate = result.group('average') @@ -1104,7 +1110,7 @@ class SSHConnection(): return 0 def Iperf_analyzeV2Server(self, lock, UE_IPAddress, device_id, statusQueue, iperf_real_options): - if (not os.path.isfile('iperf_server_' + SSH.testCase_id + '_' + device_id + '.log')): + if (not os.path.isfile('iperf_server_' + self.testCase_id + '_' + device_id + '.log')): self.ping_iperf_wrong_exit(lock, UE_IPAddress, device_id, statusQueue, 'Could not analyze from server log') return # Computing the requested bandwidth in float @@ -1129,7 +1135,7 @@ class SSHConnection(): req_bandwidth = '%.1f Gbits/sec' % req_bw req_bw = req_bw * 1000000000 - server_file = open('iperf_server_' + SSH.testCase_id + '_' + device_id + '.log', 'r') + server_file = open('iperf_server_' + self.testCase_id + '_' + device_id + '.log', 'r') br_sum = 0.0 ji_sum = 0.0 pl_sum = 0 @@ -1254,12 +1260,12 @@ class SSHConnection(): # Launch iperf server on EPC side self.open(self.EPCIPAddress, self.EPCUserName, self.EPCPassword) self.command('cd ' + self.EPCSourceCodePath + '/scripts', '\$', 5) - self.command('rm -f iperf_server_' + SSH.testCase_id + '_' + device_id + '.log', '\$', 5) + self.command('rm -f iperf_server_' + self.testCase_id + '_' + device_id + '.log', '\$', 5) port = 5001 + idx if udpIperf: - self.command('echo $USER; nohup iperf -u -s -i 1 -p ' + str(port) + ' > iperf_server_' + SSH.testCase_id + '_' + device_id + '.log &', self.EPCUserName, 5) + self.command('echo $USER; nohup iperf -u -s -i 1 -p ' + str(port) + ' > iperf_server_' + self.testCase_id + '_' + device_id + '.log &', self.EPCUserName, 5) else: - self.command('echo $USER; nohup iperf -s -i 1 -p ' + str(port) + ' > iperf_server_' + SSH.testCase_id + '_' + device_id + '.log &', self.EPCUserName, 5) + self.command('echo $USER; nohup iperf -s -i 1 -p ' + str(port) + ' > iperf_server_' + self.testCase_id + '_' + device_id + '.log &', self.EPCUserName, 5) time.sleep(0.5) self.close() @@ -1276,8 +1282,8 @@ class SSHConnection(): modified_options = modified_options.replace('-R','') time.sleep(0.5) - self.command('rm -f iperf_' + SSH.testCase_id + '_' + device_id + '.log', '\$', 5) - iperf_status = self.command('stdbuf -o0 adb -s ' + device_id + ' shell "/data/local/tmp/iperf -c ' + EPC_Iperf_UE_IPAddress + ' ' + modified_options + ' -p ' + str(port) + '" 2>&1 | stdbuf -o0 tee -a iperf_' + SSH.testCase_id + '_' + device_id + '.log', '\$', int(iperf_time)*5.0) + self.command('rm -f iperf_' + self.testCase_id + '_' + device_id + '.log', '\$', 5) + iperf_status = self.command('stdbuf -o0 adb -s ' + device_id + ' shell "/data/local/tmp/iperf -c ' + EPC_Iperf_UE_IPAddress + ' ' + modified_options + ' -p ' + str(port) + '" 2>&1 | stdbuf -o0 tee -a iperf_' + self.testCase_id + '_' + device_id + '.log', '\$', int(iperf_time)*5.0) # TIMEOUT Case if iperf_status < 0: self.close() @@ -1295,15 +1301,15 @@ class SSHConnection(): # in case of failure, retrieve server log if (clientStatus == -1): time.sleep(1) - if (os.path.isfile('iperf_server_' + SSH.testCase_id + '_' + device_id + '.log')): - os.remove('iperf_server_' + SSH.testCase_id + '_' + device_id + '.log') - self.copyin(self.EPCIPAddress, self.EPCUserName, self.EPCPassword, self.EPCSourceCodePath + '/scripts/iperf_server_' + SSH.testCase_id + '_' + device_id + '.log', '.') + if (os.path.isfile('iperf_server_' + self.testCase_id + '_' + device_id + '.log')): + os.remove('iperf_server_' + self.testCase_id + '_' + device_id + '.log') + self.copyin(self.EPCIPAddress, self.EPCUserName, self.EPCPassword, self.EPCSourceCodePath + '/scripts/iperf_server_' + self.testCase_id + '_' + device_id + '.log', '.') self.Iperf_analyzeV2Server(lock, UE_IPAddress, device_id, statusQueue, modified_options) def Iperf_common(self, lock, UE_IPAddress, device_id, idx, ue_num, statusQueue): try: # Single-UE profile -- iperf only on one UE - if SSH.iperf_profile == 'single-ue' and idx != 0: + if self.iperf_profile == 'single-ue' and idx != 0: return useIperf3 = False udpIperf = True @@ -1334,13 +1340,13 @@ class SSHConnection(): if (useIperf3): self.command('stdbuf -o0 adb -s ' + device_id + ' shell /data/local/tmp/iperf3 -s &', '\$', 5) else: - self.command('rm -f iperf_server_' + SSH.testCase_id + '_' + device_id + '.log', '\$', 5) + self.command('rm -f iperf_server_' + self.testCase_id + '_' + device_id + '.log', '\$', 5) result = re.search('-u', str(self.iperf_args)) if result is None: - self.command('echo $USER; nohup adb -s ' + device_id + ' shell "/data/local/tmp/iperf -s -i 1" > iperf_server_' + SSH.testCase_id + '_' + device_id + '.log &', self.ADBUserName, 5) + self.command('echo $USER; nohup adb -s ' + device_id + ' shell "/data/local/tmp/iperf -s -i 1" > iperf_server_' + self.testCase_id + '_' + device_id + '.log &', self.ADBUserName, 5) udpIperf = False else: - self.command('echo $USER; nohup adb -s ' + device_id + ' shell "/data/local/tmp/iperf -u -s -i 1" > iperf_server_' + SSH.testCase_id + '_' + device_id + '.log &', self.ADBUserName, 5) + self.command('echo $USER; nohup adb -s ' + device_id + ' shell "/data/local/tmp/iperf -u -s -i 1" > iperf_server_' + self.testCase_id + '_' + device_id + '.log &', self.ADBUserName, 5) time.sleep(0.5) self.close() @@ -1355,14 +1361,14 @@ class SSHConnection(): modified_options = str(self.iperf_args) time.sleep(0.5) - self.command('rm -f iperf_' + SSH.testCase_id + '_' + device_id + '.log', '\$', 5) + self.command('rm -f iperf_' + self.testCase_id + '_' + device_id + '.log', '\$', 5) if (useIperf3): - self.command('stdbuf -o0 iperf3 -c ' + UE_IPAddress + ' ' + modified_options + ' 2>&1 | stdbuf -o0 tee -a iperf_' + SSH.testCase_id + '_' + device_id + '.log', '\$', int(iperf_time)*5.0) + self.command('stdbuf -o0 iperf3 -c ' + UE_IPAddress + ' ' + modified_options + ' 2>&1 | stdbuf -o0 tee -a iperf_' + self.testCase_id + '_' + device_id + '.log', '\$', int(iperf_time)*5.0) clientStatus = 0 self.Iperf_analyzeV3Output(lock, UE_IPAddress, device_id, statusQueue) else: - iperf_status = self.command('stdbuf -o0 iperf -c ' + UE_IPAddress + ' ' + modified_options + ' 2>&1 | stdbuf -o0 tee -a iperf_' + SSH.testCase_id + '_' + device_id + '.log', '\$', int(iperf_time)*5.0) + iperf_status = self.command('stdbuf -o0 iperf -c ' + UE_IPAddress + ' ' + modified_options + ' 2>&1 | stdbuf -o0 tee -a iperf_' + self.testCase_id + '_' + device_id + '.log', '\$', int(iperf_time)*5.0) if iperf_status < 0: self.close() message = 'iperf on UE (' + str(UE_IPAddress) + ') crashed due to TIMEOUT !' @@ -1381,9 +1387,9 @@ class SSHConnection(): self.close() if (clientStatus == -1): time.sleep(1) - if (os.path.isfile('iperf_server_' + SSH.testCase_id + '_' + device_id + '.log')): - os.remove('iperf_server_' + SSH.testCase_id + '_' + device_id + '.log') - self.copyin(self.ADBIPAddress, self.ADBUserName, self.ADBPassword, self.EPCSourceCodePath + '/scripts/iperf_server_' + SSH.testCase_id + '_' + device_id + '.log', '.') + if (os.path.isfile('iperf_server_' + self.testCase_id + '_' + device_id + '.log')): + os.remove('iperf_server_' + self.testCase_id + '_' + device_id + '.log') + self.copyin(self.ADBIPAddress, self.ADBUserName, self.ADBPassword, self.EPCSourceCodePath + '/scripts/iperf_server_' + self.testCase_id + '_' + device_id + '.log', '.') self.Iperf_analyzeV2Server(lock, UE_IPAddress, device_id, statusQueue, modified_options) except: os.kill(os.getppid(),signal.SIGUSR1) @@ -1397,13 +1403,13 @@ class SSHConnection(): if (pStatus < 0): self.CreateHtmlTestRow(self.iperf_args, 'KO', pStatus) self.AutoTerminateUEandeNB() - self.CreateHtmlFooter(False) + self.CreateHtmlTabFooter(False) sys.exit(1) ueIpStatus = self.GetAllUEIPAddresses() if (ueIpStatus < 0): self.CreateHtmlTestRow(self.iperf_args, 'KO', UE_IP_ADDRESS_ISSUE) self.AutoTerminateUEandeNB() - self.CreateHtmlFooter(False) + self.CreateHtmlTabFooter(False) sys.exit(1) multi_jobs = [] i = 0 @@ -1423,7 +1429,7 @@ class SSHConnection(): if (status_queue.empty()): self.CreateHtmlTestRow(self.iperf_args, 'KO', ALL_PROCESSES_OK) self.AutoTerminateUEandeNB() - self.CreateHtmlFooter(False) + self.CreateHtmlTabFooter(False) sys.exit(1) else: iperf_status = True @@ -1447,7 +1453,7 @@ class SSHConnection(): else: self.CreateHtmlTestRowQueue(self.iperf_args, 'KO', len(self.UEDevices), html_queue) self.AutoTerminateUEandeNB() - self.CreateHtmlFooter(False) + self.CreateHtmlTabFooter(False) sys.exit(1) def CheckProcessExist(self, initialize_eNB_flag): @@ -1699,8 +1705,8 @@ class SSHConnection(): def TerminateeNB(self): self.open(self.eNBIPAddress, self.eNBUserName, self.eNBPassword) self.command('cd ' + self.eNBSourceCodePath + '/cmake_targets', '\$', 5) - self.command('echo ' + self.eNBPassword + ' | sudo -S daemon --name=enb' + str(SSH.eNB_instance) + '_daemon --stop', '\$', 5) - self.command('rm -f my-lte-softmodem-run' + str(SSH.eNB_instance) + '.sh', '\$', 5) + self.command('echo ' + self.eNBPassword + ' | sudo -S daemon --name=enb' + str(self.eNB_instance) + '_daemon --stop', '\$', 5) + self.command('rm -f my-lte-softmodem-run' + str(self.eNB_instance) + '.sh', '\$', 5) self.command('echo ' + self.eNBPassword + ' | sudo -S killall --signal SIGINT lte-softmodem || true', '\$', 5) time.sleep(5) self.command('stdbuf -o0 ps -aux | grep -v grep | grep lte-softmodem', '\$', 5) @@ -1744,7 +1750,7 @@ class SSHConnection(): logStatus = self.AnalyzeLogFile_eNB(self.eNBLogFile) if (logStatus < 0): self.CreateHtmlTestRow('N/A', 'KO', logStatus) - self.CreateHtmlFooter(False) + self.CreateHtmlTabFooter(False) sys.exit(1) else: self.CreateHtmlTestRow('N/A', 'OK', ALL_PROCESSES_OK) @@ -1818,7 +1824,7 @@ class SSHConnection(): def TerminateUE(self): terminate_ue_flag = True - SSH.GetAllUEDevices(terminate_ue_flag) + self.GetAllUEDevices(terminate_ue_flag) multi_jobs = [] for device_id in self.UEDevices: p = Process(target= SSH.TerminateUE_common, args = (device_id,)) @@ -1840,6 +1846,10 @@ class SSHConnection(): self.eNB_instance = '0' self.TerminateeNB() + def IdleSleep(self): + time.sleep(self.idle_sleep_time) + self.CreateHtmlTestRow(str(self.idle_sleep_time) + ' sec', 'OK', ALL_PROCESSES_OK) + def LogCollectBuild(self): self.open(self.eNBIPAddress, self.eNBUserName, self.eNBPassword) self.command('cd ' + self.eNBSourceCodePath, '\$', 5) @@ -1930,6 +1940,7 @@ class SSHConnection(): self.htmlFile.write(' Test Results for TEMPLATE_JOB_NAME job build #TEMPLATE_BUILD_ID\n') self.htmlFile.write('\n') self.htmlFile.write('
    \n') + self.htmlFile.write('
    \n') self.htmlFile.write(' \n') self.htmlFile.write(' \n') self.htmlFile.write(' \n') - self.htmlFile.write(' \n') - self.htmlFile.write(' \n') + self.htmlFile.write(' \n') + self.htmlFile.write(' \n') self.htmlFile.write(' \n') if (str(status) == 'OK'): self.htmlFile.write(' \n') @@ -2081,8 +2134,8 @@ class SSHConnection(): if ((not self.htmlFooterCreated) and (self.htmlHeaderCreated)): addOrangeBK = False self.htmlFile.write(' \n') - self.htmlFile.write(' \n') - self.htmlFile.write(' \n') + self.htmlFile.write(' \n') + self.htmlFile.write(' \n') self.htmlFile.write(' \n') if (str(status) == 'OK'): self.htmlFile.write(' \n') @@ -2126,6 +2179,7 @@ def Usage(): print(' --help Show this help.') print(' --mode=[Mode]') print(' TesteNB') + print(' InitiateHtml, FinalizeHtml') print(' TerminateeNB, TerminateUE, TerminateHSS, TerminateMME, TerminateSPGW') print(' LogCollectBuild, LogCollecteNB, LogCollectHSS, LogCollectMME, LogCollectSPGW, LogCollectPing, LogCollectIperf') print(' --eNBIPAddress=[eNB\'s IP Address]') @@ -2149,7 +2203,7 @@ def Usage(): print('------------------------------------------------------------') def CheckClassValidity(action,id): - if action != 'Build_eNB' and action != 'Initialize_eNB' and action != 'Terminate_eNB' and action != 'Initialize_UE' and action != 'Terminate_UE' and action != 'Attach_UE' and action != 'Detach_UE' and action != 'Ping' and action != 'Iperf' and action != 'Reboot_UE' and action != 'Initialize_HSS' and action != 'Terminate_HSS' and action != 'Initialize_MME' and action != 'Terminate_MME' and action != 'Initialize_SPGW' and action != 'Terminate_SPGW' and action != 'Initialize_CatM_module' and action != 'Terminate_CatM_module' and action != 'Attach_CatM_module' and action != 'Detach_CatM_module': + if action != 'Build_eNB' and action != 'Initialize_eNB' and action != 'Terminate_eNB' and action != 'Initialize_UE' and action != 'Terminate_UE' and action != 'Attach_UE' and action != 'Detach_UE' and action != 'Ping' and action != 'Iperf' and action != 'Reboot_UE' and action != 'Initialize_HSS' and action != 'Terminate_HSS' and action != 'Initialize_MME' and action != 'Terminate_MME' and action != 'Initialize_SPGW' and action != 'Terminate_SPGW' and action != 'Initialize_CatM_module' and action != 'Terminate_CatM_module' and action != 'Attach_CatM_module' and action != 'Detach_CatM_module' and action != 'IdleSleep': logging.debug('ERROR: test-case ' + id + ' has wrong class ' + action) return False return True @@ -2191,6 +2245,13 @@ def GetParametersFromXML(action): logging.debug('ERROR: test-case has wrong profile ' + SSH.iperf_profile) SSH.iperf_profile = 'balanced' + if action == 'IdleSleep': + string_field = test.findtext('idle_sleep_time_in_sec') + if (string_field is None): + SSH.idle_sleep_time = 5 + else: + SSH.idle_sleep_time = int(string_field) + #check if given test is in list #it is in list if one of the strings in 'list' is at the beginning of 'test' def test_in_list(test, list): @@ -2281,7 +2342,13 @@ while len(argvs) > 1: SSH.ADBPassword = matchReg.group(1) elif re.match('^\-\-XMLTestFile=(.+)$', myArgv, re.IGNORECASE): matchReg = re.match('^\-\-XMLTestFile=(.+)$', myArgv, re.IGNORECASE) - SSH.testXMLfile = matchReg.group(1) + SSH.testXMLfiles.append(matchReg.group(1)) + SSH.nbTestXMLfiles += 1 + elif re.match('^\-\-finalStatus=(.+)$', myArgv, re.IGNORECASE): + matchReg = re.match('^\-\-finalStatus=(.+)$', myArgv, re.IGNORECASE) + finalStatus = matchReg.group(1) + if ((finalStatus == 'true') or (finalStatus == 'True')): + SSH.finalStatus = True else: Usage() sys.exit('Invalid Parameter: ' + myArgv) @@ -2347,27 +2414,44 @@ elif re.match('^LogCollectIperf$', mode, re.IGNORECASE): Usage() sys.exit('Insufficient Parameter') SSH.LogCollectIperf() +elif re.match('^InitiateHtml$', mode, re.IGNORECASE): + if SSH.ADBIPAddress == '' or SSH.ADBUserName == '' or SSH.ADBPassword == '': + Usage() + sys.exit('Insufficient Parameter') + count = 0 + while (count < SSH.nbTestXMLfiles): + xml_test_file = sys.path[0] + "/" + SSH.testXMLfiles[count] + xmlTree = ET.parse(xml_test_file) + xmlRoot = xmlTree.getroot() + SSH.htmlTabRefs.append(xmlRoot.findtext('htmlTabRef',default='test-tab-' + str(count))) + SSH.htmlTabNames.append(xmlRoot.findtext('htmlTabName',default='Test-' + str(count))) + SSH.htmlTabIcons.append(xmlRoot.findtext('htmlTabIcon',default='info-sign')) + count += 1 + SSH.CreateHtmlHeader() +elif re.match('^FinalizeHtml$', mode, re.IGNORECASE): + SSH.CreateHtmlFooter(SSH.finalStatus) elif re.match('^TesteNB$', mode, re.IGNORECASE): if SSH.eNBIPAddress == '' or SSH.eNBRepository == '' or SSH.eNBBranch == '' or SSH.eNBUserName == '' or SSH.eNBPassword == '' or SSH.eNBSourceCodePath == '' or SSH.EPCIPAddress == '' or SSH.EPCUserName == '' or SSH.EPCPassword == '' or SSH.EPCType == '' or SSH.EPCSourceCodePath == '' or SSH.ADBIPAddress == '' or SSH.ADBUserName == '' or SSH.ADBPassword == '': Usage() sys.exit('Insufficient Parameter') - SSH.copyout(SSH.EPCIPAddress, SSH.EPCUserName, SSH.EPCPassword, sys.path[0] + "/tcp_iperf_stats.awk", "/tmp") - SSH.copyout(SSH.EPCIPAddress, SSH.EPCUserName, SSH.EPCPassword, sys.path[0] + "/active_net_interfaces.awk", "/tmp") - SSH.CreateHtmlHeader() - + if (SSH.EPCIPAddress != 'none'): + SSH.copyout(SSH.EPCIPAddress, SSH.EPCUserName, SSH.EPCPassword, sys.path[0] + "/tcp_iperf_stats.awk", "/tmp") + SSH.copyout(SSH.EPCIPAddress, SSH.EPCUserName, SSH.EPCPassword, sys.path[0] + "/active_net_interfaces.awk", "/tmp") #read test_case_list.xml file # if no parameters for XML file, use default value - if SSH.testXMLfile == '': + if (SSH.nbTestXMLfiles != 1): xml_test_file = sys.path[0] + "/test_case_list.xml" else: - xml_test_file = sys.path[0] + "/" + SSH.testXMLfile + xml_test_file = sys.path[0] + "/" + SSH.testXMLfiles[0] xmlTree = ET.parse(xml_test_file) xmlRoot = xmlTree.getroot() exclusion_tests=xmlRoot.findtext('TestCaseExclusionList',default='') requested_tests=xmlRoot.findtext('TestCaseRequestedList',default='') + if (SSH.nbTestXMLfiles == 1): + SSH.htmlTabRefs.append(xmlRoot.findtext('htmlTabRef',default='test-tab-0')) all_tests=xmlRoot.findall('testCase') exclusion_tests=exclusion_tests.split() @@ -2405,6 +2489,8 @@ elif re.match('^TesteNB$', mode, re.IGNORECASE): signal.signal(signal.SIGUSR1, receive_signal) + SSH.CreateHtmlTabHeader() + for test_case_id in todo_tests: for test in all_tests: id = test.get('id') @@ -2460,10 +2546,12 @@ elif re.match('^TesteNB$', mode, re.IGNORECASE): SSH.InitializeSPGW() elif action == 'Terminate_SPGW': SSH.TerminateSPGW() + elif action == 'IdleSleep': + SSH.IdleSleep() else: sys.exit('Invalid action') - SSH.CreateHtmlFooter(True) + SSH.CreateHtmlTabFooter(True) else: Usage() sys.exit('Invalid mode') diff --git a/ci-scripts/reportBuildLocally.sh b/ci-scripts/reportBuildLocally.sh index 634eac3adc..957eca4324 100755 --- a/ci-scripts/reportBuildLocally.sh +++ b/ci-scripts/reportBuildLocally.sh @@ -323,6 +323,7 @@ function report_build { echo " " >> ./build_results.html echo "" >> ./build_results.html echo "
    " >> ./build_results.html + echo "
    " >> ./build_results.html echo "
    \n') @@ -1946,37 +1957,37 @@ class SSHConnection(): self.htmlFile.write('
    \n') self.htmlFile.write(' \n') self.htmlFile.write(' \n') - self.htmlFile.write(' \n') + self.htmlFile.write(' \n') self.htmlFile.write(' \n') self.htmlFile.write(' \n') self.htmlFile.write(' \n') - self.htmlFile.write(' \n') - self.htmlFile.write(' \n') + self.htmlFile.write(' \n') + self.htmlFile.write(' \n') self.htmlFile.write(' \n') self.htmlFile.write(' \n') - self.htmlFile.write(' \n') - if (SSH.eNB_AllowMerge): + self.htmlFile.write(' \n') + if (self.eNB_AllowMerge): self.htmlFile.write(' \n') else: self.htmlFile.write(' \n') self.htmlFile.write(' \n') self.htmlFile.write(' \n') - if (SSH.eNB_AllowMerge): - self.htmlFile.write(' \n') + if (self.eNB_AllowMerge): + self.htmlFile.write(' \n') else: - self.htmlFile.write(' \n') - self.htmlFile.write(' \n') + self.htmlFile.write(' \n') + self.htmlFile.write(' \n') self.htmlFile.write(' \n') self.htmlFile.write(' \n') - if (SSH.eNB_AllowMerge): - self.htmlFile.write(' \n') + if (self.eNB_AllowMerge): + self.htmlFile.write(' \n') else: - self.htmlFile.write(' \n') - self.htmlFile.write(' \n') + self.htmlFile.write(' \n') + self.htmlFile.write(' \n') self.htmlFile.write(' \n') - if (SSH.eNB_AllowMerge): + if (self.eNB_AllowMerge): self.htmlFile.write(' \n') - self.htmlFile.write(' \n') + self.htmlFile.write(' \n') if (self.eNBTargetBranch == ''): self.htmlFile.write(' \n') else: @@ -1985,19 +1996,45 @@ class SSHConnection(): self.htmlFile.write('
    Build Start Time (UTC) Build Start Time (UTC) TEMPLATE_BUILD_TIME
    GIT Repository' + SSH.eNBRepository + ' GIT Repository ' + self.eNBRepository + '
    Job Trigger Job Trigger Merge-RequestPush to Branch
    Source Branch Source Branch Branch' + SSH.eNBBranch + ' Branch' + self.eNBBranch + '
    Source Commit ID Source Commit ID Commit ID' + SSH.eNBCommitID + ' Commit ID ' + self.eNBCommitID + '
    Target Branch Target Branch develop
    \n') terminate_ue_flag = True - SSH.GetAllUEDevices(terminate_ue_flag) - SSH.GetAllCatMDevices(terminate_ue_flag) + if (self.ADBIPAddress != 'none'): + self.GetAllUEDevices(terminate_ue_flag) + self.GetAllCatMDevices(terminate_ue_flag) + else: + self.UEDevices.append('doughq9rehg') + self.UEDevices.append('dnsgiuahgia') + self.UEDevices.append('uehgieng9') self.htmlUEConnected = len(self.UEDevices) - self.htmlFile.write('

    Jump to Final Status

    \n') + self.htmlFile.write('

    ' + str(len(self.UEDevices)) + ' UE(s) is(are) connected to ADB bench server

    \n') + self.htmlFile.write('

    ' + str(len(self.CatMDevices)) + ' CAT-M UE(s) is(are) connected to bench server

    \n') self.htmlFile.write('
    \n') + self.htmlFile.write(' \n') + self.htmlFile.write('
    \n') + self.htmlFile.close() - self.htmlFile.write('

    ' + str(len(self.UEDevices)) + ' UE(s) is(are) connected to ADB bench server

    \n') - self.htmlFile.write('

    ' + str(len(self.CatMDevices)) + ' CAT-M UE(s) is(are) connected to bench server

    \n') - self.htmlFile.write('
    \n') - - self.htmlFile.write('

    Test Summary for ' + SSH.testXMLfile + '

    \n') - self.htmlFile.write(' \n') + def CreateHtmlTabHeader(self): + if (not self.htmlHeaderCreated): + if (not os.path.isfile('test_results.html')): + self.CreateHtmlHeader() + self.htmlFile = open('test_results.html', 'a') + if (self.nbTestXMLfiles == 1): + self.htmlFile.write('
    \n') + self.htmlFile.write('

    Test Summary for ' + self.testXMLfiles[0] + '

    \n') + else: + self.htmlFile.write('
    \n') + self.htmlFile.write('
    \n') self.htmlFile.write(' \n') self.htmlFile.write(' \n') self.htmlFile.write(' \n') @@ -2010,28 +2047,44 @@ class SSHConnection(): self.htmlFile.write(' \n') self.htmlHeaderCreated = True - def CreateHtmlFooter(self, passStatus): + def CreateHtmlTabFooter(self, passStatus): if ((not self.htmlFooterCreated) and (self.htmlHeaderCreated)): - self.htmlFile.write(' \n') - self.htmlFile.write(' \n') + self.htmlFile.write(' \n') + self.htmlFile.write(' \n') if passStatus: - self.htmlFile.write(' \n') + self.htmlFile.write(' \n') else: - self.htmlFile.write(' \n') + self.htmlFile.write(' \n') self.htmlFile.write(' \n') self.htmlFile.write('
    Test IdTest Desc
    Final StatusFinal Tab StatusPASSPASS FAILFAIL
    \n') + self.htmlFile.write('
    \n') + self.htmlFooterCreated = False + + def CreateHtmlFooter(self, passStatus): + if (os.path.isfile('test_results.html')): + self.htmlFile = open('test_results.html', 'a') + self.htmlFile.write('\n') + self.htmlFile.write('

    \n') + self.htmlFile.write(' \n') + self.htmlFile.write(' \n') + self.htmlFile.write(' \n') + if passStatus: + self.htmlFile.write(' \n') + else: + self.htmlFile.write(' \n') + self.htmlFile.write(' \n') + self.htmlFile.write('
    Final StatusPASS FAIL
    \n') self.htmlFile.write('

    \n') self.htmlFile.write('
    End of Test Report -- Copyright 2018 OpenAirInterface. All Rights Reserved.
    \n') self.htmlFile.write('\n') self.htmlFile.write('\n') self.htmlFile.close() - self.htmlFooterCreated = False def CreateHtmlTestRow(self, options, status, processesStatus): if ((not self.htmlFooterCreated) and (self.htmlHeaderCreated)): self.htmlFile.write('
    ' + SSH.testCase_id + '' + SSH.desc + '' + self.testCase_id + '' + self.desc + '' + str(options) + '' + str(status) + '
    ' + SSH.testCase_id + '' + SSH.desc + '' + self.testCase_id + '' + self.desc + '' + str(options) + '' + str(status) + '
    " >> ./build_results.html echo " " >> ./build_results.html echo "
    " >> ./build_results.html @@ -339,45 +340,45 @@ function report_build { echo "
    " >> ./build_results.html echo " " >> ./build_results.html echo " " >> ./build_results.html - echo " " >> ./build_results.html + echo " " >> ./build_results.html echo " " >> ./build_results.html echo " " >> ./build_results.html echo " " >> ./build_results.html - echo " " >> ./build_results.html - echo " " >> ./build_results.html + echo " " >> ./build_results.html + echo " " >> ./test_simulator_results.html echo " " >> ./build_results.html echo " " >> ./build_results.html - echo " " >> ./build_results.html + echo " " >> ./build_results.html if [ $PU_TRIG -eq 1 ]; then echo " " >> ./build_results.html; fi if [ $MR_TRIG -eq 1 ]; then echo " " >> ./build_results.html; fi echo " " >> ./build_results.html if [ $PU_TRIG -eq 1 ] then echo " " >> ./build_results.html - echo " " >> ./build_results.html + echo " " >> ./build_results.html echo " " >> ./build_results.html echo " " >> ./build_results.html echo " " >> ./build_results.html - echo " " >> ./build_results.html + echo " " >> ./build_results.html echo " " >> ./build_results.html echo " " >> ./build_results.html fi if [ $MR_TRIG -eq 1 ] then echo " " >> ./build_results.html - echo " " >> ./build_results.html + echo " " >> ./build_results.html echo " " >> ./build_results.html echo " " >> ./build_results.html echo " " >> ./build_results.html - echo " " >> ./build_results.html + echo " " >> ./build_results.html echo " " >> ./build_results.html echo " " >> ./build_results.html echo " " >> ./build_results.html - echo " " >> ./build_results.html + echo " " >> ./build_results.html echo " " >> ./build_results.html echo " " >> ./build_results.html echo " " >> ./build_results.html - echo " " >> ./build_results.html + echo " " >> ./build_results.html echo " " >> ./build_results.html echo " " >> ./build_results.html fi diff --git a/ci-scripts/reportTestLocally.sh b/ci-scripts/reportTestLocally.sh index c6fef123d7..aae0df0d7d 100755 --- a/ci-scripts/reportTestLocally.sh +++ b/ci-scripts/reportTestLocally.sh @@ -100,6 +100,7 @@ function report_test { echo " " >> ./test_simulator_results.html echo "" >> ./test_simulator_results.html echo "
    " >> ./test_simulator_results.html + echo "
    " >> ./test_simulator_results.html echo "
    Build Start Time (UTC) Build Start Time (UTC)TEMPLATE_BUILD_TIME
    GIT Repository$GIT_URL GIT Repository$GIT_URL
    Job Trigger Job TriggerPush EventMerge-Request
    Branch Branch$SOURCE_BRANCH
    Commit ID Commit ID$SOURCE_COMMIT_ID
    Source Branch Source Branch$SOURCE_BRANCH
    Source Commit ID Source Commit ID$SOURCE_COMMIT_ID
    Target Branch Target Branch$TARGET_BRANCH
    Target Commit ID Target Commit ID$TARGET_COMMIT_ID
    " >> ./test_simulator_results.html echo " " >> ./test_simulator_results.html echo " \n') elif (processesStatus == ENB_PROCESS_REALTIME_ISSUE): - self.htmlFile.write(' \n') + elif (processesStatus == ENB_PROCESS_NOLOGFILE_TO_ANALYZE): + self.htmlFile.write(' \n') elif (processesStatus == HSS_PROCESS_FAILED): self.htmlFile.write(' \n') elif (processesStatus == MME_PROCESS_FAILED): @@ -2209,7 +2220,7 @@ class SSHConnection(): if result is not None: cellBgColor = 'red' else: - result = re.search('showed|Reestablishment', self.htmleNBFailureMsg) + result = re.search('showed|Reestablishment|Could not copy eNB logfile', self.htmleNBFailureMsg) if result is not None: cellBgColor = 'orange' self.htmlFile.write('
    " >> ./test_simulator_results.html @@ -116,45 +117,45 @@ function report_test { echo "
    " >> ./test_simulator_results.html echo " " >> ./test_simulator_results.html echo " " >> ./test_simulator_results.html - echo " " >> ./test_simulator_results.html + echo " " >> ./test_simulator_results.html echo " " >> ./test_simulator_results.html echo " " >> ./test_simulator_results.html echo " " >> ./test_simulator_results.html - echo " " >> ./test_simulator_results.html + echo " " >> ./test_simulator_results.html echo " " >> ./test_simulator_results.html echo " " >> ./test_simulator_results.html echo " " >> ./test_simulator_results.html - echo " " >> ./test_simulator_results.html + echo " " >> ./test_simulator_results.html if [ $PU_TRIG -eq 1 ]; then echo " " >> ./test_simulator_results.html; fi if [ $MR_TRIG -eq 1 ]; then echo " " >> ./test_simulator_results.html; fi echo " " >> ./test_simulator_results.html if [ $PU_TRIG -eq 1 ] then echo " " >> ./test_simulator_results.html - echo " " >> ./test_simulator_results.html + echo " " >> ./test_simulator_results.html echo " " >> ./test_simulator_results.html echo " " >> ./test_simulator_results.html echo " " >> ./test_simulator_results.html - echo " " >> ./test_simulator_results.html + echo " " >> ./test_simulator_results.html echo " " >> ./test_simulator_results.html echo " " >> ./test_simulator_results.html fi if [ $MR_TRIG -eq 1 ] then echo " " >> ./test_simulator_results.html - echo " " >> ./test_simulator_results.html + echo " " >> ./test_simulator_results.html echo " " >> ./test_simulator_results.html echo " " >> ./test_simulator_results.html echo " " >> ./test_simulator_results.html - echo " " >> ./test_simulator_results.html + echo " " >> ./test_simulator_results.html echo " " >> ./test_simulator_results.html echo " " >> ./test_simulator_results.html echo " " >> ./test_simulator_results.html - echo " " >> ./test_simulator_results.html + echo " " >> ./test_simulator_results.html echo " " >> ./test_simulator_results.html echo " " >> ./test_simulator_results.html echo " " >> ./test_simulator_results.html - echo " " >> ./test_simulator_results.html + echo " " >> ./test_simulator_results.html echo " " >> ./test_simulator_results.html echo " " >> ./test_simulator_results.html fi From 25b60e0c958a3a2380b21b56fbf9b5ad6b475974 Mon Sep 17 00:00:00 2001 From: Raphael Defosseux Date: Thu, 13 Dec 2018 10:55:39 +0100 Subject: [PATCH 196/233] CI: missing detection of UE for TAB header Signed-off-by: Raphael Defosseux --- ci-scripts/main.py | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/ci-scripts/main.py b/ci-scripts/main.py index 849e50b076..d320f34117 100644 --- a/ci-scripts/main.py +++ b/ci-scripts/main.py @@ -110,7 +110,7 @@ class SSHConnection(): self.htmlFile = '' self.htmlHeaderCreated = False self.htmlFooterCreated = False - self.htmlUEConnected = 0 + self.htmlUEConnected = -1 self.htmleNBFailureMsg = '' self.picocom_closure = False self.idle_sleep_time = 0 @@ -2040,6 +2040,17 @@ class SSHConnection(): self.htmlFile.write(' \n') self.htmlFile.write(' \n') self.htmlFile.write(' \n') + if (self.htmlUEConnected == -1): + terminate_ue_flag = True + if (self.ADBIPAddress != 'none'): + self.GetAllUEDevices(terminate_ue_flag) + self.GetAllCatMDevices(terminate_ue_flag) + else: + self.UEDevices.append('doughq9rehg') + self.UEDevices.append('dnsgiuahgia') + self.UEDevices.append('uehgieng9') + self.htmlUEConnected = len(self.UEDevices) + i = 0 while (i < self.htmlUEConnected): self.htmlFile.write(' \n') From aacbd7577c58f7bbede6d2eef3d4fa58aad6fea5 Mon Sep 17 00:00:00 2001 From: Laurent Date: Thu, 13 Dec 2018 13:45:59 +0100 Subject: [PATCH 197/233] fix 381 --- cmake_targets/tools/build_helper | 2 +- targets/ARCH/LMSSDR/USERSPACE/LIB/lms_lib.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/cmake_targets/tools/build_helper b/cmake_targets/tools/build_helper index 551fc13593..010a310230 100755 --- a/cmake_targets/tools/build_helper +++ b/cmake_targets/tools/build_helper @@ -372,7 +372,7 @@ check_install_lmssdr_driver(){ else echo_error "lmssdr support implies installing lmssdr drivers and tools" \ " from sources. check:" - echo_info "https://open-cells.com/index.php/2017/05/10/limesdr-installation/" + echo_info "https://wiki.myriadrf.org/Lime_Suite" echo_fatal "Cannot compile lmssdr device" fi diff --git a/targets/ARCH/LMSSDR/USERSPACE/LIB/lms_lib.cpp b/targets/ARCH/LMSSDR/USERSPACE/LIB/lms_lib.cpp index e1a1b768b2..1f0d78aba5 100644 --- a/targets/ARCH/LMSSDR/USERSPACE/LIB/lms_lib.cpp +++ b/targets/ARCH/LMSSDR/USERSPACE/LIB/lms_lib.cpp @@ -193,7 +193,7 @@ int trx_lms_start(openair0_device *device){ LMS_EnableChannel(lms_device,LMS_CH_RX,1,true); LMS_EnableChannel(lms_device,LMS_CH_TX,1,true); } */ - LMS_VCTCXOWrite(lms_device,129); + LMS_VCTCXOWrite(lms_device,129, true); if (LMS_SetSampleRate(lms_device,device->openair0_cfg->sample_rate,2)!=0) { From a12ccf1db3664ca4694f845359fe45aaa515bff5 Mon Sep 17 00:00:00 2001 From: Raphael Defosseux Date: Thu, 13 Dec 2018 14:42:21 +0100 Subject: [PATCH 198/233] CI: splitting the IF4p5 FDD scenario into several files Signed-off-by: Raphael Defosseux --- ci-scripts/xml_files/if4p5_usrp210_band7.xml | 214 ------------------ .../xml_files/if4p5_usrp210_band7_build.xml | 55 +++++ .../if4p5_usrp210_band7_epc_closure.xml | 48 ++++ .../if4p5_usrp210_band7_test_05mhz.xml | 102 +++++++++ .../if4p5_usrp210_band7_test_10mhz.xml | 102 +++++++++ .../if4p5_usrp210_band7_test_20mhz.xml | 102 +++++++++ 6 files changed, 409 insertions(+), 214 deletions(-) delete mode 100644 ci-scripts/xml_files/if4p5_usrp210_band7.xml create mode 100644 ci-scripts/xml_files/if4p5_usrp210_band7_build.xml create mode 100644 ci-scripts/xml_files/if4p5_usrp210_band7_epc_closure.xml create mode 100644 ci-scripts/xml_files/if4p5_usrp210_band7_test_05mhz.xml create mode 100644 ci-scripts/xml_files/if4p5_usrp210_band7_test_10mhz.xml create mode 100644 ci-scripts/xml_files/if4p5_usrp210_band7_test_20mhz.xml diff --git a/ci-scripts/xml_files/if4p5_usrp210_band7.xml b/ci-scripts/xml_files/if4p5_usrp210_band7.xml deleted file mode 100644 index a582754229..0000000000 --- a/ci-scripts/xml_files/if4p5_usrp210_band7.xml +++ /dev/null @@ -1,214 +0,0 @@ - - - - 010101 - 050101 060101 070101 040101 - 030101 030102 040301 040501 040604 040642 040401 040201 030201 030202 - 030111 030112 040301 040511 040614 040652 040401 040201 030201 030202 - 030121 030122 040301 040521 040624 040662 040401 040201 030201 030202 - 050201 060201 070201 - - - - - - Build_eNB - Build eNB (USRP -- Ethernet Fronthaul) - -t ETHERNET -w USRP -c --eNB - - - - Initialize_eNB - Initialize RRU (FDD/Band7) - -O ci-scripts/conf_files/rru.fdd.band7.conf - 1 - - - - Initialize_eNB - Initialize RCC (FDD/Band7/5MHz) - -O ci-scripts/conf_files/rcc.band7.tm1.if4p5.lo.25PRB.usrpb210.conf - 0 - - - - Initialize_eNB - Initialize RRU (FDD/Band7) - -O ci-scripts/conf_files/rru.fdd.band7.conf - 1 - - - - Initialize_eNB - Initialize RCC (FDD/Band7/10MHz) - -O ci-scripts/conf_files/rcc.band7.tm1.if4p5.lo.50PRB.usrpb210.conf - 0 - - - - Initialize_eNB - Initialize RRU (FDD/Band7) - -O ci-scripts/conf_files/rru.fdd.band7.conf - 1 - - - - Initialize_eNB - Initialize RCC (FDD/Band7/20MHz) - -O ci-scripts/conf_files/rcc.band7.tm1.if4p5.lo.100PRB.usrpb210.conf - 0 - - - - Terminate_eNB - Terminate RCC - 0 - - - - Terminate_eNB - Terminate RRU - 1 - - - - Initialize_UE - Initialize UE - - - - Terminate_UE - Terminate UE - - - - Attach_UE - Attach UE - - - - Detach_UE - Detach UE - - - - Ping - ping (5MHz - 20 sec) - -c 20 - 5 - - - - Iperf - iperf (5MHz - DL/15Mbps/UDP)(30 sec)(single-ue profile) - -u -b 15M -t 30 -i 1 - 50 - single-ue - - - - Iperf - iperf (5MHz - UL/9Mbps/UDP)(30 sec)(single-ue profile) - -u -b 9M -t 30 -i 1 -R - 50 - single-ue - - - - Ping - ping (10MHz - 20 sec) - -c 20 - 5 - - - - Iperf - iperf (10MHz - DL/32Mbps/UDP)(30 sec)(single-ue profile) - -u -b 32M -t 30 -i 1 - 50 - single-ue - - - - Iperf - iperf (10MHz - UL/20Mbps/UDP)(30 sec)(single-ue profile) - -u -b 20M -t 30 -i 1 -R - 50 - single-ue - - - - Ping - ping (20MHz - 20 sec) - -c 20 - 5 - - - - Iperf - iperf (20MHz - DL/70Mbps/UDP)(30 sec)(single-ue profile) - -u -b 70M -t 30 -i 1 - 50 - single-ue - - - - Iperf - iperf (20MHz - UL/20Mbps/UDP)(30 sec)(single-ue profile) - -u -b 20M -t 30 -i 1 -R - 50 - single-ue - - - - Initialize_HSS - Initialize HSS - - - - Initialize_MME - Initialize MME - - - - Initialize_SPGW - Initialize SPGW - - - - Terminate_HSS - Terminate HSS - - - - Terminate_MME - Terminate MME - - - - Terminate_SPGW - Terminate SPGW - - - diff --git a/ci-scripts/xml_files/if4p5_usrp210_band7_build.xml b/ci-scripts/xml_files/if4p5_usrp210_band7_build.xml new file mode 100644 index 0000000000..d4714b0de2 --- /dev/null +++ b/ci-scripts/xml_files/if4p5_usrp210_band7_build.xml @@ -0,0 +1,55 @@ + + + build-tab + Build + wrench + + 010101 + 050101 060101 070101 040101 + + + + + + Build_eNB + Build eNB (USRP -- Ethernet Fronthaul) + -t ETHERNET -w USRP -c --eNB + + + + Initialize_HSS + Initialize HSS + + + + Initialize_MME + Initialize MME + + + + Initialize_SPGW + Initialize SPGW + + + diff --git a/ci-scripts/xml_files/if4p5_usrp210_band7_epc_closure.xml b/ci-scripts/xml_files/if4p5_usrp210_band7_epc_closure.xml new file mode 100644 index 0000000000..cde3581afa --- /dev/null +++ b/ci-scripts/xml_files/if4p5_usrp210_band7_epc_closure.xml @@ -0,0 +1,48 @@ + + + epc-closure + EPC-Closure + log-out + + 050201 060201 070201 + + + + + + Terminate_HSS + Terminate HSS + + + + Terminate_MME + Terminate MME + + + + Terminate_SPGW + Terminate SPGW + + + diff --git a/ci-scripts/xml_files/if4p5_usrp210_band7_test_05mhz.xml b/ci-scripts/xml_files/if4p5_usrp210_band7_test_05mhz.xml new file mode 100644 index 0000000000..fb6642dd0f --- /dev/null +++ b/ci-scripts/xml_files/if4p5_usrp210_band7_test_05mhz.xml @@ -0,0 +1,102 @@ + + + test-05 + Test-05MHz + tasks + + 030101 030102 040301 040501 040604 040642 040401 040201 030201 030202 + + + + + + Initialize_eNB + Initialize RRU (FDD/Band7) + -O ci-scripts/conf_files/rru.fdd.band7.conf + 1 + + + + Initialize_eNB + Initialize RCC (FDD/Band7/5MHz) + -O ci-scripts/conf_files/rcc.band7.tm1.if4p5.lo.25PRB.usrpb210.conf + 0 + + + + Terminate_eNB + Terminate RCC + 0 + + + + Terminate_eNB + Terminate RRU + 1 + + + + Initialize_UE + Initialize UE + + + + Terminate_UE + Terminate UE + + + + Attach_UE + Attach UE + + + + Detach_UE + Detach UE + + + + Ping + ping (5MHz - 20 sec) + -c 20 + 5 + + + + Iperf + iperf (5MHz - DL/15Mbps/UDP)(30 sec)(single-ue profile) + -u -b 15M -t 30 -i 1 + 50 + single-ue + + + + Iperf + iperf (5MHz - UL/9Mbps/UDP)(30 sec)(single-ue profile) + -u -b 9M -t 30 -i 1 -R + 50 + single-ue + + + diff --git a/ci-scripts/xml_files/if4p5_usrp210_band7_test_10mhz.xml b/ci-scripts/xml_files/if4p5_usrp210_band7_test_10mhz.xml new file mode 100644 index 0000000000..e3cf3ae41a --- /dev/null +++ b/ci-scripts/xml_files/if4p5_usrp210_band7_test_10mhz.xml @@ -0,0 +1,102 @@ + + + test-10 + Test-10MHz + tasks + + 030111 030112 040301 040511 040614 040652 040401 040201 030201 030202 + + + + + + Initialize_eNB + Initialize RRU (FDD/Band7) + -O ci-scripts/conf_files/rru.fdd.band7.conf + 1 + + + + Initialize_eNB + Initialize RCC (FDD/Band7/10MHz) + -O ci-scripts/conf_files/rcc.band7.tm1.if4p5.lo.50PRB.usrpb210.conf + 0 + + + + Terminate_eNB + Terminate RCC + 0 + + + + Terminate_eNB + Terminate RRU + 1 + + + + Initialize_UE + Initialize UE + + + + Terminate_UE + Terminate UE + + + + Attach_UE + Attach UE + + + + Detach_UE + Detach UE + + + + Ping + ping (10MHz - 20 sec) + -c 20 + 5 + + + + Iperf + iperf (10MHz - DL/32Mbps/UDP)(30 sec)(single-ue profile) + -u -b 32M -t 30 -i 1 + 50 + single-ue + + + + Iperf + iperf (10MHz - UL/20Mbps/UDP)(30 sec)(single-ue profile) + -u -b 20M -t 30 -i 1 -R + 50 + single-ue + + + diff --git a/ci-scripts/xml_files/if4p5_usrp210_band7_test_20mhz.xml b/ci-scripts/xml_files/if4p5_usrp210_band7_test_20mhz.xml new file mode 100644 index 0000000000..8e54c90c44 --- /dev/null +++ b/ci-scripts/xml_files/if4p5_usrp210_band7_test_20mhz.xml @@ -0,0 +1,102 @@ + + + test-20 + Test-20MHz + tasks + + 030121 030122 040301 040521 040624 040662 040401 040201 030201 030202 + + + + + + Initialize_eNB + Initialize RRU (FDD/Band7) + -O ci-scripts/conf_files/rru.fdd.band7.conf + 1 + + + + Initialize_eNB + Initialize RCC (FDD/Band7/20MHz) + -O ci-scripts/conf_files/rcc.band7.tm1.if4p5.lo.100PRB.usrpb210.conf + 0 + + + + Terminate_eNB + Terminate RCC + 0 + + + + Terminate_eNB + Terminate RRU + 1 + + + + Initialize_UE + Initialize UE + + + + Terminate_UE + Terminate UE + + + + Attach_UE + Attach UE + + + + Detach_UE + Detach UE + + + + Ping + ping (20MHz - 20 sec) + -c 20 + 5 + + + + Iperf + iperf (20MHz - DL/70Mbps/UDP)(30 sec)(single-ue profile) + -u -b 70M -t 30 -i 1 + 50 + single-ue + + + + Iperf + iperf (20MHz - UL/20Mbps/UDP)(30 sec)(single-ue profile) + -u -b 20M -t 30 -i 1 -R + 50 + single-ue + + + From d318ed26cd13ccfe355071b491108ddc883505e5 Mon Sep 17 00:00:00 2001 From: Raphael Defosseux Date: Thu, 13 Dec 2018 16:07:59 +0100 Subject: [PATCH 199/233] CI: fixing the name of the tree icon Signed-off-by: Raphael Defosseux --- ci-scripts/main.py | 2 +- ci-scripts/reportBuildLocally.sh | 2 +- ci-scripts/reportTestLocally.sh | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/ci-scripts/main.py b/ci-scripts/main.py index d320f34117..9365d9a4b0 100644 --- a/ci-scripts/main.py +++ b/ci-scripts/main.py @@ -1975,7 +1975,7 @@ class SSHConnection(): if (self.eNB_AllowMerge): self.htmlFile.write(' \n') else: - self.htmlFile.write(' \n') + self.htmlFile.write(' \n') self.htmlFile.write(' \n') self.htmlFile.write(' \n') self.htmlFile.write(' \n') diff --git a/ci-scripts/reportBuildLocally.sh b/ci-scripts/reportBuildLocally.sh index 957eca4324..6526096d12 100755 --- a/ci-scripts/reportBuildLocally.sh +++ b/ci-scripts/reportBuildLocally.sh @@ -355,7 +355,7 @@ function report_build { if [ $PU_TRIG -eq 1 ] then echo " " >> ./build_results.html - echo " " >> ./build_results.html + echo " " >> ./build_results.html echo " " >> ./build_results.html echo " " >> ./build_results.html echo " " >> ./build_results.html diff --git a/ci-scripts/reportTestLocally.sh b/ci-scripts/reportTestLocally.sh index aae0df0d7d..60dcb1e421 100755 --- a/ci-scripts/reportTestLocally.sh +++ b/ci-scripts/reportTestLocally.sh @@ -132,7 +132,7 @@ function report_test { if [ $PU_TRIG -eq 1 ] then echo " " >> ./test_simulator_results.html - echo " " >> ./test_simulator_results.html + echo " " >> ./test_simulator_results.html echo " " >> ./test_simulator_results.html echo " " >> ./test_simulator_results.html echo " " >> ./test_simulator_results.html From df6cc9efc018961ae202fd2053c50590cff17883 Mon Sep 17 00:00:00 2001 From: Raphael Defosseux Date: Fri, 14 Dec 2018 15:37:55 +0100 Subject: [PATCH 200/233] CI: splitting all xml scenarios Signed-off-by: Raphael Defosseux --- ci-scripts/Jenkinsfile-tmp-ran | 2 +- ci-scripts/main.py | 1 + .../xml_files/enb_usrp210_band40_build.xml | 54 +++ .../enb_usrp210_band40_epc_closure.xml | 47 +++ .../enb_usrp210_band40_test_05mhz_tm1.xml | 119 ++++++ .../enb_usrp210_band40_test_10mhz_tm1.xml | 119 ++++++ .../enb_usrp210_band40_test_20mhz_tm1.xml | 119 ++++++ .../xml_files/enb_usrp210_band40_tracer.xml | 65 ++++ ci-scripts/xml_files/enb_usrp210_band7.xml | 363 ------------------ .../xml_files/enb_usrp210_band7_build.xml | 54 +++ .../enb_usrp210_band7_epc_closure.xml | 47 +++ .../enb_usrp210_band7_test_05mhz_tm1.xml | 143 +++++++ .../enb_usrp210_band7_test_10mhz_tm1.xml | 143 +++++++ .../enb_usrp210_band7_test_20mhz_tm1.xml | 143 +++++++ .../xml_files/enb_usrp210_band7_tracer.xml | 65 ++++ ci-scripts/xml_files/enb_usrpb210_band40.xml | 239 ------------ ci-scripts/xml_files/if4p5_usrp210_band40.xml | 217 ----------- .../xml_files/if4p5_usrp210_band40_build.xml | 55 +++ .../if4p5_usrp210_band40_epc_closure.xml | 48 +++ .../if4p5_usrp210_band40_test_05mhz.xml | 103 +++++ .../if4p5_usrp210_band40_test_10mhz.xml | 103 +++++ .../if4p5_usrp210_band40_test_20mhz.xml | 103 +++++ .../xml_files/if4p5_usrp210_band7_build.xml | 6 +- .../if4p5_usrp210_band7_epc_closure.xml | 6 +- .../if4p5_usrp210_band7_test_05mhz.xml | 7 +- .../if4p5_usrp210_band7_test_10mhz.xml | 7 +- .../if4p5_usrp210_band7_test_20mhz.xml | 7 +- 27 files changed, 1550 insertions(+), 835 deletions(-) create mode 100644 ci-scripts/xml_files/enb_usrp210_band40_build.xml create mode 100644 ci-scripts/xml_files/enb_usrp210_band40_epc_closure.xml create mode 100644 ci-scripts/xml_files/enb_usrp210_band40_test_05mhz_tm1.xml create mode 100644 ci-scripts/xml_files/enb_usrp210_band40_test_10mhz_tm1.xml create mode 100644 ci-scripts/xml_files/enb_usrp210_band40_test_20mhz_tm1.xml create mode 100644 ci-scripts/xml_files/enb_usrp210_band40_tracer.xml delete mode 100644 ci-scripts/xml_files/enb_usrp210_band7.xml create mode 100644 ci-scripts/xml_files/enb_usrp210_band7_build.xml create mode 100644 ci-scripts/xml_files/enb_usrp210_band7_epc_closure.xml create mode 100644 ci-scripts/xml_files/enb_usrp210_band7_test_05mhz_tm1.xml create mode 100644 ci-scripts/xml_files/enb_usrp210_band7_test_10mhz_tm1.xml create mode 100644 ci-scripts/xml_files/enb_usrp210_band7_test_20mhz_tm1.xml create mode 100644 ci-scripts/xml_files/enb_usrp210_band7_tracer.xml delete mode 100644 ci-scripts/xml_files/enb_usrpb210_band40.xml delete mode 100644 ci-scripts/xml_files/if4p5_usrp210_band40.xml create mode 100644 ci-scripts/xml_files/if4p5_usrp210_band40_build.xml create mode 100644 ci-scripts/xml_files/if4p5_usrp210_band40_epc_closure.xml create mode 100644 ci-scripts/xml_files/if4p5_usrp210_band40_test_05mhz.xml create mode 100644 ci-scripts/xml_files/if4p5_usrp210_band40_test_10mhz.xml create mode 100644 ci-scripts/xml_files/if4p5_usrp210_band40_test_20mhz.xml diff --git a/ci-scripts/Jenkinsfile-tmp-ran b/ci-scripts/Jenkinsfile-tmp-ran index fc01233bfb..547970e45e 100644 --- a/ci-scripts/Jenkinsfile-tmp-ran +++ b/ci-scripts/Jenkinsfile-tmp-ran @@ -350,7 +350,7 @@ pipeline { } if(fileExists("ci-scripts/test_results.html")) { sh "mv ci-scripts/test_results.html test_results-${JOB_NAME}.html" - sh "sed -i -e 's#TEMPLATE_JOB_NAME#${JOB_NAME}#' -e 's@build #TEMPLATE_BUILD_ID@build #${BUILD_ID}@' -e 's#Build-ID: TEMPLATE_BUILD_ID#Build-ID: ${BUILD_ID}#' test_results-${JOB_NAME}.html" + sh "sed -i -e 's#TEMPLATE_JOB_NAME#${JOB_NAME}#' -e 's@build #TEMPLATE_BUILD_ID@build #${BUILD_ID}@' -e 's#Build-ID: TEMPLATE_BUILD_ID#Build-ID: ${BUILD_ID}#' -e 's#TEMPLATE_STAGE_NAME#${testStageName}#' test_results-${JOB_NAME}.html" archiveArtifacts "test_results-${JOB_NAME}.html" } } diff --git a/ci-scripts/main.py b/ci-scripts/main.py index 9365d9a4b0..c5c30c8e20 100644 --- a/ci-scripts/main.py +++ b/ci-scripts/main.py @@ -1955,6 +1955,7 @@ class SSHConnection(): self.htmlFile.write(' \n') self.htmlFile.write('
    Build Start Time (UTC) Build Start Time (UTC)TEMPLATE_BUILD_TIME
    GIT Repository GIT Repository$GIT_URL
    Job Trigger Job TriggerPush EventMerge-Request
    Branch Branch$SOURCE_BRANCH
    Commit ID Commit ID$SOURCE_COMMIT_ID
    Source Branch Source Branch$SOURCE_BRANCH
    Source Commit ID Source Commit ID$SOURCE_COMMIT_ID
    Target Branch Target Branch$TARGET_BRANCH
    Target Commit ID Target Commit ID$TARGET_COMMIT_ID
    Test DescTest OptionsTest StatusUE' + str(i) + ' Status Source Branch Branch Branch' + self.eNBBranch + '
    Branch Branch$SOURCE_BRANCH
    Branch Branch$SOURCE_BRANCH
    \n') self.htmlFile.write('
    \n') + self.htmlFile.write('
    TEMPLATE_STAGE_NAME
    \n') self.htmlFile.write(' \n') self.htmlFile.write(' \n') self.htmlFile.write(' \n') diff --git a/ci-scripts/xml_files/enb_usrp210_band40_build.xml b/ci-scripts/xml_files/enb_usrp210_band40_build.xml new file mode 100644 index 0000000000..8f9489b03e --- /dev/null +++ b/ci-scripts/xml_files/enb_usrp210_band40_build.xml @@ -0,0 +1,54 @@ + + + build-tab + Build + wrench + + 010101 + 050101 060101 070101 + + + + + Build_eNB + Build eNB (USRP) + -w USRP -c --eNB + + + + Initialize_HSS + Initialize HSS + + + + Initialize_MME + Initialize MME + + + + Initialize_SPGW + Initialize SPGW + + + diff --git a/ci-scripts/xml_files/enb_usrp210_band40_epc_closure.xml b/ci-scripts/xml_files/enb_usrp210_band40_epc_closure.xml new file mode 100644 index 0000000000..ad34381a2a --- /dev/null +++ b/ci-scripts/xml_files/enb_usrp210_band40_epc_closure.xml @@ -0,0 +1,47 @@ + + + epc-closure + EPC-Closure + log-out + + 050201 060201 070201 + + + + + Terminate_HSS + Terminate HSS + + + + Terminate_MME + Terminate MME + + + + Terminate_SPGW + Terminate SPGW + + + diff --git a/ci-scripts/xml_files/enb_usrp210_band40_test_05mhz_tm1.xml b/ci-scripts/xml_files/enb_usrp210_band40_test_05mhz_tm1.xml new file mode 100644 index 0000000000..d5a25c7fa7 --- /dev/null +++ b/ci-scripts/xml_files/enb_usrp210_band40_test_05mhz_tm1.xml @@ -0,0 +1,119 @@ + + + test-05-tm1 + Test-05MHz-TM1 + tasks + + 040101 + 030104 040301 040501 040602 040601 040603 040642 040641 040643 040401 040201 030201 + + + + + Initialize_eNB + Initialize eNB (TDD/Band40/5MHz) + -O ci-scripts/conf_files/enb.band40.tm1.25PRB.FairScheduler.usrpb210.conf + + + + Terminate_eNB + Terminate eNB + + + + Initialize_UE + Initialize UE + + + + Terminate_UE + Terminate UE + + + + Attach_UE + Attach UE + + + + Detach_UE + Detach UE + + + + Ping + ping (5MHz - 20 sec) + -c 20 + 25 + + + + Iperf + iperf (5MHz - DL/6.5Mbps/UDP)(30 sec)(balanced) + -u -b 6.5M -t 30 -i 1 + 50 + balanced + + + + Iperf + iperf (5MHz - DL/6.5Mbps/UDP)(30 sec)(single-ue) + -u -b 6.5M -t 30 -i 1 + 50 + single-ue + + + + Iperf + iperf (5MHz - DL/6.5Mbps/UDP)(30 sec)(unbalanced) + -u -b 6.5M -t 30 -i 1 + 50 + unbalanced + + + + Iperf + iperf (5MHz - UL/2Mbps/UDP)(30 sec)(balanced) + -u -b 2M -t 30 -i 1 -R + 50 + balanced + + + + Iperf + iperf (5MHz - UL/2Mbps/UDP)(30 sec)(single-ue) + -u -b 2M -t 30 -i 1 -R + 50 + single-ue + + + + Iperf + iperf (5MHz - UL/2Mbps/UDP)(30 sec)(unbalanced) + -u -b 2M -t 30 -i 1 -R + 50 + unbalanced + + + diff --git a/ci-scripts/xml_files/enb_usrp210_band40_test_10mhz_tm1.xml b/ci-scripts/xml_files/enb_usrp210_band40_test_10mhz_tm1.xml new file mode 100644 index 0000000000..ef50933d4a --- /dev/null +++ b/ci-scripts/xml_files/enb_usrp210_band40_test_10mhz_tm1.xml @@ -0,0 +1,119 @@ + + + test-10-tm1 + Test-10MHz-TM1 + tasks + + 040101 + 030114 040301 040511 040612 040611 040613 040652 040651 040653 040401 040201 030201 + + + + + Initialize_eNB + Initialize eNB (TDD/Band40/10MHz/info) + -O ci-scripts/conf_files/enb.band40.tm1.50PRB.FairScheduler.usrpb210.conf + + + + Terminate_eNB + Terminate eNB + + + + Initialize_UE + Initialize UE + + + + Terminate_UE + Terminate UE + + + + Attach_UE + Attach UE + + + + Detach_UE + Detach UE + + + + Ping + ping (10MHz - 20 sec) + -c 20 + 25 + + + + Iperf + iperf (10MHz - DL/13.5Mbps/UDP)(30 sec)(balanced) + -u -b 13.5M -t 30 -i 1 + 50 + balanced + + + + Iperf + iperf (10MHz - DL/13.5Mbps/UDP)(30 sec)(single-ue) + -u -b 13.5M -t 30 -i 1 + 50 + single-ue + + + + Iperf + iperf (10MHz - DL/13.5Mbps/UDP)(30 sec)(unbalanced) + -u -b 13.5M -t 30 -i 1 + 50 + unbalanced + + + + Iperf + iperf (10MHz - UL/2Mbps/UDP)(30 sec)(balanced) + -u -b 2M -t 30 -i 1 -R + 50 + balanced + + + + Iperf + iperf (10MHz - UL/2Mbps/UDP)(30 sec)(single-ue) + -u -b 2M -t 30 -i 1 -R + 50 + single-ue + + + + Iperf + iperf (10MHz - UL/2Mbps/UDP)(30 sec)(unbalanced) + -u -b 2M -t 30 -i 1 -R + 50 + unbalanced + + + diff --git a/ci-scripts/xml_files/enb_usrp210_band40_test_20mhz_tm1.xml b/ci-scripts/xml_files/enb_usrp210_band40_test_20mhz_tm1.xml new file mode 100644 index 0000000000..9a96baac3f --- /dev/null +++ b/ci-scripts/xml_files/enb_usrp210_band40_test_20mhz_tm1.xml @@ -0,0 +1,119 @@ + + + test-20-tm1 + Test-20MHz-TM1 + tasks + + 040101 + 030124 040301 040521 040622 040621 040623 040662 040661 040663 040401 040201 030201 + + + + + Initialize_eNB + Initialize eNB (TDD/Band40/20MHz/info) + -O ci-scripts/conf_files/enb.band40.tm1.100PRB.FairScheduler.usrpb210.conf + + + + Terminate_eNB + Terminate eNB + + + + Initialize_UE + Initialize UE + + + + Terminate_UE + Terminate UE + + + + Attach_UE + Attach UE + + + + Detach_UE + Detach UE + + + + Ping + ping (20MHz - 20 sec) + -c 20 + 25 + + + + Iperf + iperf (20MHz - DL/13.5Mbps/UDP)(30 sec)(balanced) + -u -b 13.5M -t 30 -i 1 + 50 + balanced + + + + Iperf + iperf (20MHz - DL/13.5Mbps/UDP)(30 sec)(single-ue) + -u -b 13.5M -t 30 -i 1 + 50 + single-ue + + + + Iperf + iperf (20MHz - DL/13.5Mbps/UDP)(30 sec)(unbalanced) + -u -b 13.5M -t 30 -i 1 + 50 + unbalanced + + + + Iperf + iperf (20MHz - UL/2Mbps/UDP)(30 sec)(balanced) + -u -b 2M -t 30 -i 1 -R + 50 + balanced + + + + Iperf + iperf (20MHz - UL/2Mbps/UDP)(30 sec)(single-ue) + -u -b 2M -t 30 -i 1 -R + 50 + single-ue + + + + Iperf + iperf (20MHz - UL/2Mbps/UDP)(30 sec)(unbalanced) + -u -b 2M -t 30 -i 1 -R + 50 + unbalanced + + + diff --git a/ci-scripts/xml_files/enb_usrp210_band40_tracer.xml b/ci-scripts/xml_files/enb_usrp210_band40_tracer.xml new file mode 100644 index 0000000000..dceb6be97a --- /dev/null +++ b/ci-scripts/xml_files/enb_usrp210_band40_tracer.xml @@ -0,0 +1,65 @@ + + + tracer-test + T-Tracer + duplicate + + 040101 + 030100 040300 040401 040201 030201 + + + + + Initialize_eNB + Initialize eNB (TDD/Band40/5MHz) with T Tracer on + -O ci-scripts/conf_files/enb.band40.tm1.25PRB.FairScheduler.usrpb210.conf --T_stdout 0 + + + + Terminate_eNB + Terminate eNB + + + + Initialize_UE + Initialize UE + + + + Terminate_UE + Terminate UE + + + + Attach_UE + Attach single UE + 1 + + + + Detach_UE + Detach UE + + + diff --git a/ci-scripts/xml_files/enb_usrp210_band7.xml b/ci-scripts/xml_files/enb_usrp210_band7.xml deleted file mode 100644 index c85ceee81d..0000000000 --- a/ci-scripts/xml_files/enb_usrp210_band7.xml +++ /dev/null @@ -1,363 +0,0 @@ - - - - 010101 - 050101 060101 070101 040101 - 030100 040300 040401 040201 030201 - 030101 040301 040501 040603 040604 040605 040606 040607 040641 040642 040643 040644 040401 040201 030201 - 030111 040301 040511 040613 040614 040615 040616 040617 040651 040652 040653 040654 040401 040201 030201 - 030121 040301 040521 040623 040624 040625 040626 040627 040662 040661 040663 040664 040401 040201 030201 - 050201 060201 070201 - - - - - Build_eNB - Build eNB (USRP) - -w USRP -c --eNB - - - - Initialize_eNB - Initialize eNB (FDD/Band7/5MHz) with T Tracer on - -O ci-scripts/conf_files/enb.band7.tm1.25PRB.usrpb210.conf --T_stdout 0 - - - - Initialize_eNB - Initialize eNB (FDD/Band7/5MHz) - -O ci-scripts/conf_files/enb.band7.tm1.25PRB.usrpb210.conf - - - - Initialize_eNB - Initialize eNB (FDD/Band7/10MHz) - -O ci-scripts/conf_files/enb.band7.tm1.50PRB.usrpb210.conf - - - - Initialize_eNB - Initialize eNB (FDD/Band7/20MHz) - -O ci-scripts/conf_files/enb.band7.tm1.100PRB.usrpb210.conf - - - - Terminate_eNB - Terminate eNB - - - - Initialize_UE - Initialize UE - - - - Terminate_UE - Terminate UE - - - - Attach_UE - Attach single UE - 1 - - - - Attach_UE - Attach UE - - - - Detach_UE - Detach UE - - - - Ping - ping (5MHz - 20 sec) - -c 20 - 5 - - - - Ping - ping (10MHz - 20 sec) - -c 20 - 5 - - - - Ping - ping (20MHz - 20 sec) - -c 20 - 5 - - - - Iperf - iperf (5MHz - DL/15Mbps/UDP)(30 sec)(balanced profile) - -u -b 15M -t 30 -i 1 - 50 - balanced - - - - Iperf - iperf (5MHz - DL/15Mbps/UDP)(30 sec)(single-ue profile) - -u -b 15M -t 30 -i 1 - 50 - single-ue - - - - Iperf - iperf (5MHz - DL/15Mbps/UDP)(30 sec)(unbalanced profile) - -u -b 15M -t 30 -i 1 - 50 - unbalanced - - - - Iperf - iperf (5MHz - DL/TCP)(30 sec)(single-ue profile) - -t 30 -i 1 -fm - 50 - single-ue - - - - Iperf - iperf (5MHz - DL/TCP)(30 sec)(balanced profile) - -t 30 -i 1 -fm - 50 - balanced - - - - Iperf - iperf (5MHz - UL/9Mbps/UDP)(30 sec)(balanced profile) - -u -b 9M -t 30 -i 1 -R - 50 - balanced - - - - Iperf - iperf (5MHz - UL/9Mbps/UDP)(30 sec)(single-ue profile) - -u -b 9M -t 30 -i 1 -R - 50 - single-ue - - - - Iperf - iperf (5MHz - UL/TCP)(30 sec)(single-ue profile) - -t 30 -i 1 -fm -R - 50 - single-ue - - - - Iperf - iperf (5MHz - UL/TCP)(30 sec)(balanced profile) - -t 30 -i 1 -fm -R - 50 - balanced - - - - Iperf - iperf (10MHz - DL/30Mbps/UDP)(30 sec)(balanced profile) - -u -b 30M -t 30 -i 1 - 50 - balanced - - - - Iperf - iperf (10MHz - DL/30Mbps/UDP)(30 sec)(single-ue profile) - -u -b 30M -t 30 -i 1 - 50 - single-ue - - - - Iperf - iperf (10MHz - DL/30Mbps/UDP)(30 sec)(unbalanced profile) - -u -b 30M -t 30 -i 1 - 50 - unbalanced - - - - Iperf - iperf (10MHz - DL/TCP)(30 sec)(single-ue profile) - -t 30 -i 1 -fm - 50 - single-ue - - - - Iperf - iperf (10MHz - DL/TCP)(30 sec)(balanced profile) - -t 30 -i 1 -fm - 50 - balanced - - - - Iperf - iperf (10MHz - UL/20Mbps/UDP)(30 sec)(balanced profile) - -u -b 20M -t 30 -i 1 -R - 50 - balanced - - - - Iperf - iperf (10MHz - UL/20Mbps/UDP)(30 sec)(single-ue profile) - -u -b 20M -t 30 -i 1 -R - 50 - single-ue - - - - Iperf - iperf (10MHz - UL/TCP)(30 sec)(single-ue profile) - -t 30 -i 1 -fm -R - 50 - single-ue - - - - Iperf - iperf (10MHz - UL/TCP)(30 sec)(balanced profile) - -t 30 -i 1 -fm -R - 50 - balanced - - - - Iperf - iperf (20MHz - DL/70Mbps/UDP)(30 sec)(balanced profile) - -u -b 70M -t 30 -i 1 - 50 - balanced - - - - Iperf - iperf (20MHz - DL/70Mbps/UDP)(30 sec)(single-ue profile) - -u -b 70M -t 30 -i 1 - 50 - single-ue - - - - Iperf - iperf (20MHz - DL/70Mbps/UDP)(30 sec)(unbalanced profile) - -u -b 70M -t 30 -i 1 - 50 - unbalanced - - - - Iperf - iperf (20MHz - DL/TCP)(30 sec)(single-ue profile) - -t 30 -i 1 -fm - 50 - single-ue - - - - Iperf - iperf (20MHz - DL/TCP)(30 sec)(balanced profile) - -t 30 -i 1 -fm - 50 - balanced - - - - Iperf - iperf (20MHz - UL/20Mbps/UDP)(30 sec)(balanced profile) - -u -b 20M -t 30 -i 1 -R - 50 - balanced - - - - Iperf - iperf (20MHz - UL/20Mbps/UDP)(30 sec)(single-ue profile) - -u -b 20M -t 30 -i 1 -R - 50 - single-ue - - - - Iperf - iperf (20MHz - UL/TCP)(30 sec)(single-ue profile) - -t 30 -i 1 -fm -R - 50 - single-ue - - - - Iperf - iperf (20MHz - UL/TCP)(30 sec)(balanced profile) - -t 30 -i 1 -fm -R - 50 - balanced - - - - Initialize_HSS - Initialize HSS - - - - Initialize_MME - Initialize MME - - - - Initialize_SPGW - Initialize SPGW - - - - Terminate_HSS - Terminate HSS - - - - Terminate_MME - Terminate MME - - - - Terminate_SPGW - Terminate SPGW - - - diff --git a/ci-scripts/xml_files/enb_usrp210_band7_build.xml b/ci-scripts/xml_files/enb_usrp210_band7_build.xml new file mode 100644 index 0000000000..31ee57e941 --- /dev/null +++ b/ci-scripts/xml_files/enb_usrp210_band7_build.xml @@ -0,0 +1,54 @@ + + + build-tab + Build + wrench + + 010101 + 050101 060101 070101 + + + + + Build_eNB + Build eNB (USRP) + -w USRP -c --eNB + + + + Initialize_HSS + Initialize HSS + + + + Initialize_MME + Initialize MME + + + + Initialize_SPGW + Initialize SPGW + + + diff --git a/ci-scripts/xml_files/enb_usrp210_band7_epc_closure.xml b/ci-scripts/xml_files/enb_usrp210_band7_epc_closure.xml new file mode 100644 index 0000000000..07fb6951f8 --- /dev/null +++ b/ci-scripts/xml_files/enb_usrp210_band7_epc_closure.xml @@ -0,0 +1,47 @@ + + + epc-closure + EPC-Closure + log-out + + 050201 060201 070201 + + + + + Terminate_HSS + Terminate HSS + + + + Terminate_MME + Terminate MME + + + + Terminate_SPGW + Terminate SPGW + + + diff --git a/ci-scripts/xml_files/enb_usrp210_band7_test_05mhz_tm1.xml b/ci-scripts/xml_files/enb_usrp210_band7_test_05mhz_tm1.xml new file mode 100644 index 0000000000..0057eaefa4 --- /dev/null +++ b/ci-scripts/xml_files/enb_usrp210_band7_test_05mhz_tm1.xml @@ -0,0 +1,143 @@ + + + test-05-tm1 + Test-05MHz-TM1 + tasks + + 040101 + 030101 040301 040501 040603 040604 040605 040606 040607 040641 040642 040643 040644 040401 040201 030201 + + + + + Initialize_eNB + Initialize eNB (FDD/Band7/5MHz) + -O ci-scripts/conf_files/enb.band7.tm1.25PRB.usrpb210.conf + + + + Terminate_eNB + Terminate eNB + + + + Initialize_UE + Initialize UE + + + + Terminate_UE + Terminate UE + + + + Attach_UE + Attach UE + + + + Detach_UE + Detach UE + + + + Ping + ping (5MHz - 20 sec) + -c 20 + 5 + + + + Iperf + iperf (5MHz - DL/15Mbps/UDP)(30 sec)(balanced profile) + -u -b 15M -t 30 -i 1 + 50 + balanced + + + + Iperf + iperf (5MHz - DL/15Mbps/UDP)(30 sec)(single-ue profile) + -u -b 15M -t 30 -i 1 + 50 + single-ue + + + + Iperf + iperf (5MHz - DL/15Mbps/UDP)(30 sec)(unbalanced profile) + -u -b 15M -t 30 -i 1 + 50 + unbalanced + + + + Iperf + iperf (5MHz - DL/TCP)(30 sec)(single-ue profile) + -t 30 -i 1 -fm + 50 + single-ue + + + + Iperf + iperf (5MHz - DL/TCP)(30 sec)(balanced profile) + -t 30 -i 1 -fm + 50 + balanced + + + + Iperf + iperf (5MHz - UL/9Mbps/UDP)(30 sec)(balanced profile) + -u -b 9M -t 30 -i 1 -R + 50 + balanced + + + + Iperf + iperf (5MHz - UL/9Mbps/UDP)(30 sec)(single-ue profile) + -u -b 9M -t 30 -i 1 -R + 50 + single-ue + + + + Iperf + iperf (5MHz - UL/TCP)(30 sec)(single-ue profile) + -t 30 -i 1 -fm -R + 50 + single-ue + + + + Iperf + iperf (5MHz - UL/TCP)(30 sec)(balanced profile) + -t 30 -i 1 -fm -R + 50 + balanced + + + diff --git a/ci-scripts/xml_files/enb_usrp210_band7_test_10mhz_tm1.xml b/ci-scripts/xml_files/enb_usrp210_band7_test_10mhz_tm1.xml new file mode 100644 index 0000000000..92ec1efa6e --- /dev/null +++ b/ci-scripts/xml_files/enb_usrp210_band7_test_10mhz_tm1.xml @@ -0,0 +1,143 @@ + + + test-10-tm1 + Test-10MHz-TM1 + tasks + + 040101 + 030111 040301 040511 040613 040614 040615 040616 040617 040651 040652 040653 040654 040401 040201 030201 + + + + + Initialize_eNB + Initialize eNB (FDD/Band7/10MHz) + -O ci-scripts/conf_files/enb.band7.tm1.50PRB.usrpb210.conf + + + + Terminate_eNB + Terminate eNB + + + + Initialize_UE + Initialize UE + + + + Terminate_UE + Terminate UE + + + + Attach_UE + Attach UE + + + + Detach_UE + Detach UE + + + + Ping + ping (10MHz - 20 sec) + -c 20 + 5 + + + + Iperf + iperf (10MHz - DL/30Mbps/UDP)(30 sec)(balanced profile) + -u -b 30M -t 30 -i 1 + 50 + balanced + + + + Iperf + iperf (10MHz - DL/30Mbps/UDP)(30 sec)(single-ue profile) + -u -b 30M -t 30 -i 1 + 50 + single-ue + + + + Iperf + iperf (10MHz - DL/30Mbps/UDP)(30 sec)(unbalanced profile) + -u -b 30M -t 30 -i 1 + 50 + unbalanced + + + + Iperf + iperf (10MHz - DL/TCP)(30 sec)(single-ue profile) + -t 30 -i 1 -fm + 50 + single-ue + + + + Iperf + iperf (10MHz - DL/TCP)(30 sec)(balanced profile) + -t 30 -i 1 -fm + 50 + balanced + + + + Iperf + iperf (10MHz - UL/20Mbps/UDP)(30 sec)(balanced profile) + -u -b 20M -t 30 -i 1 -R + 50 + balanced + + + + Iperf + iperf (10MHz - UL/20Mbps/UDP)(30 sec)(single-ue profile) + -u -b 20M -t 30 -i 1 -R + 50 + single-ue + + + + Iperf + iperf (10MHz - UL/TCP)(30 sec)(single-ue profile) + -t 30 -i 1 -fm -R + 50 + single-ue + + + + Iperf + iperf (10MHz - UL/TCP)(30 sec)(balanced profile) + -t 30 -i 1 -fm -R + 50 + balanced + + + diff --git a/ci-scripts/xml_files/enb_usrp210_band7_test_20mhz_tm1.xml b/ci-scripts/xml_files/enb_usrp210_band7_test_20mhz_tm1.xml new file mode 100644 index 0000000000..68b3829682 --- /dev/null +++ b/ci-scripts/xml_files/enb_usrp210_band7_test_20mhz_tm1.xml @@ -0,0 +1,143 @@ + + + test-20-tm1 + Test-20MHz-TM1 + tasks + + 040101 + 030121 040301 040521 040623 040624 040625 040626 040627 040662 040661 040663 040664 040401 040201 030201 + + + + + Initialize_eNB + Initialize eNB (FDD/Band7/20MHz) + -O ci-scripts/conf_files/enb.band7.tm1.100PRB.usrpb210.conf + + + + Terminate_eNB + Terminate eNB + + + + Initialize_UE + Initialize UE + + + + Terminate_UE + Terminate UE + + + + Attach_UE + Attach UE + + + + Detach_UE + Detach UE + + + + Ping + ping (20MHz - 20 sec) + -c 20 + 5 + + + + Iperf + iperf (20MHz - DL/70Mbps/UDP)(30 sec)(balanced profile) + -u -b 70M -t 30 -i 1 + 50 + balanced + + + + Iperf + iperf (20MHz - DL/70Mbps/UDP)(30 sec)(single-ue profile) + -u -b 70M -t 30 -i 1 + 50 + single-ue + + + + Iperf + iperf (20MHz - DL/70Mbps/UDP)(30 sec)(unbalanced profile) + -u -b 70M -t 30 -i 1 + 50 + unbalanced + + + + Iperf + iperf (20MHz - DL/TCP)(30 sec)(single-ue profile) + -t 30 -i 1 -fm + 50 + single-ue + + + + Iperf + iperf (20MHz - DL/TCP)(30 sec)(balanced profile) + -t 30 -i 1 -fm + 50 + balanced + + + + Iperf + iperf (20MHz - UL/20Mbps/UDP)(30 sec)(balanced profile) + -u -b 20M -t 30 -i 1 -R + 50 + balanced + + + + Iperf + iperf (20MHz - UL/20Mbps/UDP)(30 sec)(single-ue profile) + -u -b 20M -t 30 -i 1 -R + 50 + single-ue + + + + Iperf + iperf (20MHz - UL/TCP)(30 sec)(single-ue profile) + -t 30 -i 1 -fm -R + 50 + single-ue + + + + Iperf + iperf (20MHz - UL/TCP)(30 sec)(balanced profile) + -t 30 -i 1 -fm -R + 50 + balanced + + + diff --git a/ci-scripts/xml_files/enb_usrp210_band7_tracer.xml b/ci-scripts/xml_files/enb_usrp210_band7_tracer.xml new file mode 100644 index 0000000000..4c74f52b0f --- /dev/null +++ b/ci-scripts/xml_files/enb_usrp210_band7_tracer.xml @@ -0,0 +1,65 @@ + + + tracer-test + T-Tracer + duplicate + + 040101 + 030100 040300 040401 040201 030201 + + + + + Initialize_eNB + Initialize eNB (FDD/Band7/5MHz) with T Tracer on + -O ci-scripts/conf_files/enb.band7.tm1.25PRB.usrpb210.conf --T_stdout 0 + + + + Terminate_eNB + Terminate eNB + + + + Initialize_UE + Initialize UE + + + + Terminate_UE + Terminate UE + + + + Attach_UE + Attach single UE + 1 + + + + Detach_UE + Detach UE + + + diff --git a/ci-scripts/xml_files/enb_usrpb210_band40.xml b/ci-scripts/xml_files/enb_usrpb210_band40.xml deleted file mode 100644 index 65492c4209..0000000000 --- a/ci-scripts/xml_files/enb_usrpb210_band40.xml +++ /dev/null @@ -1,239 +0,0 @@ - - - - 010101 - 050101 060101 070101 040101 - 030100 040300 040401 040201 030201 - 030104 040301 040501 040602 040601 040603 040642 040641 040643 040401 040201 030201 - 030114 040301 040511 040612 040611 040613 040652 040651 040653 040401 040201 030201 - 050201 060201 070201 - - - - - - - Build_eNB - Build eNB (USRP) - -w USRP -c --eNB - - - - Initialize_eNB - Initialize eNB (TDD/Band40/5MHz) with T Tracer on - -O ci-scripts/conf_files/enb.band40.tm1.25PRB.FairScheduler.usrpb210.conf --T_stdout 0 - - - - Initialize_eNB - Initialize eNB (TDD/Band40/5MHz) - -O ci-scripts/conf_files/enb.band40.tm1.25PRB.FairScheduler.usrpb210.conf - - - - Initialize_eNB - Initialize eNB (TDD/Band40/10MHz/info) - -O ci-scripts/conf_files/enb.band40.tm1.50PRB.FairScheduler.usrpb210.conf - - - - Initialize_eNB - Initialize eNB (TDD/Band40/20MHz/info) - -O ci-scripts/conf_files/enb.band40.tm1.100PRB.FairScheduler.usrpb210.conf - - - - Terminate_eNB - Terminate eNB - - - - Initialize_UE - Initialize UE - - - - Terminate_UE - Terminate UE - - - - Attach_UE - Attach single UE - 1 - - - - Attach_UE - Attach UE - - - - Detach_UE - Detach UE - - - - Ping - ping (5MHz - 20 sec) - -c 20 - 25 - - - - Ping - ping (10MHz - 20 sec) - -c 20 - 25 - - - - Iperf - iperf (5MHz - DL/6.5Mbps/UDP)(30 sec)(balanced) - -u -b 6.5M -t 30 -i 1 - 50 - balanced - - - - Iperf - iperf (5MHz - DL/6.5Mbps/UDP)(30 sec)(single-ue) - -u -b 6.5M -t 30 -i 1 - 50 - single-ue - - - - Iperf - iperf (5MHz - DL/6.5Mbps/UDP)(30 sec)(unbalanced) - -u -b 6.5M -t 30 -i 1 - 50 - unbalanced - - - - Iperf - iperf (10MHz - DL/13.5Mbps/UDP)(30 sec)(balanced) - -u -b 13.5M -t 30 -i 1 - 50 - balanced - - - - Iperf - iperf (10MHz - DL/13.5Mbps/UDP)(30 sec)(single-ue) - -u -b 13.5M -t 30 -i 1 - 50 - single-ue - - - - Iperf - iperf (10MHz - DL/13.5Mbps/UDP)(30 sec)(unbalanced) - -u -b 13.5M -t 30 -i 1 - 50 - unbalanced - - - - Iperf - iperf (5MHz - UL/2Mbps/UDP)(30 sec)(balanced) - -u -b 2M -t 30 -i 1 -R - 50 - balanced - - - - Iperf - iperf (5MHz - UL/2Mbps/UDP)(30 sec)(single-ue) - -u -b 2M -t 30 -i 1 -R - 50 - single-ue - - - - Iperf - iperf (5MHz - UL/2Mbps/UDP)(30 sec)(unbalanced) - -u -b 2M -t 30 -i 1 -R - 50 - unbalanced - - - - Iperf - iperf (10MHz - UL/2Mbps/UDP)(30 sec)(balanced) - -u -b 2M -t 30 -i 1 -R - 50 - balanced - - - - Iperf - iperf (10MHz - UL/2Mbps/UDP)(30 sec)(single-ue) - -u -b 2M -t 30 -i 1 -R - 50 - single-ue - - - - Iperf - iperf (10MHz - UL/2Mbps/UDP)(30 sec)(unbalanced) - -u -b 2M -t 30 -i 1 -R - 50 - unbalanced - - - - Initialize_HSS - Initialize HSS - - - - Initialize_MME - Initialize MME - - - - Initialize_SPGW - Initialize SPGW - - - - Terminate_HSS - Terminate HSS - - - - Terminate_MME - Terminate MME - - - - Terminate_SPGW - Terminate SPGW - - - diff --git a/ci-scripts/xml_files/if4p5_usrp210_band40.xml b/ci-scripts/xml_files/if4p5_usrp210_band40.xml deleted file mode 100644 index ac5d9ef5ba..0000000000 --- a/ci-scripts/xml_files/if4p5_usrp210_band40.xml +++ /dev/null @@ -1,217 +0,0 @@ - - - - - 010101 - 050101 060101 070101 040101 - 030104 030105 040301 040501 040602 040642 040401 040201 030201 030202 - 030114 030115 040301 040511 040612 040652 040401 040201 030201 030202 - 050201 060201 070201 - - - - - - - Build_eNB - Build eNB (USRP -- Ethernet Fronthaul) - -t ETHERNET -w USRP -c --eNB - - - - Initialize_eNB - Initialize RRU (TDD/Band40) - -O ci-scripts/conf_files/rru.tdd.band40.conf - 0 - - - - Initialize_eNB - Initialize RCC (TDD/Band40/5MHz) - -O ci-scripts/conf_files/rcc.band40.tm1.25PRB.FairScheduler.usrpb210.conf - 1 - - - - Initialize_eNB - Initialize RRU (TDD/Band40) - -O ci-scripts/conf_files/rru.tdd.band40.conf - 0 - - - - Initialize_eNB - Initialize RCC (TDD/Band40/10MHz/info) - -O ci-scripts/conf_files/rcc.band40.tm1.50PRB.FairScheduler.usrpb210.conf - 1 - - - - Initialize_eNB - Initialize RRU (TDD/Band40) - -O ci-scripts/conf_files/rru.tdd.band40.conf - 0 - - - - Initialize_eNB - Initialize RCC (TDD/Band40/20MHz/info) - -O ci-scripts/conf_files/rcc.band40.tm1.100PRB.FairScheduler.usrpb210.conf - 1 - - - - Terminate_eNB - Terminate RCC - 1 - - - - Terminate_eNB - Terminate RRU - 0 - - - - Initialize_UE - Initialize UE - - - - Terminate_UE - Terminate UE - - - - Attach_UE - Attach UE - - - - Detach_UE - Detach UE - - - - Ping - ping (5MHz - 20 sec) - -c 20 - 25 - - - - Ping - ping (10MHz - 20 sec) - -c 20 - 25 - - - - Ping - ping (20MHz - 20 sec) - -c 20 - 25 - - - - Iperf - iperf (5MHz - DL/6.5Mbps/UDP)(30 sec)(single-ue) - -u -b 6.5M -t 30 -i 1 - 50 - single-ue - - - - Iperf - iperf (10MHz - DL/13.5Mbps/UDP)(30 sec)(single-ue) - -u -b 13.5M -t 30 -i 1 - 50 - single-ue - - - - Iperf - iperf (20MHz - DL/13.5Mbps/UDP)(30 sec)(single-ue) - -u -b 13.5M -t 30 -i 1 - 50 - single-ue - - - - Iperf - iperf (5MHz - UL/2Mbps/UDP)(30 sec)(single-ue) - -u -b 2M -t 30 -i 1 -R - 50 - single-ue - - - - Iperf - iperf (10MHz - UL/2Mbps/UDP)(30 sec)(single-ue) - -u -b 2M -t 30 -i 1 -R - 50 - single-ue - - - - Iperf - iperf (20MHz - UL/2Mbps/UDP)(30 sec)(single-ue) - -u -b 2M -t 30 -i 1 -R - 50 - single-ue - - - - Initialize_HSS - Initialize HSS - - - - Initialize_MME - Initialize MME - - - - Initialize_SPGW - Initialize SPGW - - - - Terminate_HSS - Terminate HSS - - - - Terminate_MME - Terminate MME - - - - Terminate_SPGW - Terminate SPGW - - - diff --git a/ci-scripts/xml_files/if4p5_usrp210_band40_build.xml b/ci-scripts/xml_files/if4p5_usrp210_band40_build.xml new file mode 100644 index 0000000000..5bb7db5299 --- /dev/null +++ b/ci-scripts/xml_files/if4p5_usrp210_band40_build.xml @@ -0,0 +1,55 @@ + + + build-tab + Build + wrench + + 010101 + 050101 060101 070101 + + + + + + Build_eNB + Build eNB (USRP -- Ethernet Fronthaul) + -t ETHERNET -w USRP -c --eNB + + + + Initialize_HSS + Initialize HSS + + + + Initialize_MME + Initialize MME + + + + Initialize_SPGW + Initialize SPGW + + + diff --git a/ci-scripts/xml_files/if4p5_usrp210_band40_epc_closure.xml b/ci-scripts/xml_files/if4p5_usrp210_band40_epc_closure.xml new file mode 100644 index 0000000000..c04a8b3cf4 --- /dev/null +++ b/ci-scripts/xml_files/if4p5_usrp210_band40_epc_closure.xml @@ -0,0 +1,48 @@ + + + epc-closure + EPC-Closure + log-out + + 050201 060201 070201 + + + + + + Terminate_HSS + Terminate HSS + + + + Terminate_MME + Terminate MME + + + + Terminate_SPGW + Terminate SPGW + + + diff --git a/ci-scripts/xml_files/if4p5_usrp210_band40_test_05mhz.xml b/ci-scripts/xml_files/if4p5_usrp210_band40_test_05mhz.xml new file mode 100644 index 0000000000..1de23d05d6 --- /dev/null +++ b/ci-scripts/xml_files/if4p5_usrp210_band40_test_05mhz.xml @@ -0,0 +1,103 @@ + + + test-05 + Test-05MHz + tasks + + 040101 + 030104 030105 040301 040501 040602 040642 040401 040201 030201 030202 + + + + + + Initialize_eNB + Initialize RRU (TDD/Band40) + -O ci-scripts/conf_files/rru.tdd.band40.conf + 0 + + + + Initialize_eNB + Initialize RCC (TDD/Band40/5MHz) + -O ci-scripts/conf_files/rcc.band40.tm1.25PRB.FairScheduler.usrpb210.conf + 1 + + + + Terminate_eNB + Terminate RCC + 1 + + + + Terminate_eNB + Terminate RRU + 0 + + + + Initialize_UE + Initialize UE + + + + Terminate_UE + Terminate UE + + + + Attach_UE + Attach UE + + + + Detach_UE + Detach UE + + + + Ping + ping (5MHz - 20 sec) + -c 20 + 25 + + + + Iperf + iperf (5MHz - DL/6.5Mbps/UDP)(30 sec)(single-ue) + -u -b 6.5M -t 30 -i 1 + 50 + single-ue + + + + Iperf + iperf (5MHz - UL/2Mbps/UDP)(30 sec)(single-ue) + -u -b 2M -t 30 -i 1 -R + 50 + single-ue + + + diff --git a/ci-scripts/xml_files/if4p5_usrp210_band40_test_10mhz.xml b/ci-scripts/xml_files/if4p5_usrp210_band40_test_10mhz.xml new file mode 100644 index 0000000000..6bc37db17a --- /dev/null +++ b/ci-scripts/xml_files/if4p5_usrp210_band40_test_10mhz.xml @@ -0,0 +1,103 @@ + + + test-10 + Test-10MHz + tasks + + 040101 + 030114 030115 040301 040511 040612 040652 040401 040201 030201 030202 + + + + + + Initialize_eNB + Initialize RRU (TDD/Band40) + -O ci-scripts/conf_files/rru.tdd.band40.conf + 0 + + + + Initialize_eNB + Initialize RCC (TDD/Band40/10MHz/info) + -O ci-scripts/conf_files/rcc.band40.tm1.50PRB.FairScheduler.usrpb210.conf + 1 + + + + Terminate_eNB + Terminate RCC + 1 + + + + Terminate_eNB + Terminate RRU + 0 + + + + Initialize_UE + Initialize UE + + + + Terminate_UE + Terminate UE + + + + Attach_UE + Attach UE + + + + Detach_UE + Detach UE + + + + Ping + ping (10MHz - 20 sec) + -c 20 + 25 + + + + Iperf + iperf (10MHz - DL/13.5Mbps/UDP)(30 sec)(single-ue) + -u -b 13.5M -t 30 -i 1 + 50 + single-ue + + + + Iperf + iperf (10MHz - UL/2Mbps/UDP)(30 sec)(single-ue) + -u -b 2M -t 30 -i 1 -R + 50 + single-ue + + + diff --git a/ci-scripts/xml_files/if4p5_usrp210_band40_test_20mhz.xml b/ci-scripts/xml_files/if4p5_usrp210_band40_test_20mhz.xml new file mode 100644 index 0000000000..512c958105 --- /dev/null +++ b/ci-scripts/xml_files/if4p5_usrp210_band40_test_20mhz.xml @@ -0,0 +1,103 @@ + + + test-20 + Test-20MHz + tasks + + 040101 + 030124 030125 040301 040521 040622 040662 040401 040201 030201 030202 + + + + + + Initialize_eNB + Initialize RRU (TDD/Band40) + -O ci-scripts/conf_files/rru.tdd.band40.conf + 0 + + + + Initialize_eNB + Initialize RCC (TDD/Band40/20MHz/info) + -O ci-scripts/conf_files/rcc.band40.tm1.100PRB.FairScheduler.usrpb210.conf + 1 + + + + Terminate_eNB + Terminate RCC + 1 + + + + Terminate_eNB + Terminate RRU + 0 + + + + Initialize_UE + Initialize UE + + + + Terminate_UE + Terminate UE + + + + Attach_UE + Attach UE + + + + Detach_UE + Detach UE + + + + Ping + ping (20MHz - 20 sec) + -c 20 + 25 + + + + Iperf + iperf (20MHz - DL/13.5Mbps/UDP)(30 sec)(single-ue) + -u -b 13.5M -t 30 -i 1 + 50 + single-ue + + + + Iperf + iperf (20MHz - UL/2Mbps/UDP)(30 sec)(single-ue) + -u -b 2M -t 30 -i 1 -R + 50 + single-ue + + + diff --git a/ci-scripts/xml_files/if4p5_usrp210_band7_build.xml b/ci-scripts/xml_files/if4p5_usrp210_band7_build.xml index d4714b0de2..a0be9253db 100644 --- a/ci-scripts/xml_files/if4p5_usrp210_band7_build.xml +++ b/ci-scripts/xml_files/if4p5_usrp210_band7_build.xml @@ -21,9 +21,9 @@ --> - build-tab - Build - wrench + build-tab + Build + wrench 010101 050101 060101 070101 040101 diff --git a/ci-scripts/xml_files/if4p5_usrp210_band7_epc_closure.xml b/ci-scripts/xml_files/if4p5_usrp210_band7_epc_closure.xml index cde3581afa..8587db959d 100644 --- a/ci-scripts/xml_files/if4p5_usrp210_band7_epc_closure.xml +++ b/ci-scripts/xml_files/if4p5_usrp210_band7_epc_closure.xml @@ -21,9 +21,9 @@ --> - epc-closure - EPC-Closure - log-out + epc-closure + EPC-Closure + log-out 050201 060201 070201 diff --git a/ci-scripts/xml_files/if4p5_usrp210_band7_test_05mhz.xml b/ci-scripts/xml_files/if4p5_usrp210_band7_test_05mhz.xml index fb6642dd0f..b0501e9875 100644 --- a/ci-scripts/xml_files/if4p5_usrp210_band7_test_05mhz.xml +++ b/ci-scripts/xml_files/if4p5_usrp210_band7_test_05mhz.xml @@ -21,10 +21,11 @@ --> - test-05 - Test-05MHz - tasks + test-05 + Test-05MHz + tasks + 040101 030101 030102 040301 040501 040604 040642 040401 040201 030201 030202 diff --git a/ci-scripts/xml_files/if4p5_usrp210_band7_test_10mhz.xml b/ci-scripts/xml_files/if4p5_usrp210_band7_test_10mhz.xml index e3cf3ae41a..340d33196a 100644 --- a/ci-scripts/xml_files/if4p5_usrp210_band7_test_10mhz.xml +++ b/ci-scripts/xml_files/if4p5_usrp210_band7_test_10mhz.xml @@ -21,10 +21,11 @@ --> - test-10 - Test-10MHz - tasks + test-10 + Test-10MHz + tasks + 040101 030111 030112 040301 040511 040614 040652 040401 040201 030201 030202 diff --git a/ci-scripts/xml_files/if4p5_usrp210_band7_test_20mhz.xml b/ci-scripts/xml_files/if4p5_usrp210_band7_test_20mhz.xml index 8e54c90c44..5d8646cd5e 100644 --- a/ci-scripts/xml_files/if4p5_usrp210_band7_test_20mhz.xml +++ b/ci-scripts/xml_files/if4p5_usrp210_band7_test_20mhz.xml @@ -21,10 +21,11 @@ --> - test-20 - Test-20MHz - tasks + test-20 + Test-20MHz + tasks + 040101 030121 030122 040301 040521 040624 040662 040401 040201 030201 030202 From 6c41b6d77a60b30a14869d254a22a22ce3a8dff7 Mon Sep 17 00:00:00 2001 From: rdoost Date: Mon, 17 Dec 2018 20:24:14 -0600 Subject: [PATCH 201/233] parametrized gains --- targets/ARCH/IRIS/USERSPACE/LIB/iris_lib.cpp | 121 ++++---- .../CONF/enb.band42.tm1.25PRB.iris030.conf | 264 ++++++++++++++++++ 2 files changed, 327 insertions(+), 58 deletions(-) create mode 100644 targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band42.tm1.25PRB.iris030.conf diff --git a/targets/ARCH/IRIS/USERSPACE/LIB/iris_lib.cpp b/targets/ARCH/IRIS/USERSPACE/LIB/iris_lib.cpp index 3133742cd4..7abdf65498 100644 --- a/targets/ARCH/IRIS/USERSPACE/LIB/iris_lib.cpp +++ b/targets/ARCH/IRIS/USERSPACE/LIB/iris_lib.cpp @@ -1,7 +1,8 @@ /** iris_lib.cpp * - * \author: Rahman Doost-Mohammady : doost@rice.edu + * \authors: Rahman Doost-Mohammady : doost@rice.edu + * Clay Shepard : cws@rice.edu */ #include @@ -30,6 +31,7 @@ # include #endif +#define MOVE_DC #define SAMPLE_RATE_DOWN 1 /*! \brief Iris Configuration */ @@ -595,7 +597,8 @@ int device_init(openair0_device *device, openair0_config_t *openair0_cfg) { } for (r = 0; r < s->device_num; r++) { - switch ((int) openair0_cfg[0].sample_rate) { + //this is unnecessary -- it will set the correct master clock based on sample rate + /*switch ((int) openair0_cfg[0].sample_rate) { case 1920000: s->iris[r]->setMasterClockRate(256 * openair0_cfg[0].sample_rate); break; @@ -615,54 +618,34 @@ int device_init(openair0_device *device, openair0_config_t *openair0_cfg) { printf("Error: unknown sampling rate %f\n", openair0_cfg[0].sample_rate); exit(-1); break; - } - // display Iris settings - printf("Actual master clock: %fMHz...\n", (s->iris[r]->getMasterClockRate() / 1e6)); - - /* Setting TX/RX BW after streamers are created due to iris calibration issue */ - for (i = 0; i < s->tx_num_channels; i++) { - if (i < s->iris[r]->getNumChannels(SOAPY_SDR_TX)) { - if (s->iris[r]->getHardwareInfo()["frontend"].compare(devFE) != 0) - s->iris[r]->setBandwidth(SOAPY_SDR_TX, i, 30e6); - else - s->iris[r]->setBandwidth(SOAPY_SDR_TX, i, openair0_cfg[0].tx_bw); - - printf("Setting tx bandwidth on channel %lu/%lu: BW %f (readback %f)\n", i, - s->iris[r]->getNumChannels(SOAPY_SDR_TX), openair0_cfg[0].tx_bw / 1e6, - s->iris[r]->getBandwidth(SOAPY_SDR_TX, i) / 1e6); - } - } - for (i = 0; i < s->rx_num_channels; i++) { - if (i < s->iris[r]->getNumChannels(SOAPY_SDR_RX)) { - if (s->iris[r]->getHardwareInfo()["frontend"].compare(devFE) != 0) - s->iris[r]->setBandwidth(SOAPY_SDR_TX, i, 30e6); - else - s->iris[r]->setBandwidth(SOAPY_SDR_RX, i, openair0_cfg[0].rx_bw); - printf("Setting rx bandwidth on channel %lu/%lu : BW %f (readback %f)\n", i, - s->iris[r]->getNumChannels(SOAPY_SDR_RX), openair0_cfg[0].rx_bw / 1e6, - s->iris[r]->getBandwidth(SOAPY_SDR_RX, i) / 1e6); - } - } + }*/ for (i = 0; i < s->iris[r]->getNumChannels(SOAPY_SDR_RX); i++) { if (i < s->rx_num_channels) { s->iris[r]->setSampleRate(SOAPY_SDR_RX, i, openair0_cfg[0].sample_rate / SAMPLE_RATE_DOWN); +#ifdef MOVE_DC + printf("Moving DC out of main carrier for rx...\n"); + s->iris[r]->setFrequency(SOAPY_SDR_RX, i, "RF", openair0_cfg[0].rx_freq[i]-.75*openair0_cfg[0].sample_rate); + s->iris[r]->setFrequency(SOAPY_SDR_RX, i, "BB", .75*openair0_cfg[0].sample_rate); +#else s->iris[r]->setFrequency(SOAPY_SDR_RX, i, "RF", openair0_cfg[0].rx_freq[i]); +#endif set_rx_gain_offset(&openair0_cfg[0], i, bw_gain_adjust); //s->iris[r]->setGain(SOAPY_SDR_RX, i, openair0_cfg[0].rx_gain[i] - openair0_cfg[0].rx_gain_offset[i]); + printf("rx gain offset: %f, rx_gain: %f, tx_tgain: %f\n", openair0_cfg[0].rx_gain_offset[i], openair0_cfg[0].rx_gain[i], openair0_cfg[0].tx_gain[i]); if (s->iris[r]->getHardwareInfo()["frontend"].compare(devFE) != 0) { s->iris[r]->setGain(SOAPY_SDR_RX, i, "LNA", openair0_cfg[0].rx_gain[i] - openair0_cfg[0].rx_gain_offset[i]); //s->iris[r]->setGain(SOAPY_SDR_RX, i, "LNA", 0); s->iris[r]->setGain(SOAPY_SDR_RX, i, "LNA1", 30); s->iris[r]->setGain(SOAPY_SDR_RX, i, "LNA2", 17); - s->iris[r]->setGain(SOAPY_SDR_RX, i, "TIA", 0); - s->iris[r]->setGain(SOAPY_SDR_RX, i, "PGA", 0); + s->iris[r]->setGain(SOAPY_SDR_RX, i, "TIA", 7); + s->iris[r]->setGain(SOAPY_SDR_RX, i, "PGA", 18); s->iris[r]->setGain(SOAPY_SDR_RX, i, "ATTN", 0); } else { s->iris[r]->setGain(SOAPY_SDR_RX, i, "LNA", openair0_cfg[0].rx_gain[i] - openair0_cfg[0].rx_gain_offset[i]); // [0,30] - s->iris[r]->setGain(SOAPY_SDR_RX, i, "TIA", 0); // [0,12,6] - s->iris[r]->setGain(SOAPY_SDR_RX, i, "PGA", 0); // [-12,19,1] + s->iris[r]->setGain(SOAPY_SDR_RX, i, "TIA", 7); // [0,12,6] + s->iris[r]->setGain(SOAPY_SDR_RX, i, "PGA", 18); // [-12,19,1] //s->iris[r]->setGain(SOAPY_SDR_RX, i, 50); // [-12,19,1] } @@ -673,22 +656,29 @@ int device_init(openair0_device *device, openair0_config_t *openair0_cfg) { for (i = 0; i < s->iris[r]->getNumChannels(SOAPY_SDR_TX); i++) { if (i < s->tx_num_channels) { s->iris[r]->setSampleRate(SOAPY_SDR_TX, i, openair0_cfg[0].sample_rate / SAMPLE_RATE_DOWN); +#ifdef MOVE_DC + printf("Moving DC out of main carrier for tx...\n"); + s->iris[r]->setFrequency(SOAPY_SDR_TX, i, "RF", openair0_cfg[0].tx_freq[i]-.75*openair0_cfg[0].sample_rate); + s->iris[r]->setFrequency(SOAPY_SDR_TX, i, "BB", .75*openair0_cfg[0].sample_rate); +#else s->iris[r]->setFrequency(SOAPY_SDR_TX, i, "RF", openair0_cfg[0].tx_freq[i]); +#endif if (s->iris[r]->getHardwareInfo()["frontend"].compare(devFE) == 0) { - //s->iris[r]->setGain(SOAPY_SDR_TX, i, "PAD", openair0_cfg[0].tx_gain[i]); - s->iris[r]->setGain(SOAPY_SDR_TX, i, "PAD", 52); + s->iris[r]->setGain(SOAPY_SDR_TX, i, "PAD", openair0_cfg[0].tx_gain[i]); + //s->iris[r]->setGain(SOAPY_SDR_TX, i, "PAD", 50); s->iris[r]->setGain(SOAPY_SDR_TX, i, "IAMP", 12); //s->iris[r]->writeSetting("TX_ENABLE_DELAY", "0"); //s->iris[r]->writeSetting("TX_DISABLE_DELAY", "100"); } else { + s->iris[r]->setGain(SOAPY_SDR_TX, i, "PAD", openair0_cfg[0].tx_gain[i]); s->iris[r]->setGain(SOAPY_SDR_TX, i, "ATTN", 0); // [-18, 0, 6] dB - s->iris[r]->setGain(SOAPY_SDR_TX, i, "IAMP", 9); // [-12, 12, 1] dB - s->iris[r]->setGain(SOAPY_SDR_TX, i, "PAD", 52); //openair0_cfg[0].tx_gain[i]); + s->iris[r]->setGain(SOAPY_SDR_TX, i, "IAMP", 6); // [-12, 12, 1] dB + //s->iris[r]->setGain(SOAPY_SDR_TX, i, "PAD", 44); //openair0_cfg[0].tx_gain[i]); //s->iris[r]->setGain(SOAPY_SDR_TX, i, "PAD", 35); // [0, 52, 1] dB - s->iris[r]->setGain(SOAPY_SDR_TX, i, "PA1", 9); // 17 ??? dB + //s->iris[r]->setGain(SOAPY_SDR_TX, i, "PA1", 17); // 17 ??? dB s->iris[r]->setGain(SOAPY_SDR_TX, i, "PA2", 0); // [0, 17, 17] dB - s->iris[r]->setGain(SOAPY_SDR_TX, i, "PA3", 20); // 33 ??? dB + //s->iris[r]->setGain(SOAPY_SDR_TX, i, "PA3", 20); // 33 ??? dB s->iris[r]->writeSetting("TX_ENABLE_DELAY", "0"); s->iris[r]->writeSetting("TX_DISABLE_DELAY", "100"); } @@ -702,32 +692,47 @@ int device_init(openair0_device *device, openair0_config_t *openair0_cfg) { } - for (i = 0; i < s->iris[r]->getNumChannels(SOAPY_SDR_RX); i++) { - if (i < s->rx_num_channels) { + + printf("Actual master clock: %fMHz...\n", (s->iris[r]->getMasterClockRate() / 1e6)); - //if (s->iris[r]->getHardwareInfo()["frontend"].compare(devFE) != 0) { - // printf("\nUsing SKLK calibration...\n"); - // s->iris[r]->writeSetting(SOAPY_SDR_RX, i, "CALIBRATE", "SKLK"); - //} else { - // s->iris[r]->writeSetting(SOAPY_SDR_RX, i, "CALIBRATE", ""); - // printf("\nUsing LMS calibration...\n"); - - //} + int tx_filt_bw = openair0_cfg[0].tx_bw; + int rx_filt_bw = openair0_cfg[0].rx_bw; +#ifdef MOVE_DC //the filter is centered around the carrier, so we have to expand it if we have moved the DC tone. + tx_filt_bw *= 3; + rx_filt_bw *= 3; +#endif + /* Setting TX/RX BW */ + for (i = 0; i < s->tx_num_channels; i++) { + if (i < s->iris[r]->getNumChannels(SOAPY_SDR_TX)) { + s->iris[r]->setBandwidth(SOAPY_SDR_TX, i, tx_filt_bw); + printf("Setting tx bandwidth on channel %lu/%lu: BW %f (readback %f)\n", i, + s->iris[r]->getNumChannels(SOAPY_SDR_TX), tx_filt_bw / 1e6, + s->iris[r]->getBandwidth(SOAPY_SDR_TX, i) / 1e6); + } + } + for (i = 0; i < s->rx_num_channels; i++) { + if (i < s->iris[r]->getNumChannels(SOAPY_SDR_RX)) { + s->iris[r]->setBandwidth(SOAPY_SDR_RX, i, rx_filt_bw); + printf("Setting rx bandwidth on channel %lu/%lu : BW %f (readback %f)\n", i, + s->iris[r]->getNumChannels(SOAPY_SDR_RX), rx_filt_bw / 1e6, + s->iris[r]->getBandwidth(SOAPY_SDR_RX, i) / 1e6); } - } for (i = 0; i < s->iris[r]->getNumChannels(SOAPY_SDR_TX); i++) { if (i < s->tx_num_channels) { + printf("\nUsing SKLK calibration...\n"); + s->iris[r]->writeSetting(SOAPY_SDR_TX, i, "CALIBRATE", "SKLK"); - if (s->iris[r]->getHardwareInfo()["frontend"].compare(devFE) != 0) { - printf("\nUsing SKLK calibration...\n"); - s->iris[r]->writeSetting(SOAPY_SDR_TX, i, "CALIBRATE", "SKLK"); + } + + } + + for (i = 0; i < s->iris[r]->getNumChannels(SOAPY_SDR_RX); i++) { + if (i < s->rx_num_channels) { + printf("\nUsing SKLK calibration...\n"); + s->iris[r]->writeSetting(SOAPY_SDR_RX, i, "CALIBRATE", "SKLK"); - } else { - printf("\nUsing LMS calibration...\n"); - s->iris[r]->writeSetting(SOAPY_SDR_TX, i, "CALIBRATE", ""); - } } } diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band42.tm1.25PRB.iris030.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band42.tm1.25PRB.iris030.conf new file mode 100644 index 0000000000..764d7886e2 --- /dev/null +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band42.tm1.25PRB.iris030.conf @@ -0,0 +1,264 @@ +Active_eNBs = ( "eNB_Eurecom_LTEBox"); +# Asn1_verbosity, choice in: none, info, annoying +Asn1_verbosity = "none"; + +eNBs = +( + { + ////////// Identification parameters: + eNB_ID = 0xe00; + + cell_type = "CELL_MACRO_ENB"; + + eNB_name = "eNB_Eurecom_LTEBox"; + + // Tracking area code, 0x0000 and 0xfffe are reserved values + tracking_area_code = 1; + + plmn_list = ( { mcc = 208; mnc = 92; mnc_length = 2; } ); + + tr_s_preference = "local_mac" + + ////////// Physical parameters: + + component_carriers = ( + { + node_function = "eNodeB_3GPP"; + node_timing = "synch_to_ext_device"; + node_synch_ref = 0; + frame_type = "TDD"; + tdd_config = 1; + tdd_config_s = 0; + prefix_type = "NORMAL"; + eutra_band = 42; + downlink_frequency = 3500000000L; + uplink_frequency_offset = 0; + Nid_cell = 10; + N_RB_DL = 25; + Nid_cell_mbsfn = 0; + nb_antenna_ports = 1; + nb_antennas_tx = 1; + nb_antennas_rx = 1; + tx_gain = 48; # [~50 for DEV-FE, ~30 for CBRS-FE] + rx_gain = 80; # [115 for DEV-FE, 90 for CBRS-FE] + pbch_repetition = "FALSE"; + prach_root = 0; + prach_config_index = 0; + prach_high_speed = "DISABLE"; + prach_zero_correlation = 1; + prach_freq_offset = 2; + pucch_delta_shift = 1; + pucch_nRB_CQI = 1; + pucch_nCS_AN = 0; + pucch_n1_AN = 32; + pdsch_referenceSignalPower = -30; + pdsch_p_b = 0; + pusch_n_SB = 1; + pusch_enable64QAM = "DISABLE"; + pusch_hoppingMode = "interSubFrame"; + pusch_hoppingOffset = 0; + pusch_groupHoppingEnabled = "ENABLE"; + pusch_groupAssignment = 0; + pusch_sequenceHoppingEnabled = "DISABLE"; + pusch_nDMRS1 = 1; + phich_duration = "NORMAL"; + phich_resource = "ONESIXTH"; + srs_enable = "DISABLE"; + /* srs_BandwidthConfig =; + srs_SubframeConfig =; + srs_ackNackST =; + srs_MaxUpPts =;*/ + + pusch_p0_Nominal = -70; + pusch_alpha = "AL1"; + pucch_p0_Nominal = -96; + msg3_delta_Preamble = 6; + pucch_deltaF_Format1 = "deltaF2"; + pucch_deltaF_Format1b = "deltaF3"; + pucch_deltaF_Format2 = "deltaF0"; + pucch_deltaF_Format2a = "deltaF0"; + pucch_deltaF_Format2b = "deltaF0"; + + rach_numberOfRA_Preambles = 64; + rach_preamblesGroupAConfig = "DISABLE"; + /* + rach_sizeOfRA_PreamblesGroupA = ; + rach_messageSizeGroupA = ; + rach_messagePowerOffsetGroupB = ; + */ + rach_powerRampingStep = 4; + rach_preambleInitialReceivedTargetPower = -96; + rach_preambleTransMax = 10; + rach_raResponseWindowSize = 10; + rach_macContentionResolutionTimer = 48; + rach_maxHARQ_Msg3Tx = 4; + + pcch_default_PagingCycle = 128; + pcch_nB = "oneT"; + bcch_modificationPeriodCoeff = 2; + ue_TimersAndConstants_t300 = 1000; + ue_TimersAndConstants_t301 = 1000; + ue_TimersAndConstants_t310 = 1000; + ue_TimersAndConstants_t311 = 10000; + ue_TimersAndConstants_n310 = 20; + ue_TimersAndConstants_n311 = 1; + ue_TransmissionMode = 1; + + //Parameters for SIB18 + rxPool_sc_CP_Len = "normal"; + rxPool_sc_Period = "sf40"; + rxPool_data_CP_Len = "normal"; + rxPool_ResourceConfig_prb_Num = 20; + rxPool_ResourceConfig_prb_Start = 5; + rxPool_ResourceConfig_prb_End = 44; + rxPool_ResourceConfig_offsetIndicator_present = "prSmall"; + rxPool_ResourceConfig_offsetIndicator_choice = 0; + rxPool_ResourceConfig_subframeBitmap_present = "prBs40"; + rxPool_ResourceConfig_subframeBitmap_choice_bs_buf = "00000000000000000000"; + rxPool_ResourceConfig_subframeBitmap_choice_bs_size = 5; + rxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused = 0; +/* rxPool_dataHoppingConfig_hoppingParameter = 0; + rxPool_dataHoppingConfig_numSubbands = "ns1"; + rxPool_dataHoppingConfig_rbOffset = 0; + rxPool_commTxResourceUC-ReqAllowed = "TRUE"; +*/ + // Parameters for SIB19 + discRxPool_cp_Len = "normal" + discRxPool_discPeriod = "rf32" + discRxPool_numRetx = 1; + discRxPool_numRepetition = 2; + discRxPool_ResourceConfig_prb_Num = 5; + discRxPool_ResourceConfig_prb_Start = 3; + discRxPool_ResourceConfig_prb_End = 21; + discRxPool_ResourceConfig_offsetIndicator_present = "prSmall"; + discRxPool_ResourceConfig_offsetIndicator_choice = 0; + discRxPool_ResourceConfig_subframeBitmap_present = "prBs40"; + discRxPool_ResourceConfig_subframeBitmap_choice_bs_buf = "f0ffffffff"; + discRxPool_ResourceConfig_subframeBitmap_choice_bs_size = 5; + discRxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused = 0; + + } + ); + + srb1_parameters : + { + # timer_poll_retransmit = (ms) [5, 10, 15, 20,... 250, 300, 350, ... 500] + timer_poll_retransmit = 80; + + # timer_reordering = (ms) [0,5, ... 100, 110, 120, ... ,200] + timer_reordering = 35; + + # timer_reordering = (ms) [0,5, ... 250, 300, 350, ... ,500] + timer_status_prohibit = 0; + + # poll_pdu = [4, 8, 16, 32 , 64, 128, 256, infinity(>10000)] + poll_pdu = 4; + + # poll_byte = (kB) [25,50,75,100,125,250,375,500,750,1000,1250,1500,2000,3000,infinity(>10000)] + poll_byte = 99999; + + # max_retx_threshold = [1, 2, 3, 4 , 6, 8, 16, 32] + max_retx_threshold = 4; + } + + # ------- SCTP definitions + SCTP : + { + # Number of streams to use in input/output + SCTP_INSTREAMS = 2; + SCTP_OUTSTREAMS = 2; + }; + + + ////////// MME parameters: + mme_ip_address = ( { ipv4 = "127.0.0.20"; + ipv6 = "fe80::d65d:dfff:fe1d:f4d4"; + active = "yes"; + preference = "ipv4"; + } + ); + + NETWORK_INTERFACES : + { + ENB_INTERFACE_NAME_FOR_S1_MME = "eno1"; + ENB_IPV4_ADDRESS_FOR_S1_MME = "127.0.0.10/8"; + ENB_INTERFACE_NAME_FOR_S1U = "enp5s0"; + ENB_IPV4_ADDRESS_FOR_S1U = "127.0.0.10/8"; + ENB_PORT_FOR_S1U = 2152; # Spec 2152 + + ENB_IPV4_ADDRESS_FOR_X2C = "127.0.0.10/8"; + ENB_PORT_FOR_X2C = 36422; # Spec 36422 + }; + } +); + +MACRLCs = ( + { + num_cc = 1; + tr_s_preference = "local_L1"; + tr_n_preference = "local_RRC"; + phy_test_mode = 0; + puSch10xSnr = 200; + puCch10xSnr = 200; + } +); + +L1s = ( + { + num_cc = 1; + tr_n_preference = "local_mac"; + } +); + +RUs = ( + { + local_rf = "yes" + nb_tx = 1; + nb_rx = 1; + att_tx = 44; #apparently this is being used as tx_gain... + att_rx = 0; #apparently max_rxgain - att_rx -83 is what is used for rx_gain (at least for 5 MHz) + bands = [7]; + max_pdschReferenceSignalPower = -27; + max_rxgain = 107; + eNB_instances = [0]; + #sdr_addrs = "RF3E000025"; + } +); + +NETWORK_CONTROLLER : +{ + FLEXRAN_ENABLED = "no"; + FLEXRAN_INTERFACE_NAME = "lo"; + FLEXRAN_IPV4_ADDRESS = "127.0.0.1"; + FLEXRAN_PORT = 2210; + FLEXRAN_CACHE = "/mnt/oai_agent_cache"; + FLEXRAN_AWAIT_RECONF = "no"; +}; + +THREAD_STRUCT = ( + { + #three config for level of parallelism "PARALLEL_SINGLE_THREAD", "PARALLEL_RU_L1_SPLIT", or "PARALLEL_RU_L1_TRX_SPLIT" + parallel_config = "PARALLEL_RU_L1_TRX_SPLIT"; + #two option for worker "WORKER_DISABLE" or "WORKER_ENABLE" + worker_config = "WORKER_ENABLE"; + } +); + + log_config : + { + global_log_level ="info"; + global_log_verbosity ="medium"; + hw_log_level ="info"; + hw_log_verbosity ="medium"; + phy_log_level ="info"; + phy_log_verbosity ="medium"; + mac_log_level ="info"; + mac_log_verbosity ="high"; + rlc_log_level ="info"; + rlc_log_verbosity ="medium"; + pdcp_log_level ="info"; + pdcp_log_verbosity ="medium"; + rrc_log_level ="info"; + rrc_log_verbosity ="medium"; + }; + From 77f2879620af01d6e1302f6aec20c41b849e3693 Mon Sep 17 00:00:00 2001 From: Raphael Defosseux Date: Wed, 19 Dec 2018 10:10:33 +0100 Subject: [PATCH 202/233] CI: typo in report build script Signed-off-by: Raphael Defosseux --- ci-scripts/reportBuildLocally.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ci-scripts/reportBuildLocally.sh b/ci-scripts/reportBuildLocally.sh index 6526096d12..bfce7acd8f 100755 --- a/ci-scripts/reportBuildLocally.sh +++ b/ci-scripts/reportBuildLocally.sh @@ -310,6 +310,7 @@ function report_build { echo "############################################################" echo "JENKINS_WKSP = $JENKINS_WKSP" + echo "GIT_URL = $GIT_URL" cd ${JENKINS_WKSP} echo "" > ./build_results.html @@ -345,7 +346,7 @@ function report_build { echo " " >> ./build_results.html echo " " >> ./build_results.html echo " " >> ./build_results.html - echo " " >> ./test_simulator_results.html + echo " " >> ./build_results.html echo " " >> ./build_results.html echo " " >> ./build_results.html echo " " >> ./build_results.html From 3b915b37ff0ec85d30f9b3017ae6c4e97e3a0d6d Mon Sep 17 00:00:00 2001 From: Raphael Defosseux Date: Wed, 19 Dec 2018 16:05:09 +0100 Subject: [PATCH 203/233] Downgrading log message to DEBUG for better RT Signed-off-by: Raphael Defosseux --- targets/RT/USER/lte-ru.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/targets/RT/USER/lte-ru.c b/targets/RT/USER/lte-ru.c index dcad2ece7c..7df0a8c623 100644 --- a/targets/RT/USER/lte-ru.c +++ b/targets/RT/USER/lte-ru.c @@ -1554,8 +1554,8 @@ static void* ru_thread_tx( void* param ) { if (oai_exit) break; - LOG_I(PHY,"ru_thread_tx: Waiting for TX processing\n"); - // wait until eNBs are finished subframe RX n and TX n+4 + LOG_D(PHY,"ru_thread_tx: Waiting for TX processing\n"); + // wait until eNBs are finished subframe RX n and TX n+4 wait_on_condition(&proc->mutex_eNBs,&proc->cond_eNBs,&proc->instance_cnt_eNBs,"ru_thread_tx"); if (oai_exit) break; From c76bbd13f16cdff655981c51ef3574a33cc8f693 Mon Sep 17 00:00:00 2001 From: Rahman Doost Date: Wed, 19 Dec 2018 14:49:56 -0600 Subject: [PATCH 204/233] iris soapy0.7 support --- cmake_targets/CMakeLists.txt | 2 +- cmake_targets/tools/build_helper | 20 ++++++++++---------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt index 8e4d1afe3d..679a6596e0 100644 --- a/cmake_targets/CMakeLists.txt +++ b/cmake_targets/CMakeLists.txt @@ -557,7 +557,7 @@ set(HWLIB_IRIS_SOURCE ${OPENAIR_TARGETS}/ARCH/IRIS/USERSPACE/LIB/iris_lib.cpp ) add_library(oai_irisdevif MODULE ${HWLIB_IRIS_SOURCE}) -target_include_directories(oai_irisdevif PRIVATE /usr/local/lib/SoapySDR/modules0.6/) +target_include_directories(oai_irisdevif PRIVATE /usr/local/lib/SoapySDR/modules0.7/) target_link_libraries(oai_irisdevif SoapySDR) include_directories("${OPENAIR_TARGETS}/ARCH/mobipass/") diff --git a/cmake_targets/tools/build_helper b/cmake_targets/tools/build_helper index 658844531e..5189eca27d 100755 --- a/cmake_targets/tools/build_helper +++ b/cmake_targets/tools/build_helper @@ -386,8 +386,8 @@ install_soapy_from_source(){ cd /tmp echo "Downloading SoapySDR" rm -rf /tmp/soapysdr - git clone https://github.com/pothosware/SoapySDR.git - cd soapysdr + git clone -b soapy-sdr-0.7.0 --single-branch https://github.com/pothosware/SoapySDR.git + cd SoapySDR #git checkout tags/release_003_010_001_001 mkdir -p build cd build @@ -399,8 +399,8 @@ install_soapy_from_source(){ cd /tmp echo "Downloading SoapyRemote" rm -rf /tmp/soapyremote - git clone https://github.com/pothosware/SoapyRemote.git - cd soapyremote + git clone -b soapy-remote-0.5.0 --single-branch https://github.com/pothosware/SoapyRemote.git + cd SoapyRemote #git checkout tags/release_003_010_001_001 mkdir -p build cd build @@ -419,7 +419,7 @@ install_soapy_iris_from_source(){ cd /tmp echo "Downloading SoapyIris" rm -rf /tmp/sklk-soapyiris - git clone https://github.com/skylarkwireless/sklk-soapyiris.git + git clone -b soapy-iris-2018.08.0.1 --single-branch https://github.com/skylarkwireless/sklk-soapyiris.git cd sklk-soapyiris mkdir -p build cd build @@ -434,14 +434,14 @@ install_soapy_iris_from_source(){ check_install_soapy () { #if [[ "$OS_DISTRO" == "ubuntu" ]]; then #first we remove old installation - $SUDO apt-get remove -y soapysdr soapysdr-server libsoapysdr-dev python-soapysdr python3-soapysdr soapysdr-module-remote || true - $SUDO add-apt-repository -y ppa:myriadrf/drivers - $SUDO apt-get update - $SUDO apt-get install -y soapysdr soapysdr-server libsoapysdr-dev python-soapysdr python3-soapysdr soapysdr-module-remote + $SUDO apt-get remove -y soapysdr soapysdr-server libsoapysdr-dev python-soapysdr python3-soapysdr soapysdr-module-remote || true + #$SUDO add-apt-repository -y ppa:myriadrf/drivers + #$SUDO apt-get update + #$SUDO apt-get install -y soapysdr soapysdr-server libsoapysdr-dev python-soapysdr python3-soapysdr soapysdr-module-remote #elif [[ "$OS_BASEDISTRO" == "fedora" ]]; then # $SUDO $INSTALLER -y install software-properties-common python3-software-properties python-software-properties subversion git python3 python-numpy python3-numpy cmake swig python-dev - # install_soapy_from_source + install_soapy_from_source #fi install_soapy_iris_from_source From b3f1440249262eb1737a45e62f0ae0efa55976fb Mon Sep 17 00:00:00 2001 From: laurent Date: Sun, 23 Dec 2018 17:55:07 +0100 Subject: [PATCH 205/233] issue 384 --- cmake_targets/CMakeLists.txt | 2 - openair1/PHY/LTE_ESTIMATION/lte_adjust_sync.c | 142 ----- openair1/PHY/LTE_TRANSPORT/mcs_tbs_tools.h | 42 -- openair1/PHY/LTE_TRANSPORT/transport_proto.h | 8 - .../PHY/LTE_UE_TRANSPORT/transport_proto_ue.h | 2 - openair1/PHY/MODULATION/prach625Hz.h | 27 - openair1/PHY/Makefile.inc | 91 --- openair1/SCHED/Makefile.inc | 6 - openair2/COMMON/intertask_interface_conf.h | 42 -- openair2/COMMON/messages_types.h | 50 -- openair2/ENB_APP/Makefile.inc | 7 - openair2/LAYER2/MAC/lte_transport_init.c | 132 ---- openair2/LAYER2/Makefile.inc | 118 ---- openair2/LAYER2/RLC/UM_v9.3.0/Makefile | 49 -- openair2/LAYER2/register.h | 38 -- openair2/RRC/LTE/MESSAGES/Makefile.inc | 91 --- openair2/RRC/LTE/rrc_eNB.c | 3 - openair2/RRC/LTE/rrc_extern.h | 1 - openair2/RRC/NAS/Makefile.inc | 4 - openair2/UTIL/BIGPHYS/bigphys.c | 67 -- openair2/UTIL/BIGPHYS/defs.h | 22 - openair2/UTIL/Makefile.inc | 108 ---- openair2/UTIL/TIMER/umts_timer.c | 175 ------ openair2/UTIL/TIMER/umts_timer.h | 56 -- openair2/UTIL/TIMER/umts_timer_proto_extern.h | 44 -- openair2/UTIL/TIMER/umts_timer_struct.h | 46 -- openair2/X2AP/Makefile.inc | 107 ---- openair3/COMMON/as_message.h | 578 ------------------ openair3/COMMON/gtpv1_u_messages_def.h | 29 - openair3/COMMON/gtpv1_u_messages_types.h | 81 --- openair3/COMMON/messages_def.h | 36 -- openair3/COMMON/nas_messages_def.h | 63 -- openair3/COMMON/nas_messages_types.h | 329 ---------- openair3/COMMON/s1ap_messages_def.h | 42 -- openair3/COMMON/s1ap_messages_types.h | 91 --- openair3/COMMON/sctp_messages_def.h | 28 - openair3/COMMON/sctp_messages_types.h | 69 --- openair3/COMMON/tasks_def.h | 48 -- openair3/COMMON/udp_messages_def.h | 24 - openair3/COMMON/udp_messages_types.h | 47 -- openair3/SECU/key_nas_encryption.c | 69 --- targets/RT/USER/.ue.nvram | Bin 55 -> 0 bytes targets/RT/USER/.ue_emm.nvram | Bin 61 -> 0 bytes targets/RT/USER/.usim.nvram | Bin 616 -> 0 bytes 44 files changed, 3014 deletions(-) delete mode 100644 openair1/PHY/LTE_ESTIMATION/lte_adjust_sync.c delete mode 100644 openair1/PHY/LTE_TRANSPORT/mcs_tbs_tools.h delete mode 100644 openair1/PHY/MODULATION/prach625Hz.h delete mode 100644 openair1/PHY/Makefile.inc delete mode 100644 openair1/SCHED/Makefile.inc delete mode 100644 openair2/COMMON/intertask_interface_conf.h delete mode 100644 openair2/COMMON/messages_types.h delete mode 100644 openair2/ENB_APP/Makefile.inc delete mode 100644 openair2/LAYER2/MAC/lte_transport_init.c delete mode 100644 openair2/LAYER2/Makefile.inc delete mode 100644 openair2/LAYER2/RLC/UM_v9.3.0/Makefile delete mode 100644 openair2/LAYER2/register.h delete mode 100644 openair2/RRC/LTE/MESSAGES/Makefile.inc delete mode 100644 openair2/RRC/NAS/Makefile.inc delete mode 100644 openair2/UTIL/BIGPHYS/bigphys.c delete mode 100644 openair2/UTIL/BIGPHYS/defs.h delete mode 100644 openair2/UTIL/Makefile.inc delete mode 100644 openair2/UTIL/TIMER/umts_timer.c delete mode 100644 openair2/UTIL/TIMER/umts_timer.h delete mode 100644 openair2/UTIL/TIMER/umts_timer_proto_extern.h delete mode 100644 openair2/UTIL/TIMER/umts_timer_struct.h delete mode 100755 openair2/X2AP/Makefile.inc delete mode 100644 openair3/COMMON/as_message.h delete mode 100644 openair3/COMMON/gtpv1_u_messages_def.h delete mode 100644 openair3/COMMON/gtpv1_u_messages_types.h delete mode 100644 openair3/COMMON/messages_def.h delete mode 100644 openair3/COMMON/nas_messages_def.h delete mode 100644 openair3/COMMON/nas_messages_types.h delete mode 100644 openair3/COMMON/s1ap_messages_def.h delete mode 100644 openair3/COMMON/s1ap_messages_types.h delete mode 100644 openair3/COMMON/sctp_messages_def.h delete mode 100644 openair3/COMMON/sctp_messages_types.h delete mode 100644 openair3/COMMON/tasks_def.h delete mode 100644 openair3/COMMON/udp_messages_def.h delete mode 100644 openair3/COMMON/udp_messages_types.h delete mode 100644 openair3/SECU/key_nas_encryption.c delete mode 100644 targets/RT/USER/.ue.nvram delete mode 100644 targets/RT/USER/.ue_emm.nvram delete mode 100644 targets/RT/USER/.usim.nvram diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt index a110cca71a..efc11bcbae 100644 --- a/cmake_targets/CMakeLists.txt +++ b/cmake_targets/CMakeLists.txt @@ -2154,7 +2154,6 @@ add_executable(test_epc_generate_scenario ${OPENAIR2_DIR}/ENB_APP/enb_config.h ${OPENAIR2_DIR}/COMMON/commonDef.h ${OPENAIR2_DIR}/COMMON/messages_def.h - ${OPENAIR2_DIR}/COMMON/messages_types.h ${OPENAIR3_DIR}/S1AP/s1ap_eNB_defs.h ) target_link_libraries (test_epc_generate_scenario @@ -2174,7 +2173,6 @@ add_executable(test_epc_play_scenario ${OPENAIR3_DIR}/TEST/EPC_TEST/play_scenario.h ${OPENAIR2_DIR}/COMMON/commonDef.h ${OPENAIR2_DIR}/COMMON/messages_def.h - ${OPENAIR2_DIR}/COMMON/messages_types.h ) target_include_directories(test_epc_play_scenario PUBLIC /usr/local/share/asn1c) target_link_libraries (test_epc_play_scenario diff --git a/openair1/PHY/LTE_ESTIMATION/lte_adjust_sync.c b/openair1/PHY/LTE_ESTIMATION/lte_adjust_sync.c deleted file mode 100644 index 516cb32999..0000000000 --- a/openair1/PHY/LTE_ESTIMATION/lte_adjust_sync.c +++ /dev/null @@ -1,142 +0,0 @@ -/* - * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.openairinterface.org/?page_id=698 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - *------------------------------------------------------------------------------- - * For more information about the OpenAirInterface (OAI) Software Alliance: - * contact@openairinterface.org - */ - -#include "PHY/types.h" -#include "PHY/defs_UE.h" -#include "PHY/phy_extern_ue.h" - -#include "UTIL/LOG/vcd_signal_dumper.h" -#include "openair2/LAYER2/MAC/mac_proto.h" - -#define DEBUG_PHY - -// Adjust location synchronization point to account for drift -// The adjustment is performed once per frame based on the -// last channel estimate of the receiver - -void lte_adjust_synch(LTE_DL_FRAME_PARMS *frame_parms, - PHY_VARS_UE *ue, - module_id_t eNB_id, - uint8_t subframe, - unsigned char clear, - short coef) -{ - - static int max_pos_fil = 0; - static int count_max_pos_ok = 0; - static int first_time = 1; - int temp = 0, i, aa, max_val = 0, max_pos = 0; - int diff; - short Re,Im,ncoef; - - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_ADJUST_SYNCH, VCD_FUNCTION_IN); - - ncoef = 32767 - coef; - -#ifdef DEBUG_PHY - LOG_D(PHY,"AbsSubframe %d.%d: rx_offset (before) = %d\n",ue->proc.proc_rxtx[0].frame_rx%1024,subframe,ue->rx_offset); -#endif //DEBUG_PHY - - - // we only use channel estimates from tx antenna 0 here - for (i = 0; i < frame_parms->nb_prefix_samples; i++) { - temp = 0; - - for (aa=0; aanb_antennas_rx; aa++) { - Re = ((int16_t*)ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates_time[eNB_id][aa])[(i<<1)]; - Im = ((int16_t*)ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates_time[eNB_id][aa])[1+(i<<1)]; - temp += (Re*Re/2) + (Im*Im/2); - } - - if (temp > max_val) { - max_pos = i; - max_val = temp; - } - } - - // filter position to reduce jitter - if (clear == 1) - max_pos_fil = max_pos; - else - max_pos_fil = ((max_pos_fil * coef) + (max_pos * ncoef)) >> 15; - - // do not filter to have proactive timing adjustment - max_pos_fil = max_pos; - - if(subframe == 5) - { - diff = max_pos_fil - (frame_parms->nb_prefix_samples>>3); - -#if BASIC_SIMULATOR - /* a hack without which the UE does not connect (to be fixed somehow) */ - diff = 0; -#endif - - if ( abs(diff) < SYNCH_HYST ) - ue->rx_offset = 0; - else - ue->rx_offset = diff; - - if(abs(diff)<5) - count_max_pos_ok ++; - else - count_max_pos_ok = 0; - - if(count_max_pos_ok > 10 && first_time == 1) - { - first_time = 0; - ue->time_sync_cell = 1; - if (ue->mac_enabled==1) { - LOG_I(PHY,"[UE%d] Sending synch status to higher layers\n",ue->Mod_id); - //mac_resynch(); - dl_phy_sync_success(ue->Mod_id,ue->proc.proc_rxtx[0].frame_rx,0,1);//ue->common_vars.eNb_id); - ue->UE_mode[0] = PRACH; - } - else { - ue->UE_mode[0] = PUSCH; - } - } - - if ( ue->rx_offset < 0 ) - ue->rx_offset += FRAME_LENGTH_COMPLEX_SAMPLES; - - if ( ue->rx_offset >= FRAME_LENGTH_COMPLEX_SAMPLES ) - ue->rx_offset -= FRAME_LENGTH_COMPLEX_SAMPLES; - - - - #ifdef DEBUG_PHY - LOG_D(PHY,"AbsSubframe %d.%d: ThreadId %d diff =%i rx_offset (final) = %i : clear %d,max_pos = %d,max_pos_fil = %d (peak %d) max_val %d target_pos %d \n", - ue->proc.proc_rxtx[ue->current_thread_id[subframe]].frame_rx, - subframe, - ue->current_thread_id[subframe], - diff, - ue->rx_offset, - clear, - max_pos, - max_pos_fil, - temp,max_val, - (frame_parms->nb_prefix_samples>>3)); - #endif //DEBUG_PHY - - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_ADJUST_SYNCH, VCD_FUNCTION_OUT); - } -} diff --git a/openair1/PHY/LTE_TRANSPORT/mcs_tbs_tools.h b/openair1/PHY/LTE_TRANSPORT/mcs_tbs_tools.h deleted file mode 100644 index 59959a90fd..0000000000 --- a/openair1/PHY/LTE_TRANSPORT/mcs_tbs_tools.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.openairinterface.org/?page_id=698 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - *------------------------------------------------------------------------------- - * For more information about the OpenAirInterface (OAI) Software Alliance: - * contact@openairinterface.org - */ - -#define modOrder(I_MCS,I_TBS) ((I_MCS-I_TBS)*2+2) // Find modulation order from I_TBS and I_MCS - -/** \fn unsigned char I_TBS2I_MCS(unsigned char I_TBS); -\brief This function maps I_tbs to I_mcs according to Table 7.1.7.1-1 in 3GPP TS 36.213 V8.6.0. Where there is two supported modulation orders for the same I_TBS then either high or low modulation is chosen by changing the equality of the two first comparisons in the if-else statement. -\param I_TBS Index of Transport Block Size -\return I_MCS given I_TBS -*/ -unsigned char I_TBS2I_MCS(unsigned char I_TBS); - -/** \fn unsigned char SE2I_TBS(float SE, - unsigned char N_PRB, - unsigned char symbPerRB); -\brief This function maps a requested throughput in number of bits to I_tbs. The throughput is calculated as a function of modulation order, RB allocation and number of symbols per RB. The mapping orginates in the "Transport block size table" (Table 7.1.7.2.1-1 in 3GPP TS 36.213 V8.6.0) -\param SE Spectral Efficiency (before casting to integer, multiply by 1024, remember to divide result by 1024!) -\param N_PRB Number of PhysicalResourceBlocks allocated \sa lte_frame_parms->N_RB_DL -\param symbPerRB Number of symbols per resource block allocated to this channel -\return I_TBS given an SE and an N_PRB -*/ -unsigned char SE2I_TBS(float SE, - unsigned char N_PRB, - unsigned char symbPerRB); diff --git a/openair1/PHY/LTE_TRANSPORT/transport_proto.h b/openair1/PHY/LTE_TRANSPORT/transport_proto.h index 4b475478b6..0c0d2c962d 100644 --- a/openair1/PHY/LTE_TRANSPORT/transport_proto.h +++ b/openair1/PHY/LTE_TRANSPORT/transport_proto.h @@ -457,14 +457,6 @@ void generate_pcfich(uint8_t num_pdcch_symbols, int32_t **txdataF, uint8_t subframe); - - - - -void init_transport_channels(uint8_t); - - - void rx_ulsch(PHY_VARS_eNB *eNB, L1_rxtx_proc_t *proc, uint8_t UE_id); diff --git a/openair1/PHY/LTE_UE_TRANSPORT/transport_proto_ue.h b/openair1/PHY/LTE_UE_TRANSPORT/transport_proto_ue.h index 49b9e8b808..762db5f416 100644 --- a/openair1/PHY/LTE_UE_TRANSPORT/transport_proto_ue.h +++ b/openair1/PHY/LTE_UE_TRANSPORT/transport_proto_ue.h @@ -1438,8 +1438,6 @@ uint8_t rx_pcfich(LTE_DL_FRAME_PARMS *frame_parms, void generate_phich_reg_mapping(LTE_DL_FRAME_PARMS *frame_parms); -void init_transport_channels(uint8_t); - void generate_RIV_tables(void); /*! diff --git a/openair1/PHY/MODULATION/prach625Hz.h b/openair1/PHY/MODULATION/prach625Hz.h deleted file mode 100644 index 38b63b3b05..0000000000 --- a/openair1/PHY/MODULATION/prach625Hz.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.openairinterface.org/?page_id=698 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - *------------------------------------------------------------------------------- - * For more information about the OpenAirInterface (OAI) Software Alliance: - * contact@openairinterface.org - */ - -int16_t sig625_1_25MHz[2850*2]; -int16_t sig625_2_5MHz[5700*2]; -int16_t sig625_5MHz[11400*2]; -int16_t sig625_10MHz[22800*2]; -int16_t sig625_15MHz[34200*2]; -int16_t sig625_20MHz[45600*2]; diff --git a/openair1/PHY/Makefile.inc b/openair1/PHY/Makefile.inc deleted file mode 100644 index 90094b31f8..0000000000 --- a/openair1/PHY/Makefile.inc +++ /dev/null @@ -1,91 +0,0 @@ -PHY_OBJS = $(TOP_DIR)/PHY/LTE_TRANSPORT/pss.o -PHY_OBJS += $(TOP_DIR)/PHY/LTE_TRANSPORT/sss.o -PHY_OBJS += $(TOP_DIR)/PHY/LTE_TRANSPORT/pilots.o -PHY_OBJS += $(TOP_DIR)/PHY/LTE_TRANSPORT/pilots_ue_spec.o -PHY_OBJS += $(TOP_DIR)/PHY/LTE_TRANSPORT/pilots_mbsfn.o -PHY_OBJS += $(TOP_DIR)/PHY/LTE_TRANSPORT/dlsch_coding.o -PHY_OBJS += $(TOP_DIR)/PHY/LTE_TRANSPORT/dlsch_modulation.o -PHY_OBJS += $(TOP_DIR)/PHY/LTE_TRANSPORT/dlsch_demodulation.o -PHY_OBJS += $(TOP_DIR)/PHY/LTE_TRANSPORT/dlsch_llr_computation.o -PHY_OBJS += $(TOP_DIR)/PHY/LTE_TRANSPORT/dlsch_llr_computation_avx2.o -PHY_OBJS += $(TOP_DIR)/PHY/LTE_TRANSPORT/power_control.o -PHY_OBJS += $(TOP_DIR)/PHY/LTE_TRANSPORT/dlsch_decoding.o -PHY_OBJS += $(TOP_DIR)/PHY/LTE_TRANSPORT/dlsch_scrambling.o -PHY_OBJS += $(TOP_DIR)/PHY/LTE_TRANSPORT/dci_tools.o -PHY_OBJS += $(TOP_DIR)/PHY/LTE_TRANSPORT/uci_tools.o -PHY_OBJS += $(TOP_DIR)/PHY/LTE_TRANSPORT/lte_mcs.o -PHY_OBJS += $(TOP_DIR)/PHY/LTE_TRANSPORT/pbch.o -PHY_OBJS += $(TOP_DIR)/PHY/LTE_TRANSPORT/dci.o -PHY_OBJS += $(TOP_DIR)/PHY/LTE_TRANSPORT/phich.o -PHY_OBJS += $(TOP_DIR)/PHY/LTE_TRANSPORT/pcfich.o -PHY_OBJS += $(TOP_DIR)/PHY/LTE_TRANSPORT/pucch.o -PHY_OBJS += $(TOP_DIR)/PHY/LTE_TRANSPORT/prach.o -PHY_OBJS += $(TOP_DIR)/PHY/LTE_TRANSPORT/pmch.o -PHY_OBJS += $(TOP_DIR)/PHY/LTE_TRANSPORT/group_hopping.o -PHY_OBJS += $(TOP_DIR)/PHY/LTE_TRANSPORT/srs_modulation.o -PHY_OBJS += $(TOP_DIR)/PHY/LTE_TRANSPORT/drs_modulation.o -PHY_OBJS += $(TOP_DIR)/PHY/LTE_TRANSPORT/ulsch_modulation.o -PHY_OBJS += $(TOP_DIR)/PHY/LTE_TRANSPORT/ulsch_demodulation.o -PHY_OBJS += $(TOP_DIR)/PHY/LTE_TRANSPORT/ulsch_coding.o -PHY_OBJS += $(TOP_DIR)/PHY/LTE_TRANSPORT/ulsch_decoding.o -PHY_OBJS += $(TOP_DIR)/PHY/LTE_TRANSPORT/rar_tools.o -PHY_OBJS += $(TOP_DIR)/PHY/LTE_TRANSPORT/print_stats.o -PHY_OBJS += $(TOP_DIR)/PHY/LTE_TRANSPORT/initial_sync.o -#PHY_OBJS += $(TOP_DIR)/PHY/LTE_TRANSPORT/lte_transport_init.o -PHY_OBJS += $(TOP_DIR)/PHY/MODULATION/ofdm_mod.o -PHY_OBJS += $(TOP_DIR)/PHY/MODULATION/slot_fep.o -PHY_OBJS += $(TOP_DIR)/PHY/MODULATION/slot_fep_mbsfn.o -PHY_OBJS += $(TOP_DIR)/PHY/MODULATION/slot_fep_ul.o -PHY_OBJS += $(TOP_DIR)/PHY/MODULATION/ul_7_5_kHz.o -PHY_OBJS += $(TOP_DIR)/PHY/LTE_ESTIMATION/freq_equalization.o -PHY_OBJS += $(TOP_DIR)/PHY/LTE_ESTIMATION/lte_sync_time.o -PHY_OBJS += $(TOP_DIR)/PHY/LTE_ESTIMATION/lte_sync_timefreq.o -PHY_OBJS += $(TOP_DIR)/PHY/LTE_ESTIMATION/lte_adjust_sync.o -PHY_OBJS += $(TOP_DIR)/PHY/LTE_ESTIMATION/lte_dl_channel_estimation.o -PHY_OBJS += $(TOP_DIR)/PHY/LTE_ESTIMATION/lte_dl_bf_channel_estimation.o -PHY_OBJS += $(TOP_DIR)/PHY/LTE_ESTIMATION/lte_dl_mbsfn_channel_estimation.o -PHY_OBJS += $(TOP_DIR)/PHY/LTE_ESTIMATION/lte_ul_channel_estimation.o -PHY_OBJS += $(TOP_DIR)/PHY/LTE_ESTIMATION/lte_est_freq_offset.o -PHY_OBJS += $(TOP_DIR)/PHY/LTE_ESTIMATION/lte_ue_measurements.o -PHY_OBJS += $(TOP_DIR)/PHY/LTE_ESTIMATION/lte_eNB_measurements.o -PHY_OBJS += $(TOP_DIR)/PHY/LTE_ESTIMATION/adjust_gain.o -PHY_OBJS += $(TOP_DIR)/PHY/LTE_REFSIG/lte_dl_cell_spec.o -PHY_OBJS += $(TOP_DIR)/PHY/LTE_REFSIG/lte_dl_ue_spec.o -PHY_OBJS += $(TOP_DIR)/PHY/LTE_REFSIG/lte_gold.o -PHY_OBJS += $(TOP_DIR)/PHY/LTE_REFSIG/lte_gold_mbsfn.o -PHY_OBJS += $(TOP_DIR)/PHY/LTE_REFSIG/lte_dl_mbsfn.o -PHY_OBJS += $(TOP_DIR)/PHY/LTE_REFSIG/lte_ul_ref.o -PHY_OBJS += $(TOP_DIR)/PHY/CODING/lte_segmentation.o -PHY_OBJS += $(TOP_DIR)/PHY/CODING/ccoding_byte.o -PHY_OBJS += $(TOP_DIR)/PHY/CODING/ccoding_byte_lte.o -#PHY_OBJS += $(TOP_DIR)/PHY/CODING/3gpplte.o -PHY_OBJS += $(TOP_DIR)/PHY/CODING/3gpplte_sse.o -PHY_OBJS += $(TOP_DIR)/PHY/CODING/crc_byte.o -#PHY_OBJS += $(TOP_DIR)/PHY/CODING/3gpplte_turbo_decoder_sse.o -PHY_OBJS += $(TOP_DIR)/PHY/CODING/3gpplte_turbo_decoder_sse_8bit.o -PHY_OBJS += $(TOP_DIR)/PHY/CODING/3gpplte_turbo_decoder_sse_16bit.o -PHY_OBJS += $(TOP_DIR)/PHY/CODING/lte_rate_matching.o -PHY_OBJS += $(TOP_DIR)/PHY/CODING/rate_matching.o -PHY_OBJS += $(TOP_DIR)/PHY/CODING/viterbi.o -PHY_OBJS += $(TOP_DIR)/PHY/CODING/viterbi_lte.o -PHY_OBJS += $(TOP_DIR)/PHY/INIT/lte_init.o -PHY_OBJS += $(TOP_DIR)/PHY/INIT/lte_parms.o -PHY_OBJS += $(TOP_DIR)/PHY/INIT/init_top.o -PHY_OBJS += $(TOP_DIR)/PHY/TOOLS/file_output.o -#PHY_OBJS += $(TOP_DIR)/PHY/TOOLS/fft.o -PHY_OBJS += $(TOP_DIR)/PHY/TOOLS/lte_dfts.o -PHY_OBJS += $(TOP_DIR)/PHY/TOOLS/log2_approx.o -PHY_OBJS += $(TOP_DIR)/PHY/TOOLS/cmult_sv.o -PHY_OBJS += $(TOP_DIR)/PHY/TOOLS/cmult_vv.o -PHY_OBJS += $(TOP_DIR)/PHY/TOOLS/cadd_vv.o -PHY_OBJS += $(TOP_DIR)/PHY/TOOLS/cdot_prod.o -PHY_OBJS += $(TOP_DIR)/PHY/TOOLS/signal_energy.o -PHY_OBJS += $(TOP_DIR)/PHY/TOOLS/dB_routines.o -PHY_OBJS += $(TOP_DIR)/PHY/TOOLS/sqrt.o -ifdef SMBV -PHY_OBJS += $(TOP_DIR)/PHY/TOOLS/smbv.o -endif -PHY_OBJS += $(TOP_DIR)/PHY/TOOLS/time_meas.o -PHY_OBJS += $(TOP_DIR)/PHY/TOOLS/lut.o -#PHY_OBJS += $(TOP_DIR)/SIMULATION/TOOLS/rangen_double.o - diff --git a/openair1/SCHED/Makefile.inc b/openair1/SCHED/Makefile.inc deleted file mode 100644 index 559d3dca32..0000000000 --- a/openair1/SCHED/Makefile.inc +++ /dev/null @@ -1,6 +0,0 @@ -SCHED_OBJS = $(TOP_DIR)/SCHED/phy_procedures_lte_common.o -SCHED_OBJS += $(TOP_DIR)/SCHED/phy_procedures_lte_ue.o -SCHED_OBJS += $(TOP_DIR)/SCHED/phy_procedures_lte_eNb.o -SCHED_OBJS += $(TOP_DIR)/SCHED/pusch_pc.o -SCHED_OBJS += $(TOP_DIR)/SCHED/pucch_pc.o -SCHED_OBJS += $(TOP_DIR)/SCHED/srs_pc.o diff --git a/openair2/COMMON/intertask_interface_conf.h b/openair2/COMMON/intertask_interface_conf.h deleted file mode 100644 index 9c108f87e0..0000000000 --- a/openair2/COMMON/intertask_interface_conf.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.openairinterface.org/?page_id=698 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - *------------------------------------------------------------------------------- - * For more information about the OpenAirInterface (OAI) Software Alliance: - * contact@openairinterface.org - */ - -/* - * intertask_interface_conf.h - * - * Created on: Oct 21, 2013 - * Author: winckel - */ - -#ifndef INTERTASK_INTERFACE_CONF_H_ -#define INTERTASK_INTERFACE_CONF_H_ - -/******************************************************************************* - * Intertask Interface Constants - ******************************************************************************/ - -#define ITTI_PORT (10006) - -/* This is the queue size for signal dumper */ -#define ITTI_QUEUE_MAX_ELEMENTS (10 * 1000) -#define ITTI_DUMP_MAX_CON (5) /* Max connections in parallel */ - -#endif /* INTERTASK_INTERFACE_CONF_H_ */ diff --git a/openair2/COMMON/messages_types.h b/openair2/COMMON/messages_types.h deleted file mode 100644 index 5e5fdadd2a..0000000000 --- a/openair2/COMMON/messages_types.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.openairinterface.org/?page_id=698 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - *------------------------------------------------------------------------------- - * For more information about the OpenAirInterface (OAI) Software Alliance: - * contact@openairinterface.org - */ - -/* - * messages_types.h - * - * Created on: Oct 14, 2013 - * Author: winckel - */ - -#ifndef MESSAGES_TYPES_H_ -#define MESSAGES_TYPES_H_ - -#include "intertask_messages_types.h" -#include "timer_messages_types.h" - -#include "phy_messages_types.h" -#include "mac_messages_types.h" -#include "rlc_messages_types.h" -#include "pdcp_messages_types.h" -#include "rrc_messages_types.h" -#include "nas_messages_types.h" -#if ENABLE_RAL -#include "ral_messages_types.h" -#endif -#include "s1ap_messages_types.h" -#include "x2ap_messages_types.h" -#include "sctp_messages_types.h" -#include "udp_messages_types.h" -#include "gtpv1_u_messages_types.h" - -#endif /* MESSAGES_TYPES_H_ */ diff --git a/openair2/ENB_APP/Makefile.inc b/openair2/ENB_APP/Makefile.inc deleted file mode 100644 index e018d67610..0000000000 --- a/openair2/ENB_APP/Makefile.inc +++ /dev/null @@ -1,7 +0,0 @@ -ENB_APP_DIR = $(OPENAIR2_TOP)/ENB_APP - -ENB_APP_OBJS = $(ENB_APP_DIR)/enb_app.o \ - $(ENB_APP_DIR)/enb_config.o -ENB_APP_incl = \ - -I$(ENB_APP_DIR) -I$(OPENAIR2_TOP) - diff --git a/openair2/LAYER2/MAC/lte_transport_init.c b/openair2/LAYER2/MAC/lte_transport_init.c deleted file mode 100644 index e1f21f21e4..0000000000 --- a/openair2/LAYER2/MAC/lte_transport_init.c +++ /dev/null @@ -1,132 +0,0 @@ -/* - * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.openairinterface.org/?page_id=698 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - *------------------------------------------------------------------------------- - * For more information about the OpenAirInterface (OAI) Software Alliance: - * contact@openairinterface.org - */ - -#define UL_RB_ALLOC mac_xface->computeRIV(mac_xface->frame_parms->N_RB_UL,0,24) -#define BCCH_RB_ALLOC mac_xface->computeRIV(mac_xface->frame_parms->N_RB_UL,0,4) -#define RA_RB_ALLOC mac_xface->computeRIV(mac_xface->frame_parms->N_RB_UL,0,4) -#define DLSCH_RB_ALLOC 0x1fff -#include "extern.h" - - -void init_transport_channels(unsigned char transmission_mode) -{ - - // init DCI structures for testing - - UL_alloc_pdu.type = 0; - UL_alloc_pdu.hopping = 0; - UL_alloc_pdu.rballoc = UL_RB_ALLOC; - UL_alloc_pdu.mcs = 2; - UL_alloc_pdu.ndi = 1; - UL_alloc_pdu.TPC = 0; - UL_alloc_pdu.cqi_req = 1; - - /* - BCCH_alloc_pdu.type = 1; - BCCH_alloc_pdu.vrb_type = 0; - BCCH_alloc_pdu.rballoc = BCCH_RB_ALLOC; - BCCH_alloc_pdu.ndi = 1; - BCCH_alloc_pdu.rv = 1; - BCCH_alloc_pdu.mcs = 1; - BCCH_alloc_pdu.harq_pid = 0; - BCCH_alloc_pdu.TPC = 1; // set to 3 PRB - - // for FDD mode - BCCH_alloc_pdu_fdd.type = 1; - BCCH_alloc_pdu_fdd.vrb_type = 0; - BCCH_alloc_pdu_fdd.rballoc = BCCH_RB_ALLOC; - BCCH_alloc_pdu_fdd.ndi = 1; - BCCH_alloc_pdu_fdd.rv = 1; - BCCH_alloc_pdu_fdd.mcs = 1; - BCCH_alloc_pdu_fdd.harq_pid = 0; - BCCH_alloc_pdu_fdd.TPC = 1; // set to 3 PRB - */ - - DLSCH_alloc_pdu1A.type = 1; - DLSCH_alloc_pdu1A.vrb_type = 0; - DLSCH_alloc_pdu1A.rballoc = BCCH_RB_ALLOC; - DLSCH_alloc_pdu1A.ndi = 1; - DLSCH_alloc_pdu1A.rv = 1; - DLSCH_alloc_pdu1A.mcs = 2; - DLSCH_alloc_pdu1A.harq_pid = 0; - DLSCH_alloc_pdu1A.TPC = 1; // set to 3 PRB - - DLSCH_alloc_pdu1A_fdd.type = 1; - DLSCH_alloc_pdu1A_fdd.vrb_type = 0; - DLSCH_alloc_pdu1A_fdd.rballoc = BCCH_RB_ALLOC; - DLSCH_alloc_pdu1A_fdd.ndi = 1; - DLSCH_alloc_pdu1A_fdd.rv = 1; - DLSCH_alloc_pdu1A_fdd.mcs = 2; - DLSCH_alloc_pdu1A_fdd.harq_pid = 0; - DLSCH_alloc_pdu1A_fdd.TPC = 1; // set to 3 PRB - - RA_alloc_pdu.type = 1; - RA_alloc_pdu.vrb_type = 0; - RA_alloc_pdu.rballoc = RA_RB_ALLOC; - RA_alloc_pdu.ndi = 1; - RA_alloc_pdu.rv = 0; - RA_alloc_pdu.mcs = 0; - RA_alloc_pdu.harq_pid = 0; - RA_alloc_pdu.TPC = 1; - - RA_alloc_pdu_fdd.type = 1; - RA_alloc_pdu_fdd.vrb_type = 0; - RA_alloc_pdu_fdd.rballoc = RA_RB_ALLOC; - RA_alloc_pdu_fdd.ndi = 1; - RA_alloc_pdu_fdd.rv = 1; - RA_alloc_pdu_fdd.mcs = 1; - RA_alloc_pdu_fdd.harq_pid = 0; - RA_alloc_pdu_fdd.TPC = 1; - - - DLSCH_alloc_pdu1.rballoc = 0xf; - DLSCH_alloc_pdu1.TPC = 0; - DLSCH_alloc_pdu1.dai = 0; - DLSCH_alloc_pdu1.harq_pid = 0; - DLSCH_alloc_pdu1.tb_swap = 0; - DLSCH_alloc_pdu1.mcs1 = 4; - DLSCH_alloc_pdu1.ndi1 = 1; - DLSCH_alloc_pdu1.rv1 = 0; - - // Forget second codeword - if (transmission_mode == 6) { - DLSCH_alloc_pdu1.tpmi = 5; // PUSCH_PRECODING0 - } else { - DLSCH_alloc_pdu1.tpmi = 0; - } - - DLSCH_alloc_pdu2.rah = 0; - DLSCH_alloc_pdu2.rballoc = DLSCH_RB_ALLOC; - DLSCH_alloc_pdu2.TPC = 0; - DLSCH_alloc_pdu2.dai = 0; - DLSCH_alloc_pdu2.harq_pid = 0; - DLSCH_alloc_pdu2.tb_swap = 0; - DLSCH_alloc_pdu2.mcs1 = 4; - DLSCH_alloc_pdu2.ndi1 = 1; - DLSCH_alloc_pdu2.rv1 = 0; - - // Forget second codeword - if (transmission_mode == 6) { - DLSCH_alloc_pdu2.tpmi = 5; // PUSCH_PRECODING0 - } else { - DLSCH_alloc_pdu2.tpmi = 0; - } -} diff --git a/openair2/LAYER2/Makefile.inc b/openair2/LAYER2/Makefile.inc deleted file mode 100644 index 2f5cea7555..0000000000 --- a/openair2/LAYER2/Makefile.inc +++ /dev/null @@ -1,118 +0,0 @@ -ifeq ($(OPENAIR2),1) -EXTRA_CFLAGS += -DOPENAIR2 -endif -EXTRA_CFLAGS += -DASSERT -EXTRA_CFLAGS += -DNO_RRM - -COMMON_DIR = $(OPENAIR2_TOP)/COMMON -L2_INTERFACE_DIR = $(OPENAIR2_TOP)/RRC/L2_INTERFACE -RLC_UM_DIR = $(OPENAIR2_TOP)/LAYER2/RLC/UM_v9.3.0 -RLC_AM_DIR = $(OPENAIR2_TOP)/LAYER2/RLC/AM_v9.3.0 -RLC_TM_DIR = $(OPENAIR2_TOP)/LAYER2/RLC/TM_v9.3.0 -RLC_DIR = $(OPENAIR2_TOP)/LAYER2/RLC -PDCP_DIR = $(OPENAIR2_TOP)/LAYER2/PDCP_v10.1.0 -PHY_INTERFACE_DIR = $(OPENAIR2_TOP)/PHY_INTERFACE -RRC_DIR = $(OPENAIR2_TOP)/RRC/LITE -L2_INTERFACE_DIR = $(OPENAIR2_TOP)/RRC/L2_INTERFACE -MAC_DIR = $(OPENAIR2_TOP)/LAYER2/MAC -RRC_CELL_DIR = $(OPENAIR2_TOP)/RRC/CELLULAR - -SOURCES_L2 += $(OPENAIR2_TOP)/LAYER2/openair2_proc.c - -SOURCES_L2 += $(PDCP_DIR)/pdcp.c -SOURCES_L2 += $(PDCP_DIR)/pdcp_fifo.c -SOURCES_L2 += $(PDCP_DIR)/pdcp_sequence_manager.c -SOURCES_L2 += $(PDCP_DIR)/pdcp_primitives.c -SOURCES_L2 += $(PDCP_DIR)/pdcp_util.c -SOURCES_L2 += $(PDCP_DIR)/pdcp_security.c -SOURCES_L2 += $(PDCP_DIR)/pdcp_netlink.c - -SOURCES_L2 += $(RLC_AM_DIR)/rlc_am.c -SOURCES_L2 += $(RLC_AM_DIR)/rlc_am_init.c -SOURCES_L2 += $(RLC_AM_DIR)/rlc_am_timer_poll_retransmit.c -SOURCES_L2 += $(RLC_AM_DIR)/rlc_am_timer_reordering.c -SOURCES_L2 += $(RLC_AM_DIR)/rlc_am_timer_status_prohibit.c -SOURCES_L2 += $(RLC_AM_DIR)/rlc_am_segment.c -SOURCES_L2 += $(RLC_AM_DIR)/rlc_am_segments_holes.c -SOURCES_L2 += $(RLC_AM_DIR)/rlc_am_in_sdu.c -SOURCES_L2 += $(RLC_AM_DIR)/rlc_am_receiver.c -SOURCES_L2 += $(RLC_AM_DIR)/rlc_am_retransmit.c -SOURCES_L2 += $(RLC_AM_DIR)/rlc_am_windows.c -SOURCES_L2 += $(RLC_AM_DIR)/rlc_am_rx_list.c -SOURCES_L2 += $(RLC_AM_DIR)/rlc_am_reassembly.c -SOURCES_L2 += $(RLC_AM_DIR)/rlc_am_status_report.c - - -SOURCES_L2 += $(RLC_TM_DIR)/rlc_tm.c -SOURCES_L2 += $(RLC_TM_DIR)/rlc_tm_init.c - -SOURCES_L2 += $(RLC_UM_DIR)/rlc_um.c -SOURCES_L2 += $(RLC_UM_DIR)/rlc_um_fsm.c -SOURCES_L2 += $(RLC_UM_DIR)/rlc_um_control_primitives.c -SOURCES_L2 += $(RLC_UM_DIR)/rlc_um_segment.c -SOURCES_L2 += $(RLC_UM_DIR)/rlc_um_reassembly.c -SOURCES_L2 += $(RLC_UM_DIR)/rlc_um_receiver.c -SOURCES_L2 += $(RLC_UM_DIR)/rlc_um_dar.c - -SOURCES_L2 += $(RLC_DIR)/rlc_mac.c -SOURCES_L2 += $(RLC_DIR)/rlc.c -SOURCES_L2 += $(RLC_DIR)/rlc_rrc.c -SOURCES_L2 += $(RLC_DIR)/rlc_mpls.c - -RRC_OBJS = $(RRC_DIR)/rrc_UE.o -ifeq ($(ENABLE_RAL),1) -RRC_OBJS += $(RRC_DIR)/rrc_UE_ral.o -RRC_OBJS += $(RRC_DIR)/rrc_eNB_ral.o -endif - -RRC_OBJS += $(RRC_DIR)/rrc_eNB.o -RRC_OBJS += $(RRC_DIR)/rrc_eNB_UE_context.o -RRC_OBJS += $(RRC_DIR)/rrc_eNB_S1AP.o -ifdef USE_MME -RRC_OBJS += $(RRC_DIR)/rrc_eNB_GTPV1U.o -endif -RRC_OBJS += $(RRC_DIR)/rrc_common.o -RRC_OBJS += $(RRC_DIR)/L2_interface.o - -MAC_OBJS = $(MAC_DIR)/lte_transport_init.o -MAC_OBJS += $(MAC_DIR)/main.o -MAC_OBJS += $(MAC_DIR)/ue_procedures.o -MAC_OBJS += $(MAC_DIR)/ra_procedures.o -MAC_OBJS += $(MAC_DIR)/l1_helpers.o -MAC_OBJS += $(MAC_DIR)/rar_tools.o -MAC_OBJS += $(MAC_DIR)/eNB_scheduler.o -MAC_OBJS += $(MAC_DIR)/eNB_scheduler_dlsch.o -MAC_OBJS += $(MAC_DIR)/eNB_scheduler_ulsch.o -MAC_OBJS += $(MAC_DIR)/eNB_scheduler_mch.o -MAC_OBJS += $(MAC_DIR)/eNB_scheduler_bch.o -MAC_OBJS += $(MAC_DIR)/eNB_scheduler_primitives.o -MAC_OBJS += $(MAC_DIR)/eNB_scheduler_RA.o -MAC_OBJS += $(MAC_DIR)/pre_processor.o -MAC_OBJS += $(MAC_DIR)/config.o - -L2_INTERFACE_OBJS = $(L2_INTERFACE_DIR)/openair_rrc_L2_interface.o - -L2_OBJS=$(addsuffix .o,$(basename $(SOURCES_L2))) $(PHY_INTERFACE_OBJS) $(MAC_OBJS) $(L2_INTERFACE_OBJS) - -L2_incl = -I$(OPENAIR2_TOP) -L2_incl = -I$(OPENAIR_DIR)/common/utils/msc -L2_incl += -I$(COMMON_DIR) -L2_incl += -I$(RLC_DIR) -L2_incl += -I$(RLC_AM_DIR) -L2_incl += -I$(RLC_UM_DIR) -L2_incl += -I$(RLC_TM_DIR) -L2_incl += -I$(PDCP_DIR) -L2_incl += -I$(OPENAIR3)/MESH -L2_incl += -I$(OPENAIR2_TOP)/RRC/LITE/MESSAGES -L2_incl += -I$(OPENAIR3)/MESH/RRM - -ifeq ($(rrc_cellular),1) - include $(RRC_CELL_DIR)/Makefile.inc - L2_OBJS += $(RRC_CELLULAR_OBJS) - L2_incl += -I$(OPENAIR2_TOP)/RRC/CELLULAR - EXTRA_CFLAGS += -DRRC_CELLULAR -DCELLULAR -else - L2_OBJS += $(RRC_OBJS) - L2_incl += -I$(OPENAIR2_TOP)/RRC/LITE -endif - diff --git a/openair2/LAYER2/RLC/UM_v9.3.0/Makefile b/openair2/LAYER2/RLC/UM_v9.3.0/Makefile deleted file mode 100644 index 2d56c809cb..0000000000 --- a/openair2/LAYER2/RLC/UM_v9.3.0/Makefile +++ /dev/null @@ -1,49 +0,0 @@ -CFLAGS += -I$(RLC_DIR) -CFLAGS += -I$(RLC_UM_DIR) -CFLAGS += -I$(RLC_AM_DIR) -CFLAGS += -I$(COMMON_DIR) -CFLAGS += -I$(TRACE_DIR) -CFLAGS += -I$(LISTS_DIR) -CFLAGS += -I$(MEM_DIR) - -DEBUG_FLAGS += -O2 - -OBJ = rlc_um.o rlc_um_segment.o - - -############################################################ -# -# The following should be identical in all Makefiles -# -#define the target object files - -ifdef TARGETDIR - TARGETOBJ = $(addprefix ${TARGETDIR}/, ${OBJ}) - TARGETLIB = ${TARGETDIR}/Lib.a -endif - -include $(TARGETOBJ:.o=.d) - -# Look for source files in the parent directory -%.o: ../%.c %.d - $(CCC) -c ${DEBUG_FLAGS} ${CFLAGS} ${INCLUDE} -o $@ $< - -# Rule to remake and keep the .d dependency Makefiles -# Note that the sed command includes adding the TARGETDIR -# and that ! is used for s delimiter -%.d: ../%.c - $(SHELL) -ec '$(CCC) -MM $(CFLAGS) $< \ - | sed '\''s!\($(*F)\)\.o[ :]*!$(TARGETDIR)/\1.o $@ : !g'\'' > $@ ;\ - [ -s $@ ] || rm -f $@' -.PRECIOUS: %.d - -all: ${TARGETLIB} - -${TARGETLIB}: ${TARGETOBJ} - ar -rv ${TARGETLIB} ${TARGETOBJ} - -clean: - rm -f ${TARGETDIR}/*.o ${TARGETDIR}/*.a - -clean_dep: - rm -f ${TARGETDIR}/*.d diff --git a/openair2/LAYER2/register.h b/openair2/LAYER2/register.h deleted file mode 100644 index 8a4aeb5b12..0000000000 --- a/openair2/LAYER2/register.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.openairinterface.org/?page_id=698 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - *------------------------------------------------------------------------------- - * For more information about the OpenAirInterface (OAI) Software Alliance: - * contact@openairinterface.org - */ - -/*________________________rrc_register.h________________________ - - Authors : Hicham Anouar, Raymond Knopp - Company : EURECOM - Emails : anouar@eurecom.fr, knopp@eurecom.fr -________________________________________________________________*/ - -#ifndef __MAC_RRC_REGISTER_H__ -# define __MAC_RRC_REGISTER_H__ -#include "COMMON/mac_rrc_primitives.h" -/** @defgroup _mac_impl_register RRC Registration interface - * @ingroup _mac_impl_ - *@{ - */ -MAC_RLC_XFACE* mac_rrc_register(RRC_XFACE* RRC_xface); -int mac_rrc_unregister(RRC_XFACE *RRC_xface); -#endif diff --git a/openair2/RRC/LTE/MESSAGES/Makefile.inc b/openair2/RRC/LTE/MESSAGES/Makefile.inc deleted file mode 100644 index aa17ad51ca..0000000000 --- a/openair2/RRC/LTE/MESSAGES/Makefile.inc +++ /dev/null @@ -1,91 +0,0 @@ - -current_release_asn1_module=$(strip $(notdir $(wildcard $(OPENAIR2_DIR)/RRC/LITE/MESSAGES/asn1c/ASN1_files/.lock-*))) - -ifdef CBA - COMMON_CFLAGS += -DRel10 - COMMON_CFLAGS += -DCBA - ifneq ($(current_release_asn1_module), .lock-rel10-cba) - tmp3:=$(shell cd $(OPENAIR2_DIR)/RRC/LITE/MESSAGES ;\ - rm -f ${ASN_MODULE_SOURCES} $(ASN_MODULE_HEADERS) *.o *.d ;\ - cd $(OPENAIR2_DIR)/RRC/LITE/MESSAGES/asn1c/ASN1_files/ ;\ - rm EUTRA-RRC-Definitions.asn ;\ - ln -s EUTRA-RRC-Definitions-a20-lola.asn EUTRA-RRC-Definitions.asn ; \ - cd $(OPENAIR_TARGETS)/SIMU/USER/ ;\ - rm -f $(ASN1_MSG_OBJS1) ;\ - rm -f $(OPENAIR2_DIR)/RRC/LITE/MESSAGES/Makefile.inc.generated ;\ - rm -f $(OPENAIR2_DIR)/RRC/LITE/MESSAGES/Makefile.am.sample ;\ - rm -f $(L2_OBJS) ;\ - rm -f *.o ;\ - rm -f oaisim ;\ - rm -f $(OPENAIR2_DIR)/RRC/LITE/MESSAGES/asn1c/ASN1_files/.lock-* ;\ - touch $(OPENAIR2_DIR)/RRC/LITE/MESSAGES/asn1c/ASN1_files/.lock-rel10-cba ;\ - /bin/bash $(OPENAIR_TARGETS)/SCRIPTS/asn1_generate_rrc_messaging_c_code.bash ;\ - cd $(OPENAIR2_DIR)/RRC/LITE/MESSAGES ;\ - awk '/converter-sample.c/ {exit} // {print}' Makefile.am.sample > Makefile.inc.generated ) - endif - -else ifdef Rel10 - COMMON_CFLAGS += -DRel10 - ifneq ($(current_release_asn1_module), .lock-rel10) - tmp3:=$(shell cd $(OPENAIR2_DIR)/RRC/LITE/MESSAGES ;\ - rm -f ${ASN_MODULE_SOURCES} $(ASN_MODULE_HEADERS) *.o *.d ;\ - cd $(OPENAIR2_DIR)/RRC/LITE/MESSAGES/asn1c/ASN1_files/ ;\ - rm EUTRA-RRC-Definitions.asn ;\ - ln -s EUTRA-RRC-Definitions-a20.asn EUTRA-RRC-Definitions.asn ;\ - cd $(OPENAIR_TARGETS)/SIMU/USER/ ;\ - rm -f $(ASN1_MSG_OBJS1) ;\ - rm -f $(OPENAIR2_DIR)/RRC/LITE/MESSAGES/Makefile.inc.generated ;\ - rm -f $(OPENAIR2_DIR)/RRC/LITE/MESSAGES/Makefile.am.sample ;\ - rm -f $(L2_OBJS) ;\ - rm -f *.o ;\ - rm -f oaisim ;\ - rm -f $(OPENAIR2_DIR)/RRC/LITE/MESSAGES/asn1c/ASN1_files/.lock-* ;\ - touch $(OPENAIR2_DIR)/RRC/LITE/MESSAGES/asn1c/ASN1_files/.lock-rel10 ;\ - /bin/bash $(OPENAIR_TARGETS)/SCRIPTS/asn1_generate_rrc_messaging_c_code.bash ;\ - cd $(OPENAIR2_DIR)/RRC/LITE/MESSAGES ;\ - awk '/converter-sample.c/ {exit} // {print}' Makefile.am.sample > Makefile.inc.generated ) - endif - -else # default is rel 8 - COMMON_CFLAGS += -DRel8 - ifneq ($(current_release_asn1_module), .lock-rel8) - tmp3:=$(shell cd $(OPENAIR2_DIR)/RRC/LITE/MESSAGES ;\ - rm -f ${ASN_MODULE_SOURCES} $(ASN_MODULE_HEADERS) *.o *.d ;\ - cd $(OPENAIR2_DIR)/RRC/LITE/MESSAGES/asn1c/ASN1_files/ ;\ - rm EUTRA-RRC-Definitions.asn ;\ - ln -s EUTRA-RRC-Definitions-86.asn EUTRA-RRC-Definitions.asn ;\ - cd $(OPENAIR_TARGETS)/SIMU/USER/ ;\ - rm -f $(ASN1_MSG_OBJS1) ;\ - rm -f $(OPENAIR2_DIR)/RRC/LITE/MESSAGES/Makefile.inc.generated ;\ - rm -f $(OPENAIR2_DIR)/RRC/LITE/MESSAGES/Makefile.am.sample ;\ - rm -f $(L2_OBJS);\ - rm -f *.o ;\ - rm -f oaisim ;\ - rm -f $(OPENAIR2_DIR)/RRC/LITE/MESSAGES/asn1c/ASN1_files/.lock-* ;\ - touch $(OPENAIR2_DIR)/RRC/LITE/MESSAGES/asn1c/ASN1_files/.lock-rel8 ;\ - /bin/bash $(OPENAIR_TARGETS)/SCRIPTS/asn1_generate_rrc_messaging_c_code.bash ;\ - cd $(OPENAIR2_DIR)/RRC/LITE/MESSAGES ;\ - awk '/converter-sample.c/ {exit} // {print}' Makefile.am.sample > Makefile.inc.generated ) - endif - -endif - -tmp:=$(shell cd $(OPENAIR2_DIR)/RRC/LITE/MESSAGES ;\ - if [ ! -s Makefile.am.sample ] ; then \ - /bin/bash $(OPENAIR_TARGETS)/SCRIPTS/asn1_generate_rrc_messaging_c_code.bash ;\ - fi ;\ - if [ ! -s Makefile.inc.generated ] ; then \ - awk '/converter-sample.c/ {exit} // {print}' Makefile.am.sample > Makefile.inc.generated ;\ - fi ) - -include $(OPENAIR2_DIR)/RRC/LITE/MESSAGES/Makefile.inc.generated - -ASN_CONVERTER_SOURCES+=asn1_msg.c - -#COMMON_CFLAGS += -DEMIT_ASN_DEBUG=1 - -EXTRA_CFLAGS += -I. -I$(OPENAIR2_DIR)/RRC/LITE/MESSAGES - -ASN1_MODULE_OBJS=${ASN_MODULE_SOURCES:.c=.o} -ASN1_CONVERTER_OBJS=${ASN_CONVERTER_SOURCES:.c=.o} -ASN1_MSG_OBJS=$(ASN1_MODULE_OBJS) $(ASN1_CONVERTER_OBJS) diff --git a/openair2/RRC/LTE/rrc_eNB.c b/openair2/RRC/LTE/rrc_eNB.c index f9e51e2f08..cbce507341 100644 --- a/openair2/RRC/LTE/rrc_eNB.c +++ b/openair2/RRC/LTE/rrc_eNB.c @@ -115,9 +115,6 @@ extern RAN_CONTEXT_t RC; #endif extern eNB_MAC_INST *eNB_mac_inst; extern UE_MAC_INST *UE_mac_inst; -#ifdef BIGPHYSAREA - extern void *bigphys_malloc(int); -#endif extern uint16_t two_tier_hexagonal_cellIds[7]; diff --git a/openair2/RRC/LTE/rrc_extern.h b/openair2/RRC/LTE/rrc_extern.h index 90017dc80c..624a7efb75 100644 --- a/openair2/RRC/LTE/rrc_extern.h +++ b/openair2/RRC/LTE/rrc_extern.h @@ -53,7 +53,6 @@ extern unsigned char NB_INST; extern unsigned char NB_eNB_INST; extern unsigned char NB_UE_INST; extern unsigned short NODE_ID[1]; -extern void* bigphys_malloc(int); #endif diff --git a/openair2/RRC/NAS/Makefile.inc b/openair2/RRC/NAS/Makefile.inc deleted file mode 100644 index ea1a8a7a81..0000000000 --- a/openair2/RRC/NAS/Makefile.inc +++ /dev/null @@ -1,4 +0,0 @@ -#ifeq ($(NAS_FLAG),1) -NAS_OBJS = $(OPENAIR2_TOP)/RRC/NAS/nas_config.o -NAS_OBJS += $(OPENAIR2_TOP)/RRC/NAS/rb_config.o -#endif diff --git a/openair2/UTIL/BIGPHYS/bigphys.c b/openair2/UTIL/BIGPHYS/bigphys.c deleted file mode 100644 index 219a0c8d1b..0000000000 --- a/openair2/UTIL/BIGPHYS/bigphys.c +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.openairinterface.org/?page_id=698 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - *------------------------------------------------------------------------------- - * For more information about the OpenAirInterface (OAI) Software Alliance: - * contact@openairinterface.org - */ - -#include "defs.h" -#include "linux/module.h" - -#ifdef BIGPHYSAREA -#ifdef ARCH_64 -char *bigphys_ptr,*bigphys_current; -#else //ARCH_64 -unsigned int bigphys_ptr,bigphys_current; -#endif //ARCH_64 - -// return pointer to memory in big physical area aligned to 16 bytes - -void* bigphys_malloc(int n) -{ - - - - int n2 = n + ((16-(n%16))%16); -#ifdef ARCH_64 - char *bigphys_old; -#else - unsigned int bigphys_old; -#endif - - printk("[BIGPHYSAREA] Calling bigphys_malloc for %d (%d) bytes\n",n,n2); - -#ifdef ARCH_64 - printk("[BIGPHYSAREA] Allocated Memory @ %p\n",bigphys_current); -#endif - bigphys_old = bigphys_current; - bigphys_current += n2; - -#ifdef ARCH_64 - printk("[BIGPHYSAREA] Allocated Memory top now @ %p\n",bigphys_current); - return ((void *)(bigphys_old)); -#else //ARCH_64 - //printk("[BIGPHYSAREA] Allocated Memory %d\n",bigphys_current-bigphys_ptr); - return ((void *)(bigphys_old)); -#endif //ARCH_64 -} - -EXPORT_SYMBOL(bigphys_malloc); -#endif - - - diff --git a/openair2/UTIL/BIGPHYS/defs.h b/openair2/UTIL/BIGPHYS/defs.h deleted file mode 100644 index 69368a6d72..0000000000 --- a/openair2/UTIL/BIGPHYS/defs.h +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.openairinterface.org/?page_id=698 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - *------------------------------------------------------------------------------- - * For more information about the OpenAirInterface (OAI) Software Alliance: - * contact@openairinterface.org - */ - -void* bigphys_malloc(int); diff --git a/openair2/UTIL/Makefile.inc b/openair2/UTIL/Makefile.inc deleted file mode 100644 index fac8d7e9a1..0000000000 --- a/openair2/UTIL/Makefile.inc +++ /dev/null @@ -1,108 +0,0 @@ -MEM_DIR = $(OPENAIR2_TOP)/UTIL/MEM -LIST_DIR = $(OPENAIR2_TOP)/UTIL/LISTS -FIFO_DIR = $(OPENAIR2_TOP)/UTIL/FIFO -MATH_DIR = $(OPENAIR2_TOP)/UTIL/MATH -TIMER_DIR = $(OPENAIR2_TOP)/UTIL/TIMER -LOG_DIR=$(OPENAIR2_TOP)/UTIL/LOG -OCG_DIR=$(OPENAIR2_TOP)/UTIL/OCG -OPT_DIR=$(OPENAIR2_TOP)/UTIL/OPT -OMG_DIR=$(OPENAIR2_TOP)/UTIL/OMG -OTG_DIR=$(OPENAIR2_TOP)/UTIL/OTG -CLI_DIR=$(OPENAIR2_TOP)/UTIL/CLI -OMV_DIR=$(OPENAIR2_TOP)/UTIL/OMV -LFDS_DIR=$(OPENAIR2_TOP)/UTIL/LFDS/liblfds6.1.1/liblfds611 -OSA_DIR=$(OPENAIR2_TOP)/UTIL/OSA - -LIST_OBJ = $(LIST_DIR)/list.o - -FIFO_OBJ = $(FIFO_DIR)/pad_list.o - -LIST_OBJ += $(LIST_DIR)/list2.o - -TIMER_OBJ += $(TIMER_DIR)/umts_timer.o - -MEM_OBJ += $(MEM_DIR)/mem_block.o - -LOG_OBJS = $(LOG_DIR)/log.o -LOG_OBJS += $(LOG_DIR)/vcd_signal_dumper.o - -OCG_OBJS = $(OCG_DIR)/OCG.o -OCG_OBJS += $(OCG_DIR)/OCG_create_dir.o -OCG_OBJS += $(OCG_DIR)/OCG_detect_file.o -OCG_OBJS += $(OCG_DIR)/OCG_generate_report.o -OCG_OBJS += $(OCG_DIR)/OCG_parse_filename.o -OCG_OBJS += $(OCG_DIR)/OCG_parse_XML.o -OCG_OBJS += $(OCG_DIR)/OCG_save_XML.o - -ifdef SECU -OSA_OBJS = $(OSA_DIR)/osa_key_deriver.o -OSA_OBJS += $(OSA_DIR)/osa_stream_eia.o -OSA_OBJS += $(OSA_DIR)/osa_stream_eea.o -OSA_OBJS += $(OSA_DIR)/osa_snow3g.o -OSA_OBJS += $(OSA_DIR)/osa_rijndael.o -endif - -OPT_OBJS = $(OPT_DIR)/probe.o - -OMG_OBJS = $(OMG_DIR)/omg.o -OMG_OBJS += $(OMG_DIR)/common.o -OMG_OBJS += $(OMG_DIR)/job.o -OMG_OBJS += $(OMG_DIR)/static.o -OMG_OBJS += $(OMG_DIR)/rwp.o -OMG_OBJS += $(OMG_DIR)/rwalk.o -#OMG_OBJS += $(OMG_DIR)/omg_hashtable.o -OMG_OBJS += $(OMG_DIR)/mobility_parser.o -OMG_OBJS += $(OMG_DIR)/trace.o -OMG_OBJS += $(OMG_DIR)/sumo.o -OMG_OBJS += $(OMG_DIR)/id_manager.o -OMG_OBJS += $(OMG_DIR)/client_traci_OMG.o -OMG_OBJS += $(OMG_DIR)/storage_traci_OMG.o -OMG_OBJS += $(OMG_DIR)/socket_traci_OMG.o -OMG_OBJS += $(OMG_DIR)/steadystaterwp.o -OMG_OBJS += $(OMG_DIR)/grid.o -OMG_OBJS += $(OMG_DIR)/trace_hashtable.o - - -OTG_OBJS = $(OTG_DIR)/otg_tx.o -OTG_OBJS += $(OTG_DIR)/otg.o -OTG_OBJS += $(OTG_DIR)/otg_rx.o -OTG_OBJS += $(OTG_DIR)/otg_kpi.o -OTG_OBJS += $(OTG_DIR)/otg_form.o -OTG_OBJS += $(OTG_DIR)/otg_models.o - -MATH_OBJS = $(MATH_DIR)/oml.o - -CLI_OBJ = $(CLI_DIR)/cli_server.o -CLI_OBJ += $(CLI_DIR)/cli.o -CLI_OBJ += $(CLI_DIR)/cli_cmd.o - -UTIL_OBJ = \ - $(OSA_OBJS) \ - $(FIFO_OBJ) \ - $(LIST_OBJ) \ - $(TIMER_OBJ) \ - $(MEM_OBJ) \ - $(LOG_OBJS) \ - $(OCG_OBJS) \ - $(MATH_OBJS) \ - $(OTG_OBJS) \ - $(CLI_OBJ) \ - $(OMG_OBJS) \ - $(OPT_OBJS) - -UTIL_incl = \ - -I$(OPENAIR2_TOP)/UTIL \ - -I$(OSA_DIR) \ - -I$(LFDS_DIR)/inc \ - -I$(MEM_DIR) \ - -I$(LIST_DIR) \ - -I$(FIFO_DIR) \ - -I$(OCG_DIR) \ - -I$(LOG_DIR) \ - -I$(MATH_DIR) \ - -I$(TIMER_DIR) \ - -I$(OMG_DIR) \ - -I$(OTG_DIR) \ - -I$(CLI_DIR) \ - -I$(OPT_DIR) \ - -I$(OMV_DIR) diff --git a/openair2/UTIL/TIMER/umts_timer.c b/openair2/UTIL/TIMER/umts_timer.c deleted file mode 100644 index 1691fac363..0000000000 --- a/openair2/UTIL/TIMER/umts_timer.c +++ /dev/null @@ -1,175 +0,0 @@ -/* - * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.openairinterface.org/?page_id=698 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - *------------------------------------------------------------------------------- - * For more information about the OpenAirInterface (OAI) Software Alliance: - * contact@openairinterface.org - */ - -/*************************************************************************** - umts_timer.c - description - ------------------- - AUTHOR : Lionel GAUTHIER - COMPANY : EURECOM - EMAIL : Lionel.Gauthier@eurecom.fr - - - - ***************************************************************************/ -//#include "rtos_header.h" -#include "platform_types.h" - -#include "list.h" -#include "umts_timer_struct.h" -#include "mem_block.h" -#include "openair_defs.h" -//----------------------------------------------------------------------------- -void -umts_timer_check_time_out (list2_t * atimer_listP, uint32_t current_frame_tick_millisecondsP) -{ - //----------------------------------------------------------------------------- - struct timer_unit *timer; - mem_block_t *mem_unit; - uint8_t time_out = 255; - mem_unit = atimer_listP->head; - - // do it simple now. - while ((mem_unit) && (time_out)) { - timer = (struct timer_unit *) (mem_unit->data); - - if ((current_frame_tick_millisecondsP - timer->frame_tick_start) >= timer->frame_time_out) { - - mem_unit = list2_remove_head (atimer_listP); - (*(timer->proc)) (timer->protocol, timer->timer_id); - free_mem_block (mem_unit, __func__); - - mem_unit = atimer_listP->head; - } else { - time_out = 0; - } - } -} - -//----------------------------------------------------------------------------- -void -umts_timer_delete_timer (list2_t * atimer_listP, void *timer_idP) -{ - //----------------------------------------------------------------------------- - mem_block_t *mem_unit; - mem_unit = atimer_listP->head; - - while ((mem_unit)) { - if (((struct timer_unit *) (mem_unit->data))->timer_id == timer_idP) { - list2_remove_element (mem_unit, atimer_listP); - free_mem_block (mem_unit, __func__); - return; - } - - mem_unit = mem_unit->next; - } -} - -//----------------------------------------------------------------------------- -mem_block_t * -umts_add_timer_list_up (list2_t * atimer_listP, void (*procP) (void *, void *), void *protocolP, void *timer_idP, uint32_t frame_time_outP, uint32_t current_frame_tick_millisecondsP) -{ - //----------------------------------------------------------------------------- - struct mem_block_t *mb; - struct timer_unit *timer; - mem_block_t *mem_unit; - int32_t remaining_time; - uint8_t inserted = 0; - - mb = get_free_mem_block (sizeof (struct timer_unit), __func__); - if(mb==NULL) return NULL; - ((struct timer_unit *) (mb->data))->proc = procP; - ((struct timer_unit *) (mb->data))->protocol = protocolP; - ((struct timer_unit *) (mb->data))->timer_id = timer_idP; - ((struct timer_unit *) (mb->data))->frame_time_out = frame_time_outP; - ((struct timer_unit *) (mb->data))->frame_tick_start = current_frame_tick_millisecondsP; - - // insert the timer in list in ascending order - mem_unit = atimer_listP->head; - - while ((mem_unit) && (!inserted)) { - timer = (struct timer_unit *) (mem_unit->data); - - remaining_time = timer->frame_time_out - current_frame_tick_millisecondsP + timer->frame_tick_start; - - // not timed out - if ((remaining_time > 0) && (frame_time_outP < remaining_time)) { - inserted = 255; - - if (mem_unit == atimer_listP->head) { -#ifdef DEBUG_TIMER - msg ("[TIMER][CREATION] added timer_id %p at head time out %d current time %d proc %p \n", timer_idP, frame_time_outP, current_frame_tick_millisecondsP, *procP); -#endif - list2_add_head (mb, atimer_listP); - } else { -#ifdef DEBUG_TIMER - msg ("[TIMER][CREATION] inserted timer_id %p time out %d current time %d proc %p \n", timer_idP, frame_time_outP, current_frame_tick_millisecondsP, *procP); -#endif - mb->previous = mem_unit->previous; - mb->next = mem_unit; - mem_unit->previous->next = mb; - mem_unit->previous = mb; - } - } else { - mem_unit = mem_unit->next; - } - } - - if (!inserted) { -#ifdef DEBUG_TIMER - msg ("[TIMER][CREATION] added timer_id %p at tail time out %d current time %d proc %p \n", timer_idP, frame_time_outP, current_frame_tick_millisecondsP, *procP); -#endif - list2_add_tail (mb, atimer_listP); - } - - return mb; -} - -//----------------------------------------------------------------------------- -void -umts_stop_all_timers (list2_t * atimer_listP) -{ - //----------------------------------------------------------------------------- - list2_free (atimer_listP); -} - -//----------------------------------------------------------------------------- -void -umts_stop_all_timers_except (list2_t * atimer_listP, void (*procP) (void *, void *)) -{ - //----------------------------------------------------------------------------- - struct timer_unit *timer; - mem_block_t *mem_unit; - mem_block_t *mem_unit_to_delete; - mem_unit = atimer_listP->head; - - while ((mem_unit)) { - timer = (struct timer_unit *) (mem_unit->data); - - if (timer->proc != procP) { - mem_unit_to_delete = mem_unit; - mem_unit = mem_unit->next; - list2_remove_element (mem_unit_to_delete, atimer_listP); - free_mem_block (mem_unit_to_delete, __func__); - } else { - mem_unit = mem_unit->next; - } - } -} diff --git a/openair2/UTIL/TIMER/umts_timer.h b/openair2/UTIL/TIMER/umts_timer.h deleted file mode 100644 index 077b55cf0c..0000000000 --- a/openair2/UTIL/TIMER/umts_timer.h +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.openairinterface.org/?page_id=698 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - *------------------------------------------------------------------------------- - * For more information about the OpenAirInterface (OAI) Software Alliance: - * contact@openairinterface.org - */ - -/*************************************************************************** - umts_timer.h - description - ------------------- - AUTHOR : Lionel GAUTHIER - COMPANY : EURECOM - EMAIL : Lionel.Gauthier@eurecom.fr - - - ***************************************************************************/ -#ifndef __UMTS_TIMER_H__ -# define __UMTS_TIMER_H__ - - -# include "platform_types.h" -# include "lists_proto_extern.h" -# include "mem_mngt_proto_extern.h" - -# define UMTS_TIMER_NOT_STARTED 0x00 -# define UMTS_TIMER_STARTED 0x01 -# define UMTS_TIMER_TIMED_OUT 0x02 - - -void umts_timer_check_time_out (list2_t * atimer_listP, uint32_t current_frame_tick_millisecondsP); -mem_block *umts_add_timer_list_up (list2_t * atimer_listP, void (*procP) (void *, void *), void *protocolP, void *timer_idP, uint32_t frame_time_outP, uint32_t current_frame_tick_millisecondsP); - -struct timer_unit { - - void (*proc) (void *, void *); // proc executed when time_out - void *protocol; // arg should be a pointer on a allocated protocol entity private struct including its variables - void *timer_id; // arg should be a value or a pointer identifying the timer - // Example: rlc_am_sdu_discard_time_out(rlc_am, sdu) - uint32_t frame_time_out; - uint32_t frame_tick_start; -}; -#endif diff --git a/openair2/UTIL/TIMER/umts_timer_proto_extern.h b/openair2/UTIL/TIMER/umts_timer_proto_extern.h deleted file mode 100644 index b43b347e46..0000000000 --- a/openair2/UTIL/TIMER/umts_timer_proto_extern.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.openairinterface.org/?page_id=698 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - *------------------------------------------------------------------------------- - * For more information about the OpenAirInterface (OAI) Software Alliance: - * contact@openairinterface.org - */ - -/*************************************************************************** - umts_timer_proto_extern.h - description - ------------------- - AUTHOR : Lionel GAUTHIER - COMPANY : EURECOM - EMAIL : Lionel.Gauthier@eurecom.fr - - - ***************************************************************************/ -#ifndef __UMTS_TIMER_PROTO_EXTERN_H__ -# define __UMTS_TIMER_PROTO_EXTERN_H__ - -# include "platform_types.h" -# include "list.h" -# include "mem_block.h" - -extern void umts_timer_check_time_out (list2_t * atimer_listP, uint32_t current_frame_tick_millisecondsP); -extern void umts_timer_delete_timer (list2_t * atimer_listP, void *timer_idP); -extern mem_block_t *umts_add_timer_list_up (list2_t * atimer_listP, void (*procP) (void *, void *), void *protocolP, void *timer_idP, uint32_t frame_time_outP, - uint32_t current_frame_tick_millisecondsP); -extern void umts_stop_all_timers (list2_t * atimer_listP); -extern void umts_stop_all_timers_except (list2_t * atimer_listP, void (*procP) (void *, void *)); -#endif diff --git a/openair2/UTIL/TIMER/umts_timer_struct.h b/openair2/UTIL/TIMER/umts_timer_struct.h deleted file mode 100644 index c4886c7f80..0000000000 --- a/openair2/UTIL/TIMER/umts_timer_struct.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.openairinterface.org/?page_id=698 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - *------------------------------------------------------------------------------- - * For more information about the OpenAirInterface (OAI) Software Alliance: - * contact@openairinterface.org - */ - -/*************************************************************************** - umts_timer_struct.h - description - ------------------- - AUTHOR : Lionel GAUTHIER - COMPANY : EURECOM - EMAIL : Lionel.Gauthier@eurecom.fr - - - - ***************************************************************************/ -#ifndef __UMTS_TIMER_STRUCT_H__ -# define __UMTS_TIMER_STRUCT_H__ - -# include "platform_types.h" - -struct timer_unit { - - void (*proc) (void *, void *); // proc executed when time_out - void *protocol; // arg should be a pointer on a allocated protocol entity private struct including its variables - void *timer_id; // arg should be a value or a pointer identifying the timer - // Example: rlc_am_sdu_discard_time_out(rlc_am, sdu) - uint32_t frame_time_out; - uint32_t frame_tick_start; -}; -#endif diff --git a/openair2/X2AP/Makefile.inc b/openair2/X2AP/Makefile.inc deleted file mode 100755 index a301a9934e..0000000000 --- a/openair2/X2AP/Makefile.inc +++ /dev/null @@ -1,107 +0,0 @@ - -ASN1MESSAGESDIR=$(X2AP_DIR)/MESSAGES -ASN1DIR=$(ASN1MESSAGESDIR)/ASN1 - -#//ifeq ($(USE_MME), R10) -#// ASN1RELDIR=R10.7 -#//else -#//ASN1RELDIR=R11.2 -#//endif - -# TEMP -ASN1RELDIR=R11.2 - - -include $(ASN1DIR)/$(ASN1RELDIR)/Makefile.inc - -libx2ap_OBJECTS = \ - x2ap.o \ - x2ap_common.o \ - $(addprefix MESSAGES/ASN1/$(ASN1RELDIR)/, $(X2AP_ASN_MODULE_SOURCES)) - - - -# pull in dependency info for *existing* .o files --include $(OUTDIR)/*.d - -CFLAGS = \ - -Wall \ - -DENB_MODE \ - -DENABLE_USE_MME \ - -I. \ - -I$(ASN1MESSAGESDIR)/ASN1/$(ASN1RELDIR) \ - -I$(ASN1MESSAGESDIR) \ - -I$(OUTDIR) \ - -I../UTILS \ - $(ADD_CFLAGS) \ - $(X2AP_CFLAGS) \ - -Wuninitialized \ - -Werror=implicit-function-declaration - -X2AP_GENERATED = \ - $(OUTDIR)/x2ap_encoder.o \ - $(OUTDIR)/x2ap_decoder.o \ - $(OUTDIR)/x2ap_xer_print.o - -$(OUTDIR)/%.o : %.c - @echo "Compiling $<" - @echo "Compiling $< with CFLAGS= $(CFLAGS)" - @if [ ! -d $(dir $@) ]; then mkdir -p $(dir $@); fi; - @$(CC) -c $(CFLAGS) -o $@ $< - @$(CC) -MM $(CFLAGS) $< > $(basename $@).d - @mv -f $(basename $@).d $(basename $@).d.tmp - @sed -e 's|.*:|$@:|' < $(basename $@).d.tmp > $(basename $@).d - @sed -e 's/.*://' -e 's/\\$$//' < $(basename $@).d.tmp | fmt -1 | \ - sed -e 's/^ *//' -e 's/$$/:/' >> $(basename $@).d - @rm -f $(basename $@).d.tmp - -$(X2AP_GENERATED): %.o : %.c - @echo "Compiling $<" - @echo "Compiling $< with CFLAGS= $(CFLAGS)" - @if [ ! -d $(dir $@) ]; then mkdir -p $(dir $@); fi; - @$(CC) -c $(CFLAGS) -o $@ $< - @$(CC) -MM $(CFLAGS) $< > $(basename $@).d - @mv -f $(basename $@).d $(basename $@).d.tmp - @sed -e 's|.*:|$@:|' < $(basename $@).d.tmp > $(basename $@).d - @sed -e 's/.*://' -e 's/\\$$//' < $(basename $@).d.tmp | fmt -1 | \ - sed -e 's/^ *//' -e 's/$$/:/' >> $(basename $@).d - @rm -f $(basename $@).d.tmp - - -$(OUTDIR)/x2ap_ieregen.stamp: $(ASN1DIR)/$(ASN1RELDIR)/X2AP-PDU-Contents.asn $(ASN1DIR)/asn1tostruct.py - @if [ ! -d $(OUTDIR) ]; then mkdir -p $(OUTDIR); fi; - @python $(ASN1DIR)/asn1tostruct.py -f$< -o$(OUTDIR) - @echo Timestamp > $@ - -#ProtocolExtensionContainer -#$(ASN1DIR)/$(ASN1RELDIR)/X2AP-PDU.asn - -$(OUTDIR)/x2ap_asn1regen.stamp: $(ASN1DIR)/$(ASN1RELDIR)/X2AP-CommonDataTypes.asn $(ASN1DIR)/$(ASN1RELDIR)/X2AP-Constants.asn $(ASN1DIR)/$(ASN1RELDIR)/X2AP-IEs.asn $(ASN1DIR)/$(ASN1RELDIR)/X2AP-PDU.asn - @echo "Timestamp DIR " $(ASN1DIR) " DIRREL " $(ASN1RELDIR) -# (cd $(ASN1DIR)/$(ASN1RELDIR) && asn1c -fhave_native64 -gen-PER -fcompound-names $^) - (cd $(ASN1MESSAGESDIR) && asn1c -fhave_native64 -gen-PER -fcompound-names -fskeletons-copy $^) - @echo "Timestamp X2AP_CFLAGS: " $(X2AP_CFLAGS) - @echo Timestamp > $@ - -$(OUTDIR)/libx2ap.a: $(OUTDIR)/x2ap_ieregen.stamp $(OUTDIR)/x2ap_asn1regen.stamp $(X2AP_GENERATED) $(addprefix $(OUTDIR)/,$(libx2ap_OBJECTS)) - @echo Creating X2AP archive - @echo libx2ap_OBJECTS $(libx2ap_OBJECTS) - @$(AR) rcs $@ $(X2AP_GENERATED) $(addprefix $(OUTDIR)/,$(libx2ap_OBJECTS)) - -clean: - @$(RM_F_V) $(OUTDIR)/*.o - @$(RM_F_V) $(OUTDIR)/*.d - @$(RM_F_V) $(addprefix $(OUTDIR)/MESSAGES/ASN1/$(ASN1RELDIR), $(X2AP_ASN_MODULE_SOURCES)) - @$(RM_F_V) $(addprefix $(OUTDIR)/MESSAGES/ASN1/$(ASN1RELDIR), $(X2AP_ASN_MODULE_SOURCES:.o=.d)) - @$(RM_F_V) $(OUTDIR)/libx2ap.a - @$(RM_F_V) $(OUTDIR)/x2ap_asn1regen.stamp - @$(RM_F_V) $(OUTDIR)/x2ap_ieregen.stamp - @$(RM_F_V) $(OUTDIR)/x2ap_decoder.c $(OUTDIR)/x2ap_encoder.c - @$(RM_F_V) $(OUTDIR)/x2ap_xer_print.c $(OUTDIR)/x2ap_ies_defs.h - -cleanall: clean - @$(RM_F_V) $(addprefix $(OUTDIR)/MESSAGES/ASN1/$(ASN1RELDIR), $(X2AP_ASN_MODULE_SOURCES:.o=.c)) - @$(RM_F_V) $(addprefix $(OUTDIR)/MESSAGES/ASN1/$(ASN1RELDIR), $(X2AP_ASN_MODULE_SOURCES:.o=.h)) - -showcflags: - @echo x2ap cflags: $(CFLAGS) diff --git a/openair3/COMMON/as_message.h b/openair3/COMMON/as_message.h deleted file mode 100644 index 30810a325e..0000000000 --- a/openair3/COMMON/as_message.h +++ /dev/null @@ -1,578 +0,0 @@ -/* - * Copyright (c) 2015, EURECOM (www.eurecom.fr) - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * The views and conclusions contained in the software and documentation are those - * of the authors and should not be interpreted as representing official policies, - * either expressed or implied, of the FreeBSD Project. - */ - - -/***************************************************************************** - -Source as_message.h - -Version 0.1 - -Date 2012/10/18 - -Product NAS stack - -Subsystem Application Programming Interface - -Author Frederic Maurel - -Description Defines the messages supported by the Access Stratum sublayer - protocol (usually RRC and S1AP for E-UTRAN) and functions used - to encode and decode - -*****************************************************************************/ -#ifndef __AS_MESSAGE_H__ -#define __AS_MESSAGE_H__ - -#include "commonDef.h" -#include "networkDef.h" - -/****************************************************************************/ -/********************* G L O B A L C O N S T A N T S *******************/ -/****************************************************************************/ - -/* - * -------------------------------------------------------------------------- - * Access Stratum message types - * -------------------------------------------------------------------------- - */ -#define AS_REQUEST 0x0100 -#define AS_RESPONSE 0x0200 -#define AS_INDICATION 0x0400 -#define AS_CONFIRM 0x0800 - -/* - * -------------------------------------------------------------------------- - * Access Stratum message identifiers - * -------------------------------------------------------------------------- - */ - -/* Broadcast information */ -#define AS_BROADCAST_INFO 0x01 -#define AS_BROADCAST_INFO_IND (AS_BROADCAST_INFO | AS_INDICATION) - -/* Cell information relevant for cell selection processing */ -#define AS_CELL_INFO 0x02 -#define AS_CELL_INFO_REQ (AS_CELL_INFO | AS_REQUEST) -#define AS_CELL_INFO_CNF (AS_CELL_INFO | AS_CONFIRM) -#define AS_CELL_INFO_IND (AS_CELL_INFO | AS_INDICATION) - -/* Paging information */ -#define AS_PAGING 0x03 -#define AS_PAGING_REQ (AS_PAGING | AS_REQUEST) -#define AS_PAGING_IND (AS_PAGING | AS_INDICATION) - -/* NAS signalling connection establishment */ -#define AS_NAS_ESTABLISH 0x04 -#define AS_NAS_ESTABLISH_REQ (AS_NAS_ESTABLISH | AS_REQUEST) -#define AS_NAS_ESTABLISH_IND (AS_NAS_ESTABLISH | AS_INDICATION) -#define AS_NAS_ESTABLISH_RSP (AS_NAS_ESTABLISH | AS_RESPONSE) -#define AS_NAS_ESTABLISH_CNF (AS_NAS_ESTABLISH | AS_CONFIRM) - -/* NAS signalling connection release */ -#define AS_NAS_RELEASE 0x05 -#define AS_NAS_RELEASE_REQ (AS_NAS_RELEASE | AS_REQUEST) -#define AS_NAS_RELEASE_IND (AS_NAS_RELEASE | AS_INDICATION) - -/* Uplink information transfer */ -#define AS_UL_INFO_TRANSFER 0x06 -#define AS_UL_INFO_TRANSFER_REQ (AS_UL_INFO_TRANSFER | AS_REQUEST) -#define AS_UL_INFO_TRANSFER_CNF (AS_UL_INFO_TRANSFER | AS_CONFIRM) -#define AS_UL_INFO_TRANSFER_IND (AS_UL_INFO_TRANSFER | AS_INDICATION) - -/* Downlink information transfer */ -#define AS_DL_INFO_TRANSFER 0x07 -#define AS_DL_INFO_TRANSFER_REQ (AS_DL_INFO_TRANSFER | AS_REQUEST) -#define AS_DL_INFO_TRANSFER_CNF (AS_DL_INFO_TRANSFER | AS_CONFIRM) -#define AS_DL_INFO_TRANSFER_IND (AS_DL_INFO_TRANSFER | AS_INDICATION) - -/* Radio Access Bearer establishment */ -#define AS_RAB_ESTABLISH 0x08 -#define AS_RAB_ESTABLISH_REQ (AS_RAB_ESTABLISH | AS_REQUEST) -#define AS_RAB_ESTABLISH_IND (AS_RAB_ESTABLISH | AS_INDICATION) -#define AS_RAB_ESTABLISH_RSP (AS_RAB_ESTABLISH | AS_RESPONSE) -#define AS_RAB_ESTABLISH_CNF (AS_RAB_ESTABLISH | AS_CONFIRM) - -/* Radio Access Bearer release */ -#define AS_RAB_RELEASE 0x09 -#define AS_RAB_RELEASE_REQ (AS_RAB_RELEASE | AS_REQUEST) -#define AS_RAB_RELEASE_IND (AS_RAB_RELEASE | AS_INDICATION) - -/* NAS Cause */ -#define EPS_SERVICES_AND_NON_EPS_SERVICES_NOT_ALLOWED (8) -#define EPS_SERVICES_NOT_ALLOWED (7) -#define PLMN_NOT_ALLOWED (11) -#define TRACKING_AREA_NOT_ALLOWED (12) -#define ROAMING_NOT_ALLOWED_IN_THIS_TRACKING_AREA (13) -#define EPS_SERVICES_NOT_ALLOWED_IN_THIS_PLMN (14) -#define NO_SUITABLE_CELLS_IN_TRACKING_AREA (15) -#define NETWORK_FAILURE (17) -#define ESM_FAILURE (19) - -typedef enum nas_cause_s { - NAS_CAUSE_EPS_SERVICES_AND_NON_EPS_SERVICES_NOT_ALLOWED = EPS_SERVICES_AND_NON_EPS_SERVICES_NOT_ALLOWED, - NAS_CAUSE_EPS_SERVICES_NOT_ALLOWED = EPS_SERVICES_NOT_ALLOWED, - NAS_CAUSE_PLMN_NOT_ALLOWED = PLMN_NOT_ALLOWED, - NAS_CAUSE_TRACKING_AREA_NOT_ALLOWED = TRACKING_AREA_NOT_ALLOWED, - NAS_CAUSE_ROAMING_NOT_ALLOWED_IN_THIS_TRACKING_AREA = ROAMING_NOT_ALLOWED_IN_THIS_TRACKING_AREA, - NAS_CAUSE_EPS_SERVICES_NOT_ALLOWED_IN_THIS_PLMN = EPS_SERVICES_NOT_ALLOWED_IN_THIS_PLMN, - NAS_CAUSE_NO_SUITABLE_CELLS_IN_TRACKING_AREA = NO_SUITABLE_CELLS_IN_TRACKING_AREA, - NAS_CAUSE_NETWORK_FAILURE = NETWORK_FAILURE, - NAS_CAUSE_ESM_FAILURE = ESM_FAILURE -} nas_cause_t; - -/* - * -------------------------------------------------------------------------- - * Access Stratum message global parameters - * -------------------------------------------------------------------------- - */ - -/* Error code */ -typedef enum nas_error_code_s { - AS_SUCCESS = 1, /* Success code, transaction is going on */ - AS_TERMINATED_NAS, /* Transaction terminated by NAS */ - AS_TERMINATED_AS, /* Transaction terminated by AS */ - AS_FAILURE /* Failure code */ -} nas_error_code_t; - -/* Core network domain */ -typedef enum core_network_s { - AS_PS = 1, /* Packet-Switched */ - AS_CS /* Circuit-Switched */ -} core_network_t; - -/* SAE Temporary Mobile Subscriber Identity */ -typedef struct as_stmsi_s { - uint8_t MMEcode; /* MME code that allocated the GUTI */ - uint32_t m_tmsi; /* M-Temporary Mobile Subscriber Identity */ -} as_stmsi_t; - -/* Dedicated NAS information */ -typedef struct as_nas_info_s { - uint32_t length; /* Length of the NAS information data */ - Byte_t* data; /* Dedicated NAS information data container */ -} as_nas_info_t; - -/* Radio Access Bearer identity */ -typedef uint8_t as_rab_id_t; - -/****************************************************************************/ -/************************ G L O B A L T Y P E S ************************/ -/****************************************************************************/ - -/* - * -------------------------------------------------------------------------- - * Broadcast information - * -------------------------------------------------------------------------- - */ - -/* - * AS->NAS - Broadcast information indication - * AS may asynchronously report to NAS available PLMNs within specific - * location area - */ -typedef struct broadcast_info_ind_s { -#define PLMN_LIST_MAX_SIZE 6 - PLMN_LIST_T(PLMN_LIST_MAX_SIZE) plmnIDs; /* List of PLMN identifiers */ - ci_t cellID; /* Identity of the cell serving the listed PLMNs */ - tac_t tac; /* Code of the tracking area the cell belongs to */ -} broadcast_info_ind_t; - -/* - * -------------------------------------------------------------------------- - * Cell information relevant for cell selection processing - * -------------------------------------------------------------------------- - */ - -/* Radio access technologies supported by the network */ -#define AS_GSM (1 << NET_ACCESS_GSM) -#define AS_COMPACT (1 << NET_ACCESS_COMPACT) -#define AS_UTRAN (1 << NET_ACCESS_UTRAN) -#define AS_EGPRS (1 << NET_ACCESS_EGPRS) -#define AS_HSDPA (1 << NET_ACCESS_HSDPA) -#define AS_HSUPA (1 << NET_ACCESS_HSUPA) -#define AS_HSDUPA (1 << NET_ACCESS_HSDUPA) -#define AS_EUTRAN (1 << NET_ACCESS_EUTRAN) - -/* - * NAS->AS - Cell Information request - * NAS request AS to search for a suitable cell belonging to the selected - * PLMN to camp on. - */ -typedef struct cell_info_req_s { - plmn_t plmnID; /* Selected PLMN identity */ - Byte_t rat; /* Bitmap - set of radio access technologies */ -} cell_info_req_t; - -/* - * AS->NAS - Cell Information confirm - * AS search for a suitable cell and respond to NAS. If found, the cell - * is selected to camp on. - */ -typedef struct cell_info_cnf_s { - uint8_t errCode; /* Error code */ - ci_t cellID; /* Identity of the cell serving the selected PLMN */ - tac_t tac; /* Code of the tracking area the cell belongs to */ - AcT_t rat; /* Radio access technology supported by the cell */ - uint8_t rsrq; /* Reference signal received quality */ - uint8_t rsrp; /* Reference signal received power */ -} cell_info_cnf_t; - -/* - * AS->NAS - Cell Information indication - * AS may change cell selection if a more suitable cell is found. - */ -typedef struct cell_info_ind_s { - ci_t cellID; /* Identity of the new serving cell */ - tac_t tac; /* Code of the tracking area the cell belongs to */ -} cell_info_ind_t; - -/* - * -------------------------------------------------------------------------- - * Paging information - * -------------------------------------------------------------------------- - */ - -/* Paging cause */ -typedef enum paging_cause_s { - AS_CONNECTION_ESTABLISH, /* Establish NAS signalling connection */ - AS_EPS_ATTACH, /* Perform local detach and initiate EPS - * attach procedure */ - AS_CS_FALLBACK /* Inititate CS fallback procedure */ -} paging_cause_t; - -/* - * NAS->AS - Paging Information request - * NAS requests the AS that NAS signalling messages or user data is pending - * to be sent. - */ -typedef struct paging_req_s { - as_stmsi_t s_tmsi; /* UE identity */ - uint8_t CN_domain; /* Core network domain */ -} paging_req_t; - -/* - * AS->NAS - Paging Information indication - * AS reports to the NAS that appropriate procedure has to be initiated. - */ -typedef struct paging_ind_s { - paging_cause_t cause; /* Paging cause */ -} paging_ind_t; - -/* - * -------------------------------------------------------------------------- - * NAS signalling connection establishment - * -------------------------------------------------------------------------- - */ - -/* Cause of RRC connection establishment */ -typedef enum as_cause_s { - AS_CAUSE_UNKNOWN = 0, - AS_CAUSE_EMERGENCY = NET_ESTABLISH_CAUSE_EMERGENCY, - AS_CAUSE_HIGH_PRIO = NET_ESTABLISH_CAUSE_HIGH_PRIO, - AS_CAUSE_MT_ACCESS = NET_ESTABLISH_CAUSE_MT_ACCESS, - AS_CAUSE_MO_SIGNAL = NET_ESTABLISH_CAUSE_MO_SIGNAL, - AS_CAUSE_MO_DATA = NET_ESTABLISH_CAUSE_MO_DATA, - AS_CAUSE_V1020 = NET_ESTABLISH_CAUSE_V1020 -} as_cause_t; - -/* Type of the call associated to the RRC connection establishment */ -typedef enum as_call_type_s { - AS_TYPE_ORIGINATING_SIGNAL = NET_ESTABLISH_TYPE_ORIGINATING_SIGNAL, - AS_TYPE_EMERGENCY_CALLS = NET_ESTABLISH_TYPE_EMERGENCY_CALLS, - AS_TYPE_ORIGINATING_CALLS = NET_ESTABLISH_TYPE_ORIGINATING_CALLS, - AS_TYPE_TERMINATING_CALLS = NET_ESTABLISH_TYPE_TERMINATING_CALLS, - AS_TYPE_MO_CS_FALLBACK = NET_ESTABLISH_TYPE_MO_CS_FALLBACK -} as_call_type_t; - -/* - * NAS->AS - NAS signalling connection establishment request - * NAS requests the AS to perform the RRC connection establishment procedure - * to transfer initial NAS message to the network while UE is in IDLE mode. - */ -typedef struct nas_establish_req_s { - as_cause_t cause; /* RRC connection establishment cause */ - as_call_type_t type; /* RRC associated call type */ - as_stmsi_t s_tmsi; /* UE identity */ - plmn_t plmnID; /* Selected PLMN identity */ - as_nas_info_t initialNasMsg; /* Initial NAS message to transfer */ -} nas_establish_req_t; - -/* - * AS->NAS - NAS signalling connection establishment indication - * AS transfers the initial NAS message to the NAS. - */ -typedef struct nas_establish_ind_s { - uint32_t UEid; /* UE lower layer identifier */ - tac_t tac; /* Code of the tracking area the initiating - * UE belongs to */ - as_cause_t asCause; /* Establishment cause */ - as_nas_info_t initialNasMsg; /* Initial NAS message to transfer */ -} nas_establish_ind_t; - -/* - * NAS->AS - NAS signalling connection establishment response - * NAS responds to the AS that initial answer message has to be provided to - * the UE. - */ -typedef struct nas_establish_rsp_s { - uint32_t UEid; /* UE lower layer identifier */ - as_stmsi_t s_tmsi; /* UE identity */ - nas_error_code_t errCode; /* Transaction status */ - as_nas_info_t nasMsg; /* NAS message to transfer */ - uint32_t nas_ul_count; /* UL NAS COUNT */ - uint16_t selected_encryption_algorithm; - uint16_t selected_integrity_algorithm; -} nas_establish_rsp_t; - -/* - * AS->NAS - NAS signalling connection establishment confirm - * AS transfers the initial answer message to the NAS. - */ -typedef struct nas_establish_cnf_s { - uint32_t UEid; /* UE lower layer identifier */ - nas_error_code_t errCode; /* Transaction status */ - as_nas_info_t nasMsg; /* NAS message to transfer */ - uint32_t ul_nas_count; - uint16_t selected_encryption_algorithm; - uint16_t selected_integrity_algorithm; -} nas_establish_cnf_t; - -/* - * -------------------------------------------------------------------------- - * NAS signalling connection release - * -------------------------------------------------------------------------- - */ - -/* Release cause */ -typedef enum release_cause_s { - AS_AUTHENTICATION_FAILURE = 1, /* Authentication procedure failed */ - AS_DETACH /* Detach requested */ -} release_cause_t; - -/* - * NAS->AS - NAS signalling connection release request - * NAS requests the termination of the connection with the UE. - */ -typedef struct nas_release_req_s { - uint32_t UEid; /* UE lower layer identifier */ - as_stmsi_t s_tmsi; /* UE identity */ - release_cause_t cause; /* Release cause */ -} nas_release_req_t; - -/* - * AS->NAS - NAS signalling connection release indication - * AS reports that connection has been terminated by the network. - */ -typedef struct nas_release_ind_s { - release_cause_t cause; /* Release cause */ -} nas_release_ind_t; - -/* - * -------------------------------------------------------------------------- - * NAS information transfer - * -------------------------------------------------------------------------- - */ - -/* - * NAS->AS - Uplink data transfer request - * NAS requests the AS to transfer uplink information to the NAS that - * operates at the network side. - */ -typedef struct ul_info_transfer_req_s { - uint32_t UEid; /* UE lower layer identifier */ - as_stmsi_t s_tmsi; /* UE identity */ - as_nas_info_t nasMsg; /* Uplink NAS message */ -} ul_info_transfer_req_t; - -/* - * AS->NAS - Uplink data transfer confirm - * AS immediately notifies the NAS whether uplink information has been - * successfully sent to the network or not. - */ -typedef struct ul_info_transfer_cnf_s { - uint32_t UEid; /* UE lower layer identifier */ - nas_error_code_t errCode; /* Transaction status */ -} ul_info_transfer_cnf_t; - -/* - * AS->NAS - Uplink data transfer indication - * AS delivers the uplink information message to the NAS that operates - * at the network side. - */ -typedef struct ul_info_transfer_ind_s { - uint32_t UEid; /* UE lower layer identifier */ - as_nas_info_t nasMsg; /* Uplink NAS message */ -} ul_info_transfer_ind_t; - -/* - * NAS->AS - Downlink data transfer request - * NAS requests the AS to transfer downlink information to the NAS that - * operates at the UE side. - */ -typedef ul_info_transfer_req_t dl_info_transfer_req_t; - -/* - * AS->NAS - Downlink data transfer confirm - * AS immediately notifies the NAS whether downlink information has been - * successfully sent to the network or not. - */ -typedef ul_info_transfer_cnf_t dl_info_transfer_cnf_t; - -/* - * AS->NAS - Downlink data transfer indication - * AS delivers the downlink information message to the NAS that operates - * at the UE side. - */ -typedef ul_info_transfer_ind_t dl_info_transfer_ind_t; - -/* - * -------------------------------------------------------------------------- - * Radio Access Bearer establishment - * -------------------------------------------------------------------------- - */ - -/* TODO: Quality of Service parameters */ -typedef struct {} as_qos_t; - -/* - * NAS->AS - Radio access bearer establishment request - * NAS requests the AS to allocate transmission resources to radio access - * bearer initialized at the network side. - */ -typedef struct rab_establish_req_s { - as_stmsi_t s_tmsi; /* UE identity */ - as_rab_id_t rabID; /* Radio access bearer identity */ - as_qos_t QoS; /* Requested Quality of Service */ -} rab_establish_req_t; - -/* - * AS->NAS - Radio access bearer establishment indication - * AS notifies the NAS that specific radio access bearer has to be setup. - */ -typedef struct rab_establish_ind_s { - as_rab_id_t rabID; /* Radio access bearer identity */ -} rab_establish_ind_t; - -/* - * NAS->AS - Radio access bearer establishment response - * NAS responds to AS whether the specified radio access bearer has been - * successfully setup or not. - */ -typedef struct rab_establish_rsp_s { - as_stmsi_t s_tmsi; /* UE identity */ - as_rab_id_t rabID; /* Radio access bearer identity */ - nas_error_code_t errCode; /* Transaction status */ -} rab_establish_rsp_t; - -/* - * AS->NAS - Radio access bearer establishment confirm - * AS notifies NAS whether the specified radio access bearer has been - * successfully setup at the UE side or not. - */ -typedef struct rab_establish_cnf_s { - as_rab_id_t rabID; /* Radio access bearer identity */ - nas_error_code_t errCode; /* Transaction status */ -} rab_establish_cnf_t; - -/* - * -------------------------------------------------------------------------- - * Radio Access Bearer release - * -------------------------------------------------------------------------- - */ - -/* - * NAS->AS - Radio access bearer release request - * NAS requests the AS to release transmission resources previously allocated - * to specific radio access bearer at the network side. - */ -typedef struct rab_release_req_s { - as_stmsi_t s_tmsi; /* UE identity */ - as_rab_id_t rabID; /* Radio access bearer identity */ -} rab_release_req_t; - -/* - * AS->NAS - Radio access bearer release indication - * AS notifies NAS that specific radio access bearer has been released. - */ -typedef struct rab_release_ind_s { - as_rab_id_t rabID; /* Radio access bearer identity */ -} rab_release_ind_t; - -/* - * -------------------------------------------------------------------------- - * Structure of the AS messages handled by the network sublayer - * -------------------------------------------------------------------------- - */ -typedef struct as_message_s { - uint16_t msgID; - union { - broadcast_info_ind_t broadcast_info_ind; - cell_info_req_t cell_info_req; - cell_info_cnf_t cell_info_cnf; - cell_info_ind_t cell_info_ind; - paging_req_t paging_req; - paging_ind_t paging_ind; - nas_establish_req_t nas_establish_req; - nas_establish_ind_t nas_establish_ind; - nas_establish_rsp_t nas_establish_rsp; - nas_establish_cnf_t nas_establish_cnf; - nas_release_req_t nas_release_req; - nas_release_ind_t nas_release_ind; - ul_info_transfer_req_t ul_info_transfer_req; - ul_info_transfer_cnf_t ul_info_transfer_cnf; - ul_info_transfer_ind_t ul_info_transfer_ind; - dl_info_transfer_req_t dl_info_transfer_req; - dl_info_transfer_cnf_t dl_info_transfer_cnf; - dl_info_transfer_ind_t dl_info_transfer_ind; - rab_establish_req_t rab_establish_req; - rab_establish_ind_t rab_establish_ind; - rab_establish_rsp_t rab_establish_rsp; - rab_establish_cnf_t rab_establish_cnf; - rab_release_req_t rab_release_req; - rab_release_ind_t rab_release_ind; - } __attribute__((__packed__)) msg; -} as_message_t; - -/****************************************************************************/ -/******************** G L O B A L V A R I A B L E S ********************/ -/****************************************************************************/ - -/****************************************************************************/ -/****************** E X P O R T E D F U N C T I O N S ******************/ -/****************************************************************************/ - -int as_message_decode(const char* buffer, as_message_t* msg, int length); - -int as_message_encode(char* buffer, as_message_t* msg, int length); - -/* Implemented in the network_api.c body file */ -int as_message_send(as_message_t* as_msg); - -#endif /* __AS_MESSAGE_H__*/ diff --git a/openair3/COMMON/gtpv1_u_messages_def.h b/openair3/COMMON/gtpv1_u_messages_def.h deleted file mode 100644 index 4308853515..0000000000 --- a/openair3/COMMON/gtpv1_u_messages_def.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.openairinterface.org/?page_id=698 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - *------------------------------------------------------------------------------- - * For more information about the OpenAirInterface (OAI) Software Alliance: - * contact@openairinterface.org - */ - -MESSAGE_DEF(GTPV1U_CREATE_TUNNEL_REQ, MESSAGE_PRIORITY_MED, Gtpv1uCreateTunnelReq, gtpv1uCreateTunnelReq) -MESSAGE_DEF(GTPV1U_CREATE_TUNNEL_RESP, MESSAGE_PRIORITY_MED, Gtpv1uCreateTunnelResp, gtpv1uCreateTunnelResp) -MESSAGE_DEF(GTPV1U_UPDATE_TUNNEL_REQ, MESSAGE_PRIORITY_MED, Gtpv1uUpdateTunnelReq, gtpv1uUpdateTunnelReq) -MESSAGE_DEF(GTPV1U_UPDATE_TUNNEL_RESP, MESSAGE_PRIORITY_MED, Gtpv1uUpdateTunnelResp, gtpv1uUpdateTunnelResp) -MESSAGE_DEF(GTPV1U_DELETE_TUNNEL_REQ, MESSAGE_PRIORITY_MED, Gtpv1uDeleteTunnelReq, gtpv1uDeleteTunnelReq) -MESSAGE_DEF(GTPV1U_DELETE_TUNNEL_RESP, MESSAGE_PRIORITY_MED, Gtpv1uDeleteTunnelResp, gtpv1uDeleteTunnelResp) -MESSAGE_DEF(GTPV1U_TUNNEL_DATA_IND, MESSAGE_PRIORITY_MED, Gtpv1uTunnelDataInd, gtpv1uTunnelDataInd) -MESSAGE_DEF(GTPV1U_TUNNEL_DATA_REQ, MESSAGE_PRIORITY_MED, Gtpv1uTunnelDataReq, gtpv1uTunnelDataReq) diff --git a/openair3/COMMON/gtpv1_u_messages_types.h b/openair3/COMMON/gtpv1_u_messages_types.h deleted file mode 100644 index 594325647b..0000000000 --- a/openair3/COMMON/gtpv1_u_messages_types.h +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.openairinterface.org/?page_id=698 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - *------------------------------------------------------------------------------- - * For more information about the OpenAirInterface (OAI) Software Alliance: - * contact@openairinterface.org - */ - -#ifndef GTPV1_U_MESSAGES_TYPES_H_ -#define GTPV1_U_MESSAGES_TYPES_H_ - -#include "../SGW-LITE/sgw_lite_ie_defs.h" - -typedef struct { - Teid_t context_teid; ///< Tunnel Endpoint Identifier - ebi_t eps_bearer_id; -} Gtpv1uCreateTunnelReq; - -typedef struct { - uint8_t status; ///< Status of S1U endpoint creation (Failed = 0xFF or Success = 0x0) - Teid_t context_teid; ///< local SGW S11 Tunnel Endpoint Identifier - Teid_t S1u_teid; ///< Tunnel Endpoint Identifier - ebi_t eps_bearer_id; -} Gtpv1uCreateTunnelResp; - -typedef struct { - Teid_t context_teid; ///< S11 Tunnel Endpoint Identifier - Teid_t sgw_S1u_teid; ///< SGW S1U local Tunnel Endpoint Identifier - Teid_t enb_S1u_teid; ///< eNB S1U Tunnel Endpoint Identifier - ip_address_t enb_ip_address_for_S1u; - ebi_t eps_bearer_id; -} Gtpv1uUpdateTunnelReq; - -typedef struct { - uint8_t status; ///< Status (Failed = 0xFF or Success = 0x0) - Teid_t context_teid; ///< S11 Tunnel Endpoint Identifier - Teid_t sgw_S1u_teid; ///< SGW S1U local Tunnel Endpoint Identifier - Teid_t enb_S1u_teid; ///< eNB S1U Tunnel Endpoint Identifier - ebi_t eps_bearer_id; -} Gtpv1uUpdateTunnelResp; - -typedef struct { - Teid_t context_teid; ///< local SGW S11 Tunnel Endpoint Identifier - Teid_t S1u_teid; ///< local S1U Tunnel Endpoint Identifier to be deleted -} Gtpv1uDeleteTunnelReq; - -typedef struct { - uint8_t status; ///< Status of S1U endpoint deleteion (Failed = 0xFF or Success = 0x0) - Teid_t context_teid; ///< local SGW S11 Tunnel Endpoint Identifier - Teid_t S1u_teid; ///< local S1U Tunnel Endpoint Identifier to be deleted -} Gtpv1uDeleteTunnelResp; - -typedef struct { - uint8_t *buffer; - uint32_t length; - uint32_t offset; ///< start of message offset in buffer - Teid_t local_S1u_teid; ///< Tunnel Endpoint Identifier -} Gtpv1uTunnelDataInd; - -typedef struct { - uint8_t *buffer; - uint32_t length; - uint32_t offset; ///< start of message offset in buffer - Teid_t local_S1u_teid; ///< Tunnel Endpoint Identifier - Teid_t S1u_enb_teid; ///< Tunnel Endpoint Identifier -} Gtpv1uTunnelDataReq; - -#endif /* GTPV1_U_MESSAGES_TYPES_H_ */ diff --git a/openair3/COMMON/messages_def.h b/openair3/COMMON/messages_def.h deleted file mode 100644 index 1c1cdbaf0f..0000000000 --- a/openair3/COMMON/messages_def.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.openairinterface.org/?page_id=698 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - *------------------------------------------------------------------------------- - * For more information about the OpenAirInterface (OAI) Software Alliance: - * contact@openairinterface.org - */ - -// These messages files are mandatory and must always be placed in first position -#include "intertask_messages_def.h" -#include "timer_messages_def.h" - -// Messages files used between tasks -#include "gtpv1_u_messages_def.h" -#include "ip_forward_messages_def.h" -#include "nas_messages_def.h" -#include "s11_messages_def.h" -#include "s1ap_messages_def.h" -#include "s6a_messages_def.h" -#include "sctp_messages_def.h" -#include "sgw_lite_def.h" -#include "udp_messages_def.h" -#include "mme_app_messages_def.h" diff --git a/openair3/COMMON/nas_messages_def.h b/openair3/COMMON/nas_messages_def.h deleted file mode 100644 index 9bdcde4fdf..0000000000 --- a/openair3/COMMON/nas_messages_def.h +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.openairinterface.org/?page_id=698 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - *------------------------------------------------------------------------------- - * For more information about the OpenAirInterface (OAI) Software Alliance: - * contact@openairinterface.org - */ - -//WARNING: Do not include this header directly. Use intertask_interface.h instead. - -// Messages for NAS logging -MESSAGE_DEF(NAS_DL_EMM_RAW_MSG, MESSAGE_PRIORITY_MED, nas_raw_msg_t, nas_dl_emm_raw_msg) -MESSAGE_DEF(NAS_UL_EMM_RAW_MSG, MESSAGE_PRIORITY_MED, nas_raw_msg_t, nas_ul_emm_raw_msg) - -MESSAGE_DEF(NAS_DL_EMM_PLAIN_MSG, MESSAGE_PRIORITY_MED, nas_emm_plain_msg_t, nas_dl_emm_plain_msg) -MESSAGE_DEF(NAS_UL_EMM_PLAIN_MSG, MESSAGE_PRIORITY_MED, nas_emm_plain_msg_t, nas_ul_emm_plain_msg) -MESSAGE_DEF(NAS_DL_EMM_PROTECTED_MSG, MESSAGE_PRIORITY_MED, nas_emm_protected_msg_t, nas_dl_emm_protected_msg) -MESSAGE_DEF(NAS_UL_EMM_PROTECTED_MSG, MESSAGE_PRIORITY_MED, nas_emm_protected_msg_t, nas_ul_emm_protected_msg) - -MESSAGE_DEF(NAS_DL_ESM_RAW_MSG, MESSAGE_PRIORITY_MED, nas_raw_msg_t, nas_dl_esm_raw_msg) -MESSAGE_DEF(NAS_UL_ESM_RAW_MSG, MESSAGE_PRIORITY_MED, nas_raw_msg_t, nas_ul_esm_raw_msg) - -MESSAGE_DEF(NAS_DL_ESM_PLAIN_MSG, MESSAGE_PRIORITY_MED, nas_esm_plain_msg_t, nas_dl_esm_plain_msg) -MESSAGE_DEF(NAS_UL_ESM_PLAIN_MSG, MESSAGE_PRIORITY_MED, nas_esm_plain_msg_t, nas_ul_esm_plain_msg) -MESSAGE_DEF(NAS_DL_ESM_PROTECTED_MSG, MESSAGE_PRIORITY_MED, nas_esm_protected_msg_t, nas_dl_esm_protected_msg) -MESSAGE_DEF(NAS_UL_ESM_PROTECTED_MSG, MESSAGE_PRIORITY_MED, nas_esm_protected_msg_t, nas_ul_esm_protected_msg) - -/* */ -MESSAGE_DEF(NAS_PAGING_IND, MESSAGE_PRIORITY_MED, nas_paging_ind_t, nas_paging_ind) -MESSAGE_DEF(NAS_PDN_CONNECTIVITY_REQ, MESSAGE_PRIORITY_MED, nas_pdn_connectivity_req_t, nas_pdn_connectivity_req) -MESSAGE_DEF(NAS_CONNECTION_ESTABLISHMENT_IND, MESSAGE_PRIORITY_MED, nas_conn_est_ind_t, nas_conn_est_ind) -MESSAGE_DEF(NAS_CONNECTION_ESTABLISHMENT_CNF, MESSAGE_PRIORITY_MED, nas_conn_est_cnf_t, nas_conn_est_cnf) -MESSAGE_DEF(NAS_CONNECTION_RELEASE_IND, MESSAGE_PRIORITY_MED, nas_conn_rel_ind_t, nas_conn_rel_ind) -MESSAGE_DEF(NAS_UPLINK_DATA_IND, MESSAGE_PRIORITY_MED, nas_ul_data_ind_t, nas_ul_data_ind) -MESSAGE_DEF(NAS_DOWNLINK_DATA_REQ, MESSAGE_PRIORITY_MED, nas_dl_data_req_t, nas_dl_data_req) -MESSAGE_DEF(NAS_DOWNLINK_DATA_CNF, MESSAGE_PRIORITY_MED, nas_dl_data_cnf_t, nas_dl_data_cnf) -MESSAGE_DEF(NAS_DOWNLINK_DATA_REJ, MESSAGE_PRIORITY_MED, nas_dl_data_rej_t, nas_dl_data_rej) -MESSAGE_DEF(NAS_RAB_ESTABLISHMENT_REQ, MESSAGE_PRIORITY_MED, nas_rab_est_req_t, nas_rab_est_req) -MESSAGE_DEF(NAS_RAB_ESTABLISHMENT_RESP, MESSAGE_PRIORITY_MED, nas_rab_est_rsp_t, nas_rab_est_rsp) -MESSAGE_DEF(NAS_RAB_RELEASE_REQ, MESSAGE_PRIORITY_MED, nas_rab_rel_req_t, nas_rab_rel_req) - -/* NAS layer -> MME app messages */ -MESSAGE_DEF(NAS_AUTHENTICATION_PARAM_REQ, MESSAGE_PRIORITY_MED, nas_auth_param_req_t, nas_auth_param_req) - -/* MME app -> NAS layer messages */ -MESSAGE_DEF(NAS_PDN_CONNECTIVITY_RSP, MESSAGE_PRIORITY_MED, nas_pdn_connectivity_rsp_t, nas_pdn_connectivity_rsp) -MESSAGE_DEF(NAS_PDN_CONNECTIVITY_FAIL, MESSAGE_PRIORITY_MED, nas_pdn_connectivity_fail_t, nas_pdn_connectivity_fail) -MESSAGE_DEF(NAS_AUTHENTICATION_PARAM_RSP, MESSAGE_PRIORITY_MED, nas_auth_param_rsp_t, nas_auth_param_rsp) -MESSAGE_DEF(NAS_AUTHENTICATION_PARAM_FAIL, MESSAGE_PRIORITY_MED, nas_auth_param_fail_t, nas_auth_param_fail) - diff --git a/openair3/COMMON/nas_messages_types.h b/openair3/COMMON/nas_messages_types.h deleted file mode 100644 index 81a44fa4f4..0000000000 --- a/openair3/COMMON/nas_messages_types.h +++ /dev/null @@ -1,329 +0,0 @@ -/* - * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.openairinterface.org/?page_id=698 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - *------------------------------------------------------------------------------- - * For more information about the OpenAirInterface (OAI) Software Alliance: - * contact@openairinterface.org - */ - -#include "as_message.h" -#include "nas_message.h" - -#ifndef NAS_MESSAGES_TYPES_H_ -#define NAS_MESSAGES_TYPES_H_ - -#define NAS_DL_EMM_RAW_MSG(mSGpTR) (mSGpTR)->ittiMsg.nas_dl_emm_raw_msg -#define NAS_UL_EMM_RAW_MSG(mSGpTR) (mSGpTR)->ittiMsg.nas_ul_emm_raw_msg - -#define NAS_DL_EMM_PROTECTED_MSG(mSGpTR) (mSGpTR)->ittiMsg.nas_dl_emm_protected_msg -#define NAS_UL_EMM_PROTECTED_MSG(mSGpTR) (mSGpTR)->ittiMsg.nas_ul_emm_protected_msg -#define NAS_DL_EMM_PLAIN_MSG(mSGpTR) (mSGpTR)->ittiMsg.nas_dl_emm_plain_msg -#define NAS_UL_EMM_PLAIN_MSG(mSGpTR) (mSGpTR)->ittiMsg.nas_ul_emm_plain_msg - -#define NAS_DL_ESM_RAW_MSG(mSGpTR) (mSGpTR)->ittiMsg.nas_dl_esm_raw_msg -#define NAS_UL_ESM_RAW_MSG(mSGpTR) (mSGpTR)->ittiMsg.nas_ul_esm_raw_msg - -#define NAS_DL_ESM_PROTECTED_MSG(mSGpTR) (mSGpTR)->ittiMsg.nas_dl_esm_protected_msg -#define NAS_UL_ESM_PROTECTED_MSG(mSGpTR) (mSGpTR)->ittiMsg.nas_ul_esm_protected_msg -#define NAS_DL_ESM_PLAIN_MSG(mSGpTR) (mSGpTR)->ittiMsg.nas_dl_esm_plain_msg -#define NAS_UL_ESM_PLAIN_MSG(mSGpTR) (mSGpTR)->ittiMsg.nas_ul_esm_plain_msg - -#define NAS_UL_DATA_IND(mSGpTR) (mSGpTR)->ittiMsg.nas_ul_data_ind -#define NAS_DL_DATA_REQ(mSGpTR) (mSGpTR)->ittiMsg.nas_dl_data_req -#define NAS_DL_DATA_CNF(mSGpTR) (mSGpTR)->ittiMsg.nas_dl_data_cnf -#define NAS_DL_DATA_REJ(mSGpTR) (mSGpTR)->ittiMsg.nas_dl_data_rej -#define NAS_PDN_CONNECTIVITY_REQ(mSGpTR) (mSGpTR)->ittiMsg.nas_pdn_connectivity_req -#define NAS_PDN_CONNECTIVITY_RSP(mSGpTR) (mSGpTR)->ittiMsg.nas_pdn_connectivity_rsp -#define NAS_PDN_CONNECTIVITY_FAIL(mSGpTR) (mSGpTR)->ittiMsg.nas_pdn_connectivity_fail -#define NAS_CONN_EST_IND(mSGpTR) (mSGpTR)->ittiMsg.nas_conn_est_ind -#define NAS_CONNECTION_ESTABLISHMENT_CNF(mSGpTR) (mSGpTR)->ittiMsg.nas_conn_est_cnf -#define NAS_BEARER_PARAM(mSGpTR) (mSGpTR)->ittiMsg.nas_bearer_param -#define NAS_AUTHENTICATION_REQ(mSGpTR) (mSGpTR)->ittiMsg.nas_auth_req -#define NAS_AUTHENTICATION_PARAM_REQ(mSGpTR) (mSGpTR)->ittiMsg.nas_auth_param_req -#define NAS_AUTHENTICATION_PARAM_RSP(mSGpTR) (mSGpTR)->ittiMsg.nas_auth_param_rsp -#define NAS_AUTHENTICATION_PARAM_FAIL(mSGpTR) (mSGpTR)->ittiMsg.nas_auth_param_fail - -#define NAS_DATA_LENGHT_MAX 256 - - - -typedef enum { - EMM_MSG_HEADER = 1, - EMM_MSG_ATTACH_REQUEST, - EMM_MSG_ATTACH_ACCEPT, - EMM_MSG_ATTACH_COMPLETE, - EMM_MSG_ATTACH_REJECT, - EMM_MSG_DETACH_REQUEST, - EMM_MSG_DETACH_ACCEPT, - EMM_MSG_TRACKING_AREA_UPDATE_REQUEST, - EMM_MSG_TRACKING_AREA_UPDATE_ACCEPT, - EMM_MSG_TRACKING_AREA_UPDATE_COMPLETE, - EMM_MSG_TRACKING_AREA_UPDATE_REJECT, - EMM_MSG_EXTENDED_SERVICE_REQUEST, - EMM_MSG_SERVICE_REQUEST, - EMM_MSG_SERVICE_REJECT, - EMM_MSG_GUTI_REALLOCATION_COMMAND, - EMM_MSG_GUTI_REALLOCATION_COMPLETE, - EMM_MSG_AUTHENTICATION_REQUEST, - EMM_MSG_AUTHENTICATION_RESPONSE, - EMM_MSG_AUTHENTICATION_REJECT, - EMM_MSG_AUTHENTICATION_FAILURE, - EMM_MSG_IDENTITY_REQUEST, - EMM_MSG_IDENTITY_RESPONSE, - EMM_MSG_SECURITY_MODE_COMMAND, - EMM_MSG_SECURITY_MODE_COMPLETE, - EMM_MSG_SECURITY_MODE_REJECT, - EMM_MSG_EMM_STATUS, - EMM_MSG_EMM_INFORMATION, - EMM_MSG_DOWNLINK_NAS_TRANSPORT, - EMM_MSG_UPLINK_NAS_TRANSPORT, - EMM_MSG_CS_SERVICE_NOTIFICATION, -} emm_message_ids_t; - - - -typedef enum { - ESM_MSG_HEADER = 1, - ESM_MSG_ACTIVATE_DEFAULT_EPS_BEARER_CONTEXT_REQUEST, - ESM_MSG_ACTIVATE_DEFAULT_EPS_BEARER_CONTEXT_ACCEPT, - ESM_MSG_ACTIVATE_DEFAULT_EPS_BEARER_CONTEXT_REJECT, - ESM_MSG_ACTIVATE_DEDICATED_EPS_BEARER_CONTEXT_REQUEST, - ESM_MSG_ACTIVATE_DEDICATED_EPS_BEARER_CONTEXT_ACCEPT, - ESM_MSG_ACTIVATE_DEDICATED_EPS_BEARER_CONTEXT_REJECT, - ESM_MSG_MODIFY_EPS_BEARER_CONTEXT_REQUEST, - ESM_MSG_MODIFY_EPS_BEARER_CONTEXT_ACCEPT, - ESM_MSG_MODIFY_EPS_BEARER_CONTEXT_REJECT, - ESM_MSG_DEACTIVATE_EPS_BEARER_CONTEXT_REQUEST, - ESM_MSG_DEACTIVATE_EPS_BEARER_CONTEXT_ACCEPT, - ESM_MSG_PDN_CONNECTIVITY_REQUEST, - ESM_MSG_PDN_CONNECTIVITY_REJECT, - ESM_MSG_PDN_DISCONNECT_REQUEST, - ESM_MSG_PDN_DISCONNECT_REJECT, - ESM_MSG_BEARER_RESOURCE_ALLOCATION_REQUEST, - ESM_MSG_BEARER_RESOURCE_ALLOCATION_REJECT, - ESM_MSG_BEARER_RESOURCE_MODIFICATION_REQUEST, - ESM_MSG_BEARER_RESOURCE_MODIFICATION_REJECT, - ESM_MSG_ESM_INFORMATION_REQUEST, - ESM_MSG_ESM_INFORMATION_RESPONSE, - ESM_MSG_ESM_STATUS, -} esm_message_ids_t; - - - -typedef struct nas_raw_msg_s { - uint32_t lenght; - uint8_t data[NAS_DATA_LENGHT_MAX]; -} nas_raw_msg_t; - - - -typedef struct nas_emm_plain_msg_s { - emm_message_ids_t present; - EMM_msg choice; - -} nas_emm_plain_msg_t; - - - -typedef struct nas_emm_protected_msg_s { - nas_message_security_header_t header; - emm_message_ids_t present; - EMM_msg choice; -} nas_emm_protected_msg_t; - - -typedef struct nas_esm_plain_msg_s { - esm_message_ids_t present; - ESM_msg choice; - -} nas_esm_plain_msg_t; - - -typedef struct nas_esm_protected_msg_s { - nas_message_security_header_t header; - esm_message_ids_t present; - ESM_msg choice; -} nas_esm_protected_msg_t; - - -typedef struct nas_paging_ind_s { - -} nas_paging_ind_t; - - -typedef struct nas_pdn_connectivity_req_s { - int pti; // nas ref Identity of the procedure transaction executed to activate the PDN connection entry - unsigned ue_id; // nas ref - char imsi[16]; - uint8_t imsi_length; - network_qos_t qos; - pco_flat_t pco; - OctetString apn; - OctetString pdn_addr; - int pdn_type; - void *proc_data; - int request_type; -} nas_pdn_connectivity_req_t; - - -typedef struct nas_pdn_connectivity_rsp_s { - int pti; // nas ref Identity of the procedure transaction executed to activate the PDN connection entry - unsigned ue_id; // nas ref - network_qos_t qos; - pco_flat_t pco; - OctetString apn; - OctetString pdn_addr; - int pdn_type; - void *proc_data; - int request_type; - - unsigned eNB_ue_s1ap_id:24; - uint32_t mme_ue_s1ap_id; - - /* Key eNB */ - //uint8_t keNB[32]; - - ambr_t ambr; - ambr_t apn_ambr; - - /* EPS bearer ID */ - unsigned ebi:4; - - /* QoS */ - qci_t qci; - priority_level_t prio_level; - pre_emp_vulnerability_t pre_emp_vulnerability; - pre_emp_capability_t pre_emp_capability; - - /* S-GW TEID for user-plane */ - Teid_t sgw_s1u_teid; - /* S-GW IP address for User-Plane */ - ip_address_t sgw_s1u_address; -} nas_pdn_connectivity_rsp_t; - - -typedef struct nas_pdn_connectivity_fail_s { - unsigned ue_id; // nas ref -} nas_pdn_connectivity_fail_t; - - -typedef struct nas_conn_est_ind_s { - nas_establish_ind_t nas; - - /* Transparent message from s1ap to be forwarded to MME_APP or - * to S1AP if connection establishment is rejected by NAS. - */ - s1ap_initial_ue_message_t transparent; -} nas_conn_est_ind_t; - - -typedef nas_establish_rsp_t nas_conn_est_rej_t; - - -typedef nas_establish_cnf_t nas_conn_est_cnf_t; - - -typedef struct nas_conn_rel_ind_s { - -} nas_conn_rel_ind_t; - -typedef ul_info_transfer_ind_t nas_ul_data_ind_t; -typedef dl_info_transfer_req_t nas_dl_data_req_t; -typedef dl_info_transfer_cnf_t nas_dl_data_cnf_t; - - -typedef struct nas_dl_data_rej_s { - uint32_t UEid; /* UE lower layer identifier */ - as_nas_info_t nasMsg; /* Uplink NAS message */ -} nas_dl_data_rej_t; - -typedef struct nas_rab_est_req_s { - -} nas_rab_est_req_t; - - -typedef struct nas_rab_est_rsp_s { - -} nas_rab_est_rsp_t; - - -typedef struct nas_rab_rel_req_s { - -} nas_rab_rel_req_t; - - -typedef struct nas_attach_req_s { - /* TODO: Set the correct size */ - char apn[100]; - char imsi[16]; -#define INITIAL_REQUEST (0x1) - unsigned initial:1; - s1ap_initial_ue_message_t transparent; -} nas_attach_req_t; - - -typedef struct nas_auth_req_s { - /* UE imsi */ - char imsi[16]; - -#define NAS_FAILURE_OK 0x0 -#define NAS_FAILURE_IND 0x1 - unsigned failure:1; - int cause; -} nas_auth_req_t; - - -typedef struct nas_auth_resp_s { - char imsi[16]; -} nas_auth_resp_t; - -typedef struct nas_auth_param_req_s { - /* UE identifier */ - uint32_t ue_id; - - /* Imsi of the UE (In case of initial request) */ - char imsi[16]; - uint8_t imsi_length; - - /* Indicates whether the procedure corresponds to a new connection or not */ - uint8_t initial_req:1; - - uint8_t re_synchronization:1; - uint8_t auts[14]; -} nas_auth_param_req_t; - - -typedef struct nas_auth_param_rsp_s { - /* UE identifier */ - uint32_t ue_id; - - /* For future use: nb of vectors provided */ - uint8_t nb_vectors; - - /* Consider only one E-UTRAN vector for the moment... */ - eutran_vector_t vector; -} nas_auth_param_rsp_t; - -typedef struct nas_auth_param_fail_s { - /* UE identifier */ - uint32_t ue_id; - - /* S6A mapped to NAS cause */ - nas_cause_t cause; -} nas_auth_param_fail_t; - - -#endif /* NAS_MESSAGES_TYPES_H_ */ diff --git a/openair3/COMMON/s1ap_messages_def.h b/openair3/COMMON/s1ap_messages_def.h deleted file mode 100644 index ffb9aa4236..0000000000 --- a/openair3/COMMON/s1ap_messages_def.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.openairinterface.org/?page_id=698 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - *------------------------------------------------------------------------------- - * For more information about the OpenAirInterface (OAI) Software Alliance: - * contact@openairinterface.org - */ - -//WARNING: Do not include this header directly. Use intertask_interface.h instead. - -/* Messages for S1AP logging */ -MESSAGE_DEF(S1AP_UPLINK_NAS_LOG , MESSAGE_PRIORITY_MED, IttiMsgText , s1ap_uplink_nas_log) -MESSAGE_DEF(S1AP_UE_CAPABILITY_IND_LOG , MESSAGE_PRIORITY_MED, IttiMsgText , s1ap_ue_capability_ind_log) -MESSAGE_DEF(S1AP_INITIAL_CONTEXT_SETUP_LOG , MESSAGE_PRIORITY_MED, IttiMsgText , s1ap_initial_context_setup_log) -MESSAGE_DEF(S1AP_NAS_NON_DELIVERY_IND_LOG , MESSAGE_PRIORITY_MED, IttiMsgText , s1ap_nas_non_delivery_ind_log) -MESSAGE_DEF(S1AP_DOWNLINK_NAS_LOG , MESSAGE_PRIORITY_MED, IttiMsgText , s1ap_downlink_nas_log) -MESSAGE_DEF(S1AP_S1_SETUP_LOG , MESSAGE_PRIORITY_MED, IttiMsgText , s1ap_s1_setup_log) -MESSAGE_DEF(S1AP_INITIAL_UE_MESSAGE_LOG , MESSAGE_PRIORITY_MED, IttiMsgText , s1ap_initial_ue_message_log) -MESSAGE_DEF(S1AP_UE_CONTEXT_RELEASE_REQ_LOG, MESSAGE_PRIORITY_MED, IttiMsgText , s1ap_ue_context_release_req_log) -MESSAGE_DEF(S1AP_UE_CONTEXT_RELEASE_COMMAND_LOG, MESSAGE_PRIORITY_MED, IttiMsgText , s1ap_ue_context_release_command_log) -MESSAGE_DEF(S1AP_UE_CONTEXT_RELEASE_LOG , MESSAGE_PRIORITY_MED, IttiMsgText , s1ap_ue_context_release_log) -MESSAGE_DEF(S1AP_ERROR_INDICATION_LOG , MESSAGE_PRIORITY_MED, IttiMsgText , s1ap_error_indication_log) - -MESSAGE_DEF(S1AP_UE_CAPABILITIES_IND , MESSAGE_PRIORITY_MED, s1ap_ue_cap_ind_t , s1ap_ue_cap_ind) -MESSAGE_DEF(S1AP_ENB_DEREGISTERED_IND , MESSAGE_PRIORITY_MED, s1ap_eNB_deregistered_ind_t , s1ap_eNB_deregistered_ind) -MESSAGE_DEF(S1AP_DEREGISTER_UE_REQ , MESSAGE_PRIORITY_MED, s1ap_deregister_ue_req_t , s1ap_deregister_ue_req) -MESSAGE_DEF(S1AP_UE_CONTEXT_RELEASE_REQ , MESSAGE_PRIORITY_MED, s1ap_ue_context_release_req_t , s1ap_ue_context_release_req) -MESSAGE_DEF(S1AP_UE_CONTEXT_RELEASE_COMMAND, MESSAGE_PRIORITY_MED, s1ap_ue_context_release_command_t, s1ap_ue_context_release_command) -MESSAGE_DEF(S1AP_UE_CONTEXT_RELEASE_COMPLETE, MESSAGE_PRIORITY_MED, s1ap_ue_context_release_complete_t, s1ap_ue_context_release_complete) diff --git a/openair3/COMMON/s1ap_messages_types.h b/openair3/COMMON/s1ap_messages_types.h deleted file mode 100644 index e6c3bba504..0000000000 --- a/openair3/COMMON/s1ap_messages_types.h +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.openairinterface.org/?page_id=698 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - *------------------------------------------------------------------------------- - * For more information about the OpenAirInterface (OAI) Software Alliance: - * contact@openairinterface.org - */ - -#ifndef S1AP_MESSAGES_TYPES_H_ -#define S1AP_MESSAGES_TYPES_H_ - -#define S1AP_ENB_DEREGISTERED_IND(mSGpTR) (mSGpTR)->ittiMsg.s1ap_eNB_deregistered_ind -#define S1AP_DEREGISTER_UE_REQ(mSGpTR) (mSGpTR)->ittiMsg.s1ap_deregister_ue_req -#define S1AP_UE_CONTEXT_RELEASE_REQ(mSGpTR) (mSGpTR)->ittiMsg.s1ap_ue_context_release_req -#define S1AP_UE_CONTEXT_RELEASE_COMMAND(mSGpTR) (mSGpTR)->ittiMsg.s1ap_ue_context_release_command -#define S1AP_UE_CONTEXT_RELEASE_COMPLETE(mSGpTR) (mSGpTR)->ittiMsg.s1ap_ue_context_release_complete - -typedef struct s1ap_initial_ue_message_s { - unsigned eNB_ue_s1ap_id:24; - uint32_t mme_ue_s1ap_id; - cgi_t e_utran_cgi; -} s1ap_initial_ue_message_t; - -typedef struct s1ap_initial_ctxt_setup_req_s { - unsigned eNB_ue_s1ap_id:24; - uint32_t mme_ue_s1ap_id; - - /* Key eNB */ - uint8_t keNB[32]; - - ambr_t ambr; - ambr_t apn_ambr; - - /* EPS bearer ID */ - unsigned ebi:4; - - /* QoS */ - qci_t qci; - priority_level_t prio_level; - pre_emp_vulnerability_t pre_emp_vulnerability; - pre_emp_capability_t pre_emp_capability; - - /* S-GW TEID for user-plane */ - Teid_t teid; - /* S-GW IP address for User-Plane */ - ip_address_t s_gw_address; -} s1ap_initial_ctxt_setup_req_t; - -typedef struct s1ap_ue_cap_ind_s { - unsigned eNB_ue_s1ap_id:24; - uint32_t mme_ue_s1ap_id; - uint8_t radio_capabilities[100]; - uint32_t radio_capabilities_length; -} s1ap_ue_cap_ind_t; - -#define S1AP_ITTI_UE_PER_DEREGISTER_MESSAGE 20 -typedef struct s1ap_eNB_deregistered_ind_s { - uint8_t nb_ue_to_deregister; - uint32_t mme_ue_s1ap_id[S1AP_ITTI_UE_PER_DEREGISTER_MESSAGE]; -} s1ap_eNB_deregistered_ind_t; - -typedef struct s1ap_deregister_ue_req_s { - uint32_t mme_ue_s1ap_id; -} s1ap_deregister_ue_req_t; - -typedef struct s1ap_ue_context_release_req_s { - uint32_t mme_ue_s1ap_id; -} s1ap_ue_context_release_req_t; - -typedef struct s1ap_ue_context_release_command_s { - uint32_t mme_ue_s1ap_id; -} s1ap_ue_context_release_command_t; - -typedef struct s1ap_ue_context_release_complete_s { - uint32_t mme_ue_s1ap_id; -} s1ap_ue_context_release_complete_t; - -#endif /* S1AP_MESSAGES_TYPES_H_ */ diff --git a/openair3/COMMON/sctp_messages_def.h b/openair3/COMMON/sctp_messages_def.h deleted file mode 100644 index c2d51c91eb..0000000000 --- a/openair3/COMMON/sctp_messages_def.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.openairinterface.org/?page_id=698 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - *------------------------------------------------------------------------------- - * For more information about the OpenAirInterface (OAI) Software Alliance: - * contact@openairinterface.org - */ - -//WARNING: Do not include this header directly. Use intertask_interface.h instead. - -MESSAGE_DEF(SCTP_INIT_MSG, MESSAGE_PRIORITY_MED, SctpInit, sctpInit) -MESSAGE_DEF(SCTP_DATA_REQ, MESSAGE_PRIORITY_MED, sctp_data_req_t, sctp_data_req) -MESSAGE_DEF(SCTP_DATA_IND, MESSAGE_PRIORITY_MED, sctp_data_ind_t, sctp_data_ind) -MESSAGE_DEF(SCTP_NEW_ASSOCIATION, MESSAGE_PRIORITY_MAX, sctp_new_peer_t, sctp_new_peer) -MESSAGE_DEF(SCTP_CLOSE_ASSOCIATION, MESSAGE_PRIORITY_MAX, sctp_close_association_t, sctp_close_association) diff --git a/openair3/COMMON/sctp_messages_types.h b/openair3/COMMON/sctp_messages_types.h deleted file mode 100644 index 98a92c66b6..0000000000 --- a/openair3/COMMON/sctp_messages_types.h +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.openairinterface.org/?page_id=698 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - *------------------------------------------------------------------------------- - * For more information about the OpenAirInterface (OAI) Software Alliance: - * contact@openairinterface.org - */ - -#ifndef SCTP_MESSAGES_TYPES_H_ -#define SCTP_MESSAGES_TYPES_H_ - -#define SCTP_DATA_IND(mSGpTR) (mSGpTR)->ittiMsg.sctp_data_ind -#define SCTP_DATA_REQ(mSGpTR) (mSGpTR)->ittiMsg.sctp_data_req -#define SCTP_INIT_MSG(mSGpTR) (mSGpTR)->ittiMsg.sctpInit -#define SCTP_CLOSE_ASSOCIATION(mSGpTR) (mSGpTR)->ittiMsg.sctp_close_association - -typedef struct sctp_data_req_s { - uint8_t *buffer; - uint32_t bufLen; - uint32_t assocId; - uint16_t stream; -} sctp_data_req_t; - -typedef struct sctp_data_ind_s { - uint8_t *buffer; ///< SCTP buffer - uint32_t buf_length; ///< SCTP buffer length - int32_t assoc_id; ///< SCTP physical association ID - uint8_t stream; ///< Stream number on which data had been received - uint16_t instreams; ///< Number of input streams for the SCTP connection between peers - uint16_t outstreams; ///< Number of output streams for the SCTP connection between peers -} sctp_data_ind_t; - -typedef struct sctp_init_s { - /* Request usage of ipv4 */ - unsigned ipv4:1; - /* Request usage of ipv6 */ - unsigned ipv6:1; - uint8_t nb_ipv4_addr; - uint32_t ipv4_address[10]; - uint8_t nb_ipv6_addr; - char *ipv6_address[10]; - uint16_t port; - uint32_t ppid; -} SctpInit; - -typedef struct sctp_close_association_s { - uint32_t assoc_id; -} sctp_close_association_t; - -typedef struct sctp_new_peer_s { - uint32_t instreams; - uint32_t outstreams; - uint32_t assoc_id; -} sctp_new_peer_t; - -#endif /* SCTP_MESSAGES_TYPES_H_ */ diff --git a/openair3/COMMON/tasks_def.h b/openair3/COMMON/tasks_def.h deleted file mode 100644 index d1b7b8d756..0000000000 --- a/openair3/COMMON/tasks_def.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.openairinterface.org/?page_id=698 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - *------------------------------------------------------------------------------- - * For more information about the OpenAirInterface (OAI) Software Alliance: - * contact@openairinterface.org - */ - -// This task is mandatory and must always be placed in first position -TASK_DEF(TASK_TIMER, TASK_PRIORITY_MED, 10) - -// Other possible tasks in the process - -/// GTPV1-U task -TASK_DEF(TASK_GTPV1_U, TASK_PRIORITY_MED, 200) -/// FW_IP task -TASK_DEF(TASK_FW_IP, TASK_PRIORITY_MED, 200) -/// MME Applicative task -TASK_DEF(TASK_MME_APP, TASK_PRIORITY_MED, 200) -/// NAS task -TASK_DEF(TASK_NAS_MME, TASK_PRIORITY_MED, 200) -/// S11 task -TASK_DEF(TASK_S11, TASK_PRIORITY_MED, 200) -/// S1AP task -TASK_DEF(TASK_S1AP, TASK_PRIORITY_MED, 200) -/// S6a task -TASK_DEF(TASK_S6A, TASK_PRIORITY_MED, 200) -/// SCTP task -TASK_DEF(TASK_SCTP, TASK_PRIORITY_MED, 200) -/// Serving and Proxy Gateway Application task -TASK_DEF(TASK_SPGW_APP, TASK_PRIORITY_MED, 200) -/// UDP task -TASK_DEF(TASK_UDP, TASK_PRIORITY_MED, 200) -//MESSAGE GENERATOR TASK -TASK_DEF(TASK_MSC, TASK_PRIORITY_MED, 200) diff --git a/openair3/COMMON/udp_messages_def.h b/openair3/COMMON/udp_messages_def.h deleted file mode 100644 index 35322f2450..0000000000 --- a/openair3/COMMON/udp_messages_def.h +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.openairinterface.org/?page_id=698 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - *------------------------------------------------------------------------------- - * For more information about the OpenAirInterface (OAI) Software Alliance: - * contact@openairinterface.org - */ - -MESSAGE_DEF(UDP_INIT, MESSAGE_PRIORITY_MED, udp_init_t, udp_init) -MESSAGE_DEF(UDP_DATA_REQ, MESSAGE_PRIORITY_MED, udp_data_req_t, udp_data_req) -MESSAGE_DEF(UDP_DATA_IND, MESSAGE_PRIORITY_MED, udp_data_ind_t, udp_data_ind) diff --git a/openair3/COMMON/udp_messages_types.h b/openair3/COMMON/udp_messages_types.h deleted file mode 100644 index 7825a924d1..0000000000 --- a/openair3/COMMON/udp_messages_types.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.openairinterface.org/?page_id=698 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - *------------------------------------------------------------------------------- - * For more information about the OpenAirInterface (OAI) Software Alliance: - * contact@openairinterface.org - */ - -#ifndef UDP_MESSAGES_TYPES_H_ -#define UDP_MESSAGES_TYPES_H_ - -#define UDP_INIT(mSGpTR) (mSGpTR)->ittiMsg.udp_init - -typedef struct { - uint32_t port; - char *address; -} udp_init_t; - -typedef struct { - uint8_t *buffer; - uint32_t buffer_length; - uint32_t buffer_offset; - uint32_t peer_address; - uint32_t peer_port; -} udp_data_req_t; - -typedef struct { - uint8_t *buffer; - uint32_t buffer_length; - uint32_t peer_address; - uint32_t peer_port; -} udp_data_ind_t; - -#endif /* UDP_MESSAGES_TYPES_H_ */ diff --git a/openair3/SECU/key_nas_encryption.c b/openair3/SECU/key_nas_encryption.c deleted file mode 100644 index aa641137ef..0000000000 --- a/openair3/SECU/key_nas_encryption.c +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.openairinterface.org/?page_id=698 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - *------------------------------------------------------------------------------- - * For more information about the OpenAirInterface (OAI) Software Alliance: - * contact@openairinterface.org - */ - -#include -#include "secu_defs.h" - -/*! - * Derive the kNASenc from kasme and perform truncate on the generated key to - * reduce his size to 128 bits. Definition of the derivation function can - * be found in 3GPP TS.33401 #A.7 - * @param[in] nas_alg_type NAS algorithm distinguisher - * @param[in] nas_enc_alg_id NAS encryption/integrity algorithm identifier. - * Possible values are: - * - 0 for EIA0 algorithm (Null Integrity Protection algorithm) - * - 1 for 128-EIA1 SNOW 3G - * - 2 for 128-EIA2 AES - * @param[in] kasme Key for MME as provided by AUC - * @param[out] knas Truncated ouput key as derived by KDF - */ - -/*int derive_key_nas(algorithm_type_dist_t nas_alg_type, uint8_t nas_enc_alg_id, - const uint8_t kasme[32], uint8_t** knas) -{ - uint8_t s[7]; - uint8_t knas_temp[32]; - - // FC - s[0] = 0x15; - - // P0 = algorithm type distinguisher - s[1] = nas_alg_type & 0xFF; - - // L0 = length(P0) = 1 - s[2] = 0x00; - s[3] = 0x01; - - // P1 - s[4] = nas_enc_alg_id; - - // L1 = length(P1) = 1 - s[5] = 0x00; - s[6] = 0x01; - - kdf((uint8_t*)kasme, 32, s, 7, (uint8_t**)&knas_temp, 32); - - // Truncate the generate key to 128 bits - memcpy(knas, knas_temp, 16); - - return 0; -} -*/ diff --git a/targets/RT/USER/.ue.nvram b/targets/RT/USER/.ue.nvram deleted file mode 100644 index 17469c87add15bffcfe07e54a19cd93743f18818..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 55 zcmXpuH8V6cHZU?Wurx6=v1D)!4RUq%_hoJ|hDo*rfmenHWqO7}*;Y zz+5~;6AMVP8BDe?GO!C8CkiUN=0mJ=<_dNTQgACu%u7y%nBmF{6ah2Img5i0Pf1M6 z&r4PCEJ@7COk{B72=jMwbo2Lfh1fwy5)_IIpl}3+pCFjU2xJL^SxgK{`Vd)W24HYN zU4@?oGzF*~Wa@zih)Uu~kZlJV6#eDFWIm8o)7J-+{y-Ab97q~qV&sRX2T) Date: Sun, 23 Dec 2018 18:05:51 +0100 Subject: [PATCH 206/233] issue 384 --- cmake_targets/CMakeLists.txt | 1 - cmake_targets/at_commands/CMakeLists.txt | 3 +-- common/utils/assertions.h | 2 -- openair2/COMMON/platform_constants.h | 4 ---- openair2/COMMON/rrc_messages_types.h | 4 ---- openair2/ENB_APP/enb_config.h | 4 ---- openair3/TEST/EPC_TEST/generate_scenario.h | 4 ---- 7 files changed, 1 insertion(+), 21 deletions(-) diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt index efc11bcbae..6ec1239a74 100644 --- a/cmake_targets/CMakeLists.txt +++ b/cmake_targets/CMakeLists.txt @@ -183,7 +183,6 @@ set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,-rpath -Wl,${CMAKE_CU ######################### # set a flag for changes in the source code # these changes are related to hardcoded path to include .h files -add_definitions(-DCMAKER) set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS} -g -DMALLOC_CHECK_=3") set(CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS} -g -DMALLOC_CHECK_=3 -O2") diff --git a/cmake_targets/at_commands/CMakeLists.txt b/cmake_targets/at_commands/CMakeLists.txt index 54f369f977..bd71125cf0 100755 --- a/cmake_targets/at_commands/CMakeLists.txt +++ b/cmake_targets/at_commands/CMakeLists.txt @@ -76,7 +76,6 @@ macro(add_boolean_option name val helpstr) endmacro(add_boolean_option) # compilation flags -# added CMAKER conditional compilation to not bother legacy building system ############################################# if(NOT CMAKE_BUILD_TYPE) set(CMAKE_BUILD_TYPE "RelWithDebInfo" CACHE STRING "Choose the type of build, options are: None(CMAKE_CXX_FLAGS or CMAKE_C_FLAGS used) Debug Release RelWithDebInfo MinSizeRel." FORCE) @@ -84,7 +83,7 @@ endif() set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS Debug Release RelWithDebInfo MinSizeRel) # -set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -msse4.2 -std=gnu99 -Wall -Wstrict-prototypes -fno-strict-aliasing -rdynamic -funroll-loops -Wno-packed-bitfield-compat -DCMAKER") +set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -msse4.2 -std=gnu99 -Wall -Wstrict-prototypes -fno-strict-aliasing -rdynamic -funroll-loops -Wno-packed-bitfield-compat ") set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -ggdb -DMALLOC_CHECK_=3") set(CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO} -ggdb -DMALLOC_CHECK_=3 -O2") diff --git a/common/utils/assertions.h b/common/utils/assertions.h index b872b009e2..77e939affe 100644 --- a/common/utils/assertions.h +++ b/common/utils/assertions.h @@ -22,9 +22,7 @@ #include #include #include -#ifdef CMAKER #include -#endif #if defined(ENB_MODE) # define display_backtrace() diff --git a/openair2/COMMON/platform_constants.h b/openair2/COMMON/platform_constants.h index b00e08588a..6a3b7f8005 100644 --- a/openair2/COMMON/platform_constants.h +++ b/openair2/COMMON/platform_constants.h @@ -28,11 +28,7 @@ ***************************************************************************/ -#ifdef CMAKER #include "LTE_asn_constant.h" -#else -#include "RRC/LTE/MESSAGES/asn1_constants.h" -#endif #ifndef __PLATFORM_CONSTANTS_H__ # define __PLATFORM_CONSTANTS_H__ diff --git a/openair2/COMMON/rrc_messages_types.h b/openair2/COMMON/rrc_messages_types.h index c1b554c216..9a47580dbc 100644 --- a/openair2/COMMON/rrc_messages_types.h +++ b/openair2/COMMON/rrc_messages_types.h @@ -32,11 +32,7 @@ #include "as_message.h" #include "rrc_types.h" #include "s1ap_messages_types.h" -#ifdef CMAKER #include "LTE_SystemInformationBlockType2.h" -#else - #include "RRC/LTE/MESSAGES/LTE_SystemInformationBlockType2.h" -#endif #include "LTE_SL-OffsetIndicator-r12.h" #include "LTE_SubframeBitmapSL-r12.h" #include "LTE_SL-CP-Len-r12.h" diff --git a/openair2/ENB_APP/enb_config.h b/openair2/ENB_APP/enb_config.h index 1b47a112cf..f5cf301828 100644 --- a/openair2/ENB_APP/enb_config.h +++ b/openair2/ENB_APP/enb_config.h @@ -40,12 +40,8 @@ #include "PHY/impl_defs_lte.h" #include "PHY/defs_eNB.h" #include "s1ap_messages_types.h" -#ifdef CMAKER #include "LTE_SystemInformationBlockType2.h" #include "rrc_messages_types.h" -#else -#include "RRC/LTE/MESSAGES/LTE_SystemInformationBlockType2.h" -#endif #include "RRC/LTE/rrc_defs.h" #include diff --git a/openair3/TEST/EPC_TEST/generate_scenario.h b/openair3/TEST/EPC_TEST/generate_scenario.h index 0f240f483d..b2042a894c 100644 --- a/openair3/TEST/EPC_TEST/generate_scenario.h +++ b/openair3/TEST/EPC_TEST/generate_scenario.h @@ -38,11 +38,7 @@ #include "platform_constants.h" #include "PHY/impl_defs_lte.h" #include "s1ap_messages_types.h" -#ifdef CMAKER #include "SystemInformationBlockType2.h" -#else -#include "RRC/LTE/MESSAGES/SystemInformationBlockType2.h" -#endif #define IPV4_STR_ADDR_TO_INT_NWBO(AdDr_StR,NwBo,MeSsAgE ) do {\ struct in_addr inp;\ From 4753f92badf08568407048f5f28e840621da4559 Mon Sep 17 00:00:00 2001 From: laurent Date: Wed, 26 Dec 2018 10:25:56 +0100 Subject: [PATCH 207/233] remove more files, add a LOG_E() for UE not developped use case --- common/utils/time_utils.h | 23 - openair1/PHY/CODING/scrambler.h | 1047 ----------------- openair1/PHY/INIT/init_extern.h | 21 - openair1/PHY/INIT/init_vars.h | 21 - .../LTE_ESTIMATION/lte_estimation_extern.h | 21 - openair1/SCHED_UE/phy_procedures_lte_ue.c | 2 +- .../RLC/AM_v9.3.0/rlc_am_proto_extern.h | 21 - openair2/RRC/LTE/rrc_2_rrm_msg.c | 439 ------- openair2/RRC/LTE/rrc_UE.c | 4 +- openair3/NAS/COMMON/API/NETWORK/l2_message.h | 310 ----- openair3/NAS/TOOLS/network.h | 123 -- openair3/UTILS/mme_config.c | 716 ----------- 12 files changed, 4 insertions(+), 2744 deletions(-) delete mode 100644 common/utils/time_utils.h delete mode 100644 openair1/PHY/CODING/scrambler.h delete mode 100644 openair1/PHY/INIT/init_extern.h delete mode 100644 openair1/PHY/INIT/init_vars.h delete mode 100644 openair1/PHY/LTE_ESTIMATION/lte_estimation_extern.h delete mode 100644 openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_proto_extern.h delete mode 100644 openair2/RRC/LTE/rrc_2_rrm_msg.c delete mode 100644 openair3/NAS/COMMON/API/NETWORK/l2_message.h delete mode 100644 openair3/NAS/TOOLS/network.h delete mode 100644 openair3/UTILS/mme_config.c diff --git a/common/utils/time_utils.h b/common/utils/time_utils.h deleted file mode 100644 index ee82c8cf95..0000000000 --- a/common/utils/time_utils.h +++ /dev/null @@ -1,23 +0,0 @@ -#ifndef _TIME_UTILS_H_ -#define _TIME_UTILS_H_ - -#include -#include - -static inline int64_t clock_difftime_ns(struct timespec start, struct timespec end) -{ - struct timespec temp; - int64_t temp_ns; - - if ((end.tv_nsec-start.tv_nsec)<0) { - temp.tv_sec = end.tv_sec-start.tv_sec-1; - temp.tv_nsec = 1000000000+end.tv_nsec-start.tv_nsec; - } else { - temp.tv_sec = end.tv_sec-start.tv_sec; - temp.tv_nsec = end.tv_nsec-start.tv_nsec; - } - temp_ns = (int64_t)(temp.tv_sec) * (int64_t)1000000000 + (temp.tv_nsec); - return temp_ns; -} - -#endif /* _TIME_UTILS_H_ */ diff --git a/openair1/PHY/CODING/scrambler.h b/openair1/PHY/CODING/scrambler.h deleted file mode 100644 index 3c1b1de0a7..0000000000 --- a/openair1/PHY/CODING/scrambler.h +++ /dev/null @@ -1,1047 +0,0 @@ -/* - * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.openairinterface.org/?page_id=698 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - *------------------------------------------------------------------------------- - * For more information about the OpenAirInterface (OAI) Software Alliance: - * contact@openairinterface.org - */ - -unsigned char scrambling_sequence[1024] = { - 208, - 127, - 52, - 95, - 204, - 135, - 48, - 31, - 248, - 32, - 208, - 135, - 192, - 232, - 63, - 175, - 4, - 212, - 119, - 24, - 169, - 162, - 101, - 144, - 75, - 109, - 75, - 29, - 91, - 191, - 165, - 246, - 177, - 71, - 16, - 92, - 68, - 80, - 132, - 4, - 248, - 251, - 32, - 65, - 125, - 56, - 94, - 86, - 152, - 11, - 201, - 134, - 39, - 250, - 19, - 162, - 25, - 190, - 62, - 3, - 190, - 18, - 188, - 215, - 97, - 239, - 72, - 11, - 0, - 26, - 57, - 211, - 146, - 37, - 205, - 121, - 204, - 83, - 13, - 206, - 53, - 27, - 214, - 32, - 54, - 214, - 82, - 125, - 226, - 108, - 169, - 102, - 247, - 255, - 32, - 171, - 201, - 112, - 20, - 253, - 65, - 192, - 38, - 78, - 114, - 40, - 95, - 32, - 70, - 194, - 242, - 153, - 207, - 63, - 61, - 117, - 122, - 32, - 73, - 60, - 160, - 140, - 99, - 235, - 118, - 176, - 75, - 102, - 254, - 5, - 67, - 194, - 122, - 62, - 226, - 56, - 69, - 123, - 213, - 179, - 119, - 221, - 23, - 63, - 26, - 160, - 233, - 166, - 179, - 243, - 169, - 190, - 183, - 146, - 169, - 185, - 216, - 214, - 158, - 86, - 139, - 214, - 143, - 181, - 0, - 9, - 147, - 254, - 105, - 138, - 213, - 118, - 14, - 74, - 153, - 110, - 41, - 47, - 172, - 91, - 216, - 117, - 156, - 62, - 56, - 75, - 113, - 6, - 123, - 178, - 118, - 97, - 82, - 75, - 96, - 21, - 148, - 170, - 120, - 227, - 0, - 245, - 25, - 147, - 243, - 185, - 203, - 135, - 48, - 104, - 89, - 38, - 71, - 30, - 74, - 219, - 130, - 107, - 75, - 244, - 138, - 8, - 8, - 248, - 175, - 65, - 234, - 35, - 125, - 138, - 0, - 95, - 23, - 171, - 177, - 166, - 196, - 173, - 235, - 244, - 124, - 20, - 22, - 78, - 32, - 207, - 173, - 103, - 232, - 84, - 18, - 227, - 246, - 127, - 136, - 28, - 188, - 39, - 132, - 79, - 14, - 62, - 80, - 248, - 171, - 21, - 160, - 188, - 110, - 125, - 55, - 198, - 139, - 185, - 28, - 127, - 239, - 246, - 223, - 47, - 55, - 63, - 63, - 129, - 253, - 175, - 122, - 182, - 139, - 52, - 163, - 164, - 177, - 6, - 187, - 220, - 159, - 76, - 36, - 164, - 108, - 218, - 189, - 250, - 148, - 201, - 45, - 207, - 174, - 81, - 195, - 108, - 96, - 203, - 132, - 210, - 34, - 142, - 247, - 238, - 139, - 84, - 84, - 194, - 168, - 46, - 9, - 238, - 29, - 135, - 115, - 95, - 12, - 218, - 18, - 134, - 110, - 83, - 110, - 44, - 80, - 80, - 216, - 126, - 160, - 65, - 142, - 142, - 209, - 69, - 234, - 200, - 184, - 171, - 248, - 185, - 148, - 203, - 90, - 143, - 231, - 29, - 47, - 214, - 151, - 154, - 137, - 152, - 228, - 192, - 182, - 108, - 200, - 226, - 204, - 82, - 170, - 110, - 197, - 143, - 169, - 230, - 75, - 204, - 177, - 222, - 142, - 1, - 104, - 130, - 224, - 201, - 29, - 223, - 246, - 132, - 173, - 42, - 33, - 165, - 147, - 208, - 124, - 208, - 198, - 51, - 78, - 76, - 216, - 164, - 250, - 186, - 214, - 57, - 52, - 52, - 199, - 37, - 3, - 242, - 120, - 179, - 26, - 233, - 51, - 42, - 11, - 108, - 26, - 41, - 192, - 41, - 221, - 71, - 16, - 67, - 131, - 90, - 226, - 181, - 0, - 244, - 183, - 31, - 78, - 241, - 221, - 173, - 248, - 146, - 23, - 244, - 102, - 194, - 201, - 16, - 25, - 155, - 110, - 146, - 54, - 246, - 40, - 5, - 78, - 94, - 47, - 135, - 60, - 103, - 29, - 175, - 142, - 9, - 213, - 70, - 159, - 168, - 176, - 217, - 91, - 13, - 1, - 254, - 104, - 135, - 20, - 135, - 147, - 23, - 141, - 8, - 115, - 180, - 201, - 50, - 246, - 4, - 12, - 72, - 59, - 166, - 22, - 61, - 77, - 140, - 183, - 150, - 255, - 55, - 31, - 71, - 215, - 83, - 75, - 169, - 137, - 104, - 237, - 88, - 118, - 146, - 247, - 95, - 182, - 241, - 29, - 98, - 243, - 152, - 52, - 230, - 114, - 27, - 247, - 116, - 78, - 152, - 202, - 96, - 15, - 112, - 196, - 245, - 148, - 9, - 228, - 111, - 131, - 179, - 198, - 243, - 35, - 140, - 234, - 248, - 8, - 197, - 218, - 35, - 246, - 172, - 207, - 93, - 62, - 157, - 196, - 149, - 199, - 136, - 30, - 70, - 13, - 116, - 63, - 171, - 207, - 254, - 51, - 18, - 126, - 246, - 195, - 218, - 222, - 204, - 105, - 132, - 150, - 123, - 136, - 24, - 23, - 143, - 162, - 175, - 185, - 148, - 104, - 135, - 118, - 44, - 126, - 59, - 67, - 114, - 157, - 194, - 201, - 231, - 40, - 80, - 42, - 195, - 50, - 133, - 186, - 43, - 134, - 234, - 170, - 96, - 177, - 67, - 61, - 121, - 31, - 171, - 120, - 208, - 74, - 84, - 33, - 148, - 199, - 59, - 171, - 244, - 243, - 114, - 92, - 90, - 99, - 89, - 181, - 25, - 224, - 39, - 149, - 209, - 40, - 151, - 1, - 171, - 106, - 75, - 126, - 134, - 35, - 187, - 12, - 31, - 114, - 240, - 229, - 182, - 48, - 86, - 192, - 247, - 109, - 78, - 111, - 74, - 207, - 72, - 232, - 177, - 126, - 167, - 213, - 139, - 124, - 122, - 18, - 108, - 35, - 213, - 86, - 218, - 226, - 143, - 169, - 11, - 165, - 137, - 241, - 146, - 115, - 208, - 178, - 197, - 0, - 119, - 147, - 29, - 144, - 167, - 236, - 133, - 233, - 23, - 140, - 30, - 186, - 159, - 76, - 6, - 150, - 13, - 72, - 34, - 240, - 114, - 192, - 238, - 72, - 42, - 177, - 15, - 33, - 162, - 170, - 167, - 64, - 169, - 78, - 162, - 226, - 229, - 191, - 209, - 140, - 213, - 161, - 23, - 147, - 249, - 103, - 56, - 153, - 108, - 105, - 148, - 177, - 245, - 168, - 201, - 101, - 103, - 5, - 104, - 90, - 171, - 155, - 153, - 121, - 130, - 35, - 112, - 242, - 140, - 206, - 125, - 225, - 79, - 154, - 161, - 143, - 71, - 45, - 145, - 15, - 95, - 105, - 202, - 158, - 11, - 119, - 124, - 66, - 60, - 86, - 118, - 120, - 101, - 209, - 58, - 211, - 184, - 42, - 142, - 66, - 201, - 147, - 149, - 26, - 213, - 168, - 108, - 93, - 237, - 168, - 152, - 128, - 44, - 87, - 140, - 248, - 218, - 189, - 93, - 25, - 76, - 249, - 103, - 187, - 167, - 31, - 194, - 133, - 247, - 148, - 20, - 169, - 141, - 166, - 118, - 102, - 208, - 187, - 177, - 71, - 70, - 182, - 55, - 205, - 174, - 20, - 234, - 146, - 78, - 115, - 199, - 104, - 89, - 254, - 232, - 246, - 208, - 127, - 242, - 221, - 200, - 198, - 66, - 153, - 12, - 25, - 184, - 78, - 203, - 45, - 233, - 51, - 253, - 169, - 30, - 5, - 65, - 188, - 226, - 167, - 236, - 17, - 173, - 193, - 123, - 249, - 117, - 107, - 140, - 56, - 91, - 180, - 19, - 79, - 5, - 204, - 185, - 109, - 37, - 187, - 147, - 197, - 58, - 100, - 40, - 11, - 22, - 248, - 236, - 189, - 218, - 3, - 109, - 243, - 153, - 247, - 142, - 35, - 59, - 228, - 102, - 130, - 141, - 200, - 201, - 101, - 139, - 129, - 21, - 246, - 111, - 143, - 95, - 249, - 7, - 196, - 85, - 133, - 175, - 59, - 130, - 214, - 255, - 36, - 49, - 209, - 144, - 168, - 20, - 126, - 19, - 198, - 119, - 221, - 229, - 245, - 173, - 218, - 244, - 14, - 53, - 221, - 252, - 107, - 213, - 65, - 129, - 23, - 187, - 196, - 118, - 77, - 205, - 9, - 75, - 179, - 23, - 176, - 49, - 41, - 84, - 163, - 182, - 156, - 167, - 247, - 95, - 212, - 43, - 183, - 152, - 63, - 252, - 67, - 21, - 224, - 128, - 201, - 251, - 136, - 117, - 214, - 96, - 226, - 157, - 79, - 154, - 98, - 120, - 65, - 134, - 130, - 138, - 197, - 64, - 171, - 85, - 144, - 120, - 179, - 180 -}; diff --git a/openair1/PHY/INIT/init_extern.h b/openair1/PHY/INIT/init_extern.h deleted file mode 100644 index 4690bba42e..0000000000 --- a/openair1/PHY/INIT/init_extern.h +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.openairinterface.org/?page_id=698 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - *------------------------------------------------------------------------------- - * For more information about the OpenAirInterface (OAI) Software Alliance: - * contact@openairinterface.org - */ - diff --git a/openair1/PHY/INIT/init_vars.h b/openair1/PHY/INIT/init_vars.h deleted file mode 100644 index 4690bba42e..0000000000 --- a/openair1/PHY/INIT/init_vars.h +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.openairinterface.org/?page_id=698 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - *------------------------------------------------------------------------------- - * For more information about the OpenAirInterface (OAI) Software Alliance: - * contact@openairinterface.org - */ - diff --git a/openair1/PHY/LTE_ESTIMATION/lte_estimation_extern.h b/openair1/PHY/LTE_ESTIMATION/lte_estimation_extern.h deleted file mode 100644 index 4690bba42e..0000000000 --- a/openair1/PHY/LTE_ESTIMATION/lte_estimation_extern.h +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.openairinterface.org/?page_id=698 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - *------------------------------------------------------------------------------- - * For more information about the OpenAirInterface (OAI) Software Alliance: - * contact@openairinterface.org - */ - diff --git a/openair1/SCHED_UE/phy_procedures_lte_ue.c b/openair1/SCHED_UE/phy_procedures_lte_ue.c index 2af47fb2c0..6e50efe2e7 100644 --- a/openair1/SCHED_UE/phy_procedures_lte_ue.c +++ b/openair1/SCHED_UE/phy_procedures_lte_ue.c @@ -4783,7 +4783,7 @@ void phy_procedures_UE_lte(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,u if (msg_p != NULL) { switch (ITTI_MSG_ID(msg_p)) { case PHY_FIND_CELL_REQ: - LOG_I(PHY, "[UE %d] Received %s\n", ITTI_MSG_INSTANCE (msg_p) - NB_eNB_INST, ITTI_MSG_NAME (msg_p)); + LOG_E(PHY, "[UE %d] Received PLMN doesn't match SIM data, but not developped further processing %s\n", ITTI_MSG_INSTANCE (msg_p) - NB_eNB_INST, ITTI_MSG_NAME (msg_p)); /* TODO process the message */ break; diff --git a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_proto_extern.h b/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_proto_extern.h deleted file mode 100644 index 4690bba42e..0000000000 --- a/openair2/LAYER2/RLC/AM_v9.3.0/rlc_am_proto_extern.h +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.openairinterface.org/?page_id=698 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - *------------------------------------------------------------------------------- - * For more information about the OpenAirInterface (OAI) Software Alliance: - * contact@openairinterface.org - */ - diff --git a/openair2/RRC/LTE/rrc_2_rrm_msg.c b/openair2/RRC/LTE/rrc_2_rrm_msg.c deleted file mode 100644 index 87a0a3557b..0000000000 --- a/openair2/RRC/LTE/rrc_2_rrm_msg.c +++ /dev/null @@ -1,439 +0,0 @@ -/* - * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.openairinterface.org/?page_id=698 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - *------------------------------------------------------------------------------- - * For more information about the OpenAirInterface (OAI) Software Alliance: - * contact@openairinterface.org - */ - -/*! -******************************************************************************* - -\file rrc_2_rrm_msg.c - -\brief data formating for sending message over socket between RRC and RRM - -\author BURLOT Pascal - -\date 16/07/08 - -\par Historique: - P.BURLOT 2009-01-20 - bug fix (memeory leak) - Macro changed : - RRM_CALLOC() by RRM_CALLOC2() in msg_rrc_sensing_meas_ind() - -******************************************************************************* -*/ -#ifdef RRC_EMUL - -#include -#include -#include -#include -#include "L3_rrc_defs.h" -#include "rrm_sock.h" -#include "L3_rrc_interface.h" -#include "rrc_rrm_msg.h" -#include "rrm_util.h" - -#else - -#include "defs.h" - -#endif - -#ifdef TRACE -//! Macro creant la chaine a partir du nom de la variable -#define STRINGIZER(x) #x -//! Tableau pour le mode trace faisant la translation entre le numero et le nom du message -const char *Str_msg_rrc_rrm[NB_MSG_RRC_RRM] = { - STRINGIZER(RRM_RB_ESTABLISH_REQ ), - STRINGIZER(RRC_RB_ESTABLISH_RESP ), - STRINGIZER(RRC_RB_ESTABLISH_CFM ), - STRINGIZER(RRM_RB_MODIFY_REQ ), - STRINGIZER(RRC_RB_MODIFY_RESP ), - STRINGIZER(RRC_RB_MODIFY_CFM ), - STRINGIZER(RRM_RB_RELEASE_REQ ), - STRINGIZER(RRC_RB_RELEASE_RESP ), - STRINGIZER(RRC_MR_ATTACH_IND ), - STRINGIZER(RRM_SENSING_MEAS_REQ ), - STRINGIZER(RRC_SENSING_MEAS_RESP ), - STRINGIZER(RRC_CX_ESTABLISH_IND ), - STRINGIZER(RRC_PHY_SYNCH_TO_MR_IND ), - STRINGIZER(RRC_PHY_SYNCH_TO_CH_IND ), - STRINGIZER(RRCI_CX_ESTABLISH_RESP ), - STRINGIZER(RRC_SENSING_MEAS_IND ), - STRINGIZER(RRM_SENSING_MEAS_RESP ), - STRINGIZER(RRC_RB_MEAS_IND ), - STRINGIZER(RRM_RB_MEAS_RESP ), - STRINGIZER(RRM_INIT_CH_REQ ), - STRINGIZER(RRCI_INIT_MR_REQ ) -} ; -#endif - -/*! -******************************************************************************* -\brief This function initialize the message header -\return any return value -*/ -static void init_rrc_msg_head( - msg_head_t *msg_head , //!< message header to initialize - Instance_t inst , //!< Instance ID - MSG_RRC_RRM_T msg_type , //!< type of message to initialize - unsigned int size , //!< size of message - Transaction_t Trans_id //!< transaction id associated to this message -) -{ - if ( msg_head != NULL ) { - msg_head->start = START_MSG ; - msg_head->msg_type = 0xFF & msg_type ; - msg_head->inst = inst ; - msg_head->Trans_id = Trans_id ; - msg_head->size = size; - } -} - - -/*! -******************************************************************************* -\brief La fonction formate en un message generique de reponse pour les - fonctions : - - rrc_rb_establish_resp(),rrc_rb_modify_resp(),rrc_rb_modify_resp(), - - rrc_rb_release_resp() et rrc_sensing_meas_resp() . -\return message formate -*/ -msg_t mesg; -msg_t *msg_rrc_generic_resp( - Instance_t inst , //!< Instance ID - MSG_RRC_RRM_T msg_type , //!< type of message - Transaction_t Trans_id //!< Transaction ID -) -{ - init_rrc_msg_head(&(mesg.head),inst, msg_type, 0 , Trans_id); - mesg.data = NULL ; - - return &mesg ; -} - -/*! -******************************************************************************* -\brief La fonction formate en un message les parametres de la fonction - rrc_rb_establish_resp(). -\return message formate -*/ -msg_t *msg_rrc_rb_establish_resp( - Instance_t inst , //!< Instance ID - Transaction_t Trans_id //!< Transaction ID -) -{ - return msg_rrc_generic_resp( inst, RRC_RB_ESTABLISH_RESP, Trans_id) ; -} -/*! -******************************************************************************* -\brief La fonction formate en un message les parametres de la fonction - rrc_rb_establish_cfm(). -\return message formate -*/ -rrc_rb_establish_cfm_t P_rb_est_cfm ;//= RRM_CALLOC(rrc_rb_establish_cfm_t , 1 ) ; -msg_t *msg_rrc_rb_establish_cfm( - Instance_t inst , //!< Instance ID - RB_ID Rb_id , //!< Radio Bearer ID used by RRC - RB_TYPE RB_type , //!< Radio Bearer Type - Transaction_t Trans_id //!< Transaction ID -) -{ - // msg_t mesg; - - init_rrc_msg_head(&(mesg.head),inst,RRC_RB_ESTABLISH_CFM, sizeof( rrc_rb_establish_cfm_t ) ,Trans_id); - P_rb_est_cfm.Rb_id = Rb_id ; - P_rb_est_cfm.RB_type = RB_type ; - mesg.data = (char *) &P_rb_est_cfm ; - return &mesg ; - -} - -/*! -******************************************************************************* -\brief La fonction formate en un message les parametres de la fonction - rrc_rb_modify_resp(). -\return message formate -*/ -msg_t *msg_rrc_rb_modify_resp( - Instance_t inst , //!< Instance ID - Transaction_t Trans_id //!< Transaction ID -) -{ - return msg_rrc_generic_resp( inst,RRC_RB_MODIFY_RESP, Trans_id) ; -} -/*! -******************************************************************************* -\brief La fonction formate en un message les parametres de la fonction - rrc_rb_modify_cfm(). -\return message formate -*/ -rrc_rb_modify_cfm_t P_rb_md_cfm; -msg_t *msg_rrc_rb_modify_cfm( - Instance_t inst , //!< Instance ID - RB_ID Rb_id , //!< Radio Bearer ID used by RRC - Transaction_t Trans_id //!< Transaction ID -) -{ - // msg_t mesg; - init_rrc_msg_head(&(mesg.head),inst,RRC_RB_MODIFY_CFM, sizeof( rrc_rb_modify_cfm_t ) ,Trans_id); - P_rb_md_cfm.Rb_id = Rb_id ; - mesg.data = (char *) &P_rb_md_cfm ; - return &mesg ; - -} - -/*! -******************************************************************************* -\brief La fonction formate en un message les parametres de la fonction - rrc_rb_release_resp(). -\return message formate -*/ -msg_t *msg_rrc_rb_release_resp( - Instance_t inst , //!< Instance ID - Transaction_t Trans_id //!< Transaction ID -) -{ - return msg_rrc_generic_resp( inst,RRC_RB_RELEASE_RESP, Trans_id) ; -} -/*! -******************************************************************************* -\brief La fonction formate en un message les parametres de la fonction - rrc_MR_attach_ind(). -\return message formate -*/ -rrc_MR_attach_ind_t P_att_ind; -msg_t * msg_rrc_MR_attach_ind( - Instance_t inst , //!< Instance ID - L2_ID L2_id -) -{ - // msg_t mesg; - init_rrc_msg_head(&(mesg.head),inst,RRC_MR_ATTACH_IND, sizeof( rrc_MR_attach_ind_t ) ,0); - memcpy( P_att_ind.L2_id.L2_id, L2_id.L2_id, sizeof(L2_ID) ) ; - mesg.data = (char *) &P_att_ind ; - return &mesg ; -} - -/*! -******************************************************************************* -\brief La fonction formate en un message les parametres de la fonction - rrc_sensing_meas_resp(). -\return message formate -*/ -msg_t *msg_rrc_sensing_meas_resp( - Instance_t inst , //!< Instance ID - Transaction_t Trans_id //!< Transaction ID -) -{ - return msg_rrc_generic_resp( inst,RRC_SENSING_MEAS_RESP, Trans_id) ; -} -/*! -******************************************************************************* -\brief La fonction formate en un message les parametres de la fonction - rrc_cx_establish_ind(). -\return message formate -*/ -rrc_cx_establish_ind_t P_cx_est_ind; -msg_t * msg_rrc_cx_establish_ind( - Instance_t inst , //!< Instance ID - L2_ID L2_id , //!< Layer 2 (MAC) ID - Transaction_t Trans_id , //!< Transaction ID - unsigned char *L3_info , //!< Optional L3 Information - L3_INFO_T L3_info_t , //!< Type of L3 Information - RB_ID DTCH_B_id , //!< RBID of broadcast IP service (MR only) - RB_ID DTCH_id //!< RBID of default IP service (MR only) -) -{ - //msg_t mesg; - init_rrc_msg_head(&(mesg.head),inst,RRC_CX_ESTABLISH_IND, sizeof( rrc_cx_establish_ind_t ) ,Trans_id); - memcpy( P_cx_est_ind.L2_id.L2_id, L2_id.L2_id, sizeof(L2_ID) ) ; - P_cx_est_ind.DTCH_B_id = DTCH_B_id ; - P_cx_est_ind.DTCH_id = DTCH_id ; - P_cx_est_ind.L3_info_t = L3_info_t ; - - if ( L3_info_t == IPv4_ADDR ) { - memcpy( P_cx_est_ind.L3_info, L3_info, 4 ); - } else if ( L3_info_t == IPv6_ADDR ) { - memcpy( P_cx_est_ind.L3_info, L3_info, 16 ); - } - - mesg.data = (char *) &P_cx_est_ind ; - return &mesg ; -} -/*! -******************************************************************************* -\brief La fonction formate en un message les parametres de la fonction - rrc_phy_synch_to_MR_ind(). -\return message formate -*/ -rrc_phy_synch_to_MR_ind_t P_snc_mr; -msg_t * msg_rrc_phy_synch_to_MR_ind( - Instance_t inst , //!< Instance ID - L2_ID L2_id -) -{ - //msg_t smsg; - init_rrc_msg_head(&(mesg.head),inst,RRC_PHY_SYNCH_TO_MR_IND, sizeof( rrc_phy_synch_to_MR_ind_t ) ,0); - memcpy(&P_snc_mr.L2_id,(L2_ID*)&L2_id,sizeof(L2_ID)); - mesg.data = (char *)&P_snc_mr ; - msg("[msg_rrc_phy_synch_to_MR_ind] from Inst :%d\n",mesg.head.inst); - return &mesg ; -} -/*! -******************************************************************************* -\brief La fonction formate en un message les parametres de la fonction - rrc_phy_synch_to_CH_ind(). -\return message formate -*/ -rrc_phy_synch_to_CH_ind_t P_snc_ch; -msg_t * msg_rrc_phy_synch_to_CH_ind( - Instance_t inst , //!< Instance ID - unsigned int Ch_index , //!< Clusterhead index - L2_ID L2_id -) -{ - // msg_t smsg; - init_rrc_msg_head(&(mesg.head),inst, RRC_PHY_SYNCH_TO_CH_IND, sizeof( rrc_phy_synch_to_CH_ind_t ) ,0); - P_snc_ch.Ch_index = Ch_index ; - memcpy(&P_snc_ch.L2_id,(L2_ID*)&L2_id,sizeof(L2_ID)); - mesg.data = (char *) &P_snc_ch; - msg("[msg_rrc_phy_synch_to_CH_ind] from Inst :%d\n",mesg.head.inst); - return &mesg ; -} - -/*! -******************************************************************************* -\brief La fonction formate en un message les parametres de la fonction - rrc_sensing_meas_ind(). -\return message formate -*/ -rrc_sensing_meas_ind_t P_sens_ind; -msg_t * msg_rrc_sensing_meas_ind( - Instance_t inst , //!< Instance ID - L2_ID L2_id , //!< Layer 2 ID (MAC) of sensing node - unsigned int NB_meas , //!< Layer 2 ID (MAC) of sensing node - SENSING_MEAS_T *Sensing_meas , //!< Sensing Information - Transaction_t Trans_id //!< Transaction ID -) -{ - - // msg_t mesg; - unsigned int size = sizeof( rrc_sensing_meas_ind_t ) + (NB_meas-1) * sizeof(SENSING_MEAS_T) ; - // Note : (NB_meas-1) car la première est incorporé dans rrc_sensing_meas_ind_t - init_rrc_msg_head(&(mesg.head),inst, RRC_SENSING_MEAS_IND, size ,Trans_id); - memcpy( P_sens_ind.L2_id.L2_id, L2_id.L2_id, sizeof(L2_ID) ) ; - - if ( NB_meas > 0 ) { - memcpy( P_sens_ind.Sensing_meas , Sensing_meas, NB_meas * sizeof(SENSING_MEAS_T) ) ; - } - - P_sens_ind.NB_meas = NB_meas ; - mesg.data = (char *) &P_sens_ind ; - return &mesg ; -} - -/*! -******************************************************************************* -\brief La fonction formate en un message les parametres de la fonction - rrc_rb_meas_ind(). -\return message formate -*/ -rrc_rb_meas_ind_t P_rb_meas; -msg_t * msg_rrc_rb_meas_ind( - Instance_t inst , //!< Instance ID - RB_ID Rb_id , //!< Radio Bearer ID - L2_ID L2_id , //!< Layer 2 (MAC) IDs for link - MEAS_MODE Meas_mode , //!< Measurement mode (periodic or event-driven) - MAC_RLC_MEAS_T *Mac_rlc_meas , //!< MAC/RLC measurements - Transaction_t Trans_id //!< Transaction ID -) -{ - //msg_t mesg; - init_rrc_msg_head(&(mesg.head),inst, RRC_RB_MEAS_IND, sizeof( rrc_rb_meas_ind_t ) ,Trans_id); - memcpy( P_rb_meas.L2_id.L2_id, L2_id.L2_id, sizeof(L2_ID) ) ; - memcpy( &(P_rb_meas.Mac_rlc_meas), Mac_rlc_meas, sizeof(L2_ID) ) ; - P_rb_meas.Rb_id = Rb_id ; - P_rb_meas.Meas_mode = Meas_mode ; - mesg.data = (char *) &P_rb_meas; - return &mesg ; - -} - - - -/*****************************************************************************/ -rrc_init_scan_req_t P_init_scan; -msg_t * msg_rrc_init_scan_req( - Instance_t inst , //!< Instance ID - L2_ID L2_id , //!< Layer 2 (MAC) IDs for link - unsigned int Interv -) -{ - //msg_t mesg; - msg("RRCI: inst %d sendind rrc_init_scan_req from FC %d %d\n",inst,L2_id.L2_id[0],L2_id.L2_id[7]); - init_rrc_msg_head(&(mesg.head),inst, RRC_INIT_SCAN_REQ, sizeof( rrc_init_scan_req_t ) ,0); - memcpy( &P_init_scan.L2_id.L2_id[0], &L2_id.L2_id[0], sizeof(L2_ID) ) ; - P_init_scan.interv=Interv; - - return &mesg ; - -} - - - -/*****************************************************************************/ - -rrc_update_sens_t P_update_sens; -msg_t * msg_rrc_update_sens( - Instance_t inst , //!< Instance ID - Sens_ch_t *Sens, - L2_ID L2_id, - unsigned char NB_info -) -{ - //msg_t mesg; - init_rrc_msg_head(&(mesg.head),inst, RRC_UPDATE_SENS, sizeof( rrc_update_sens_t ) ,0); - memcpy( &P_update_sens.L2_id.L2_id[0], &L2_id.L2_id[0], sizeof(L2_ID) ) ; - memcpy( &P_update_sens.Sens_meas[0], (rrc_update_sens_t *)Sens, NB_info*sizeof(Sens_ch_t) ) ; - P_update_sens.NB_info=NB_info; - return &mesg ; - -} - - - -/*****************************************************************************/ - -rrc_end_scan_req_t P_end_scan; -msg_t * msg_rrc_end_scan_req( - Instance_t inst , //!< Instance ID - unsigned char CH_index -) -{ - - //msg_t mesg; - msg("RRC: send END_SCAN_REQ, INST %d\n",inst); - init_rrc_msg_head(&(mesg.head),inst, RRC_END_SCAN_REQ, sizeof( rrc_end_scan_req_t ) ,0); - P_update_sens.L2_id.L2_id[0]=CH_index; - return &mesg ; - -} - diff --git a/openair2/RRC/LTE/rrc_UE.c b/openair2/RRC/LTE/rrc_UE.c index 5a35f7aafe..65150d32ab 100644 --- a/openair2/RRC/LTE/rrc_UE.c +++ b/openair2/RRC/LTE/rrc_UE.c @@ -3301,6 +3301,7 @@ int decode_SIB1( const protocol_ctxt_t* const ctxt_pP, const uint8_t eNB_index, msg_p = itti_alloc_new_message(TASK_RRC_UE, PHY_FIND_NEXT_CELL_REQ); itti_send_msg_to_task(TASK_PHY_UE, ctxt_pP->instance, msg_p); + LOG_E(RRC, "Synched with a cell, but PLMN doesn't match our SIM, the message PHY_FIND_NEXT_CELL_REQ is sent but lost in current UE implementation! \n"); } } #endif @@ -4718,7 +4719,6 @@ void *rrc_ue_task( void *args_p ) break; case MESSAGE_TEST: - LOG_D(RRC, "[UE %d] Received %s\n", ue_mod_id, ITTI_MSG_NAME (msg_p)); break; /* MAC messages */ @@ -5113,6 +5113,7 @@ void *rrc_ue_task( void *args_p ) break; // PHY_FIND_CELL_IND case PHY_MEAS_REPORT_IND: { + LOG_D(RRC, "[UE %d] Received %s\n", ue_mod_id, ITTI_MSG_NAME (msg_p)); MessageDef *message_p; message_p = itti_alloc_new_message(TASK_RRC_UE, RRC_RAL_MEASUREMENT_REPORT_IND); @@ -5130,6 +5131,7 @@ void *rrc_ue_task( void *args_p ) } case RRC_RAL_CONFIGURE_THRESHOLD_REQ: + LOG_D(RRC, "[UE %d] Received %s\n", ue_mod_id, ITTI_MSG_NAME (msg_p)); rrc_ue_ral_handle_configure_threshold_request(ue_mod_id, msg_p); break; diff --git a/openair3/NAS/COMMON/API/NETWORK/l2_message.h b/openair3/NAS/COMMON/API/NETWORK/l2_message.h deleted file mode 100644 index 9cf65b7736..0000000000 --- a/openair3/NAS/COMMON/API/NETWORK/l2_message.h +++ /dev/null @@ -1,310 +0,0 @@ -/* - * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.openairinterface.org/?page_id=698 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - *------------------------------------------------------------------------------- - * For more information about the OpenAirInterface (OAI) Software Alliance: - * contact@openairinterface.org - */ - -/***************************************************************************** - -Source as_message.h - -Version 0.1 - -Date 2012/10/18 - -Product NAS stack - -Subsystem Application Programming Interface - -Author Frederic Maurel - -Description Defines the messages supported by the Access Stratum sublayer - protocol (usually RRC and S1AP for E-UTRAN) and functions used - to encode and decode - -*****************************************************************************/ -#ifndef __AS_MESSAGE_H__ -#define __AS_MESSAGE_H__ - -#include "commonDef.h" -#include "networkDef.h" - -/****************************************************************************/ -/********************* G L O B A L C O N S T A N T S *******************/ -/****************************************************************************/ - -/* Access Stratum Message types */ -#define AS_REQUEST 0x0100 -#define AS_RESPONSE 0x0200 -#define AS_INDICATION 0x0400 -#define AS_CONFIRM 0x0800 - -/* - * Access Stratum Message identifiers - * ---------------------------------- - */ - -/* Cell information relevant for cell selection processing */ -#define AS_CELL_INFO 0x01 -#define AS_CELL_INFO_REQ (AS_CELL_INFO | AS_REQUEST) -#define AS_CELL_INFO_RSP (AS_CELL_INFO | AS_RESPONSE) -#define AS_CELL_INFO_IND (AS_CELL_INFO | AS_INDICATION) - -/* Security mode control */ -#define AS_SECURITY 0x02 -#define AS_SECURITY_REQ (AS_SECURITY | AS_REQUEST) -#define AS_SECURITY_RSP (AS_SECURITY | AS_RESPONSE) - -/* Paging information */ -#define AS_PAGING 0x03 -#define AS_PAGING_IND (AS_PAGING | AS_INDICATION) - -/* NAS signalling connection establishment */ -#define AS_NAS_ESTABLISH 0x04 -#define AS_NAS_ESTABLISH_REQ (AS_NAS_ESTABLISH | AS_REQUEST) -#define AS_NAS_ESTABLISH_RSP (AS_NAS_ESTABLISH | AS_RESPONSE) - -/* NAS signalling connection release */ -#define AS_NAS_RELEASE 0x05 -#define AS_NAS_RELEASE_REQ (AS_NAS_RELEASE | AS_REQUEST) -#define AS_NAS_RELEASE_IND (AS_NAS_RELEASE | AS_INDICATION) - -/* NAS information transfer */ -#define AS_INFO_TRANSFER 0x10 -#define AS_UL_INFO_TRANSFER (AS_INFO_TRANSFER | AS_REQUEST) -#define AS_DL_INFO_TRANSFER (AS_INFO_TRANSFER | AS_INDICATION) - -/****************************************************************************/ -/************************ G L O B A L T Y P E S ************************/ -/****************************************************************************/ - -/* - * -------------------------------------------------------------------------- - * Available PLMNs and cell Information - * -------------------------------------------------------------------------- - */ - -/* Radio access technologies supported by the network */ -#define AS_GSM (1 << NET_ACCESS_GSM) -#define AS_COMPACT (1 << NET_ACCESS_COMPACT) -#define AS_UTRAN (1 << NET_ACCESS_UTRAN) -#define AS_EGPRS (1 << NET_ACCESS_EGPRS) -#define AS_HSDPA (1 << NET_ACCESS_HSDPA) -#define AS_HSUPA (1 << NET_ACCESS_HSUPA) -#define AS_HSDUPA (1 << NET_ACCESS_HSDUPA) -#define AS_EUTRAN (1 << NET_ACCESS_EUTRAN) - -/* - * NAS->AS -K_eNB refresh request - * NAS request AS to refresh its KeNB key - */ -typedef struct kenb_refresh_req_s { - Byte_t kenb[32]; -} kenb_refresh_req_t; - -/* - * NAS->AS - Cell Information request - * NAS request AS to search for a suitable cell belonging to the selected - * PLMN to camp on. - */ -typedef struct { - plmn_t plmnID; /* PLMN identifier */ - Byte_t rat; /* Bitmap - set of radio access technologies */ -} cell_info_req_t; - -/* - * AS->NAS - Cell Information response - * AS search for a suitable cell and respond to NAS. If found, the cell - * is selected to camp on. - */ -typedef struct { - plmn_t plmnID; /* PLMN identifier */ - TAC_t tac; /* identifies a tracking area the PLMN belongs to */ - CI_t cellID; /* identifies a cell within a PLMN */ - AcT_t rat; /* radio access technology supported by the cell */ -} cell_info_rsp_t; - -/* - * AS->NAS - Cell Information indication - * AS Reports available PLMNs with associated Radio Access Technologies - * to NAS on request from NAS or autonomously. - */ -typedef struct { -#define PLMN_LIST_MAX_SIZE 6 - PLMN_LIST_T(PLMN_LIST_MAX_SIZE) plmnIDs; /* List of PLMN identifiers */ - Byte_t rat[PLMN_LIST_MAX_SIZE]; /* Radio access technologies */ - TAC_t tac; /* identifies a tracking area within a scope of PLMNs */ - CI_t cellID; /* identifies a cell within a PLMN */ -} cell_info_ind_t; - -/* - * -------------------------------------------------------------------------- - * Security mode control - * -------------------------------------------------------------------------- - */ - -/* - * TODO: NAS->AS - Security command request - */ -typedef struct {} security_req_t; - - -/* - * TODO: AS->NAS - Security command response - */ -typedef struct {} security_rsp_t; - - -/* - * -------------------------------------------------------------------------- - * Paging information - * -------------------------------------------------------------------------- - */ - -/* - * TODO: AS->NAS - Paging Information indication - */ -typedef struct {} paging_ind_t; - -/* - * -------------------------------------------------------------------------- - * NAS signalling connection establishment - * -------------------------------------------------------------------------- - */ - -/* Cause of RRC connection establishment */ -#define AS_CAUSE_EMERGENCY (NET_ESTABLISH_CAUSE_EMERGENCY) -#define AS_CAUSE_HIGH_PRIO (NET_ESTABLISH_CAUSE_HIGH_PRIO) -#define AS_CAUSE_MT_ACCESS (NET_ESTABLISH_CAUSE_MT_ACCESS) -#define AS_CAUSE_MO_SIGNAL (NET_ESTABLISH_CAUSE_MO_SIGNAL) -#define AS_CAUSE_MO_DATA (NET_ESTABLISH_CAUSE_MO_DATA) -#define AS_CAUSE_V1020 (NET_ESTABLISH_CAUSE_V1020) - -/* Type of the call associated to the RRC connection establishment */ -#define AS_TYPE_ORIGINATING_SIGNAL (NET_ESTABLISH_TYPE_ORIGINATING_SIGNAL) -#define AS_TYPE_EMERGENCY_CALLS (NET_ESTABLISH_TYPE_EMERGENCY_CALLS) -#define AS_TYPE_ORIGINATING_CALLS (NET_ESTABLISH_TYPE_ORIGINATING_CALLS) -#define AS_TYPE_TERMINATING_CALLS (NET_ESTABLISH_TYPE_TERMINATING_CALLS) -#define AS_TYPE_MO_CS_FALLBACK (NET_ESTABLISH_TYPE_MO_CS_FALLBACK) - - -/* Structure of the SAE Temporary Mobile Subscriber Identity */ -typedef struct { - uint8_t MMEcode; /* MME code that allocated the GUTI */ - uint32_t m_tmsi; /* M-Temporary Mobile Subscriber Identity */ -} as_stmsi_t; - -/* Structure of the dedicated NAS information */ -typedef struct { - uint32_t length; /* Length of the NAS information data */ - Byte_t* data; /* Dedicated NAS information data container */ -} as_nas_info_t; - -/* - * NAS->AS - NAS signalling connection establishment request - * NAS request AS to perform the RRC connection establishment procedure - * to transfer initial NAS message to the network while UE is in IDLE mode. - */ -typedef struct { - uint8_t cause; /* Connection establishment cause */ - uint8_t type; /* Associated call type */ - plmn_t plmnID; /* Identifier of the selected PLMN */ - as_stmsi_t s_tmsi; /* SAE Temporary Mobile Subscriber Identity */ - as_nas_info_t initialNasMsg;/* Initial NAS message to transfer */ -} nas_establish_req_t; - -/* - * TODO: AS->NAS - NAS signalling connection establishment response - */ -typedef struct {} nas_establish_rsp_t; - -/* - * -------------------------------------------------------------------------- - * NAS signalling connection release - * -------------------------------------------------------------------------- - */ - -/* - * TODO: NAS->AS - NAS signalling connection release request - */ -typedef struct {} nas_release_req_t; - -/* - * TODO: AS->NAS - NAS signalling connection release indication - */ -typedef struct {} nas_release_ind_t; - -/* - * -------------------------------------------------------------------------- - * NAS information transfer - * -------------------------------------------------------------------------- - */ - -/* - * AS->NAS - Downlink data transfer - * AS notifies upper layer that NAS or non-3GPP dedicated downlink information - * has to be transfered to NAS. -*/ -typedef as_nas_info_t dl_info_transfer_t; - -/* - * NAS->AS - Uplink data transfer request - * NAS requests under layer to transfer NAS or non-3GPP dedicated uplink - * information to AS. - */ -typedef as_nas_info_t ul_info_transfer_t; - -/* - * -------------------------------------------------------------------------- - * Structure of the AS messages handled by the network sublayer - * -------------------------------------------------------------------------- - */ -typedef struct { - uint16_t msgID; - union { - cell_info_req_t cell_info_req; - cell_info_rsp_t cell_info_rsp; - cell_info_ind_t cell_info_ind; - security_req_t security_req; - security_rsp_t security_rsp; - paging_ind_t paging_ind; - nas_establish_req_t nas_establish_req; - nas_establish_rsp_t nas_establish_rsp; - nas_release_req_t nas_release_req; - nas_release_ind_t nas_release_ind; - ul_info_transfer_t ul_info_transfer; - dl_info_transfer_t dl_info_transfer; - } __attribute__((__packed__)) msg; -} as_message_t; - -/****************************************************************************/ -/******************** G L O B A L V A R I A B L E S ********************/ -/****************************************************************************/ - -/****************************************************************************/ -/****************** E X P O R T E D F U N C T I O N S ******************/ -/****************************************************************************/ - -int as_message_decode(const char* buffer, int length, as_message_t* msg); - -int as_message_encode(char* buffer, int length, const as_message_t* msg); - -/* Implemented in the network_api.c body file */ -int as_message_send(as_message_t* as_msg, const void* nas_msg); - -#endif /* __AS_MESSAGE_H__*/ diff --git a/openair3/NAS/TOOLS/network.h b/openair3/NAS/TOOLS/network.h deleted file mode 100644 index cde82f4560..0000000000 --- a/openair3/NAS/TOOLS/network.h +++ /dev/null @@ -1,123 +0,0 @@ -/* - * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.openairinterface.org/?page_id=698 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - *------------------------------------------------------------------------------- - * For more information about the OpenAirInterface (OAI) Software Alliance: - * contact@openairinterface.org - */ - -/***************************************************************************** -Source network.h - -Version 0.1 - -Date 2013/03/26 - -Product USIM data generator - -Subsystem PLMN network operators - -Author Frederic Maurel - -Description Defines a list of PLMN network operators - -*****************************************************************************/ -#ifndef __NETWORK_H__ -#define __NETWORK_H__ - -#include "commonDef.h" -#include "networkDef.h" - -/****************************************************************************/ -/********************* G L O B A L C O N S T A N T S *******************/ -/****************************************************************************/ -/* - * PLMN network operator record index - */ -#define TEST1 0 -#define SFR1 1 -#define SFR2 2 -#define SFR3 3 -#define OAI_LTEBOX 4 -#define TM1 5 -#define FCT1 6 -#define VDF1 7 -#define VDF2 8 -#define VDF3 9 -#define VDF4 10 -#define VDF5 11 - - -#define SELECTED_PLMN TEST1 //SFR1 - -#define TEST_PLMN {0,0,0x0f,1,1,0} // 00101 -#define SFR_PLMN_1 {0,2,0x0f,8,0,1} // 20810 -#define SFR_PLMN_2 {0,2,0x0f,8,1,1} // 20811 -#define SFR_PLMN_3 {0,2,0x0f,8,3,1} // 20813 -#define OAI_LTEBOX_PLMN {0,2,0x0f,8,3,9} //20893 -#define TM_PLMN_1 {1,3,0,0,8,2} // 310280 -#define FCT_PLMN_1 {1,3,8,0,2,0} // 310028 -#define VDF_PLMN_1 {2,2,0x0f,2,0,1} // 22210 -#define VDF_PLMN_2 {1,2,0x0f,4,0x0f,1} // 2141 -#define VDF_PLMN_3 {1,2,0x0f,4,0x0f,6} // 2146 -#define VDF_PLMN_4 {6,2,0x0f,2,0x0f,2} // 2622 -#define VDF_PLMN_5 {6,2,0x0f,2,0x0f,4} // 2624 - - -/****************************************************************************/ -/************************ G L O B A L T Y P E S ************************/ -/****************************************************************************/ - -/* - * PLMN network operator record - */ -typedef struct { - unsigned int num; - plmn_t plmn; - char fullname[NET_FORMAT_LONG_SIZE + 1]; - char shortname[NET_FORMAT_SHORT_SIZE + 1]; - tac_t tac_start; - tac_t tac_end; -} network_record_t; - - -/****************************************************************************/ -/******************** G L O B A L V A R I A B L E S ********************/ -/****************************************************************************/ - -/* - * The list of PLMN network operator records - */ -network_record_t network_records[] = { - {00101, TEST_PLMN, "Test network", "OAI4G", 0x0001, 0xfffd}, - {20810, SFR_PLMN_1, "SFR France", "SFR", 0x0001, 0xfffd}, - {20811, SFR_PLMN_2, "SFR France", "SFR", 0x0001, 0xfffd}, - {20813, SFR_PLMN_3, "SFR France", "SFR", 0x0001, 0xfffd}, - {20893, OAI_LTEBOX_PLMN, "OAI LTEBOX", "OAIALU", 0x0001, 0xfffd}, - {310280,TM_PLMN_1, "T-Mobile USA", "T-Mobile", 0x0001, 0xfffd}, - {310028,FCT_PLMN_1, "FICTITIOUS USA", "FICTITIO", 0x0001, 0xfffd}, - {22210, VDF_PLMN_1, "Vodafone Italia", "VODAFONE", 0x0001, 0xfffd}, - {2141, VDF_PLMN_2, "Vodafone Spain", "VODAFONE", 0x0001, 0xfffd}, - {2146, VDF_PLMN_3, "Vodafone Spain", "VODAFONE", 0x0001, 0xfffd}, - {2622, VDF_PLMN_4, "Vodafone Germ", "VODAFONE", 0x0001, 0xfffd}, - {2624, VDF_PLMN_5, "Vodafone Germ", "VODAFONE", 0x0001, 0xfffd}, -}; - -/****************************************************************************/ -/****************** E X P O R T E D F U N C T I O N S ******************/ -/****************************************************************************/ - -#endif /* __NETWORK_H__*/ diff --git a/openair3/UTILS/mme_config.c b/openair3/UTILS/mme_config.c deleted file mode 100644 index d2c25af10a..0000000000 --- a/openair3/UTILS/mme_config.c +++ /dev/null @@ -1,716 +0,0 @@ -/* - * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The OpenAirInterface Software Alliance licenses this file to You under - * the OAI Public License, Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.openairinterface.org/?page_id=698 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - *------------------------------------------------------------------------------- - * For more information about the OpenAirInterface (OAI) Software Alliance: - * contact@openairinterface.org - */ - -#if HAVE_CONFIG_H -# include "config.h" -#endif - -#include -#include -#include -#include -#include -#include -#include - -#include /* To provide inet_addr */ - -#include "intertask_interface.h" -#include "assertions.h" -#include "msc.h" -#include "mme_config.h" -#include "spgw_config.h" -#include "intertask_interface_conf.h" - -mme_config_t mme_config; - -int mme_config_find_mnc_length(const char mcc_digit1P, - const char mcc_digit2P, - const char mcc_digit3P, - const char mnc_digit1P, - const char mnc_digit2P, - const char mnc_digit3P) -{ - - uint16_t mcc = 100*mcc_digit1P + 10*mcc_digit2P + mcc_digit3P; - uint16_t mnc3= 100*mnc_digit1P + 10*mnc_digit2P + mnc_digit3P; - uint16_t mnc2= 10*mnc_digit1P + mnc_digit2P; - int plmn_index = 0; - - AssertFatal((mcc_digit1P >= 0) && (mcc_digit1P <= 9) - && (mcc_digit2P >= 0) && (mcc_digit2P <= 9) - && (mcc_digit3P >= 0) && (mcc_digit3P <= 9) , - "BAD MCC PARAMETER (%d%d%d)!\n", - mcc_digit1P, mcc_digit2P, mcc_digit3P); - - AssertFatal((mnc_digit2P >= 0) && (mnc_digit2P <= 9) - && (mnc_digit1P >= 0) && (mnc_digit1P <= 9) , - "BAD MNC PARAMETER (%d.%d.%d)!\n", - mnc_digit1P, mnc_digit2P, mnc_digit3P); - - - while (plmn_index < mme_config.gummei.nb_plmns) { - if (mme_config.gummei.plmn_mcc[plmn_index] == mcc) { - if ((mme_config.gummei.plmn_mnc[plmn_index] == mnc2) && - (mme_config.gummei.plmn_mnc_len[plmn_index] == 2)) { - return 2; - } else if ((mme_config.gummei.plmn_mnc[plmn_index] == mnc3) && - (mme_config.gummei.plmn_mnc_len[plmn_index] == 3)) { - return 3; - } - } - - plmn_index += 1; - } - - return 0; -} - - -static -void mme_config_init(mme_config_t *mme_config_p) -{ - memset(mme_config_p, 0, sizeof(mme_config_t)); - - pthread_rwlock_init(&mme_config_p->rw_lock, NULL); - - mme_config_p->verbosity_level = 0; - mme_config_p->config_file = NULL; - mme_config_p->max_eNBs = MAX_NUMBER_OF_ENB; - mme_config_p->max_ues = MAX_NUMBER_OF_UE; - - mme_config_p->emergency_attach_supported = 0; - mme_config_p->unauthenticated_imsi_supported = 0; - - /* Timer configuration */ - mme_config_p->gtpv1u_config.port_number = GTPV1_U_PORT_NUMBER; - mme_config_p->s1ap_config.port_number = S1AP_PORT_NUMBER; - /* IP configuration */ - mme_config_p->ipv4.sgw_ip_address_for_S1u_S12_S4_up = inet_addr(DEFAULT_SGW_IP_ADDRESS_FOR_S1U_S12_S4_UP); - - mme_config_p->ipv4.mme_interface_name_for_S1_MME = DEFAULT_MME_INTERFACE_NAME_FOR_S1_MME; - mme_config_p->ipv4.mme_ip_address_for_S1_MME = inet_addr(DEFAULT_MME_IP_ADDRESS_FOR_S1_MME); - - mme_config_p->ipv4.mme_interface_name_for_S11 = DEFAULT_MME_INTERFACE_NAME_FOR_S11; - mme_config_p->ipv4.mme_ip_address_for_S11 = inet_addr(DEFAULT_MME_IP_ADDRESS_FOR_S11); - - mme_config_p->ipv4.sgw_ip_address_for_S11 = inet_addr(DEFAULT_SGW_IP_ADDRESS_FOR_S11); - - mme_config_p->s6a_config.conf_file = S6A_CONF_FILE; - - mme_config_p->itti_config.queue_size = ITTI_QUEUE_MAX_ELEMENTS; - mme_config_p->itti_config.log_file = NULL; - - mme_config_p->sctp_config.in_streams = SCTP_IN_STREAMS; - mme_config_p->sctp_config.out_streams = SCTP_OUT_STREAMS; - - mme_config_p->relative_capacity = RELATIVE_CAPACITY; - - mme_config_p->mme_statistic_timer = MME_STATISTIC_TIMER_S; - - mme_config_p->gummei.nb_mme_gid = 1; - mme_config_p->gummei.mme_gid = calloc(1, sizeof(*mme_config_p->gummei.mme_gid)); - mme_config_p->gummei.mme_gid[0] = MMEGID; - mme_config_p->gummei.nb_mmec = 1; - mme_config_p->gummei.mmec = calloc(1, sizeof(*mme_config_p->gummei.mmec)); - mme_config_p->gummei.mmec[0] = MMEC; - - /* Set the TAI */ - mme_config_p->gummei.nb_plmns = 1; - mme_config_p->gummei.plmn_mcc = calloc(1, sizeof(*mme_config_p->gummei.plmn_mcc)); - mme_config_p->gummei.plmn_mnc = calloc(1, sizeof(*mme_config_p->gummei.plmn_mnc)); - mme_config_p->gummei.plmn_mnc_len = calloc(1, sizeof(*mme_config_p->gummei.plmn_mnc_len)); - mme_config_p->gummei.plmn_tac = calloc(1, sizeof(*mme_config_p->gummei.plmn_tac)); - - - mme_config_p->gummei.plmn_mcc[0] = PLMN_MCC; - mme_config_p->gummei.plmn_mnc[0] = PLMN_MNC; - mme_config_p->gummei.plmn_mnc_len[0] = PLMN_MNC_LEN; - mme_config_p->gummei.plmn_tac[0] = PLMN_TAC; - - mme_config_p->s1ap_config.outcome_drop_timer_sec = S1AP_OUTCOME_TIMER_DEFAULT; -} - -int mme_system(char *command_pP, int abort_on_errorP) -{ - int ret = -1; - - if (command_pP) { - fprintf(stdout, "system command: %s\n",command_pP); - ret = system(command_pP); - - if (ret < 0) { - fprintf(stderr, "ERROR in system command %s: %d\n", - command_pP,ret); - - if (abort_on_errorP) { - exit(-1); // may be not exit - } - } - } - - return ret; -} - - -static int config_parse_file(mme_config_t *mme_config_p) -{ - config_t cfg; - config_setting_t *setting_mme = NULL; - config_setting_t *setting = NULL; - config_setting_t *subsetting = NULL; - config_setting_t *sub2setting = NULL; - - long int alongint; - int i, num; - char *astring = NULL; - char *address = NULL; - char *cidr = NULL; - - const char* tac = NULL; - const char* mcc = NULL; - const char* mnc = NULL; - - char *sgw_ip_address_for_S1u_S12_S4_up = NULL; - char *mme_interface_name_for_S1_MME = NULL; - char *mme_ip_address_for_S1_MME = NULL; - char *mme_interface_name_for_S11 = NULL; - char *mme_ip_address_for_S11 = NULL; - char *sgw_ip_address_for_S11 = NULL; - char system_cmd[256]; - - config_init(&cfg); - - if(mme_config_p->config_file != NULL) { - /* Read the file. If there is an error, report it and exit. */ - if(! config_read_file(&cfg, mme_config_p->config_file)) { - fprintf(stdout, "ERROR: %s:%d - %s\n", mme_config_p->config_file, config_error_line(&cfg), config_error_text(&cfg)); - config_destroy(&cfg); - AssertFatal (1 == 0, "Failed to parse MME configuration file %s!\n", mme_config_p->config_file); - } - } else { - fprintf(stdout, "ERROR No MME configuration file provided!\n"); - config_destroy(&cfg); - AssertFatal (0, "No MME configuration file provided!\n"); - } - - setting_mme = config_lookup(&cfg, MME_CONFIG_STRING_MME_CONFIG); - - if(setting_mme != NULL) { - // GENERAL MME SETTINGS - if( (config_setting_lookup_string( setting_mme, MME_CONFIG_STRING_REALM, (const char **)&astring) )) { - mme_config_p->realm = strdup(astring); - mme_config_p->realm_length = strlen(mme_config_p->realm); - } - - if( (config_setting_lookup_int( setting_mme, MME_CONFIG_STRING_MAXENB, &alongint) )) { - mme_config_p->max_eNBs = (uint32_t)alongint; - } - - if( (config_setting_lookup_int( setting_mme, MME_CONFIG_STRING_MAXUE, &alongint) )) { - mme_config_p->max_ues = (uint32_t)alongint; - } - - if( (config_setting_lookup_int( setting_mme, MME_CONFIG_STRING_RELATIVE_CAPACITY, &alongint) )) { - mme_config_p->relative_capacity = (uint8_t)alongint; - } - - if( (config_setting_lookup_int( setting_mme, MME_CONFIG_STRING_STATISTIC_TIMER, &alongint) )) { - mme_config_p->mme_statistic_timer = (uint32_t)alongint; - } - - if( (config_setting_lookup_string( setting_mme, MME_CONFIG_STRING_EMERGENCY_ATTACH_SUPPORTED, (const char **)&astring) )) { - if (strcasecmp(astring , "yes") == 0) - mme_config_p->emergency_attach_supported = 1; - else - mme_config_p->emergency_attach_supported = 0; - } - - if( (config_setting_lookup_string( setting_mme, MME_CONFIG_STRING_UNAUTHENTICATED_IMSI_SUPPORTED, (const char **)&astring) )) { - if (strcasecmp(astring , "yes") == 0) - mme_config_p->unauthenticated_imsi_supported = 1; - else - mme_config_p->unauthenticated_imsi_supported = 0; - } - - if( (config_setting_lookup_string( setting_mme, MME_CONFIG_STRING_ASN1_VERBOSITY, (const char **)&astring) )) { - if (strcasecmp(astring , MME_CONFIG_STRING_ASN1_VERBOSITY_NONE) == 0) - mme_config_p->verbosity_level = 0; - else if (strcasecmp(astring , MME_CONFIG_STRING_ASN1_VERBOSITY_ANNOYING) == 0) - mme_config_p->verbosity_level = 2; - else if (strcasecmp(astring , MME_CONFIG_STRING_ASN1_VERBOSITY_INFO) == 0) - mme_config_p->verbosity_level = 1; - else - mme_config_p->verbosity_level = 0; - } - - // ITTI SETTING - setting = config_setting_get_member (setting_mme, MME_CONFIG_STRING_INTERTASK_INTERFACE_CONFIG); - - if (setting != NULL) { - if( (config_setting_lookup_int( setting, MME_CONFIG_STRING_INTERTASK_INTERFACE_QUEUE_SIZE, &alongint) )) { - mme_config_p->itti_config.queue_size = (uint32_t)alongint; - } - } - - // S6A SETTING - setting = config_setting_get_member (setting_mme, MME_CONFIG_STRING_S6A_CONFIG); - - if (setting != NULL) { - if( (config_setting_lookup_string( setting, MME_CONFIG_STRING_S6A_CONF_FILE_PATH, (const char **)&astring) )) { - if (astring != NULL) - mme_config_p->s6a_config.conf_file = strdup(astring); - } - - if( (config_setting_lookup_string( setting, MME_CONFIG_STRING_S6A_HSS_HOSTNAME, (const char **)&astring) )) { - if (astring != NULL) - mme_config_p->s6a_config.hss_host_name = strdup(astring); - else - AssertFatal (1 == 0, - "You have to provide a valid HSS hostname %s=...\n", - MME_CONFIG_STRING_S6A_HSS_HOSTNAME); - } - } - - // SCTP SETTING - setting = config_setting_get_member (setting_mme, MME_CONFIG_STRING_SCTP_CONFIG); - - if (setting != NULL) { - if( (config_setting_lookup_int( setting, MME_CONFIG_STRING_SCTP_INSTREAMS, &alongint) )) { - mme_config_p->sctp_config.in_streams = (uint16_t)alongint; - } - - if( (config_setting_lookup_int( setting, MME_CONFIG_STRING_SCTP_OUTSTREAMS, &alongint) )) { - mme_config_p->sctp_config.out_streams = (uint16_t)alongint; - } - } - - // S1AP SETTING - setting = config_setting_get_member (setting_mme, MME_CONFIG_STRING_S1AP_CONFIG); - - if (setting != NULL) { - if( (config_setting_lookup_int( setting, MME_CONFIG_STRING_S1AP_OUTCOME_TIMER, &alongint) )) { - mme_config_p->s1ap_config.outcome_drop_timer_sec = (uint8_t)alongint; - } - - if( (config_setting_lookup_int( setting, MME_CONFIG_STRING_S1AP_PORT, &alongint) )) { - mme_config_p->s1ap_config.port_number = (uint16_t)alongint; - } - } - - // GUMMEI SETTING - setting = config_setting_get_member (setting_mme, MME_CONFIG_STRING_GUMMEI_CONFIG); - - if (setting != NULL) { - subsetting = config_setting_get_member (setting, MME_CONFIG_STRING_MME_CODE); - - if (subsetting != NULL) { - num = config_setting_length(subsetting); - - if (mme_config_p->gummei.nb_mmec != num) { - if (mme_config_p->gummei.mmec != NULL) { - free(mme_config_p->gummei.mmec); - } - - mme_config_p->gummei.mmec = calloc(num, sizeof(*mme_config_p->gummei.mmec)); - } - - mme_config_p->gummei.nb_mmec = num; - - for (i = 0; i < num; i++) { - mme_config_p->gummei.mmec[i] = config_setting_get_int_elem(subsetting, i); - } - } - - subsetting = config_setting_get_member (setting, MME_CONFIG_STRING_MME_GID); - - if (subsetting != NULL) { - num = config_setting_length(subsetting); - - if (mme_config_p->gummei.nb_mme_gid != num) { - if (mme_config_p->gummei.mme_gid != NULL) { - free(mme_config_p->gummei.mme_gid); - } - - mme_config_p->gummei.mme_gid = calloc(num, sizeof(*mme_config_p->gummei.mme_gid)); - } - - mme_config_p->gummei.nb_mme_gid = num; - - for (i = 0; i < num; i++) { - mme_config_p->gummei.mme_gid[i] = config_setting_get_int_elem(subsetting, i); - } - } - - subsetting = config_setting_get_member (setting, MME_CONFIG_STRING_TAI_LIST); - - if (subsetting != NULL) { - num = config_setting_length(subsetting); - - if (mme_config_p->gummei.nb_plmns != num) { - if (mme_config_p->gummei.plmn_mcc != NULL) free(mme_config_p->gummei.plmn_mcc); - - if (mme_config_p->gummei.plmn_mnc != NULL) free(mme_config_p->gummei.plmn_mnc); - - if (mme_config_p->gummei.plmn_mnc_len != NULL) free(mme_config_p->gummei.plmn_mnc_len); - - if (mme_config_p->gummei.plmn_tac != NULL) free(mme_config_p->gummei.plmn_tac); - - mme_config_p->gummei.plmn_mcc = calloc(num, sizeof(*mme_config_p->gummei.plmn_mcc)); - mme_config_p->gummei.plmn_mnc = calloc(num, sizeof(*mme_config_p->gummei.plmn_mnc)); - mme_config_p->gummei.plmn_mnc_len = calloc(num, sizeof(*mme_config_p->gummei.plmn_mnc_len)); - mme_config_p->gummei.plmn_tac = calloc(num, sizeof(*mme_config_p->gummei.plmn_tac)); - } - - mme_config_p->gummei.nb_plmns = num; - - for (i = 0; i < num; i++) { - sub2setting = config_setting_get_elem(subsetting, i); - - if (sub2setting != NULL) { - if( (config_setting_lookup_string( sub2setting, MME_CONFIG_STRING_MCC, &mcc) )) { - mme_config_p->gummei.plmn_mcc[i] = (uint16_t)atoi(mcc); - } - - if( (config_setting_lookup_string( sub2setting, MME_CONFIG_STRING_MNC, &mnc) )) { - mme_config_p->gummei.plmn_mnc[i] = (uint16_t)atoi(mnc); - mme_config_p->gummei.plmn_mnc_len[i] = strlen(mnc); - AssertFatal((mme_config_p->gummei.plmn_mnc_len[i] == 2) || (mme_config_p->gummei.plmn_mnc_len[i] == 3), - "Bad MNC length %u, must be 2 or 3", mme_config_p->gummei.plmn_mnc_len[i]); - } - - if( (config_setting_lookup_string( sub2setting, MME_CONFIG_STRING_TAC, &tac) )) { - mme_config_p->gummei.plmn_tac[i] = (uint16_t)atoi(tac); - AssertFatal(mme_config_p->gummei.plmn_tac[i] != 0, - "TAC must not be 0"); - } - } - } - } - } - - // NETWORK INTERFACE SETTING - setting = config_setting_get_member (setting_mme, MME_CONFIG_STRING_NETWORK_INTERFACES_CONFIG); - - if(setting != NULL) { - if( ( - config_setting_lookup_string( setting, MME_CONFIG_STRING_INTERFACE_NAME_FOR_S1_MME, - (const char **)&mme_interface_name_for_S1_MME) - && config_setting_lookup_string( setting, MME_CONFIG_STRING_IPV4_ADDRESS_FOR_S1_MME, - (const char **)&mme_ip_address_for_S1_MME) - && config_setting_lookup_string( setting, MME_CONFIG_STRING_INTERFACE_NAME_FOR_S11_MME, - (const char **)&mme_interface_name_for_S11) - && config_setting_lookup_string( setting, MME_CONFIG_STRING_IPV4_ADDRESS_FOR_S11_MME, - (const char **)&mme_ip_address_for_S11) - ) - ) { - mme_config_p->ipv4.mme_interface_name_for_S1_MME = strdup(mme_interface_name_for_S1_MME); - cidr = strdup(mme_ip_address_for_S1_MME); - address = strtok(cidr, "/"); - IPV4_STR_ADDR_TO_INT_NWBO ( address, mme_config_p->ipv4.mme_ip_address_for_S1_MME, "BAD IP ADDRESS FORMAT FOR MME S1_MME !\n" ) - free(cidr); - - mme_config_p->ipv4.mme_interface_name_for_S11 = strdup(mme_interface_name_for_S11); - cidr = strdup(mme_ip_address_for_S11); - address = strtok(cidr, "/"); - IPV4_STR_ADDR_TO_INT_NWBO ( address, mme_config_p->ipv4.mme_ip_address_for_S11, "BAD IP ADDRESS FORMAT FOR MME S11 !\n" ) - free(cidr); - - if (strncasecmp("tun",mme_config_p->ipv4.mme_interface_name_for_S1_MME, strlen("tun")) == 0) { - if (snprintf(system_cmd, 256, - "ip link set %s down ;openvpn --rmtun --dev %s", - mme_config_p->ipv4.mme_interface_name_for_S1_MME, - mme_config_p->ipv4.mme_interface_name_for_S1_MME - ) > 0) { - mme_system(system_cmd, 1); - } else { - fprintf(stderr, "Del %s\n", mme_config_p->ipv4.mme_interface_name_for_S1_MME); - } - - if (snprintf(system_cmd, 256, - "openvpn --mktun --dev %s;sync;ifconfig %s up;sync", - mme_config_p->ipv4.mme_interface_name_for_S1_MME, - mme_config_p->ipv4.mme_interface_name_for_S1_MME) > 0) { - mme_system(system_cmd, 1); - } else { - fprintf(stderr, "Create %s\n", mme_config_p->ipv4.mme_interface_name_for_S1_MME); - } - - if (snprintf(system_cmd, 256, - "ip -4 addr add %s dev %s", - mme_ip_address_for_S1_MME, - mme_config_p->ipv4.mme_interface_name_for_S1_MME) > 0) { - mme_system(system_cmd, 1); - } else { - fprintf(stderr, "Set IPv4 address on %s\n", mme_config_p->ipv4.mme_interface_name_for_S1_MME); - } - } - - } - } - - // NAS SETTING - setting = config_setting_get_member (setting_mme, MME_CONFIG_STRING_NAS_CONFIG); - - if (setting != NULL) { - subsetting = config_setting_get_member (setting, MME_CONFIG_STRING_NAS_SUPPORTED_INTEGRITY_ALGORITHM_LIST); - - if (subsetting != NULL) { - num = config_setting_length(subsetting); - - if (num <= 8) { - for (i = 0; i < num; i++) { - astring = config_setting_get_string_elem(subsetting, i); - - if (strcmp("EIA0", astring) == 0) mme_config_p->nas_config.prefered_integrity_algorithm[i] = NAS_CONFIG_SECURITY_ALGORITHMS_EIA0; - else if (strcmp("EIA1", astring) == 0) mme_config_p->nas_config.prefered_integrity_algorithm[i] = NAS_CONFIG_SECURITY_ALGORITHMS_EIA1; - else if (strcmp("EIA2", astring) == 0) mme_config_p->nas_config.prefered_integrity_algorithm[i] = NAS_CONFIG_SECURITY_ALGORITHMS_EIA2; - else if (strcmp("EIA3", astring) == 0) mme_config_p->nas_config.prefered_integrity_algorithm[i] = NAS_CONFIG_SECURITY_ALGORITHMS_EIA0; - else if (strcmp("EIA4", astring) == 0) mme_config_p->nas_config.prefered_integrity_algorithm[i] = NAS_CONFIG_SECURITY_ALGORITHMS_EIA0; - else if (strcmp("EIA5", astring) == 0) mme_config_p->nas_config.prefered_integrity_algorithm[i] = NAS_CONFIG_SECURITY_ALGORITHMS_EIA0; - else if (strcmp("EIA6", astring) == 0) mme_config_p->nas_config.prefered_integrity_algorithm[i] = NAS_CONFIG_SECURITY_ALGORITHMS_EIA0; - else if (strcmp("EIA7", astring) == 0) mme_config_p->nas_config.prefered_integrity_algorithm[i] = NAS_CONFIG_SECURITY_ALGORITHMS_EIA0; - } - - for (i = num; i < 8; i++) { - mme_config_p->nas_config.prefered_integrity_algorithm[i] = NAS_CONFIG_SECURITY_ALGORITHMS_EIA0; - } - } - } - - subsetting = config_setting_get_member (setting, MME_CONFIG_STRING_NAS_SUPPORTED_CIPHERING_ALGORITHM_LIST); - - if (subsetting != NULL) { - num = config_setting_length(subsetting); - - if (num <= 8) { - for (i = 0; i < num; i++) { - astring = config_setting_get_string_elem(subsetting, i); - - if (strcmp("EEA0", astring) == 0) mme_config_p->nas_config.prefered_ciphering_algorithm[i] = NAS_CONFIG_SECURITY_ALGORITHMS_EEA0; - else if (strcmp("EEA1", astring) == 0) mme_config_p->nas_config.prefered_ciphering_algorithm[i] = NAS_CONFIG_SECURITY_ALGORITHMS_EEA1; - else if (strcmp("EEA2", astring) == 0) mme_config_p->nas_config.prefered_ciphering_algorithm[i] = NAS_CONFIG_SECURITY_ALGORITHMS_EEA2; - else if (strcmp("EEA3", astring) == 0) mme_config_p->nas_config.prefered_ciphering_algorithm[i] = NAS_CONFIG_SECURITY_ALGORITHMS_EEA0; - else if (strcmp("EEA4", astring) == 0) mme_config_p->nas_config.prefered_ciphering_algorithm[i] = NAS_CONFIG_SECURITY_ALGORITHMS_EEA0; - else if (strcmp("EEA5", astring) == 0) mme_config_p->nas_config.prefered_ciphering_algorithm[i] = NAS_CONFIG_SECURITY_ALGORITHMS_EEA0; - else if (strcmp("EEA6", astring) == 0) mme_config_p->nas_config.prefered_ciphering_algorithm[i] = NAS_CONFIG_SECURITY_ALGORITHMS_EEA0; - else if (strcmp("EEA7", astring) == 0) mme_config_p->nas_config.prefered_ciphering_algorithm[i] = NAS_CONFIG_SECURITY_ALGORITHMS_EEA0; - } - - for (i = num; i < 8; i++) { - mme_config_p->nas_config.prefered_ciphering_algorithm[i] = NAS_CONFIG_SECURITY_ALGORITHMS_EEA0; - } - } - } - - } - } - - setting = config_lookup(&cfg, SGW_CONFIG_STRING_SGW_CONFIG); - - if(setting != NULL) { - subsetting = config_setting_get_member (setting, SGW_CONFIG_STRING_NETWORK_INTERFACES_CONFIG); - - if(subsetting != NULL) { - if( ( - config_setting_lookup_string( subsetting, SGW_CONFIG_STRING_SGW_IPV4_ADDRESS_FOR_S1U_S12_S4_UP, - (const char **)&sgw_ip_address_for_S1u_S12_S4_up) - && config_setting_lookup_string( subsetting, SGW_CONFIG_STRING_SGW_IPV4_ADDRESS_FOR_S11, - (const char **)&sgw_ip_address_for_S11) - && config_setting_lookup_int( subsetting, SGW_CONFIG_STRING_SGW_PORT_FOR_S1U_S12_S4_UP, &alongint) - ) - ) { - cidr = strdup(sgw_ip_address_for_S1u_S12_S4_up); - address = strtok(cidr, "/"); - IPV4_STR_ADDR_TO_INT_NWBO ( address, mme_config_p->ipv4.sgw_ip_address_for_S1u_S12_S4_up, "BAD IP ADDRESS FORMAT FOR SGW S1u_S12_S4 !\n" ) - free(cidr); - - cidr = strdup(sgw_ip_address_for_S11); - address = strtok(cidr, "/"); - IPV4_STR_ADDR_TO_INT_NWBO ( address, mme_config_p->ipv4.sgw_ip_address_for_S11, "BAD IP ADDRESS FORMAT FOR SGW S11 !\n" ) - free(cidr); - - mme_config_p->gtpv1u_config.port_number = (uint16_t) alongint; - } - } - } - - return 0; -} - -#define DISPLAY_ARRAY(size, format, args...) \ -do { \ - int i; \ - for (i = 0; i < size; i++) { \ - fprintf(stdout, format, args); \ - if ((i != (size - 1)) && ((i + 1) % 10 == 0)) \ - { \ - fprintf(stdout, "\n "); \ - } \ - } \ - if (i > 0) \ - fprintf(stdout, "\n"); \ -} while(0) - -static void config_display(mme_config_t *mme_config_p) -{ - int j; - - fprintf(stdout, "==== EURECOM %s v%s ====\n", PACKAGE_NAME, PACKAGE_VERSION); - fprintf(stdout, "Configuration:\n"); - fprintf(stdout, "- File ...............: %s\n", mme_config_p->config_file); - fprintf(stdout, "- Verbosity level ....: %d\n", mme_config_p->verbosity_level); - fprintf(stdout, "- Realm ..............: %s\n", mme_config_p->realm); - fprintf(stdout, "- Max eNBs ...........: %u\n", mme_config_p->max_eNBs); - fprintf(stdout, "- Max UEs ............: %u\n", mme_config_p->max_ues); - fprintf(stdout, "- Emergency support ..: %s\n", mme_config_p->emergency_attach_supported == 0 ? "FALSE" : "TRUE"); - fprintf(stdout, "- Unauth IMSI support : %s\n", mme_config_p->unauthenticated_imsi_supported == 0 ? "FALSE" : "TRUE"); - fprintf(stdout, "- Relative capa ......: %u\n\n", mme_config_p->relative_capacity); - fprintf(stdout, "- Statistics timer ...: %u (seconds)\n\n", mme_config_p->mme_statistic_timer); - fprintf(stdout, "- S1-U:\n"); - fprintf(stdout, " port number ......: %d\n", mme_config_p->gtpv1u_config.port_number); - fprintf(stdout, "- S1-MME:\n"); - fprintf(stdout, " port number ......: %d\n", mme_config_p->s1ap_config.port_number); - fprintf(stdout, "- IP:\n"); - //fprintf(stdout, " s1-u iface .......: %s\n", mme_config_p->ipv4.sgw_interface_name_for_S1u_S12_S4_up); - fprintf(stdout, " s1-u ip ..........: %s\n", - inet_ntoa(*((struct in_addr *)&mme_config_p->ipv4.sgw_ip_address_for_S1u_S12_S4_up))); - //fprintf(stdout, " sgi iface ........: %s\n", mme_config_p->ipv4.pgw_interface_name_for_SGI); - //fprintf(stdout, " sgi ip ...........: %s/%d\n", - // inet_ntoa(*((struct in_addr *)&mme_config_p->ipv4.pgw_ip_addr_for_SGI)), - // mme_config_p->ipv4.pgw_ip_netmask_for_SGI); - fprintf(stdout, " s1-MME iface .....: %s\n", mme_config_p->ipv4.mme_interface_name_for_S1_MME); - fprintf(stdout, " s1-MME ip ........: %s\n", - inet_ntoa(*((struct in_addr *)&mme_config_p->ipv4.mme_ip_address_for_S1_MME))); - //fprintf(stdout, " s11 S-GW iface ...: %s\n", mme_config_p->ipv4.sgw_interface_name_for_S11); - //fprintf(stdout, " s11 S-GW ip ......: %s/%d\n", - // inet_ntoa(*((struct in_addr *)&mme_config_p->ipv4.sgw_ip_address_for_S11)), - // mme_config_p->ipv4.sgw_ip_netmask_for_S11); - fprintf(stdout, " s11 MME iface ....: %s\n", mme_config_p->ipv4.mme_interface_name_for_S11); - fprintf(stdout, " s11 S-GW ip ......: %s\n", - inet_ntoa(*((struct in_addr *)&mme_config_p->ipv4.mme_ip_address_for_S11))); - fprintf(stdout, "- ITTI:\n"); - fprintf(stdout, " queue size .......: %u (bytes)\n", mme_config_p->itti_config.queue_size); - fprintf(stdout, " log file .........: %s\n", mme_config_p->itti_config.log_file); - fprintf(stdout, "- SCTP:\n"); - fprintf(stdout, " in streams .......: %u\n", mme_config_p->sctp_config.in_streams); - fprintf(stdout, " out streams ......: %u\n", mme_config_p->sctp_config.out_streams); - fprintf(stdout, "- GUMMEI:\n"); - fprintf(stdout, " mme group ids ....:\n "); - DISPLAY_ARRAY(mme_config_p->gummei.nb_mme_gid, "| %u ", mme_config_p->gummei.mme_gid[i]); - fprintf(stdout, " mme codes ........:\n "); - DISPLAY_ARRAY(mme_config_p->gummei.nb_mmec, "| %u ", mme_config_p->gummei.mmec[i]); - fprintf(stdout, " plmns ............: (mcc.mnc:tac)\n"); - - for (j= 0; j < mme_config_p->gummei.nb_plmns; j++) { - if (mme_config_p->gummei.plmn_mnc_len[j] ==2 ) { - fprintf(stdout, " %3u.%3u:%u\n", - mme_config_p->gummei.plmn_mcc[j], - mme_config_p->gummei.plmn_mnc[j], - mme_config_p->gummei.plmn_tac[j]); - } else { - fprintf(stdout, " %3u.%03u:%u\n", - mme_config_p->gummei.plmn_mcc[j], - mme_config_p->gummei.plmn_mnc[j], - mme_config_p->gummei.plmn_tac[j]); - } - } - - fprintf(stdout, "- S6A:\n"); - fprintf(stdout, " conf file ........: %s\n", mme_config_p->s6a_config.conf_file); -} - -static void usage(void) -{ - fprintf(stdout, "==== EURECOM %s v%s ====\n", PACKAGE_NAME, PACKAGE_VERSION); - fprintf(stdout, "Please report any bug to: %s\n\n", PACKAGE_BUGREPORT); - fprintf(stdout, "Usage: oaisim_mme [options]\n\n"); - fprintf(stdout, "Available options:\n"); - fprintf(stdout, "-h Print this help and return\n"); - fprintf(stdout, "-c\n"); - fprintf(stdout, " Set the configuration file for mme\n"); - fprintf(stdout, " See template in UTILS/CONF\n"); - fprintf(stdout, "-K\n"); - fprintf(stdout, " Output intertask messages to provided file\n"); - fprintf(stdout, "-V Print %s version and return\n", PACKAGE_NAME); - fprintf(stdout, "-v[1-2] Debug level:\n"); - fprintf(stdout, " 1 -> ASN1 XER printf on and ASN1 debug off\n"); - fprintf(stdout, " 2 -> ASN1 XER printf on and ASN1 debug on\n"); -} - -extern void -nwGtpv1uDisplayBanner(void); - -int config_parse_opt_line(int argc, char *argv[], mme_config_t *mme_config_p) -{ - int c; - mme_config_init(mme_config_p); - - /* Parsing command line */ - while ((c = getopt (argc, argv, "O:c:hi:K:v:V")) != -1) { - switch (c) { - case 'O': - case 'c': { - /* Store the given configuration file. If no file is given, - * then the default values will be used. - */ - int config_file_len = 0; - config_file_len = strlen(optarg); - mme_config_p->config_file = malloc(sizeof(char) * (config_file_len + 1)); - memcpy(mme_config_p->config_file, optarg, config_file_len); - mme_config_p->config_file[config_file_len] = '\0'; - } - break; - - case 'v': { - mme_config_p->verbosity_level = atoi(optarg); - } - break; - - case 'V': { - fprintf(stdout, "==== EURECOM %s v%s ====\n" - "Please report any bug to: %s\n", PACKAGE_NAME, PACKAGE_VERSION, - PACKAGE_BUGREPORT); - exit(0); - nwGtpv1uDisplayBanner(); - } - break; - - case 'K': - mme_config_p->itti_config.log_file = strdup(optarg); - break; - - case 'h': /* Fall through */ - default: - usage(); - exit(0); - } - } - - /* Parse the configuration file using libconfig */ - if (config_parse_file(mme_config_p) != 0) { - return -1; - } - - /* Display the configuration */ - config_display(mme_config_p); - return 0; -} From 1e0d81613102f7df2e84d405372933235872cdcb Mon Sep 17 00:00:00 2001 From: Raphael Defosseux Date: Fri, 4 Jan 2019 10:42:31 +0100 Subject: [PATCH 208/233] CI: little fix when assessing build status Signed-off-by: Raphael Defosseux --- ci-scripts/waitBuildOnVM.sh | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/ci-scripts/waitBuildOnVM.sh b/ci-scripts/waitBuildOnVM.sh index 21a2f7a9e1..2820b88647 100755 --- a/ci-scripts/waitBuildOnVM.sh +++ b/ci-scripts/waitBuildOnVM.sh @@ -136,7 +136,12 @@ function check_on_vm_build { echo "Checking build status" echo "############################################################" - LOG_FILES=`ls $ARCHIVES_LOC/*.txt $ARCHIVES_LOC/*.xml` + if [[ "$VM_NAME" == *"-cppcheck"* ]] + then + LOG_FILES=`ls $ARCHIVES_LOC/*.txt $ARCHIVES_LOC/*.xml` + else + LOG_FILES=`ls $ARCHIVES_LOC/*.txt` + fi STATUS=0 NB_FOUND_FILES=0 From 824f98b1252db7b51d9a6e0a0427a83a02351da1 Mon Sep 17 00:00:00 2001 From: laurent Date: Fri, 4 Jan 2019 14:25:01 +0100 Subject: [PATCH 209/233] add dirty -I in Makefile --- common/utils/T/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/utils/T/Makefile b/common/utils/T/Makefile index 87a6e34c5d..0588c88a45 100644 --- a/common/utils/T/Makefile +++ b/common/utils/T/Makefile @@ -19,7 +19,7 @@ T_IDs.h: $(GENIDS) T_messages.txt ./$(GENIDS) T_messages.txt T_IDs.h check_vcd: - gcc -Wall -I. -I.. -I../itti -Itracer -o _check_vcd check_vcd.c tracer/database.c tracer/utils.c -lm -pthread + gcc -Wall -I. -I.. -I../itti -I../../../openair2/COMMON -Itracer -o _check_vcd check_vcd.c tracer/database.c tracer/utils.c -lm -pthread ./_check_vcd || (rm -f ./_check_vcd ./T_IDs.h ./T_messages.txt.h && false) rm -f ./_check_vcd From 718f754c07f6981cffc6ddb4934b1cb738889da8 Mon Sep 17 00:00:00 2001 From: frtabu Date: Mon, 7 Jan 2019 19:36:24 +0100 Subject: [PATCH 210/233] modify tcp_bridge_oai.c to support remote connections, old behavior is maintained, define TCPBRIDGE environment variable to the enb ip address on ue side. --- targets/ARCH/tcp_bridge/tcp_bridge_oai.c | 389 +++++++++++++---------- 1 file changed, 225 insertions(+), 164 deletions(-) diff --git a/targets/ARCH/tcp_bridge/tcp_bridge_oai.c b/targets/ARCH/tcp_bridge/tcp_bridge_oai.c index 32fddb9c2d..b06d327da2 100644 --- a/targets/ARCH/tcp_bridge/tcp_bridge_oai.c +++ b/targets/ARCH/tcp_bridge/tcp_bridge_oai.c @@ -8,33 +8,47 @@ #include #include -int fullread(int fd, void *_buf, int count) -{ +const int port = 4043; +#define helpTxt "\ +\x1b[31m\ +tcp_bridge: error: you have to run one UE and one eNB\n\ +For this, export TCPBRIDGE=enb (eNB case) or \n\ + TCPBRIDGE= (UE case)\n\ +\x1b[m" + +int fullread(int fd, void *_buf, int count) { char *buf = _buf; int ret = 0; int l; + while (count) { l = read(fd, buf, count); + if (l <= 0) return -1; + count -= l; buf += l; ret += l; } + return ret; } -int fullwrite(int fd, void *_buf, int count) -{ +int fullwrite(int fd, void *_buf, int count) { char *buf = _buf; int ret = 0; int l; + while (count) { l = write(fd, buf, count); + if (l <= 0) return -1; + count -= l; buf += l; ret += l; } + return ret; } @@ -44,157 +58,188 @@ typedef struct { int sock; int samples_per_subframe; uint64_t timestamp; - uint64_t next_tx_timestamp; int is_enb; + char *ip; } tcp_bridge_state_t; -void verify_connection(int fd, int is_enb) -{ +void verify_connection(int fd, int is_enb) { char c = is_enb; + if (fullwrite(fd, &c, 1) != 1) exit(1); + if (fullread(fd, &c, 1) != 1) exit(1); + if (c == is_enb) { - printf("\x1b[31mtcp_bridge: error: you have to run one UE and one eNB" - " (did you run 'export ENODEB=1' in the eNB terminal?)\x1b[m\n"); + printf(helpTxt); exit(1); } } -int tcp_bridge_start(openair0_device *device) -{ - int port = 4043; - tcp_bridge_state_t *tcp_bridge = device->priv; - int try; - int max_try = 5; - - int sock = socket(AF_INET, SOCK_STREAM, 0); - if (sock == -1) { perror("tcp_bridge: socket"); exit(1); } - - int enable = 1; - if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &enable, sizeof(int))) - { perror("tcp_bridge: SO_REUSEADDR"); exit(1); } +int start_enb(tcp_bridge_state_t *tcp_bridge) { struct sockaddr_in addr = { - sin_family: AF_INET, - sin_port: htons(port), - sin_addr: { s_addr: INADDR_ANY } +sin_family: + AF_INET, +sin_port: + htons(port), +sin_addr: + { s_addr: INADDR_ANY } }; - if (bind(sock, (struct sockaddr *)&addr, sizeof(addr))) { - if (errno == EADDRINUSE) goto client_mode; - { perror("tcp_bridge: bind"); exit(1); } + if (bind(tcp_bridge->sock, (struct sockaddr *)&addr, sizeof(addr))) { + perror("tcp_bridge: bind"); + exit(1); } - if (listen(sock, 5)) - { perror("tcp_bridge: listen"); exit(1); } + if (listen(tcp_bridge->sock, 5)) { + perror("tcp_bridge: listen"); + exit(1); + } printf("tcp_bridge: wait for connection on port %d\n", port); - socklen_t len = sizeof(addr); - int sock2 = accept(sock, (struct sockaddr *)&addr, &len); - if (sock2 == -1) - { perror("tcp_bridge: accept"); exit(1); } + int sockServ = accept(tcp_bridge->sock, (struct sockaddr *)&addr, &len); - close(sock); - - tcp_bridge->sock = sock2; + if ( sockServ == -1) { + perror("tcp_bridge: accept"); + exit(1); + } + verify_connection(sockServ, tcp_bridge->is_enb); printf("tcp_bridge: connection established\n"); - - verify_connection(sock2, tcp_bridge->is_enb); - + close(tcp_bridge->sock); + tcp_bridge->sock=sockServ; return 0; +} -client_mode: - addr.sin_addr.s_addr = inet_addr("127.0.0.1"); +int start_ue(tcp_bridge_state_t *tcp_bridge) { +struct sockaddr_in addr = {sin_family: + AF_INET, +sin_port: + htons(port), +sin_addr: + { s_addr: INADDR_ANY } + }; + addr.sin_addr.s_addr = inet_addr(tcp_bridge->ip); - for (try = 0; try < max_try; try++) { - if (try != 0) sleep(1); + while(1) { + printf("tcp_bridge: trying to connect to %s:%d\n", tcp_bridge->ip, port); - printf("tcp_bridge: trying to connect to 127.0.0.1:%d (attempt %d/%d)\n", - port, try+1, max_try); - - if (connect(sock, (struct sockaddr *)&addr, sizeof(addr)) == 0) { + if (connect(tcp_bridge->sock, (struct sockaddr *)&addr, sizeof(addr)) == 0) { + verify_connection(tcp_bridge->sock, tcp_bridge->is_enb); printf("tcp_bridge: connection established\n"); - tcp_bridge->sock = sock; - verify_connection(sock, tcp_bridge->is_enb); return 0; } perror("tcp_bridge"); + sleep(1); } - printf("tcp_bridge: connection failed\n"); - - exit(1); + return 0; } -int tcp_bridge_request(openair0_device *device, void *msg, ssize_t msg_len) { abort(); return 0; } -int tcp_bridge_reply(openair0_device *device, void *msg, ssize_t msg_len) { abort(); return 0; } -int tcp_bridge_get_stats(openair0_device* device) { return 0; } -int tcp_bridge_reset_stats(openair0_device* device) { return 0; } -void tcp_bridge_end(openair0_device *device) {} -int tcp_bridge_stop(openair0_device *device) { return 0; } -int tcp_bridge_set_freq(openair0_device* device, openair0_config_t *openair0_cfg,int exmimo_dump_config) { return 0; } -int tcp_bridge_set_gains(openair0_device* device, openair0_config_t *openair0_cfg) { return 0; } +int tcp_bridge_start(openair0_device *device) { + tcp_bridge_state_t *tcp_bridge = device->priv; + tcp_bridge->sock = socket(AF_INET, SOCK_STREAM, 0); -int tcp_bridge_write(openair0_device *device, openair0_timestamp timestamp, void **buff, int nsamps, int cc, int flags) -{ - if (cc != 1) { printf("tcp_bridge: only 1 antenna supported\n"); exit(1); } - tcp_bridge_state_t *t = device->priv; - /* deal with discontinuities in output (think: eNB in TDD mode) */ - if (t->next_tx_timestamp && timestamp != t->next_tx_timestamp) { - uint32_t b[4096]; - uint64_t to_send = timestamp - t->next_tx_timestamp; - memset(b, 0, 4096 * sizeof(uint32_t)); - while (to_send) { - int len = to_send > 4096 ? 4096 : to_send; - int n = fullwrite(t->sock, b, len * 4); - if (n != len * 4) { - printf("tcp_bridge: write error ret %d error %s\n", n, strerror(errno)); - abort(); - } - to_send -= len; - } + if (tcp_bridge->sock == -1) { + perror("tcp_bridge: socket"); + exit(1); } + + int enable = 1; + + if (setsockopt(tcp_bridge->sock, SOL_SOCKET, SO_REUSEADDR, &enable, sizeof(int))) { + perror("tcp_bridge: SO_REUSEADDR"); + exit(1); + } + + if ( tcp_bridge->is_enb ) + return start_enb(tcp_bridge); + else + return start_ue(tcp_bridge); +} + +int tcp_bridge_request(openair0_device *device, void *msg, ssize_t msg_len) { + abort(); + return 0; +} +int tcp_bridge_reply(openair0_device *device, void *msg, ssize_t msg_len) { + abort(); + return 0; +} +int tcp_bridge_get_stats(openair0_device *device) { + return 0; +} +int tcp_bridge_reset_stats(openair0_device *device) { + return 0; +} +void tcp_bridge_end(openair0_device *device) {} +int tcp_bridge_stop(openair0_device *device) { + return 0; +} +int tcp_bridge_set_freq(openair0_device *device, openair0_config_t *openair0_cfg,int exmimo_dump_config) { + return 0; +} +int tcp_bridge_set_gains(openair0_device *device, openair0_config_t *openair0_cfg) { + return 0; +} + +int tcp_bridge_write(openair0_device *device, openair0_timestamp timestamp, void **buff, int nsamps, int cc, int flags) { + if (cc != 1) { + printf("tcp_bridge: only 1 antenna supported\n"); + exit(1); + } + + tcp_bridge_state_t *t = device->priv; int n = fullwrite(t->sock, buff[0], nsamps * 4); + if (n != nsamps * 4) { printf("tcp_bridge: write error ret %d (wanted %d) error %s\n", n, nsamps*4, strerror(errno)); abort(); } - t->next_tx_timestamp = timestamp + nsamps; + return nsamps; } -int tcp_bridge_read(openair0_device *device, openair0_timestamp *timestamp, void **buff, int nsamps, int cc) -{ - if (cc != 1) { printf("tcp_bridge: only 1 antenna supported\n"); exit(1); } +int tcp_bridge_read(openair0_device *device, openair0_timestamp *timestamp, void **buff, int nsamps, int cc) { + if (cc != 1) { + printf("tcp_bridge: only 1 antenna supported\n"); + exit(1); + } + tcp_bridge_state_t *t = device->priv; int n = fullread(t->sock, buff[0], nsamps * 4); + if (n != nsamps * 4) { printf("tcp_bridge: read error ret %d nsamps*4 %d error %s\n", n, nsamps * 4, strerror(errno)); abort(); } + *timestamp = t->timestamp; t->timestamp += nsamps; return nsamps; } -int tcp_bridge_read_ue(openair0_device *device, openair0_timestamp *timestamp, void **buff, int nsamps, int cc) -{ - if (cc != 1) { printf("tcp_bridge: only 1 antenna supported\n"); exit(1); } +int tcp_bridge_read_ue(openair0_device *device, openair0_timestamp *timestamp, void **buff, int nsamps, int cc) { + if (cc != 1) { + printf("tcp_bridge: only 1 antenna supported\n"); + exit(1); + } + tcp_bridge_state_t *t = device->priv; int n; /* In synch mode, UE does not write, but we need to - * send something to the eNodeB. - * We know that UE is in synch mode when it reads - * 10 subframes at a time. - */ + send something to the eNodeB. + We know that UE is in synch mode when it reads + 10 subframes at a time. + */ if (nsamps == t->samples_per_subframe * 10) { uint32_t b[nsamps]; memset(b, 0, nsamps * 4); n = fullwrite(t->sock, b, nsamps * 4); + if (n != nsamps * 4) { printf("tcp_bridge: write error ret %d error %s\n", n, strerror(errno)); abort(); @@ -205,96 +250,106 @@ int tcp_bridge_read_ue(openair0_device *device, openair0_timestamp *timestamp, v } /* To startup proper communcation between eNB and UE, - * we need to understand that: - * - eNodeB starts reading subframe 0 - * - then eNodeB starts sending subframe 4 - * and then repeats read/write for each subframe. - * The UE: - * - reads 10 subframes at a time until it is synchronized - * - then reads subframe n and writes subframe n+2 - * We also want to enforce that the subframe 0 is read - * at the beginning of the UE RX buffer, not in the middle - * of it. - * So it means: - * - for the eNodeB: let it run as in normal mode (as with a B210) - * - for the UE, on its very first read: - * - we want this read to get data from subframe 0 - * but the first write of eNodeB is subframe 4 - * so we first need to read and ignore 6 subframes - * - the UE will start its TX only at the subframe 2 - * corresponding to the subframe 0 it just read, - * so we need to write 12 subframes before anything - * (the function tcp_bridge_read_ue takes care to - * insert dummy TX data during the synch phase) - * - * Here is a drawing of the beginning of things to make - * this logic clearer. - * - * We see that eNB starts RX at subframe 0, starts TX at subfram 4, - * and that UE starts RX at subframe 10 and TX at subframe 12. - * - * We understand that the UE has to transmit 12 empty - * subframes for the eNodeB to start its processing. - * - * And because the eNodeB starts its TX at subframe 4 and we - * want the UE to start its RX at subframe 10, we need to - * read and ignore 6 subframes in the UE. - * - * ------------------------------------------------------------------------- - * eNB RX: | *0* | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 ... - * ------------------------------------------------------------------------- - * - * ------------------------------------------------------------------------- - * eNB TX: | 0 | 1 | 2 | 3 | *4* | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 ... - * ------------------------------------------------------------------------- - * - * ------------------------------------------------------------------------- - * UE RX: | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | *10* | 11 | 12 | 13 | 14 ... - * ------------------------------------------------------------------------- - * - * ------------------------------------------------------------------------- - * UE TX: | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | *12* | 13 | 14 ... - * ------------------------------------------------------------------------- - * - * As a final note, we do TX before RX to ensure that the eNB will - * get some data and send us something so there is no deadlock - * at the beginning of things. Hopefully the kernel buffers for - * the sockets are big enough so that the first (big) TX can - * return to user mode before the buffers are full. If this - * is wrong in some environment, we will need to work by smaller - * units of data at a time. - */ -int tcp_bridge_ue_first_read(openair0_device *device, openair0_timestamp *timestamp, void **buff, int nsamps, int cc) -{ - if (cc != 1) { printf("tcp_bridge: only 1 antenna supported\n"); exit(1); } - tcp_bridge_state_t *t = device->priv; + we need to understand that: + - eNodeB starts reading subframe 0 + - then eNodeB starts sending subframe 4 + and then repeats read/write for each subframe. + The UE: + - reads 10 subframes at a time until it is synchronized + - then reads subframe n and writes subframe n+2 + We also want to enforce that the subframe 0 is read + at the beginning of the UE RX buffer, not in the middle + of it. + So it means: + - for the eNodeB: let it run as in normal mode (as with a B210) + - for the UE, on its very first read: + - we want this read to get data from subframe 0 + but the first write of eNodeB is subframe 4 + so we first need to read and ignore 6 subframes + - the UE will start its TX only at the subframe 2 + corresponding to the subframe 0 it just read, + so we need to write 12 subframes before anything + (the function tcp_bridge_read_ue takes care to + insert dummy TX data during the synch phase) + Here is a drawing of the beginning of things to make + this logic clearer. + + We see that eNB starts RX at subframe 0, starts TX at subfram 4, + and that UE starts RX at subframe 10 and TX at subframe 12. + + We understand that the UE has to transmit 12 empty + subframes for the eNodeB to start its processing. + + And because the eNodeB starts its TX at subframe 4 and we + want the UE to start its RX at subframe 10, we need to + read and ignore 6 subframes in the UE. + + ------------------------------------------------------------------------- + eNB RX: | *0* | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 ... + ------------------------------------------------------------------------- + + ------------------------------------------------------------------------- + eNB TX: | 0 | 1 | 2 | 3 | *4* | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 ... + ------------------------------------------------------------------------- + + ------------------------------------------------------------------------- + UE RX: | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | *10* | 11 | 12 | 13 | 14 ... + ------------------------------------------------------------------------- + + ------------------------------------------------------------------------- + UE TX: | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | *12* | 13 | 14 ... + ------------------------------------------------------------------------- + + As a final note, we do TX before RX to ensure that the eNB will + get some data and send us something so there is no deadlock + at the beginning of things. Hopefully the kernel buffers for + the sockets are big enough so that the first (big) TX can + return to user mode before the buffers are full. If this + is wrong in some environment, we will need to work by smaller + units of data at a time. +*/ +int tcp_bridge_ue_first_read(openair0_device *device, openair0_timestamp *timestamp, void **buff, int nsamps, int cc) { + if (cc != 1) { + printf("tcp_bridge: only 1 antenna supported\n"); + exit(1); + } + + tcp_bridge_state_t *t = device->priv; uint32_t b[t->samples_per_subframe * 12]; memset(b, 0, t->samples_per_subframe * 12 * 4); int n = fullwrite(t->sock, b, t->samples_per_subframe * 12 * 4); + if (n != t->samples_per_subframe * 12 * 4) { printf("tcp_bridge: write error ret %d error %s\n", n, strerror(errno)); abort(); } + n = fullread(t->sock, b, t->samples_per_subframe * 6 * 4); + if (n != t->samples_per_subframe * 6 * 4) { printf("tcp_bridge: read error ret %d error %s\n", n, strerror(errno)); abort(); } device->trx_read_func = tcp_bridge_read_ue; - return tcp_bridge_read_ue(device, timestamp, buff, nsamps, cc); } __attribute__((__visibility__("default"))) -int device_init(openair0_device* device, openair0_config_t *openair0_cfg) -{ - tcp_bridge_state_t *tcp_bridge = (tcp_bridge_state_t*)malloc(sizeof(tcp_bridge_state_t)); - memset(tcp_bridge, 0, sizeof(tcp_bridge_state_t)); +int device_init(openair0_device *device, openair0_config_t *openair0_cfg) { + tcp_bridge_state_t *tcp_bridge = (tcp_bridge_state_t *)calloc(sizeof(tcp_bridge_state_t),1); - tcp_bridge->is_enb = getenv("ENODEB") != NULL; + if ((tcp_bridge->ip=getenv("TCPBRIDGE")) == NULL ) { + /* for compatibility, we test the ENB environment variable */ + if ((tcp_bridge->ip=getenv("ENODEB")) != NULL ) { + tcp_bridge->ip=strdup("enb"); + } else { + tcp_bridge->ip=strdup("127.0.0.1"); + } + } + tcp_bridge->is_enb = strncasecmp(tcp_bridge->ip,"enb",3) == 0; printf("tcp_bridge: running as %s\n", tcp_bridge->is_enb ? "eNB" : "UE"); /* only 25, 50 or 100 PRBs handled for the moment */ @@ -323,15 +378,21 @@ int device_init(openair0_device* device, openair0_config_t *openair0_cfg) device->priv = tcp_bridge; switch ((int)openair0_cfg[0].sample_rate) { - case 30720000: tcp_bridge->samples_per_subframe = 30720; break; - case 15360000: tcp_bridge->samples_per_subframe = 15360; break; - case 7680000: tcp_bridge->samples_per_subframe = 7680; break; + case 30720000: + tcp_bridge->samples_per_subframe = 30720; + break; + + case 15360000: + tcp_bridge->samples_per_subframe = 15360; + break; + + case 7680000: + tcp_bridge->samples_per_subframe = 7680; + break; } /* let's pretend to be a b2x0 */ device->type = USRP_B200_DEV; - device->openair0_cfg=&openair0_cfg[0]; - return 0; } From a975014beba20400d06418004e7c605669d0c07c Mon Sep 17 00:00:00 2001 From: Raphael Defosseux Date: Tue, 8 Jan 2019 15:54:28 +0100 Subject: [PATCH 211/233] CI: disabling basic-sim test at TDD-20MHz in order to stop getting false negatives Signed-off-by: Raphael Defosseux --- ci-scripts/runTestOnVM.sh | 99 ++++++++++++++++++++------------------- 1 file changed, 50 insertions(+), 49 deletions(-) diff --git a/ci-scripts/runTestOnVM.sh b/ci-scripts/runTestOnVM.sh index 3878d2e36f..bed46f0ace 100755 --- a/ci-scripts/runTestOnVM.sh +++ b/ci-scripts/runTestOnVM.sh @@ -961,55 +961,56 @@ function run_test_on_vm { recover_core_dump $VM_CMDS $VM_IP_ADDR $ARCHIVES_LOC/$CURRENT_ENB_LOG_FILE $ARCHIVES_LOC sleep 10 - echo "############################################################" - echo "Starting the eNB in TDD-20MHz mode" - echo "############################################################" - CURRENT_ENB_LOG_FILE=tdd_20MHz_enb.log - start_basic_sim_enb $VM_CMDS $VM_IP_ADDR $EPC_VM_IP_ADDR $CURRENT_ENB_LOG_FILE 100 lte-tdd-basic-sim.conf none - - echo "############################################################" - echo "Starting the UE in TDD-20MHz mode" - echo "############################################################" - CURRENT_UE_LOG_FILE=tdd_20MHz_ue.log - start_basic_sim_ue $VM_CMDS $VM_IP_ADDR $CURRENT_UE_LOG_FILE 100 2350 - if [ $UE_SYNC -eq 0 ] - then - echo "Problem w/ eNB and UE not syncing" - terminate_enb_ue_basic_sim $VM_CMDS $VM_IP_ADDR - scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_ENB_LOG_FILE $ARCHIVES_LOC - scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_UE_LOG_FILE $ARCHIVES_LOC - recover_core_dump $VM_CMDS $VM_IP_ADDR $ARCHIVES_LOC/$CURRENT_ENB_LOG_FILE $ARCHIVES_LOC - terminate_ltebox_epc $EPC_VM_CMDS $EPC_VM_IP_ADDR - echo "TEST_KO" > $ARCHIVES_LOC/test_final_status.log - exit -1 - fi - get_ue_ip_addr $VM_CMDS $VM_IP_ADDR - - echo "############################################################" - echo "Pinging the UE" - echo "############################################################" - PING_LOG_FILE=tdd_20MHz_ping_ue.txt - ping_ue_ip_addr $EPC_VM_CMDS $EPC_VM_IP_ADDR $UE_IP_ADDR $PING_LOG_FILE - scp -o StrictHostKeyChecking=no ubuntu@$EPC_VM_IP_ADDR:/home/ubuntu/$PING_LOG_FILE $ARCHIVES_LOC - check_ping_result $ARCHIVES_LOC/$PING_LOG_FILE 20 - - echo "############################################################" - echo "Iperf DL" - echo "############################################################" - CURR_IPERF_LOG_BASE=tdd_20MHz_iperf_dl - iperf_dl $VM_CMDS $VM_IP_ADDR $EPC_VM_CMDS $EPC_VM_IP_ADDR 6 $CURR_IPERF_LOG_BASE - scp -o StrictHostKeyChecking=no ubuntu@$EPC_VM_IP_ADDR:/home/ubuntu/${CURR_IPERF_LOG_BASE}_client.txt $ARCHIVES_LOC - scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/${CURR_IPERF_LOG_BASE}_server.txt $ARCHIVES_LOC - check_iperf $ARCHIVES_LOC/$CURR_IPERF_LOG_BASE 6 - - echo "############################################################" - echo "Terminate enb/ue simulators" - echo "############################################################" - terminate_enb_ue_basic_sim $VM_CMDS $VM_IP_ADDR - scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_ENB_LOG_FILE $ARCHIVES_LOC - scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_UE_LOG_FILE $ARCHIVES_LOC - recover_core_dump $VM_CMDS $VM_IP_ADDR $ARCHIVES_LOC/$CURRENT_ENB_LOG_FILE $ARCHIVES_LOC - sleep 10 +# Disabling TDD-20MHz in order to stop getting false negatives +# echo "############################################################" +# echo "Starting the eNB in TDD-20MHz mode" +# echo "############################################################" +# CURRENT_ENB_LOG_FILE=tdd_20MHz_enb.log +# start_basic_sim_enb $VM_CMDS $VM_IP_ADDR $EPC_VM_IP_ADDR $CURRENT_ENB_LOG_FILE 100 lte-tdd-basic-sim.conf none +# +# echo "############################################################" +# echo "Starting the UE in TDD-20MHz mode" +# echo "############################################################" +# CURRENT_UE_LOG_FILE=tdd_20MHz_ue.log +# start_basic_sim_ue $VM_CMDS $VM_IP_ADDR $CURRENT_UE_LOG_FILE 100 2350 +# if [ $UE_SYNC -eq 0 ] +# then +# echo "Problem w/ eNB and UE not syncing" +# terminate_enb_ue_basic_sim $VM_CMDS $VM_IP_ADDR +# scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_ENB_LOG_FILE $ARCHIVES_LOC +# scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_UE_LOG_FILE $ARCHIVES_LOC +# recover_core_dump $VM_CMDS $VM_IP_ADDR $ARCHIVES_LOC/$CURRENT_ENB_LOG_FILE $ARCHIVES_LOC +# terminate_ltebox_epc $EPC_VM_CMDS $EPC_VM_IP_ADDR +# echo "TEST_KO" > $ARCHIVES_LOC/test_final_status.log +# exit -1 +# fi +# get_ue_ip_addr $VM_CMDS $VM_IP_ADDR +# +# echo "############################################################" +# echo "Pinging the UE" +# echo "############################################################" +# PING_LOG_FILE=tdd_20MHz_ping_ue.txt +# ping_ue_ip_addr $EPC_VM_CMDS $EPC_VM_IP_ADDR $UE_IP_ADDR $PING_LOG_FILE +# scp -o StrictHostKeyChecking=no ubuntu@$EPC_VM_IP_ADDR:/home/ubuntu/$PING_LOG_FILE $ARCHIVES_LOC +# check_ping_result $ARCHIVES_LOC/$PING_LOG_FILE 20 +# +# echo "############################################################" +# echo "Iperf DL" +# echo "############################################################" +# CURR_IPERF_LOG_BASE=tdd_20MHz_iperf_dl +# iperf_dl $VM_CMDS $VM_IP_ADDR $EPC_VM_CMDS $EPC_VM_IP_ADDR 6 $CURR_IPERF_LOG_BASE +# scp -o StrictHostKeyChecking=no ubuntu@$EPC_VM_IP_ADDR:/home/ubuntu/${CURR_IPERF_LOG_BASE}_client.txt $ARCHIVES_LOC +# scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/${CURR_IPERF_LOG_BASE}_server.txt $ARCHIVES_LOC +# check_iperf $ARCHIVES_LOC/$CURR_IPERF_LOG_BASE 6 +# +# echo "############################################################" +# echo "Terminate enb/ue simulators" +# echo "############################################################" +# terminate_enb_ue_basic_sim $VM_CMDS $VM_IP_ADDR +# scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_ENB_LOG_FILE $ARCHIVES_LOC +# scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_UE_LOG_FILE $ARCHIVES_LOC +# recover_core_dump $VM_CMDS $VM_IP_ADDR $ARCHIVES_LOC/$CURRENT_ENB_LOG_FILE $ARCHIVES_LOC +# sleep 10 echo "############################################################" echo "Terminate EPC" From 29064e6d497e51e5dd7f24a4579794cbcfe2a84a Mon Sep 17 00:00:00 2001 From: Raymond Knopp Date: Wed, 9 Jan 2019 23:30:13 +0100 Subject: [PATCH 212/233] corrected bug in handling of UE_mode during initial connection once timing synchronization condition (hysteresis count) is satisfied. --- openair1/PHY/LTE_ESTIMATION/lte_adjust_sync_ue.c | 5 +++-- openair1/PHY/LTE_UE_TRANSPORT/dlsch_decoding.c | 2 +- openair1/SCHED_UE/phy_procedures_lte_ue.c | 15 ++++++++------- openair2/LAYER2/MAC/ue_procedures.c | 2 +- openair2/LAYER2/PDCP_v10.1.0/pdcp.c | 5 ++++- openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c | 4 ++-- openair2/LAYER2/RLC/rlc.c | 9 ++++++++- openair3/NAS/TOOLS/ue_eurecom_test_sfr.conf | 11 ++++++++--- 8 files changed, 35 insertions(+), 18 deletions(-) diff --git a/openair1/PHY/LTE_ESTIMATION/lte_adjust_sync_ue.c b/openair1/PHY/LTE_ESTIMATION/lte_adjust_sync_ue.c index c912c88934..e8a0913e73 100644 --- a/openair1/PHY/LTE_ESTIMATION/lte_adjust_sync_ue.c +++ b/openair1/PHY/LTE_ESTIMATION/lte_adjust_sync_ue.c @@ -36,7 +36,7 @@ void lte_adjust_synch(LTE_DL_FRAME_PARMS *frame_parms, PHY_VARS_UE *ue, module_id_t eNB_id, - uint8_t subframe, + uint8_t subframe, unsigned char clear, short coef) { @@ -96,6 +96,7 @@ void lte_adjust_synch(LTE_DL_FRAME_PARMS *frame_parms, else count_max_pos_ok = 0; + if(count_max_pos_ok > 10 && first_time == 1) { first_time = 0; @@ -103,7 +104,7 @@ void lte_adjust_synch(LTE_DL_FRAME_PARMS *frame_parms, if (ue->mac_enabled==1) { LOG_I(PHY,"[UE%d] Sending synch status to higher layers\n",ue->Mod_id); //mac_resynch(); - dl_phy_sync_success(ue->Mod_id,ue->proc.proc_rxtx[0].frame_rx,0,1);//ue->common_vars.eNb_id); + //dl_phy_sync_success(ue->Mod_id,ue->proc.proc_rxtx[0].frame_rx,0,1);//ue->common_vars.eNb_id); ue->UE_mode[0] = PRACH; } else { diff --git a/openair1/PHY/LTE_UE_TRANSPORT/dlsch_decoding.c b/openair1/PHY/LTE_UE_TRANSPORT/dlsch_decoding.c index afbd19329d..177d9cf6e6 100644 --- a/openair1/PHY/LTE_UE_TRANSPORT/dlsch_decoding.c +++ b/openair1/PHY/LTE_UE_TRANSPORT/dlsch_decoding.c @@ -38,7 +38,7 @@ #include "common/utils/LOG/vcd_signal_dumper.h" #include "PHY/LTE_UE_TRANSPORT/transport_proto_ue.h" //#define DEBUG_DLSCH_DECODING -#define UE_DEBUG_TRACE 1 +//#define UE_DEBUG_TRACE 1 void free_ue_dlsch(LTE_UE_DLSCH_t *dlsch) diff --git a/openair1/SCHED_UE/phy_procedures_lte_ue.c b/openair1/SCHED_UE/phy_procedures_lte_ue.c index f8fc0369bd..0cc03d4147 100644 --- a/openair1/SCHED_UE/phy_procedures_lte_ue.c +++ b/openair1/SCHED_UE/phy_procedures_lte_ue.c @@ -1438,10 +1438,11 @@ void ue_prach_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,uin prach_power = generate_prach(ue,eNB_id,subframe_tx,frame_tx); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_GENERATE_PRACH, VCD_FUNCTION_OUT); // stop_meas(&ue->tx_prach); - LOG_D(PHY,"[UE %d][RAPROC] PRACH PL %d dB, power %d dBm, digital power %d dB (amp %d)\n", + LOG_I(PHY,"[UE %d][RAPROC] PRACH PL %d dB, power %d dBm (max %d dBm), digital power %d dB (amp %d)\n", ue->Mod_id, get_PL(ue->Mod_id,ue->CC_id,eNB_id), ue->tx_power_dBm[subframe_tx], + ue->tx_power_max_dBm, dB_fixed(prach_power), ue->prach_vars[eNB_id]->amp); @@ -1657,7 +1658,7 @@ void ue_ulsch_uespec_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB } - if ( LOG_DEBUGFLAG(DEBUG_UE_PHYPROC)){ + //if ( LOG_DEBUGFLAG(DEBUG_UE_PHYPROC)){ LOG_D(PHY, "[UE %d][PUSCH %d] AbsSubframe %d.%d Generating PUSCH : first_rb %d, nb_rb %d, round %d, mcs %d, rv %d, " "cyclic_shift %d (cyclic_shift_common %d,n_DMRS2 %d,n_PRS %d), ACK (%d,%d), O_ACK %d, ack_status_cw0 %d ack_status_cw1 %d bundling %d, Nbundled %d, CQI %d, RI %d\n", @@ -1679,7 +1680,7 @@ void ue_ulsch_uespec_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB ue->ulsch[eNB_id]->bundling, Nbundled, cqi_status, ri_status); - } + //} @@ -1816,10 +1817,10 @@ void ue_ulsch_uespec_procedures(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB T(T_UE_PHY_PUSCH_TX_POWER, T_INT(eNB_id), T_INT(frame_tx%1024), T_INT(subframe_tx),T_INT(ue->tx_power_dBm[subframe_tx]), T_INT(tx_amp),T_INT(ue->ulsch[eNB_id]->f_pusch),T_INT(get_PL(Mod_id,0,eNB_id)),T_INT(nb_rb)); - if (LOG_DEBUGFLAG(DEBUG_UE_PHYPROC)) { + //if (LOG_DEBUGFLAG(DEBUG_UE_PHYPROC)) { LOG_D(PHY,"[UE %d][PUSCH %d] AbsSubFrame %d.%d, generating PUSCH, Po_PUSCH: %d dBm (max %d dBm), amp %d\n", Mod_id,harq_pid,frame_tx%1024,subframe_tx,ue->tx_power_dBm[subframe_tx],ue->tx_power_max_dBm, tx_amp); - } + //} if (LOG_DEBUGFLAG(UE_TIMING)) { start_meas(&ue->ulsch_modulation_stats); } @@ -2368,7 +2369,7 @@ void phy_procedures_UE_TX(PHY_VARS_UE *ue,UE_rxtx_proc_t *proc,uint8_t eNB_id,ui if (subframe_select(&ue->frame_parms,proc->subframe_tx) == SF_UL || ue->frame_parms.frame_type == FDD) { - if (ue->UE_mode[eNB_id] != PRACH ) { + if (ue->UE_mode[eNB_id] > PRACH ) { // check cell srs subframe and ue srs subframe. This has an impact on pusch encoding isSubframeSRS = is_srs_occasion_common(&ue->frame_parms,proc->frame_tx,proc->subframe_tx); @@ -2641,7 +2642,7 @@ void ue_pbch_procedures(uint8_t eNB_id,PHY_VARS_UE *ue,UE_rxtx_proc_t *proc, uin } // if this is the first PBCH after initial synchronization, make L1 state = PRACH - if (ue->UE_mode[eNB_id]==NOT_SYNCHED) ue->UE_mode[eNB_id] = PRACH; + //if (ue->UE_mode[eNB_id]==NOT_SYNCHED) ue->UE_mode[eNB_id] = PRACH; if (first_run) { first_run = 0; diff --git a/openair2/LAYER2/MAC/ue_procedures.c b/openair2/LAYER2/MAC/ue_procedures.c index 207815b122..080e241c86 100644 --- a/openair2/LAYER2/MAC/ue_procedures.c +++ b/openair2/LAYER2/MAC/ue_procedures.c @@ -2070,7 +2070,7 @@ ue_get_sdu(module_id_t module_idP, int CC_id, frame_t frameP, if (sdu_lengths[num_sdus]) { sdu_length_total += sdu_lengths[num_sdus]; sdu_lcids[num_sdus] = lcid; - LOG_D(MAC, + LOG_I(MAC, "[UE %d] TX Multiplex RLC PDU TX Got %d bytes for LcId%d\n", module_idP, sdu_lengths[num_sdus], lcid); diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp.c b/openair2/LAYER2/PDCP_v10.1.0/pdcp.c index 6167e1e6ca..5477fb8c3a 100644 --- a/openair2/LAYER2/PDCP_v10.1.0/pdcp.c +++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp.c @@ -182,6 +182,7 @@ boolean_t pdcp_data_req( (unsigned char*)&pdcp_pdu_p->data[0], sdu_buffer_sizeP); #endif + LOG_D(PDCP, "Before rlc_data_req 1, srb_flagP: %d, rb_idP: %d \n", srb_flagP, rb_idP); rlc_status = rlc_data_req(ctxt_pP, srb_flagP, MBMS_FLAG_YES, rb_idP, muiP, confirmP, sdu_buffer_sizeP, pdcp_pdu_p #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) ,NULL, NULL @@ -366,6 +367,7 @@ boolean_t pdcp_data_req( LOG_DUMPMSG(PDCP,DEBUG_PDCP,(char *)pdcp_pdu_p->data,pdcp_pdu_size, "[MSG] PDCP DL %s PDU on rb_id %d\n",(srb_flagP)? "CONTROL" : "DATA", rb_idP); + LOG_D(PDCP, "Before rlc_data_req 2, srb_flagP: %d, rb_idP: %d \n", srb_flagP, rb_idP); rlc_status = rlc_data_req(ctxt_pP, srb_flagP, MBMS_FLAG_NO, rb_idP, muiP, confirmP, pdcp_pdu_size, pdcp_pdu_p #if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) ,sourceL2Id @@ -962,7 +964,7 @@ pdcp_run ( RRC_DCCH_DATA_REQ (msg_p).frame, 0, RRC_DCCH_DATA_REQ (msg_p).eNB_index); - LOG_I(PDCP, PROTOCOL_CTXT_FMT"Received %s from %s: instance %d, rb_id %d, muiP %d, confirmP %d, mode %d\n", + LOG_D(PDCP, PROTOCOL_CTXT_FMT"Received %s from %s: instance %d, rb_id %d, muiP %d, confirmP %d, mode %d\n", PROTOCOL_CTXT_ARGS(&ctxt), ITTI_MSG_NAME (msg_p), ITTI_MSG_ORIGIN_NAME(msg_p), @@ -972,6 +974,7 @@ pdcp_run ( RRC_DCCH_DATA_REQ (msg_p).confirmp, RRC_DCCH_DATA_REQ (msg_p).mode); + LOG_D(PDCP, "Before calling pdcp_data_req from pdcp_run! RRC_DCCH_DATA_REQ (msg_p).rb_id: %d \n", RRC_DCCH_DATA_REQ (msg_p).rb_id); result = pdcp_data_req (&ctxt, SRB_FLAG_YES, RRC_DCCH_DATA_REQ (msg_p).rb_id, diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c b/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c index 7cab8cb40e..4f53736a6b 100644 --- a/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c +++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c @@ -719,11 +719,11 @@ int pdcp_fifo_read_input_sdus (const protocol_ctxt_t* const ctxt_pP) if (!ctxt.enb_flag) { if (rab_id != 0) { if (rab_id == UE_IP_DEFAULT_RAB_ID) { - LOG_I(PDCP, "PDCP_COLL_KEY_DEFAULT_DRB_VALUE(module_id=%d, rnti=%x, enb_flag=%d)\n", + LOG_D(PDCP, "PDCP_COLL_KEY_DEFAULT_DRB_VALUE(module_id=%d, rnti=%x, enb_flag=%d)\n", ctxt.module_id, ctxt.rnti, ctxt.enb_flag); key = PDCP_COLL_KEY_DEFAULT_DRB_VALUE(ctxt.module_id, ctxt.rnti, ctxt.enb_flag); h_rc = hashtable_get(pdcp_coll_p, key, (void**)&pdcp_p); - LOG_I(PDCP,"request key %x : (%d,%x,%d,%d)\n", + LOG_D(PDCP,"request key %x : (%d,%x,%d,%d)\n", (uint8_t)key,ctxt.module_id, ctxt.rnti, ctxt.enb_flag, rab_id); } else { rab_id = rab_id % LTE_maxDRB; diff --git a/openair2/LAYER2/RLC/rlc.c b/openair2/LAYER2/RLC/rlc.c index e56877d601..b65f2b0274 100644 --- a/openair2/LAYER2/RLC/rlc.c +++ b/openair2/LAYER2/RLC/rlc.c @@ -403,11 +403,18 @@ rlc_op_status_t rlc_data_req (const protocol_ctxt_t* const ctxt_pP, key = RLC_COLL_KEY_MBMS_VALUE(ctxt_pP->module_id, ctxt_pP->rnti, ctxt_pP->enb_flag, mbms_id_p->service_id, mbms_id_p->session_id); } if (sourceL2Id && destinationL2Id){ - key = RLC_COLL_KEY_SOURCE_DEST_VALUE(ctxt_pP->module_id, ctxt_pP->rnti, ctxt_pP->enb_flag, rb_idP, *sourceL2Id, *destinationL2Id, srb_flagP); + LOG_I (RLC, "RLC_COLL_KEY_VALUE: ctxt_pP->module_id: %d, ctxt_pP->rnti: %d, ctxt_pP->enb_flag: %d, rb_idP:%d, srb_flagP: %d \n \n", ctxt_pP->module_id, ctxt_pP->rnti, ctxt_pP->enb_flag, rb_idP, srb_flagP); + key = RLC_COLL_KEY_VALUE(ctxt_pP->module_id, ctxt_pP->rnti, ctxt_pP->enb_flag, rb_idP, srb_flagP); + + //Thinh's line originally uncommented + //key = RLC_COLL_KEY_SOURCE_DEST_VALUE(ctxt_pP->module_id, ctxt_pP->rnti, ctxt_pP->enb_flag, rb_idP, *sourceL2Id, *destinationL2Id, srb_flagP); + + //key_lcid = RLC_COLL_KEY_LCID_SOURCE_DEST_VALUE(ctxt_pP->module_id, ctxt_pP->rnti, ctxt_pP->enb_flag, chan_idP, *sourceL2Id, *destinationL2Id, srb_flagP); } else #endif { + LOG_I (RLC, "RLC_COLL_KEY_VALUE: ctxt_pP->module_id: %d, ctxt_pP->rnti: %d, ctxt_pP->enb_flag: %d, rb_idP:%d, srb_flagP: %d \n \n", ctxt_pP->module_id, ctxt_pP->rnti, ctxt_pP->enb_flag, rb_idP, srb_flagP); key = RLC_COLL_KEY_VALUE(ctxt_pP->module_id, ctxt_pP->rnti, ctxt_pP->enb_flag, rb_idP, srb_flagP); } diff --git a/openair3/NAS/TOOLS/ue_eurecom_test_sfr.conf b/openair3/NAS/TOOLS/ue_eurecom_test_sfr.conf index 33405805a6..679b9584d6 100644 --- a/openair3/NAS/TOOLS/ue_eurecom_test_sfr.conf +++ b/openair3/NAS/TOOLS/ue_eurecom_test_sfr.conf @@ -86,9 +86,14 @@ UE0: }; SIM: { - MSIN="0100001111"; - USIM_API_K="8baf473f2f8fd09487cccbd7097c6862"; - OPC="e734f8734007d6c5ce7a0508809e7e9c"; + #MSIN="0100001111"; + #USIM_API_K="8baf473f2f8fd09487cccbd7097c6862"; + #OPC="e734f8734007d6c5ce7a0508809e7e9c"; + #MSISDN="33611123456"; + + MSIN="0000000001"; + USIM_API_K="fec86ba6eb707ed08905757b1bb44b8f"; #Amerique-ltebox + OPC="C42449363BBAD02B66D16BC975D77CC1"; MSISDN="33611123456"; }; From ce7067c7b8b42b5f5a31d7c6e398eb0cf2b07252 Mon Sep 17 00:00:00 2001 From: Raphael Defosseux Date: Thu, 10 Jan 2019 16:35:13 +0100 Subject: [PATCH 213/233] CI: fixing scp timeout failure like the ssh session timeout failure Signed-off-by: Raphael Defosseux --- ci-scripts/main.py | 104 +++++++++++++++++++++++++++------------------ 1 file changed, 63 insertions(+), 41 deletions(-) diff --git a/ci-scripts/main.py b/ci-scripts/main.py index c5c30c8e20..710e06c2c2 100644 --- a/ci-scripts/main.py +++ b/ci-scripts/main.py @@ -203,59 +203,81 @@ class SSHConnection(): logging.debug('\u001B[1;37;41m Unexpected Others during closing\u001B[0m') def copyin(self, ipaddress, username, password, source, destination): + count = 0 + copy_status = False logging.debug('scp '+ username + '@' + ipaddress + ':' + source + ' ' + destination) - scp_spawn = pexpect.spawn('scp '+ username + '@' + ipaddress + ':' + source + ' ' + destination, timeout = 5) - scp_response = scp_spawn.expect(['Are you sure you want to continue connecting (yes/no)?', 'password:', pexpect.EOF, pexpect.TIMEOUT]) - if scp_response == 0: - scp_spawn.sendline('yes') - scp_spawn.expect('password:') - scp_spawn.sendline(password) - scp_response = scp_spawn.expect(['\$', 'Permission denied', 'password:', pexpect.EOF, pexpect.TIMEOUT]) + while count < 4: + scp_spawn = pexpect.spawn('scp '+ username + '@' + ipaddress + ':' + source + ' ' + destination, timeout = 5) + scp_response = scp_spawn.expect(['Are you sure you want to continue connecting (yes/no)?', 'password:', pexpect.EOF, pexpect.TIMEOUT]) if scp_response == 0: - pass + scp_spawn.sendline('yes') + scp_spawn.expect('password:') + scp_spawn.sendline(password) + scp_response = scp_spawn.expect(['\$', 'Permission denied', 'password:', pexpect.EOF, pexpect.TIMEOUT]) + if scp_response == 0: + count = 10 + copy_status = True + else: + logging.debug('1 - scp_response = ' + str(scp_response)) + elif scp_response == 1: + scp_spawn.sendline(password) + scp_response = scp_spawn.expect(['\$', 'Permission denied', 'password:', pexpect.EOF, pexpect.TIMEOUT]) + if scp_response == 0 or scp_response == 3: + count = 10 + copy_status = True + else: + logging.debug('2 - scp_response = ' + str(scp_response)) + elif scp_response == 2: + count = 10 + copy_status = True else: - logging.debug('1 - scp_response = ' + str(scp_response)) - sys.exit('SCP failed') - elif scp_response == 1: - scp_spawn.sendline(password) - scp_response = scp_spawn.expect(['\$', 'Permission denied', 'password:', pexpect.EOF, pexpect.TIMEOUT]) - if scp_response == 0 or scp_response == 3: - pass - else: - logging.debug('2 - scp_response = ' + str(scp_response)) - sys.exit('SCP failed') - elif scp_response == 2: + logging.debug('3 - scp_response = ' + str(scp_response)) + # adding a tempo when failure + if not copy_status: + time.sleep(1) + count += 1 + if copy_status: pass else: - logging.debug('3 - scp_response = ' + str(scp_response)) sys.exit('SCP failed') def copyout(self, ipaddress, username, password, source, destination): + count = 0 + copy_status = False logging.debug('scp ' + source + ' ' + username + '@' + ipaddress + ':' + destination) - scp_spawn = pexpect.spawn('scp ' + source + ' ' + username + '@' + ipaddress + ':' + destination, timeout = 5) - scp_response = scp_spawn.expect(['Are you sure you want to continue connecting (yes/no)?', 'password:', pexpect.EOF, pexpect.TIMEOUT]) - if scp_response == 0: - scp_spawn.sendline('yes') - scp_spawn.expect('password:') - scp_spawn.sendline(password) - scp_response = scp_spawn.expect(['\$', 'Permission denied', 'password:', pexpect.EOF, pexpect.TIMEOUT]) + while count < 4: + scp_spawn = pexpect.spawn('scp ' + source + ' ' + username + '@' + ipaddress + ':' + destination, timeout = 5) + scp_response = scp_spawn.expect(['Are you sure you want to continue connecting (yes/no)?', 'password:', pexpect.EOF, pexpect.TIMEOUT]) if scp_response == 0: - pass + scp_spawn.sendline('yes') + scp_spawn.expect('password:') + scp_spawn.sendline(password) + scp_response = scp_spawn.expect(['\$', 'Permission denied', 'password:', pexpect.EOF, pexpect.TIMEOUT]) + if scp_response == 0: + count = 10 + copy_status = True + else: + logging.debug('1 - scp_response = ' + str(scp_response)) + elif scp_response == 1: + scp_spawn.sendline(password) + scp_response = scp_spawn.expect(['\$', 'Permission denied', 'password:', pexpect.EOF, pexpect.TIMEOUT]) + if scp_response == 0 or scp_response == 3: + count = 10 + copy_status = True + else: + logging.debug('2 - scp_response = ' + str(scp_response)) + elif scp_response == 2: + count = 10 + copy_status = True else: - logging.debug('1 - scp_response = ' + str(scp_response)) - sys.exit('SCP failed') - elif scp_response == 1: - scp_spawn.sendline(password) - scp_response = scp_spawn.expect(['\$', 'Permission denied', 'password:', pexpect.EOF, pexpect.TIMEOUT]) - if scp_response == 0 or scp_response == 3: - pass - else: - logging.debug('2 - scp_response = ' + str(scp_response)) - sys.exit('SCP failed') - elif scp_response == 2: + logging.debug('3 - scp_response = ' + str(scp_response)) + # adding a tempo when failure + if not copy_status: + time.sleep(1) + count += 1 + if copy_status: pass else: - logging.debug('3 - scp_response = ' + str(scp_response)) sys.exit('SCP failed') def BuildeNB(self): @@ -2061,7 +2083,7 @@ class SSHConnection(): def CreateHtmlTabFooter(self, passStatus): if ((not self.htmlFooterCreated) and (self.htmlHeaderCreated)): - self.htmlFile.write(' \n') + self.htmlFile.write(' \n') self.htmlFile.write(' \n') if passStatus: self.htmlFile.write(' \n') From 95746536c04dc64213c1373e0b1cd14204160df5 Mon Sep 17 00:00:00 2001 From: Raymond Knopp Date: Thu, 10 Jan 2019 18:39:07 +0100 Subject: [PATCH 214/233] Fix for the Internet connectivity issue --- openair2/LAYER2/PDCP_v10.1.0/pdcp.c | 6 +++++- openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c | 4 ++-- openair2/LAYER2/RLC/rlc_mac.c | 1 + 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp.c b/openair2/LAYER2/PDCP_v10.1.0/pdcp.c index 5477fb8c3a..47723f9b40 100644 --- a/openair2/LAYER2/PDCP_v10.1.0/pdcp.c +++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp.c @@ -473,6 +473,7 @@ pdcp_data_ind( LOG_DUMPMSG(PDCP,DEBUG_PDCP,(char *)sdu_buffer_pP->data,sdu_buffer_sizeP, "[MSG] PDCP UL %s PDU on rb_id %d\n", (srb_flagP)? "CONTROL" : "DATA", rb_idP); + #if T_TRACER if (ctxt_pP->enb_flag != ENB_FLAG_NO) T(T_ENB_PDCP_UL, T_INT(ctxt_pP->module_id), T_INT(ctxt_pP->rnti), T_INT(rb_idP), T_INT(sdu_buffer_sizeP)); @@ -802,13 +803,16 @@ pdcp_data_ind( } else { ((pdcp_data_ind_header_t*) new_sdu_p->data)->rb_id = rb_id + (ctxt_pP->module_id * LTE_maxDRB); } - ((pdcp_data_ind_header_t*) new_sdu_p->data)->inst = ctxt_pP->module_id; + + //Panos: Commented this out because it cancels the assignment in #if defined(ENABLE_USE_MME) case + //((pdcp_data_ind_header_t*) new_sdu_p->data)->inst = ctxt_pP->module_id; #ifdef DEBUG_PDCP_FIFO_FLUSH_SDU static uint32_t pdcp_inst = 0; ((pdcp_data_ind_header_t*) new_sdu_p->data)->inst = pdcp_inst++; LOG_D(PDCP, "inst=%d size=%d\n", ((pdcp_data_ind_header_t*) new_sdu_p->data)->inst, ((pdcp_data_ind_header_t *) new_sdu_p->data)->data_size); #endif + //((pdcp_data_ind_header_t*) new_sdu_p->data)->inst = 1; //pdcp_inst++; memcpy(&new_sdu_p->data[sizeof (pdcp_data_ind_header_t)], \ &sdu_buffer_pP->data[payload_offset], \ diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c b/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c index 4f53736a6b..cf89a6dc1b 100644 --- a/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c +++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c @@ -168,7 +168,7 @@ int pdcp_fifo_flush_sdus(const protocol_ctxt_t* const ctxt_pP) ((pdcp_data_ind_header_t*) sdu_p->data)->inst, ((pdcp_data_ind_header_t *) sdu_p->data)->data_size); #else - ((pdcp_data_ind_header_t *)(sdu_p->data))->inst = 0; + //((pdcp_data_ind_header_t *)(sdu_p->data))->inst = 0; #endif #if defined(LINK_ENB_PDCP_TO_GTPV1U) @@ -195,7 +195,7 @@ int pdcp_fifo_flush_sdus(const protocol_ctxt_t* const ctxt_pP) #endif /* defined(ENABLE_USE_MME) */ #ifdef PDCP_DEBUG - LOG_D(PDCP, "PDCP->IP TTI %d INST %d: Preparing %d Bytes of data from rab %d to Nas_mesh\n", + LOG_I(PDCP, "PDCP->IP TTI %d INST %d: Preparing %d Bytes of data from rab %d to Nas_mesh\n", ctxt_pP->frame, ((pdcp_data_ind_header_t *)(sdu_p->data))->inst, ((pdcp_data_ind_header_t *)(sdu_p->data))->data_size, ((pdcp_data_ind_header_t *)(sdu_p->data))->rb_id); #endif //PDCP_DEBUG diff --git a/openair2/LAYER2/RLC/rlc_mac.c b/openair2/LAYER2/RLC/rlc_mac.c index da90a58a59..d4ec487c85 100644 --- a/openair2/LAYER2/RLC/rlc_mac.c +++ b/openair2/LAYER2/RLC/rlc_mac.c @@ -254,6 +254,7 @@ void mac_rlc_data_ind ( srb_flag_t srb_flag = (channel_idP <= 2) ? SRB_FLAG_YES : SRB_FLAG_NO; protocol_ctxt_t ctxt; + PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, module_idP, enb_flagP, rntiP, frameP, 0, eNB_index); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_MAC_RLC_DATA_IND,VCD_FUNCTION_IN); From 0a7934d1fb1ccf5589c1b20b78d271798f8127d2 Mon Sep 17 00:00:00 2001 From: Raymond Knopp Date: Mon, 14 Jan 2019 12:18:56 +0100 Subject: [PATCH 215/233] minor change for simulation targets --- openair1/SCHED_UE/phy_procedures_lte_ue.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openair1/SCHED_UE/phy_procedures_lte_ue.c b/openair1/SCHED_UE/phy_procedures_lte_ue.c index faaa897d64..4fd99cb15f 100644 --- a/openair1/SCHED_UE/phy_procedures_lte_ue.c +++ b/openair1/SCHED_UE/phy_procedures_lte_ue.c @@ -2410,8 +2410,8 @@ void ue_pbch_procedures(uint8_t eNB_id,PHY_VARS_UE *ue,UE_rxtx_proc_t *proc, uin ue->UE_mode[eNB_id]==NOT_SYNCHED ? 1 : 0); } - // if this is the first PBCH after initial synchronization, make L1 state = PRACH - //if (ue->UE_mode[eNB_id]==NOT_SYNCHED) ue->UE_mode[eNB_id] = PRACH; + // if this is the first PBCH after initial synchronization and no timing correction is performed, make L1 state = PRACH + if (ue->UE_mode[eNB_id]==NOT_SYNCHED && ue->no_timing_correction == 1) ue->UE_mode[eNB_id] = PRACH; if (first_run) { first_run = 0; From 942a5cf2dbbd2c2d046fc8254f19e2e23414bbc3 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Mon, 14 Jan 2019 16:18:31 +0100 Subject: [PATCH 216/233] CI: adapt parameters for better FDD performances --- ci-scripts/conf_files/enb.band7.tm1.100PRB.usrpb210.conf | 6 +++--- ci-scripts/conf_files/enb.band7.tm1.25PRB.usrpb210.conf | 8 ++++---- ci-scripts/conf_files/enb.band7.tm1.50PRB.usrpb210.conf | 8 ++++---- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/ci-scripts/conf_files/enb.band7.tm1.100PRB.usrpb210.conf b/ci-scripts/conf_files/enb.band7.tm1.100PRB.usrpb210.conf index f3cb31f449..2c2ca635a6 100644 --- a/ci-scripts/conf_files/enb.band7.tm1.100PRB.usrpb210.conf +++ b/ci-scripts/conf_files/enb.band7.tm1.100PRB.usrpb210.conf @@ -197,8 +197,8 @@ MACRLCs = ( tr_s_preference = "local_L1"; tr_n_preference = "local_RRC"; phy_test_mode = 0; - puSch10xSnr = 200; - puCch10xSnr = 200; + puSch10xSnr = 160; + puCch10xSnr = 160; } ); @@ -227,7 +227,7 @@ RUs = ( THREAD_STRUCT = ( { #three config for level of parallelism "PARALLEL_SINGLE_THREAD", "PARALLEL_RU_L1_SPLIT", or "PARALLEL_RU_L1_TRX_SPLIT" - parallel_config = "PARALLEL_RU_L1_TRX_SPLIT"; + parallel_config = "PARALLEL_SINGLE_THREAD"; #two option for worker "WORKER_DISABLE" or "WORKER_ENABLE" worker_config = "WORKER_ENABLE"; } diff --git a/ci-scripts/conf_files/enb.band7.tm1.25PRB.usrpb210.conf b/ci-scripts/conf_files/enb.band7.tm1.25PRB.usrpb210.conf index e33daa7a8a..4dd8c1ee22 100644 --- a/ci-scripts/conf_files/enb.band7.tm1.25PRB.usrpb210.conf +++ b/ci-scripts/conf_files/enb.band7.tm1.25PRB.usrpb210.conf @@ -197,8 +197,8 @@ MACRLCs = ( tr_s_preference = "local_L1"; tr_n_preference = "local_RRC"; phy_test_mode = 0; - puSch10xSnr = 200; - puCch10xSnr = 200; + puSch10xSnr = 160; + puCch10xSnr = 160; } ); @@ -218,7 +218,7 @@ RUs = ( att_rx = 0; bands = [7]; max_pdschReferenceSignalPower = -27; - max_rxgain = 115; + max_rxgain = 125; eNB_instances = [0]; } @@ -227,7 +227,7 @@ RUs = ( THREAD_STRUCT = ( { #three config for level of parallelism "PARALLEL_SINGLE_THREAD", "PARALLEL_RU_L1_SPLIT", or "PARALLEL_RU_L1_TRX_SPLIT" - parallel_config = "PARALLEL_RU_L1_TRX_SPLIT"; + parallel_config = "PARALLEL_SINGLE_THREAD"; #two option for worker "WORKER_DISABLE" or "WORKER_ENABLE" worker_config = "WORKER_ENABLE"; } diff --git a/ci-scripts/conf_files/enb.band7.tm1.50PRB.usrpb210.conf b/ci-scripts/conf_files/enb.band7.tm1.50PRB.usrpb210.conf index 32e8bb9931..cae47b152c 100644 --- a/ci-scripts/conf_files/enb.band7.tm1.50PRB.usrpb210.conf +++ b/ci-scripts/conf_files/enb.band7.tm1.50PRB.usrpb210.conf @@ -197,8 +197,8 @@ MACRLCs = ( tr_s_preference = "local_L1"; tr_n_preference = "local_RRC"; phy_test_mode = 0; - puSch10xSnr = 200; - puCch10xSnr = 200; + puSch10xSnr = 160; + puCch10xSnr = 160; } ); @@ -218,7 +218,7 @@ RUs = ( att_rx = 0; bands = [7]; max_pdschReferenceSignalPower = -27; - max_rxgain = 115; + max_rxgain = 120; eNB_instances = [0]; } @@ -227,7 +227,7 @@ RUs = ( THREAD_STRUCT = ( { #three config for level of parallelism "PARALLEL_SINGLE_THREAD", "PARALLEL_RU_L1_SPLIT", or "PARALLEL_RU_L1_TRX_SPLIT" - parallel_config = "PARALLEL_RU_L1_TRX_SPLIT"; + parallel_config = "PARALLEL_SINGLE_THREAD"; #two option for worker "WORKER_DISABLE" or "WORKER_ENABLE" worker_config = "WORKER_ENABLE"; } From 0019707cd18ce633f44148d824bca730e80d2c71 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Mon, 14 Jan 2019 16:28:16 +0100 Subject: [PATCH 217/233] T: fix early logs The variable T_stdout needs to be 1 at startup to avoid missing logs. --- common/utils/T/T.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/utils/T/T.c b/common/utils/T/T.c index fbd3f75a0c..140da30688 100644 --- a/common/utils/T/T.c +++ b/common/utils/T/T.c @@ -19,7 +19,7 @@ /* array used to activate/disactivate a log */ static int T_IDs[T_NUMBER_OF_IDS]; int *T_active = T_IDs; -int T_stdout; +int T_stdout = 1; static int T_socket; From e179213be05ba5c268b09354bf56e95277b7b354 Mon Sep 17 00:00:00 2001 From: frtabu Date: Mon, 14 Jan 2019 19:13:12 +0100 Subject: [PATCH 218/233] exit softmodem when a command line option requiring an argument is specified without an option value. Previous behavior was to print a message and ignore the option --- common/config/config_cmdline.c | 12 +- common/config/config_userapi.c | 6 + common/config/config_userapi.h | 5 +- common/config/libconfig/config_libconfig.c | 487 +++++++++++---------- targets/RT/USER/lte-softmodem.c | 4 +- targets/RT/USER/lte-uesoftmodem.c | 2 +- 6 files changed, 281 insertions(+), 235 deletions(-) diff --git a/common/config/config_cmdline.c b/common/config/config_cmdline.c index 7fca12540d..635287afb4 100644 --- a/common/config/config_cmdline.c +++ b/common/config/config_cmdline.c @@ -75,6 +75,7 @@ int processoption(paramdef_t *cfgoptions, char *value) { if ( value == NULL) { if( (cfgoptions->paramflags &PARAMFLAG_BOOL) == 0 ) { /* not a boolean, argument required */ fprintf(stderr,"[CONFIG] command line, option %s requires an argument\n",cfgoptions->optname); + exit_fun("[CONFIG] command line parsing fatal error"); return 0; } else { /* boolean value option without argument, set value to true*/ tmpval = defbool; @@ -143,7 +144,10 @@ int processoption(paramdef_t *cfgoptions, char *value) { return optisset; } -int config_check_cmdlineopt(char *prefix) { +/*--------------------------------------------------------------------*/ +/* check unknown options in the command line +*/ +int config_check_unknown_cmdlineopt(char *prefix) { int unknowndetected=0; char testprefix[CONFIG_MAXOPTLENGTH]=""; int finalcheck = 0; @@ -161,6 +165,8 @@ int config_check_cmdlineopt(char *prefix) { if ( !finalcheck && testprefix[0]==0 && index(config_get_if()->argv[i],'.') != NULL) continue; + if ( !finalcheck && isdigit(config_get_if()->argv[i][0])) continue; + if ( !finalcheck && config_get_if()->argv[i][0] == '-' && isdigit(config_get_if()->argv[i][1])) continue; if ( (config_get_if()->argv_info[i] & CONFIG_CMDLINEOPT_PROCESSED) == 0 ) { @@ -173,7 +179,7 @@ int config_check_cmdlineopt(char *prefix) { printf_cmdl("[CONFIG] %i unknown option(s) in command line starting with %s (section %s)\n", unknowndetected,testprefix,((prefix==NULL)?"":prefix)); return unknowndetected; -} /* parse_cmdline*/ +} /* config_check_unknown_cmdlineopt */ int config_process_cmdline(paramdef_t *cfgoptions,int numoptions, char *prefix) { int c = config_get_if()->argc; @@ -269,7 +275,7 @@ int config_process_cmdline(paramdef_t *cfgoptions,int numoptions, char *prefix) printf_cmdl("[CONFIG] %s %i options set from command line\n",((prefix == NULL) ? "(root)":prefix),j); if ( !(CONFIG_ISFLAGSET( CONFIG_NOCHECKUNKOPT )) ) { - i=config_check_cmdlineopt(prefix); + i=config_check_unknown_cmdlineopt(prefix); if (i > 0) { fprintf(stderr,"[CONFIG] %i unknown options for section %s detected in command line\n", diff --git a/common/config/config_userapi.c b/common/config/config_userapi.c index afbe1ae887..b149bfd636 100644 --- a/common/config/config_userapi.c +++ b/common/config/config_userapi.c @@ -370,6 +370,12 @@ int config_checkstr_assign_integer(paramdef_t *param) { return -1; } +void config_set_checkfunctions(paramdef_t *params, checkedparam_t *checkfunctions, int numparams) { + for (int i=0; i< numparams ; i++ ) { + params[i].chkPptr = &(checkfunctions[i]); + } +} + int config_setdefault_string(paramdef_t *cfgoptions, char *prefix) { int status = 0; diff --git a/common/config/config_userapi.h b/common/config/config_userapi.h index 5542148343..d0508ffbeb 100644 --- a/common/config/config_userapi.h +++ b/common/config/config_userapi.h @@ -57,10 +57,13 @@ extern int config_assign_ipv4addr(paramdef_t *cfgoptions, char *ipv4addr); /* apis to get/check parameters, to be used by oai modules, at configuration time */ #define CONFIG_CHECKALLSECTIONS "ALLSECTIONS" -extern int config_check_cmdlineopt(char *prefix); +extern int config_check_unknown_cmdlineopt(char *prefix); extern int config_get(paramdef_t *params,int numparams, char *prefix); extern int config_getlist(paramlist_def_t *ParamList, paramdef_t *params, int numparams, char *prefix); +/* apis to set some of the paramdef_t fields before using the get/getlist api's */ +extern void config_set_checkfunctions(paramdef_t *params, checkedparam_t *checkfunctions, int numparams); + /* apis to retrieve parameters info after calling get or getlist functions */ extern int config_isparamset(paramdef_t *params,int paramidx); extern int config_get_processedint(paramdef_t *cfgoption); diff --git a/common/config/libconfig/config_libconfig.c b/common/config/libconfig/config_libconfig.c index cb6fa46293..2d861f2dc3 100644 --- a/common/config/libconfig/config_libconfig.c +++ b/common/config/libconfig/config_libconfig.c @@ -42,60 +42,60 @@ #include "errno.h" #if ( LIBCONFIG_VER_MAJOR == 1 && LIBCONFIG_VER_MINOR < 5) -#define config_setting_lookup config_lookup_from + #define config_setting_lookup config_lookup_from #endif void config_libconfig_end(void ); -int read_strlist(paramdef_t *cfgoptions,config_setting_t *setting, char *cfgpath) -{ -const char *str; -int st; -int numelt; +int read_strlist(paramdef_t *cfgoptions,config_setting_t *setting, char *cfgpath) { + const char *str; + int st; + int numelt; + numelt=config_setting_length(setting); + config_check_valptr(cfgoptions,(char **)&(cfgoptions->strlistptr), sizeof(char *) * numelt); + st=0; - numelt=config_setting_length(setting); - config_check_valptr(cfgoptions,(char **)&(cfgoptions->strlistptr), sizeof(char *) * numelt); - st=0; - for (int i=0; i< numelt ; i++) { - str=config_setting_get_string_elem(setting,i); - if (str==NULL) { - printf("[LIBCONFIG] %s%i not found in config file\n", cfgoptions->optname,i); - } else { - config_check_valptr(cfgoptions,&(cfgoptions->strlistptr[i]),strlen(str)+1); - sprintf(cfgoptions->strlistptr[i],"%s",str); - st++; - printf_params("[LIBCONFIG] %s%i: %s\n", cfgpath,i,cfgoptions->strlistptr[i]); - } - } - cfgoptions->numelt=numelt; - return st; + for (int i=0; i< numelt ; i++) { + str=config_setting_get_string_elem(setting,i); + + if (str==NULL) { + printf("[LIBCONFIG] %s%i not found in config file\n", cfgoptions->optname,i); + } else { + config_check_valptr(cfgoptions,&(cfgoptions->strlistptr[i]),strlen(str)+1); + sprintf(cfgoptions->strlistptr[i],"%s",str); + st++; + printf_params("[LIBCONFIG] %s%i: %s\n", cfgpath,i,cfgoptions->strlistptr[i]); + } + } + + cfgoptions->numelt=numelt; + return st; } -int read_intarray(paramdef_t *cfgoptions,config_setting_t *setting, char *cfgpath) -{ +int read_intarray(paramdef_t *cfgoptions,config_setting_t *setting, char *cfgpath) { + cfgoptions->numelt=config_setting_length(setting); - cfgoptions->numelt=config_setting_length(setting); - - if (cfgoptions->numelt > 0) { - cfgoptions->iptr=malloc(sizeof(int) * (cfgoptions->numelt)); - for (int i=0; i< cfgoptions->numelt && cfgoptions->iptr != NULL; i++) { - cfgoptions->iptr[i]=config_setting_get_int_elem(setting,i); - printf_params("[LIBCONFIG] %s[%i]: %i\n", cfgpath,i,cfgoptions->iptr[i]); - } /* for loop on array element... */ - } - return cfgoptions->numelt; + if (cfgoptions->numelt > 0) { + cfgoptions->iptr=malloc(sizeof(int) * (cfgoptions->numelt)); + + for (int i=0; i< cfgoptions->numelt && cfgoptions->iptr != NULL; i++) { + cfgoptions->iptr[i]=config_setting_get_int_elem(setting,i); + printf_params("[LIBCONFIG] %s[%i]: %i\n", cfgpath,i,cfgoptions->iptr[i]); + } /* for loop on array element... */ + } + + return cfgoptions->numelt; } -int config_libconfig_get(paramdef_t *cfgoptions,int numoptions, char *prefix ) -{ +int config_libconfig_get(paramdef_t *cfgoptions,int numoptions, char *prefix ) { config_setting_t *setting; char *str; int i,u; long long int llu; - double dbl; + double dbl; int rst; int status=0; int notfound; @@ -104,211 +104,244 @@ int config_libconfig_get(paramdef_t *cfgoptions,int numoptions, char *prefix ) int numdefvals=0; char cfgpath[512]; /* 512 should be enough for the sprintf below */ - for(i=0;iparamflags & PARAMFLAG_DONOTREAD) != 0) { + printf_params("[LIBCONFIG] %s.%s ignored\n", cfgpath,cfgoptions[i].optname ); + continue; + } - if( (cfgoptions->paramflags & PARAMFLAG_DONOTREAD) != 0) { - printf_params("[LIBCONFIG] %s.%s ignored\n", cfgpath,cfgoptions[i].optname ); - continue; - } - notfound=0; - defval=0; - switch(cfgoptions[i].type) - { - case TYPE_STRING: - if ( config_lookup_string(&(libconfig_privdata.cfg),cfgpath, (const char **)&str)) { - if ( cfgoptions[i].numelt > 0 && str != NULL && strlen(str) >= cfgoptions[i].numelt ) { - fprintf(stderr,"[LIBCONFIG] %s: %s exceeds maximum length of %i bytes, value truncated\n", - cfgpath,str,cfgoptions[i].numelt); - str[strlen(str)-1] = 0; - } - if (cfgoptions[i].numelt == 0 ) { - // config_check_valptr(&(cfgoptions[i]), (char **)(&(cfgoptions[i].strptr)), sizeof(char *)); - config_check_valptr(&(cfgoptions[i]), cfgoptions[i].strptr, strlen(str)+1); - sprintf( *(cfgoptions[i].strptr) , "%s", str); - printf_params("[LIBCONFIG] %s: \"%s\"\n", cfgpath,*(cfgoptions[i].strptr) ); - } else { - sprintf( (char *)(cfgoptions[i].strptr) , "%s", str); - printf_params("[LIBCONFIG] %s: \"%s\"\n", cfgpath,(char *)cfgoptions[i].strptr ); - } - } else { - defval=config_setdefault_string(&(cfgoptions[i]),prefix); - } - break; - case TYPE_STRINGLIST: - setting = config_setting_lookup (config_root_setting(&(libconfig_privdata.cfg)),cfgpath ); - if ( setting != NULL) { - read_strlist(&cfgoptions[i],setting,cfgpath); - } else { - defval=config_setdefault_stringlist(&(cfgoptions[i]),prefix); - } - break; - case TYPE_UINT8: - case TYPE_INT8: - case TYPE_UINT16: - case TYPE_INT16: - case TYPE_UINT32: - case TYPE_INT32: - case TYPE_MASK: - if ( config_lookup_int(&(libconfig_privdata.cfg),cfgpath, &u)) { - config_check_valptr(&(cfgoptions[i]), (char **)(&(cfgoptions[i].iptr)),sizeof(int32_t)); - config_assign_int(&(cfgoptions[i]),cfgpath,u); - } else { - defval=config_setdefault_int(&(cfgoptions[i]),prefix); - } - break; - case TYPE_UINT64: - case TYPE_INT64: - if ( config_lookup_int64(&(libconfig_privdata.cfg),cfgpath, &llu)) { - config_check_valptr(&(cfgoptions[i]), (char **)&(cfgoptions[i].i64ptr),sizeof(long long)); - if(cfgoptions[i].type==TYPE_UINT64) { - *(cfgoptions[i].u64ptr) = (uint64_t)llu; - printf_params("[LIBCONFIG] %s: %llu\n", cfgpath,(long long unsigned)(*(cfgoptions[i].u64ptr)) ); - } else { - *(cfgoptions[i].iptr) = llu; - printf_params("[LIBCONFIG] %s: %lli\n", cfgpath,(long long unsigned)(*(cfgoptions[i].i64ptr)) ); - } - } else { - defval=config_setdefault_int64(&(cfgoptions[i]),prefix); - } - break; - case TYPE_UINTARRAY: - case TYPE_INTARRAY: - setting = config_setting_lookup (config_root_setting(&(libconfig_privdata.cfg)),cfgpath ); - if ( setting != NULL) { - read_intarray(&cfgoptions[i],setting,cfgpath); - } else { - defval=config_setdefault_intlist(&(cfgoptions[i]),prefix); - } - break; - case TYPE_DOUBLE: - if ( config_lookup_float(&(libconfig_privdata.cfg),cfgpath, &dbl)) { - config_check_valptr(&(cfgoptions[i]), (char **)&(cfgoptions[i].dblptr),sizeof(double)); - *(cfgoptions[i].dblptr) = dbl; - printf_params("[LIBCONFIG] %s: %lf\n", cfgpath,*(cfgoptions[i].dblptr) ); - } else { - defval=config_setdefault_double(&(cfgoptions[i]),prefix); - } - break; - case TYPE_IPV4ADDR: - if ( !config_lookup_string(&(libconfig_privdata.cfg),cfgpath, (const char **)&str)) { - defval=config_setdefault_ipv4addr(&(cfgoptions[i]),prefix); - } else { - rst=config_assign_ipv4addr(cfgoptions, str); - if (rst < 0) { - fprintf(stderr,"[LIBCONFIG] %s not valid for %s \n", str, cfgpath); - fatalerror=1; - } - } - break; - case TYPE_LIST: - setting = config_setting_lookup (config_root_setting(&(libconfig_privdata.cfg)),cfgpath ); - if ( setting) { - cfgoptions[i].numelt=config_setting_length(setting); - } else { - notfound=1; - } - break; - default: - fprintf(stderr,"[LIBCONFIG] %s type %i not supported\n", cfgpath,cfgoptions[i].type); - fatalerror=1; - break; - } /* switch on param type */ - if( notfound == 1) { - printf("[LIBCONFIG] %s not found in %s ", cfgpath,libconfig_privdata.configfile ); - if ( (cfgoptions[i].paramflags & PARAMFLAG_MANDATORY) != 0) { - fatalerror=1; - printf(" mandatory parameter missing\n"); + notfound=0; + defval=0; + + switch(cfgoptions[i].type) { + case TYPE_STRING: + if ( config_lookup_string(&(libconfig_privdata.cfg),cfgpath, (const char **)&str)) { + if ( cfgoptions[i].numelt > 0 && str != NULL && strlen(str) >= cfgoptions[i].numelt ) { + fprintf(stderr,"[LIBCONFIG] %s: %s exceeds maximum length of %i bytes, value truncated\n", + cfgpath,str,cfgoptions[i].numelt); + str[strlen(str)-1] = 0; + } + + if (cfgoptions[i].numelt == 0 ) { + // config_check_valptr(&(cfgoptions[i]), (char **)(&(cfgoptions[i].strptr)), sizeof(char *)); + config_check_valptr(&(cfgoptions[i]), cfgoptions[i].strptr, strlen(str)+1); + sprintf( *(cfgoptions[i].strptr) , "%s", str); + printf_params("[LIBCONFIG] %s: \"%s\"\n", cfgpath,*(cfgoptions[i].strptr) ); + } else { + sprintf( (char *)(cfgoptions[i].strptr) , "%s", str); + printf_params("[LIBCONFIG] %s: \"%s\"\n", cfgpath,(char *)cfgoptions[i].strptr ); + } } else { - printf("\n"); + defval=config_setdefault_string(&(cfgoptions[i]),prefix); } + + break; + + case TYPE_STRINGLIST: + setting = config_setting_lookup (config_root_setting(&(libconfig_privdata.cfg)),cfgpath ); + + if ( setting != NULL) { + read_strlist(&cfgoptions[i],setting,cfgpath); + } else { + defval=config_setdefault_stringlist(&(cfgoptions[i]),prefix); + } + + break; + + case TYPE_UINT8: + case TYPE_INT8: + case TYPE_UINT16: + case TYPE_INT16: + case TYPE_UINT32: + case TYPE_INT32: + case TYPE_MASK: + if ( config_lookup_int(&(libconfig_privdata.cfg),cfgpath, &u)) { + config_check_valptr(&(cfgoptions[i]), (char **)(&(cfgoptions[i].iptr)),sizeof(int32_t)); + config_assign_int(&(cfgoptions[i]),cfgpath,u); + } else { + defval=config_setdefault_int(&(cfgoptions[i]),prefix); + } + + break; + + case TYPE_UINT64: + case TYPE_INT64: + if ( config_lookup_int64(&(libconfig_privdata.cfg),cfgpath, &llu)) { + config_check_valptr(&(cfgoptions[i]), (char **)&(cfgoptions[i].i64ptr),sizeof(long long)); + + if(cfgoptions[i].type==TYPE_UINT64) { + *(cfgoptions[i].u64ptr) = (uint64_t)llu; + printf_params("[LIBCONFIG] %s: %llu\n", cfgpath,(long long unsigned)(*(cfgoptions[i].u64ptr)) ); + } else { + *(cfgoptions[i].iptr) = llu; + printf_params("[LIBCONFIG] %s: %llu\n", cfgpath,(long long unsigned)(*(cfgoptions[i].i64ptr)) ); + } + } else { + defval=config_setdefault_int64(&(cfgoptions[i]),prefix); + } + + break; + + case TYPE_UINTARRAY: + case TYPE_INTARRAY: + setting = config_setting_lookup (config_root_setting(&(libconfig_privdata.cfg)),cfgpath ); + + if ( setting != NULL) { + read_intarray(&cfgoptions[i],setting,cfgpath); + } else { + defval=config_setdefault_intlist(&(cfgoptions[i]),prefix); + } + + break; + + case TYPE_DOUBLE: + if ( config_lookup_float(&(libconfig_privdata.cfg),cfgpath, &dbl)) { + config_check_valptr(&(cfgoptions[i]), (char **)&(cfgoptions[i].dblptr),sizeof(double)); + *(cfgoptions[i].dblptr) = dbl; + printf_params("[LIBCONFIG] %s: %lf\n", cfgpath,*(cfgoptions[i].dblptr) ); + } else { + defval=config_setdefault_double(&(cfgoptions[i]),prefix); + } + + break; + + case TYPE_IPV4ADDR: + if ( !config_lookup_string(&(libconfig_privdata.cfg),cfgpath, (const char **)&str)) { + defval=config_setdefault_ipv4addr(&(cfgoptions[i]),prefix); + } else { + rst=config_assign_ipv4addr(cfgoptions, str); + + if (rst < 0) { + fprintf(stderr,"[LIBCONFIG] %s not valid for %s \n", str, cfgpath); + fatalerror=1; + } + } + + break; + + case TYPE_LIST: + setting = config_setting_lookup (config_root_setting(&(libconfig_privdata.cfg)),cfgpath ); + + if ( setting) { + cfgoptions[i].numelt=config_setting_length(setting); + } else { + notfound=1; + } + + break; + + default: + fprintf(stderr,"[LIBCONFIG] %s type %i not supported\n", cfgpath,cfgoptions[i].type); + fatalerror=1; + break; + } /* switch on param type */ + + if( notfound == 1) { + printf("[LIBCONFIG] %s not found in %s ", cfgpath,libconfig_privdata.configfile ); + + if ( (cfgoptions[i].paramflags & PARAMFLAG_MANDATORY) != 0) { + fatalerror=1; + printf(" mandatory parameter missing\n"); + } else { + printf("\n"); + } } else { if (defval == 1) { - numdefvals++; - cfgoptions[i].paramflags = cfgoptions[i].paramflags | PARAMFLAG_PARAMSETDEF; + numdefvals++; + cfgoptions[i].paramflags = cfgoptions[i].paramflags | PARAMFLAG_PARAMSETDEF; } else { - cfgoptions[i].paramflags = cfgoptions[i].paramflags | PARAMFLAG_PARAMSET; + cfgoptions[i].paramflags = cfgoptions[i].paramflags | PARAMFLAG_PARAMSET; } + status++; } } /* for loop on options */ + printf("[LIBCONFIG] %s: %i/%i parameters successfully set, (%i to default value)\n", - ((prefix == NULL)?"(root)":prefix), + ((prefix == NULL)?"(root)":prefix), status,numoptions,numdefvals ); + if (fatalerror == 1) { - fprintf(stderr,"[LIBCONFIG] fatal errors found when processing %s \n", libconfig_privdata.configfile ); - config_libconfig_end(); - end_configmodule(); + fprintf(stderr,"[LIBCONFIG] fatal errors found when processing %s \n", libconfig_privdata.configfile ); + config_libconfig_end(); + end_configmodule(); } + return status; } -int config_libconfig_getlist(paramlist_def_t *ParamList, - paramdef_t *params, int numparams, char *prefix) -{ -config_setting_t *setting; -int i,j,status; -char *listpath=NULL; -char cfgpath[MAX_OPTNAME_SIZE*2 + 6]; /* prefix.listname.[listindex] */ +int config_libconfig_getlist(paramlist_def_t *ParamList, + paramdef_t *params, int numparams, char *prefix) { + config_setting_t *setting; + int i,j,status; + char *listpath=NULL; + char cfgpath[MAX_OPTNAME_SIZE*2 + 6]; /* prefix.listname.[listindex] */ - if (prefix != NULL) - { - i=asprintf(&listpath ,"%s.%s",prefix,ParamList->listname); - } - else - { - i=asprintf(&listpath ,"%s",ParamList->listname); - } - setting = config_lookup(&(libconfig_privdata.cfg), listpath); - if ( setting) { - status = ParamList->numelt = config_setting_length(setting); - printf_params("[LIBCONFIG] %i %s in config file %s \n", - ParamList->numelt,listpath,libconfig_privdata.configfile ); + if (prefix != NULL) { + i=asprintf(&listpath ,"%s.%s",prefix,ParamList->listname); + } else { + i=asprintf(&listpath ,"%s",ParamList->listname); + } + + setting = config_lookup(&(libconfig_privdata.cfg), listpath); + + if ( setting) { + status = ParamList->numelt = config_setting_length(setting); + printf_params("[LIBCONFIG] %i %s in config file %s \n", + ParamList->numelt,listpath,libconfig_privdata.configfile ); + } else { + printf("[LIBCONFIG] list %s not found in config file %s \n", + listpath,libconfig_privdata.configfile ); + ParamList->numelt= 0; + status = -1; + } + + if (ParamList->numelt > 0 && params != NULL) { + ParamList->paramarray = malloc(ParamList->numelt * sizeof(paramdef_t *)); + + if ( ParamList->paramarray != NULL) { + config_get_if()->ptrs[config_get_if()->numptrs] = (char *)(ParamList->paramarray); + config_get_if()->numptrs++; } else { - printf("[LIBCONFIG] list %s not found in config file %s \n", - listpath,libconfig_privdata.configfile ); - ParamList->numelt= 0; - status = -1; + fprintf (stderr,"[LIBCONFIG] %s %d malloc error\n",__FILE__, __LINE__); + exit(-1); } - if (ParamList->numelt > 0 && params != NULL) { - ParamList->paramarray = malloc(ParamList->numelt * sizeof(paramdef_t *)); - if ( ParamList->paramarray != NULL) { - config_get_if()->ptrs[config_get_if()->numptrs] = (char *)(ParamList->paramarray); - config_get_if()->numptrs++; - } else { - fprintf (stderr,"[LIBCONFIG] %s %d malloc error\n",__FILE__, __LINE__); - exit(-1); - } - for (i=0 ; i < ParamList->numelt ; i++) { - ParamList->paramarray[i] = malloc(numparams * sizeof(paramdef_t)); - if ( ParamList->paramarray[i] != NULL) { - config_get_if()->ptrs[config_get_if()->numptrs] = (char *)(ParamList->paramarray[i]); - config_get_if()->numptrs++; - } else { - fprintf (stderr,"[LIBCONFIG] %s %d malloc error\n",__FILE__, __LINE__); - exit(-1); - } - - memcpy(ParamList->paramarray[i], params, sizeof(paramdef_t)*numparams); - for (j=0;jparamarray[i][j].strptr = NULL ; - } - sprintf(cfgpath,"%s.[%i]",listpath,i); - config_libconfig_get(ParamList->paramarray[i], numparams, cfgpath ); - } /* for i... */ - } /* ParamList->numelt > 0 && params != NULL */ - if (listpath != NULL) - free(listpath); - return status; + + for (i=0 ; i < ParamList->numelt ; i++) { + ParamList->paramarray[i] = malloc(numparams * sizeof(paramdef_t)); + + if ( ParamList->paramarray[i] != NULL) { + config_get_if()->ptrs[config_get_if()->numptrs] = (char *)(ParamList->paramarray[i]); + config_get_if()->numptrs++; + } else { + fprintf (stderr,"[LIBCONFIG] %s %d malloc error\n",__FILE__, __LINE__); + exit(-1); + } + + memcpy(ParamList->paramarray[i], params, sizeof(paramdef_t)*numparams); + + for (j=0; jparamarray[i][j].strptr = NULL ; + } + + sprintf(cfgpath,"%s.[%i]",listpath,i); + config_libconfig_get(ParamList->paramarray[i], numparams, cfgpath ); + } /* for i... */ + } /* ParamList->numelt > 0 && params != NULL */ + + if (listpath != NULL) + free(listpath); + + return status; } -int config_libconfig_init(char *cfgP[], int numP) -{ +int config_libconfig_init(char *cfgP[], int numP) { config_init(&(libconfig_privdata.cfg)); libconfig_privdata.configfile = strdup((char *)cfgP[0]); config_get_if()->numptrs=0; @@ -317,24 +350,22 @@ int config_libconfig_init(char *cfgP[], int numP) /* Read the file. If there is an error, report it and exit. */ if(! config_read_file(&(libconfig_privdata.cfg), libconfig_privdata.configfile)) { fprintf(stderr,"[LIBCONFIG] %s %d file %s - %d - %s\n",__FILE__, __LINE__, - libconfig_privdata.configfile, config_error_line(&(libconfig_privdata.cfg)), - config_error_text(&(libconfig_privdata.cfg))); + libconfig_privdata.configfile, config_error_line(&(libconfig_privdata.cfg)), + config_error_text(&(libconfig_privdata.cfg))); config_destroy(&(libconfig_privdata.cfg)); printf( "\n"); return -1; } - return 0; } -void config_libconfig_end(void ) -{ +void config_libconfig_end(void ) { config_destroy(&(libconfig_privdata.cfg)); + if ( libconfig_privdata.configfile != NULL ) { - free(libconfig_privdata.configfile); - libconfig_privdata.configfile=NULL; - } - + free(libconfig_privdata.configfile); + libconfig_privdata.configfile=NULL; + } } diff --git a/targets/RT/USER/lte-softmodem.c b/targets/RT/USER/lte-softmodem.c index 5dde1034a4..2ded10d3b0 100644 --- a/targets/RT/USER/lte-softmodem.c +++ b/targets/RT/USER/lte-softmodem.c @@ -689,7 +689,7 @@ int main( int argc, char **argv ) { #if T_TRACER T_Config_Init(); #endif - ret=config_check_cmdlineopt(NULL); + ret=config_check_unknown_cmdlineopt(NULL); if (ret != 0) { LOG_E(ENB_APP, "%i unknown options in command line\n",ret); @@ -938,7 +938,7 @@ int main( int argc, char **argv ) { sync_var=0; pthread_cond_broadcast(&sync_cond); pthread_mutex_unlock(&sync_mutex); - ret=config_check_cmdlineopt(CONFIG_CHECKALLSECTIONS); + ret=config_check_unknown_cmdlineopt(CONFIG_CHECKALLSECTIONS); if (ret != 0) { LOG_E(ENB_APP, "%i unknown options in command line (invalid section name)\n",ret); diff --git a/targets/RT/USER/lte-uesoftmodem.c b/targets/RT/USER/lte-uesoftmodem.c index 1cd0b24f81..38937226e5 100644 --- a/targets/RT/USER/lte-uesoftmodem.c +++ b/targets/RT/USER/lte-uesoftmodem.c @@ -1010,7 +1010,7 @@ int main( int argc, char **argv ) { } #endif - ret=config_check_cmdlineopt(CONFIG_CHECKALLSECTIONS); + ret=config_check_unknown_cmdlineopt(CONFIG_CHECKALLSECTIONS); if (ret != 0) { LOG_E(ENB_APP, "%i unknown options in command line (invalid section name)\n",ret); From 7308f1da98fa89fb8a0f8eb3713e7f9acc376773 Mon Sep 17 00:00:00 2001 From: Raphael Defosseux Date: Tue, 15 Jan 2019 12:12:21 +0100 Subject: [PATCH 219/233] CI: updating the IF4p5 conf files w/ same values as in monolithic also disabling LLL realtime issues as an error until PRACH allocation is fixed Signed-off-by: Raphael Defosseux --- .../conf_files/rcc.band7.tm1.if4p5.lo.100PRB.usrpb210.conf | 6 +++--- .../conf_files/rcc.band7.tm1.if4p5.lo.25PRB.usrpb210.conf | 6 +++--- .../conf_files/rcc.band7.tm1.if4p5.lo.50PRB.usrpb210.conf | 6 +++--- ci-scripts/main.py | 3 ++- 4 files changed, 11 insertions(+), 10 deletions(-) diff --git a/ci-scripts/conf_files/rcc.band7.tm1.if4p5.lo.100PRB.usrpb210.conf b/ci-scripts/conf_files/rcc.band7.tm1.if4p5.lo.100PRB.usrpb210.conf index fc2f24b8a1..6c80a4f7cf 100644 --- a/ci-scripts/conf_files/rcc.band7.tm1.if4p5.lo.100PRB.usrpb210.conf +++ b/ci-scripts/conf_files/rcc.band7.tm1.if4p5.lo.100PRB.usrpb210.conf @@ -200,8 +200,8 @@ MACRLCs = ( tr_s_preference = "local_L1"; tr_n_preference = "local_RRC"; phy_test_mode = 0; - puSch10xSnr = 200; - puCch10xSnr = 200; + puSch10xSnr = 160; + puCch10xSnr = 160; } ); @@ -234,7 +234,7 @@ RUs = ( THREAD_STRUCT = ( { #three config for level of parallelism "PARALLEL_SINGLE_THREAD", "PARALLEL_RU_L1_SPLIT", or "PARALLEL_RU_L1_TRX_SPLIT" - parallel_config = "PARALLEL_RU_L1_TRX_SPLIT"; + parallel_config = "PARALLEL_SINGLE_THREAD"; #two option for worker "WORKER_DISABLE" or "WORKER_ENABLE" worker_config = "WORKER_ENABLE"; } diff --git a/ci-scripts/conf_files/rcc.band7.tm1.if4p5.lo.25PRB.usrpb210.conf b/ci-scripts/conf_files/rcc.band7.tm1.if4p5.lo.25PRB.usrpb210.conf index 010ef28061..f4be50810c 100644 --- a/ci-scripts/conf_files/rcc.band7.tm1.if4p5.lo.25PRB.usrpb210.conf +++ b/ci-scripts/conf_files/rcc.band7.tm1.if4p5.lo.25PRB.usrpb210.conf @@ -200,8 +200,8 @@ MACRLCs = ( tr_s_preference = "local_L1"; tr_n_preference = "local_RRC"; phy_test_mode = 0; - puSch10xSnr = 200; - puCch10xSnr = 200; + puSch10xSnr = 160; + puCch10xSnr = 160; } ); @@ -234,7 +234,7 @@ RUs = ( THREAD_STRUCT = ( { #three config for level of parallelism "PARALLEL_SINGLE_THREAD", "PARALLEL_RU_L1_SPLIT", or "PARALLEL_RU_L1_TRX_SPLIT" - parallel_config = "PARALLEL_RU_L1_TRX_SPLIT"; + parallel_config = "PARALLEL_SINGLE_THREAD"; #two option for worker "WORKER_DISABLE" or "WORKER_ENABLE" worker_config = "WORKER_ENABLE"; } diff --git a/ci-scripts/conf_files/rcc.band7.tm1.if4p5.lo.50PRB.usrpb210.conf b/ci-scripts/conf_files/rcc.band7.tm1.if4p5.lo.50PRB.usrpb210.conf index ddf01096cd..48c8370b4b 100644 --- a/ci-scripts/conf_files/rcc.band7.tm1.if4p5.lo.50PRB.usrpb210.conf +++ b/ci-scripts/conf_files/rcc.band7.tm1.if4p5.lo.50PRB.usrpb210.conf @@ -200,8 +200,8 @@ MACRLCs = ( tr_s_preference = "local_L1"; tr_n_preference = "local_RRC"; phy_test_mode = 0; - puSch10xSnr = 200; - puCch10xSnr = 200; + puSch10xSnr = 160; + puCch10xSnr = 160; } ); @@ -234,7 +234,7 @@ RUs = ( THREAD_STRUCT = ( { #three config for level of parallelism "PARALLEL_SINGLE_THREAD", "PARALLEL_RU_L1_SPLIT", or "PARALLEL_RU_L1_TRX_SPLIT" - parallel_config = "PARALLEL_RU_L1_TRX_SPLIT"; + parallel_config = "PARALLEL_SINGLE_THREAD"; #two option for worker "WORKER_DISABLE" or "WORKER_ENABLE" worker_config = "WORKER_ENABLE"; } diff --git a/ci-scripts/main.py b/ci-scripts/main.py index 710e06c2c2..97652736c0 100644 --- a/ci-scripts/main.py +++ b/ci-scripts/main.py @@ -1716,7 +1716,8 @@ class SSHConnection(): return ENB_PROCESS_ASSERTION if foundRealTimeIssue: logging.debug('\u001B[1;37;41m eNB faced real time issues! \u001B[0m') - return ENB_PROCESS_REALTIME_ISSUE + self.htmleNBFailureMsg += 'eNB faced real time issues!\n' + #return ENB_PROCESS_REALTIME_ISSUE if rlcDiscardBuffer > 0: rlcMsg = 'eNB RLC discarded ' + str(rlcDiscardBuffer) + ' buffer(s)' logging.debug('\u001B[1;37;41m ' + rlcMsg + ' \u001B[0m') From 1de4a57e7bd05c2caed49a15c88b3395fb1c7ff3 Mon Sep 17 00:00:00 2001 From: Raphael Defosseux Date: Tue, 15 Jan 2019 16:26:31 +0100 Subject: [PATCH 220/233] CI: modified also RRU config Signed-off-by: Raphael Defosseux --- ci-scripts/conf_files/rru.fdd.band7.conf | 2 +- ci-scripts/main.py | 2 +- .../xml_files/enb_usrp210_band7_test_20mhz_tm1.xml | 12 ++++++------ .../xml_files/if4p5_usrp210_band7_test_10mhz.xml | 6 +++--- .../xml_files/if4p5_usrp210_band7_test_20mhz.xml | 8 ++++---- 5 files changed, 15 insertions(+), 15 deletions(-) diff --git a/ci-scripts/conf_files/rru.fdd.band7.conf b/ci-scripts/conf_files/rru.fdd.band7.conf index ff5e13908e..dab69e1f1e 100644 --- a/ci-scripts/conf_files/rru.fdd.band7.conf +++ b/ci-scripts/conf_files/rru.fdd.band7.conf @@ -20,7 +20,7 @@ RUs = ( THREAD_STRUCT = ( { #three config for level of parallelism "PARALLEL_SINGLE_THREAD", "PARALLEL_RU_L1_SPLIT", or "PARALLEL_RU_L1_TRX_SPLIT" - parallel_config = "PARALLEL_RU_L1_TRX_SPLIT"; + parallel_config = "PARALLEL_SINGLE_THREAD"; #two option for worker "WORKER_DISABLE" or "WORKER_ENABLE" worker_config = "WORKER_ENABLE"; } diff --git a/ci-scripts/main.py b/ci-scripts/main.py index 97652736c0..7774a92de5 100644 --- a/ci-scripts/main.py +++ b/ci-scripts/main.py @@ -206,7 +206,7 @@ class SSHConnection(): count = 0 copy_status = False logging.debug('scp '+ username + '@' + ipaddress + ':' + source + ' ' + destination) - while count < 4: + while count < 10: scp_spawn = pexpect.spawn('scp '+ username + '@' + ipaddress + ':' + source + ' ' + destination, timeout = 5) scp_response = scp_spawn.expect(['Are you sure you want to continue connecting (yes/no)?', 'password:', pexpect.EOF, pexpect.TIMEOUT]) if scp_response == 0: diff --git a/ci-scripts/xml_files/enb_usrp210_band7_test_20mhz_tm1.xml b/ci-scripts/xml_files/enb_usrp210_band7_test_20mhz_tm1.xml index 68b3829682..b6c441b19a 100644 --- a/ci-scripts/xml_files/enb_usrp210_band7_test_20mhz_tm1.xml +++ b/ci-scripts/xml_files/enb_usrp210_band7_test_20mhz_tm1.xml @@ -26,9 +26,9 @@ tasks 040101 - 030121 040301 040521 040623 040624 040625 040626 040627 040662 040661 040663 040664 040401 040201 030201 + 030121 040301 040521 040623 040624 040625 040662 040401 040201 030201 - + 040626 040627 040661 040663 040664 Initialize_eNB @@ -110,16 +110,16 @@ Iperf - iperf (20MHz - UL/20Mbps/UDP)(30 sec)(balanced profile) - -u -b 20M -t 30 -i 1 -R + iperf (20MHz - UL/12Mbps/UDP)(30 sec)(balanced profile) + -u -b 12M -t 30 -i 1 -R 50 balanced Iperf - iperf (20MHz - UL/20Mbps/UDP)(30 sec)(single-ue profile) - -u -b 20M -t 30 -i 1 -R + iperf (20MHz - UL/17Mbps/UDP)(30 sec)(single-ue profile) + -u -b 17M -t 30 -i 1 -R 50 single-ue diff --git a/ci-scripts/xml_files/if4p5_usrp210_band7_test_10mhz.xml b/ci-scripts/xml_files/if4p5_usrp210_band7_test_10mhz.xml index 340d33196a..88fb30b840 100644 --- a/ci-scripts/xml_files/if4p5_usrp210_band7_test_10mhz.xml +++ b/ci-scripts/xml_files/if4p5_usrp210_band7_test_10mhz.xml @@ -94,9 +94,9 @@ Iperf - iperf (10MHz - UL/20Mbps/UDP)(30 sec)(single-ue profile) - -u -b 20M -t 30 -i 1 -R - 50 + iperf (10MHz - UL/5Mbps/UDP)(30 sec)(single-ue profile) + -u -b 5M -t 30 -i 1 -R + 60 single-ue diff --git a/ci-scripts/xml_files/if4p5_usrp210_band7_test_20mhz.xml b/ci-scripts/xml_files/if4p5_usrp210_band7_test_20mhz.xml index 5d8646cd5e..798fc1bc8f 100644 --- a/ci-scripts/xml_files/if4p5_usrp210_band7_test_20mhz.xml +++ b/ci-scripts/xml_files/if4p5_usrp210_band7_test_20mhz.xml @@ -86,16 +86,16 @@ Iperf - iperf (20MHz - DL/70Mbps/UDP)(30 sec)(single-ue profile) - -u -b 70M -t 30 -i 1 + iperf (20MHz - DL/50Mbps/UDP)(30 sec)(single-ue profile) + -u -b 50M -t 30 -i 1 50 single-ue Iperf - iperf (20MHz - UL/20Mbps/UDP)(30 sec)(single-ue profile) - -u -b 20M -t 30 -i 1 -R + iperf (20MHz - UL/10Mbps/UDP)(30 sec)(single-ue profile) + -u -b 10M -t 30 -i 1 -R 50 single-ue From 7d715cd4bc2696e503166d6fab7dc727f424d351 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Tue, 15 Jan 2019 17:34:59 +0100 Subject: [PATCH 221/233] fix UE configuration file (for CI) --- openair3/NAS/TOOLS/ue_eurecom_test_sfr.conf | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/openair3/NAS/TOOLS/ue_eurecom_test_sfr.conf b/openair3/NAS/TOOLS/ue_eurecom_test_sfr.conf index 679b9584d6..33405805a6 100644 --- a/openair3/NAS/TOOLS/ue_eurecom_test_sfr.conf +++ b/openair3/NAS/TOOLS/ue_eurecom_test_sfr.conf @@ -86,14 +86,9 @@ UE0: }; SIM: { - #MSIN="0100001111"; - #USIM_API_K="8baf473f2f8fd09487cccbd7097c6862"; - #OPC="e734f8734007d6c5ce7a0508809e7e9c"; - #MSISDN="33611123456"; - - MSIN="0000000001"; - USIM_API_K="fec86ba6eb707ed08905757b1bb44b8f"; #Amerique-ltebox - OPC="C42449363BBAD02B66D16BC975D77CC1"; + MSIN="0100001111"; + USIM_API_K="8baf473f2f8fd09487cccbd7097c6862"; + OPC="e734f8734007d6c5ce7a0508809e7e9c"; MSISDN="33611123456"; }; From 6bb767487717a3dd3ccce81ed449e92e7b8769f7 Mon Sep 17 00:00:00 2001 From: Raphael Defosseux Date: Wed, 16 Jan 2019 14:25:38 +0100 Subject: [PATCH 222/233] Fixing usage of old structure/field names --> temporary as old code is kept in comment Signed-off-by: Raphael Defosseux --- targets/RT/USER/lte-enb.c | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/targets/RT/USER/lte-enb.c b/targets/RT/USER/lte-enb.c index 55043bba31..d1296a8bdb 100755 --- a/targets/RT/USER/lte-enb.c +++ b/targets/RT/USER/lte-enb.c @@ -164,7 +164,9 @@ static inline int rxtx(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc, char *thread_name // ******************************************************************* +#if defined(PRE_SCD_THREAD) RU_t *ru = RC.ru[0]; +#endif if (nfapi_mode == 1) { // I am a PNF and I need to let nFAPI know that we have a (sub)frame tick @@ -218,6 +220,8 @@ static inline int rxtx(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc, char *thread_name phy_procedures_eNB_uespec_RX(eNB, proc); } +#if 0 + // Original Code from Fujitsu w/ old structure/field name if(get_thread_parallel_conf() == PARALLEL_RU_L1_TRX_SPLIT && nfapi_mode != 2){ if(wait_on_condition(&proc[1].mutex_rxtx,&proc[1].cond_rxtx,&proc[1].pipe_ready,"wakeup_tx")<0) { LOG_E(PHY,"Frame %d, subframe %d: TX1 not ready\n",proc[1].frame_rx,proc[1].subframe_rx); @@ -225,6 +229,14 @@ static inline int rxtx(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc, char *thread_name } if (release_thread(&proc[1].mutex_rxtx,&proc[1].pipe_ready,"wakeup_tx")<0) return(-1); } +#endif + if(get_thread_parallel_conf() == PARALLEL_RU_L1_TRX_SPLIT && nfapi_mode != 2){ + if (wait_on_condition(&proc->mutex,&proc->cond,&proc->instance_cnt, "wakeup_tx")<0) { + LOG_E(PHY,"Frame %d, subframe %d: TX1 not ready\n",proc->frame_rx,proc->subframe_rx); + return(-1); + } + if (release_thread(&proc->mutex,&proc->instance_cnt,"wakeup_tx")<0) return(-1); + } VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ULSCH_SCHEDULER, 1 ); @@ -951,8 +963,11 @@ void init_eNB_proc(int inst) { pthread_create( &L1_proc->pthread, attr0, L1_thread, proc ); pthread_create( &L1_proc_tx->pthread, attr1, L1_thread_tx, proc); } else if (nfapi_mode == 2) { // this is neccesary in VNF or L2 FAPI simulator. - pthread_create( &proc_rxtx[0].pthread_rxtx, attr0, eNB_thread_rxtx, &proc_rxtx[0] ); - pthread_create( &proc_rxtx[1].pthread_rxtx, attr1, eNB_thread_rxtx, &proc_rxtx[1] ); + // Original Code from Fujitsu w/ old structure/field name + //pthread_create( &proc_rxtx[0].pthread_rxtx, attr0, eNB_thread_rxtx, &proc_rxtx[0] ); + //pthread_create( &proc_rxtx[1].pthread_rxtx, attr1, eNB_thread_rxtx, &proc_rxtx[1] ); + pthread_create( &L1_proc->pthread, attr0, L1_thread, proc ); + pthread_create( &L1_proc_tx->pthread, attr1, L1_thread, proc); } pthread_create( &proc->pthread_prach, attr_prach, eNB_thread_prach, eNB ); From c12dfe19db2336527de2d871ec9b48e08bc6a043 Mon Sep 17 00:00:00 2001 From: Raphael Defosseux Date: Wed, 16 Jan 2019 15:54:39 +0100 Subject: [PATCH 223/233] Fix in the UE side Signed-off-by: Raphael Defosseux --- targets/RT/USER/lte-uesoftmodem.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/targets/RT/USER/lte-uesoftmodem.c b/targets/RT/USER/lte-uesoftmodem.c index e2cdb88ae9..07b411e262 100755 --- a/targets/RT/USER/lte-uesoftmodem.c +++ b/targets/RT/USER/lte-uesoftmodem.c @@ -728,7 +728,6 @@ int main( int argc, char **argv ) { #endif int CC_id; uint8_t abstraction_flag=0; - unsigned int start_msc=0; #ifdef PDCP_USE_NETLINK #ifdef UESIM_EXPANSION memset(inst_pdcp_list, 0, sizeof(inst_pdcp_list)); @@ -1001,12 +1000,12 @@ int main( int argc, char **argv ) { init_UE_stub_single_thread(NB_UE_INST,eMBMS_active,uecap_xer_in,emul_iface); } else { - init_UE(NB_UE_INST,eMBMS_active,uecap_xer_in,0,phy_test,UE_scan,UE_scan_carrier,mode,(int)rx_gain[0][0],tx_max_power[0], + init_UE(NB_UE_INST,eMBMS_active,uecap_xer_in,0,get_softmodem_params()->phy_test,UE_scan,UE_scan_carrier,mode,(int)rx_gain[0][0],tx_max_power[0], frame_parms[0]); } - if (phy_test==0) { + if (get_softmodem_params()->phy_test==0) { printf("Filling UE band info\n"); fill_ue_band_info(); dl_phy_sync_success (0, 0, 0, 1); @@ -1016,7 +1015,7 @@ int main( int argc, char **argv ) { number_of_cards = 1; for(CC_id=0; CC_idrf_map.card=0; - PHY_vars_UE_g[0][CC_id]->rf_map.chain=CC_id+chain_offset; + PHY_vars_UE_g[0][CC_id]->rf_map.chain=CC_id+(get_softmodem_params()->chain_offset); } } // connect the TX/RX buffers From bf25aba22752486418e0ed1130953a13e91817ab Mon Sep 17 00:00:00 2001 From: Raphael Defosseux Date: Wed, 16 Jan 2019 17:24:04 +0100 Subject: [PATCH 224/233] CI: adding eNB characteristics to HTML report Signed-off-by: Raphael Defosseux --- ci-scripts/Jenkinsfile-tmp-ran | 2 +- ci-scripts/main.py | 69 +++++++++++++++++++++++++++++++--- 2 files changed, 64 insertions(+), 7 deletions(-) diff --git a/ci-scripts/Jenkinsfile-tmp-ran b/ci-scripts/Jenkinsfile-tmp-ran index 547970e45e..39347b3558 100644 --- a/ci-scripts/Jenkinsfile-tmp-ran +++ b/ci-scripts/Jenkinsfile-tmp-ran @@ -218,7 +218,7 @@ pipeline { buildStageStatus = false } } - sh "python3 main.py --mode=FinalizeHtml --finalStatus=${buildStageStatus}" + sh "python3 main.py --mode=FinalizeHtml --finalStatus=${buildStageStatus} --eNBIPAddress=${params.eNB_IPAddress} --eNBUserName=${eNB_Username} --eNBPassword=${eNB_Password}" } } } diff --git a/ci-scripts/main.py b/ci-scripts/main.py index 7774a92de5..7e18ba7c6e 100644 --- a/ci-scripts/main.py +++ b/ci-scripts/main.py @@ -118,6 +118,12 @@ class SSHConnection(): self.htmlTabNames = [] self.htmlTabIcons = [] self.finalStatus = False + self.eNBOsVersion = '' + self.eNBKernelVersion = '' + self.eNBUhdVersion = '' + self.eNBCpuNb = '' + self.eNBCpuModel = '' + self.eNBCpuMHz = '' def open(self, ipaddress, username, password): count = 0 @@ -1947,6 +1953,37 @@ class SSHConnection(): self.command('cp /opt/ltebox/var/log/xGwLog.0 .', '\$', 5) self.command('zip spgw.log.zip xGwLog.0', '\$', 60) self.close() + def RetrieveSystemVersion(self): + if self.eNBIPAddress == '' or self.eNBUserName == '' or self.eNBPassword == '': + Usage() + sys.exit('Insufficient Parameter') + self.open(self.eNBIPAddress, self.eNBUserName, self.eNBPassword) + self.command('lsb_release -a', '\$', 5) + result = re.search('Description:\\\\t(?P[a-zA-Z0-9\-\_\.\ ]+)', str(self.ssh.before)) + if result is not None: + self.eNBOsVersion = result.group('os_type') + logging.debug('OS is: ' + self.eNBOsVersion) + self.command('uname -r', '\$', 5) + result = re.search('uname -r\\\\r\\\\n(?P[a-zA-Z0-9\-\_\.]+)', str(self.ssh.before)) + if result is not None: + self.eNBKernelVersion = result.group('kernel_version') + logging.debug('Kernel Version is: ' + self.eNBKernelVersion) + self.command('dpkg --list | egrep --color=never uhd-host', '\$', 5) + result = re.search('uhd-host *(?P[0-9\.]+)', str(self.ssh.before)) + if result is not None: + self.eNBUhdVersion = result.group('uhd_version') + logging.debug('UHD Version is: ' + self.eNBUhdVersion) + self.command('lscpu', '\$', 5) + result = re.search('CPU\(s\): *(?P[0-9]+).*Model name: *(?P[a-zA-Z0-9\-\_\.\ \(\)]+).*CPU MHz: *(?P[0-9\.]+)', str(self.ssh.before)) + if result is not None: + self.eNBCpuNb = result.group('nb_cpus') + logging.debug('nb_cpus: ' + self.eNBCpuNb) + self.eNBCpuModel = result.group('model') + logging.debug('model: ' + self.eNBCpuModel) + self.eNBCpuMHz = result.group('cpu_mhz') + ' MHz' + logging.debug('cpu_mhz: ' + self.eNBCpuMHz) + self.close() + #----------------------------------------------------------- # HTML Reporting.... #----------------------------------------------------------- @@ -2097,17 +2134,37 @@ class SSHConnection(): def CreateHtmlFooter(self, passStatus): if (os.path.isfile('test_results.html')): + self.RetrieveSystemVersion() self.htmlFile = open('test_results.html', 'a') self.htmlFile.write('\n') self.htmlFile.write('

    \n') - self.htmlFile.write('
    Build Start Time (UTC)
    GIT Repository$GIT_URL$GIT_URL
    Job Trigger
    Final Tab StatusPASS
    \n') - self.htmlFile.write(' \n') - self.htmlFile.write(' \n') + self.htmlFile.write('
    Final Status
    \n') + self.htmlFile.write(' \n') + self.htmlFile.write(' \n') + self.htmlFile.write(' \n') + self.htmlFile.write(' \n') + self.htmlFile.write(' \n') + self.htmlFile.write(' \n') + self.htmlFile.write(' \n') + self.htmlFile.write(' \n') + self.htmlFile.write(' \n') + self.htmlFile.write(' \n') + self.htmlFile.write(' \n') + self.htmlFile.write(' \n') + self.htmlFile.write(' \n') + self.htmlFile.write(' \n') + self.htmlFile.write(' \n') + self.htmlFile.write(' \n') + self.htmlFile.write(' \n') + self.htmlFile.write(' \n') + self.htmlFile.write(' \n') + self.htmlFile.write(' \n') + self.htmlFile.write(' \n') if passStatus: - self.htmlFile.write(' \n') + self.htmlFile.write(' \n') else: - self.htmlFile.write(' \n') - self.htmlFile.write(' \n') + self.htmlFile.write(' \n') + self.htmlFile.write(' \n') self.htmlFile.write('
    eNB Server Characteristics
    OS Version' + self.eNBOsVersion + 'Kernel Version' + self.eNBKernelVersion + 'UHD Version' + self.eNBUhdVersion + '
    Nb CPUs' + self.eNBCpuNb + 'CPU Model Name' + self.eNBCpuModel + 'CPU Frequency' + self.eNBCpuMHz + '
    Final StatusPASS PASS FAIL FAIL
    \n') self.htmlFile.write('

    \n') self.htmlFile.write('
    End of Test Report -- Copyright 2018 OpenAirInterface. All Rights Reserved.
    \n') From 161aeebaaa8bb54c0ffbed6ade709c87c67e9da0 Mon Sep 17 00:00:00 2001 From: frtabu Date: Wed, 16 Jan 2019 17:57:54 +0100 Subject: [PATCH 225/233] attempt to fix TDD basic_simulator failure --- targets/ARCH/tcp_bridge/tcp_bridge_oai.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/targets/ARCH/tcp_bridge/tcp_bridge_oai.c b/targets/ARCH/tcp_bridge/tcp_bridge_oai.c index b06d327da2..b0f131de91 100644 --- a/targets/ARCH/tcp_bridge/tcp_bridge_oai.c +++ b/targets/ARCH/tcp_bridge/tcp_bridge_oai.c @@ -58,6 +58,7 @@ typedef struct { int sock; int samples_per_subframe; uint64_t timestamp; + uint64_t next_tx_timestamp; int is_enb; char *ip; } tcp_bridge_state_t; @@ -192,6 +193,26 @@ int tcp_bridge_write(openair0_device *device, openair0_timestamp timestamp, void } tcp_bridge_state_t *t = device->priv; + + /* deal with discontinuities in output (think: eNB in TDD mode) */ + if (t->next_tx_timestamp && timestamp != t->next_tx_timestamp) { + uint32_t b[4096]; + uint64_t to_send = timestamp - t->next_tx_timestamp; + memset(b, 0, 4096 * sizeof(uint32_t)); + + while (to_send) { + int len = to_send > 4096 ? 4096 : to_send; + int n = fullwrite(t->sock, b, len * 4); + + if (n != len * 4) { + printf("tcp_bridge: write error ret %d error %s\n", n, strerror(errno)); + abort(); + } + + to_send -= len; + } + } + int n = fullwrite(t->sock, buff[0], nsamps * 4); if (n != nsamps * 4) { @@ -199,6 +220,7 @@ int tcp_bridge_write(openair0_device *device, openair0_timestamp timestamp, void abort(); } + t->next_tx_timestamp = timestamp + nsamps; return nsamps; } From d62f8f93495e7cc00dfa645bc76e5b787cd26cde Mon Sep 17 00:00:00 2001 From: Raphael Defosseux Date: Thu, 17 Jan 2019 13:07:07 +0100 Subject: [PATCH 226/233] Fix merge: removed very old code Signed-off-by: Raphael Defosseux --- targets/RT/USER/lte-enb.c | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/targets/RT/USER/lte-enb.c b/targets/RT/USER/lte-enb.c index d1296a8bdb..0268ff0747 100755 --- a/targets/RT/USER/lte-enb.c +++ b/targets/RT/USER/lte-enb.c @@ -220,24 +220,6 @@ static inline int rxtx(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc, char *thread_name phy_procedures_eNB_uespec_RX(eNB, proc); } -#if 0 - // Original Code from Fujitsu w/ old structure/field name - if(get_thread_parallel_conf() == PARALLEL_RU_L1_TRX_SPLIT && nfapi_mode != 2){ - if(wait_on_condition(&proc[1].mutex_rxtx,&proc[1].cond_rxtx,&proc[1].pipe_ready,"wakeup_tx")<0) { - LOG_E(PHY,"Frame %d, subframe %d: TX1 not ready\n",proc[1].frame_rx,proc[1].subframe_rx); - return(-1); - } - if (release_thread(&proc[1].mutex_rxtx,&proc[1].pipe_ready,"wakeup_tx")<0) return(-1); - } -#endif - if(get_thread_parallel_conf() == PARALLEL_RU_L1_TRX_SPLIT && nfapi_mode != 2){ - if (wait_on_condition(&proc->mutex,&proc->cond,&proc->instance_cnt, "wakeup_tx")<0) { - LOG_E(PHY,"Frame %d, subframe %d: TX1 not ready\n",proc->frame_rx,proc->subframe_rx); - return(-1); - } - if (release_thread(&proc->mutex,&proc->instance_cnt,"wakeup_tx")<0) return(-1); - } - VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ULSCH_SCHEDULER, 1 ); #if defined(PRE_SCD_THREAD) From eb92fa917b13782507a17fa7ff4d5b061ef0e28e Mon Sep 17 00:00:00 2001 From: matzakos Date: Thu, 17 Jan 2019 15:29:15 +0100 Subject: [PATCH 227/233] Fixed eNB threading issues creating problems for nfapi emulator. --- nfapi/open-nFAPI/pnf/src/pnf.c | 2 +- nfapi/open-nFAPI/pnf/src/pnf_p7.c | 2 +- nfapi/open-nFAPI/vnf/src/vnf_p7.c | 4 +-- .../CONF/rcc.band7.tm1.50PRB.nfapi.conf | 26 +++++++++++++------ targets/RT/USER/lte-enb.c | 4 +-- 5 files changed, 24 insertions(+), 14 deletions(-) diff --git a/nfapi/open-nFAPI/pnf/src/pnf.c b/nfapi/open-nFAPI/pnf/src/pnf.c index d0a7fa6fd1..0cacf8c66f 100755 --- a/nfapi/open-nFAPI/pnf/src/pnf.c +++ b/nfapi/open-nFAPI/pnf/src/pnf.c @@ -1260,7 +1260,7 @@ int pnf_connect(pnf_t* pnf) address = inet_ntoa(addr->sin_addr); } - NFAPI_TRACE(NFAPI_TRACE_NOTE, "Host address info %d Family:%s Address:%s\n", i++, family, address); + //NFAPI_TRACE(NFAPI_TRACE_NOTE, "Host address info %d Family:%s Address:%s\n", i++, family, address); if (pnf->sctp) { diff --git a/nfapi/open-nFAPI/pnf/src/pnf_p7.c b/nfapi/open-nFAPI/pnf/src/pnf_p7.c index 8d94c23476..81abed81a9 100755 --- a/nfapi/open-nFAPI/pnf/src/pnf_p7.c +++ b/nfapi/open-nFAPI/pnf/src/pnf_p7.c @@ -379,7 +379,7 @@ static uint32_t get_sf_time(uint32_t now_hr, uint32_t sf_start_hr) { if(now_hr < sf_start_hr) { - NFAPI_TRACE(NFAPI_TRACE_INFO, "now is earlier than start of subframe now_hr:%u sf_start_hr:%u\n", now_hr, sf_start_hr); + //NFAPI_TRACE(NFAPI_TRACE_INFO, "now is earlier than start of subframe now_hr:%u sf_start_hr:%u\n", now_hr, sf_start_hr); return 0; } else diff --git a/nfapi/open-nFAPI/vnf/src/vnf_p7.c b/nfapi/open-nFAPI/vnf/src/vnf_p7.c index cea259c35b..4b7acabec3 100755 --- a/nfapi/open-nFAPI/vnf/src/vnf_p7.c +++ b/nfapi/open-nFAPI/vnf/src/vnf_p7.c @@ -1203,12 +1203,12 @@ void vnf_handle_ul_node_sync(void *pRecvMsg, int recvMsgLen, vnf_p7_t* vnf_p7) if(phy->in_sync == 0) { - NFAPI_TRACE(NFAPI_TRACE_NOTE, "***** Adjusting VNF phy_id:%d SFN/SF (%s) from %d to %d (%d) mode:%s zeroCount:%u sync:%s\n", + /*NFAPI_TRACE(NFAPI_TRACE_NOTE, "***** Adjusting VNF phy_id:%d SFN/SF (%s) from %d to %d (%d) mode:%s zeroCount:%u sync:%s\n", ind.header.phy_id, (phy->in_sync ? "via sfn" : "now"), NFAPI_SFNSF2DEC(curr_sfn_sf), NFAPI_SFNSF2DEC(new_sfn_sf), phy->adjustment, phy->filtered_adjust ? "FILTERED" : "ABSOLUTE", phy->zero_count, - phy->in_sync ? "IN_SYNC" : "OUT_OF_SYNC"); + phy->in_sync ? "IN_SYNC" : "OUT_OF_SYNC");*/ phy->sfn_sf = new_sfn_sf; } diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.50PRB.nfapi.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.50PRB.nfapi.conf index ced031163d..472d84c7e2 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.50PRB.nfapi.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/rcc.band7.tm1.50PRB.nfapi.conf @@ -172,7 +172,7 @@ eNBs = ////////// MME parameters: - mme_ip_address = ( { ipv4 = "127.0.0.3"; + mme_ip_address = ( { ipv4 = "192.168.12.26"; ipv6 = "192:168:30::17"; active = "yes"; preference = "ipv4"; @@ -181,14 +181,24 @@ eNBs = NETWORK_INTERFACES : { - ENB_INTERFACE_NAME_FOR_S1_MME = "lo"; - ENB_IPV4_ADDRESS_FOR_S1_MME = "127.0.0.2/24"; - ENB_INTERFACE_NAME_FOR_S1U = "lo"; - ENB_IPV4_ADDRESS_FOR_S1U = "127.0.0.5/24"; - ENB_PORT_FOR_S1U = 2152; # Spec 2152 + #ENB_INTERFACE_NAME_FOR_S1_MME = "lo"; + #ENB_IPV4_ADDRESS_FOR_S1_MME = "127.0.0.2/24"; + #ENB_INTERFACE_NAME_FOR_S1U = "lo"; + #ENB_IPV4_ADDRESS_FOR_S1U = "127.0.0.5/24"; + #ENB_PORT_FOR_S1U = 2152; # Spec 2152 - ENB_IPV4_ADDRESS_FOR_X2C = "127.0.0.2/24"; + #ENB_IPV4_ADDRESS_FOR_X2C = "127.0.0.2/24"; + #ENB_PORT_FOR_X2C = 36422; # Spec 36422 + + ENB_INTERFACE_NAME_FOR_S1_MME = "enp0s31f6"; + ENB_IPV4_ADDRESS_FOR_S1_MME = "192.168.12.188/24"; + ENB_INTERFACE_NAME_FOR_S1U = "enp0s31f6"; + ENB_IPV4_ADDRESS_FOR_S1U = "192.168.12.188/24"; + ENB_PORT_FOR_S1U = 2152; # Spec 2152 + + ENB_IPV4_ADDRESS_FOR_X2C = "192.168.12.188/24"; ENB_PORT_FOR_X2C = 36422; # Spec 36422 + }; } ); @@ -196,7 +206,7 @@ eNBs = MACRLCs = ( { num_cc = 1; - local_s_if_name = "lo"; + local_s_if_name = "lo:"; remote_s_address = "127.0.0.1"; local_s_address = "127.0.0.2"; local_s_portc = 50001; diff --git a/targets/RT/USER/lte-enb.c b/targets/RT/USER/lte-enb.c index 0268ff0747..9db1684bd2 100755 --- a/targets/RT/USER/lte-enb.c +++ b/targets/RT/USER/lte-enb.c @@ -948,8 +948,8 @@ void init_eNB_proc(int inst) { // Original Code from Fujitsu w/ old structure/field name //pthread_create( &proc_rxtx[0].pthread_rxtx, attr0, eNB_thread_rxtx, &proc_rxtx[0] ); //pthread_create( &proc_rxtx[1].pthread_rxtx, attr1, eNB_thread_rxtx, &proc_rxtx[1] ); - pthread_create( &L1_proc->pthread, attr0, L1_thread, proc ); - pthread_create( &L1_proc_tx->pthread, attr1, L1_thread, proc); + pthread_create( &L1_proc->pthread, attr0, L1_thread, L1_proc ); + pthread_create( &L1_proc_tx->pthread, attr1, L1_thread, L1_proc_tx); } pthread_create( &proc->pthread_prach, attr_prach, eNB_thread_prach, eNB ); From d0190899d27b79e5daa79a037b70ce7155285c60 Mon Sep 17 00:00:00 2001 From: Raphael Defosseux Date: Thu, 17 Jan 2019 23:09:10 +0100 Subject: [PATCH 228/233] Try out to comment added lines Signed-off-by: Raphael Defosseux --- openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c b/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c index 7cae1129a3..906fbaba5a 100755 --- a/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c +++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c @@ -174,9 +174,9 @@ int pdcp_fifo_flush_sdus(const protocol_ctxt_t* const ctxt_pP) // Raphael: was suppressed by Raymond --> should be suppressed? // value of sdu_p->data->inst is set in pdcp_data_ind // it's necessary to set 1 in case of UE with S1. - if (ctxt_pP->enb_flag){ - ((pdcp_data_ind_header_t *)(sdu_p->data))->inst = 0; - } + //if (ctxt_pP->enb_flag){ + // ((pdcp_data_ind_header_t *)(sdu_p->data))->inst = 0; + //} #endif #if defined(LINK_ENB_PDCP_TO_GTPV1U) From 458a50fb369de268faee3fb722bfb0938b8c9d94 Mon Sep 17 00:00:00 2001 From: Raphael Defosseux Date: Fri, 18 Jan 2019 13:59:53 +0100 Subject: [PATCH 229/233] CI: fixing finally the copyin network issue when retrieving eNB log file Signed-off-by: Raphael Defosseux --- ci-scripts/main.py | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/ci-scripts/main.py b/ci-scripts/main.py index 7e18ba7c6e..23e51960ca 100644 --- a/ci-scripts/main.py +++ b/ci-scripts/main.py @@ -42,6 +42,7 @@ ENB_PROCESS_OK = +1 ENB_PROCESS_SEG_FAULT = -11 ENB_PROCESS_ASSERTION = -12 ENB_PROCESS_REALTIME_ISSUE = -13 +ENB_PROCESS_NOLOGFILE_TO_ANALYZE = -14 HSS_PROCESS_FAILED = -2 HSS_PROCESS_OK = +2 MME_PROCESS_FAILED = -3 @@ -243,9 +244,9 @@ class SSHConnection(): time.sleep(1) count += 1 if copy_status: - pass + return 0 else: - sys.exit('SCP failed') + return -1 def copyout(self, ipaddress, username, password, source, destination): count = 0 @@ -466,8 +467,9 @@ class SSHConnection(): self.close() time.sleep(1) pcap_log_file = 'enb_' + self.testCase_id + '_s1log.pcap' - self.copyin(self.EPCIPAddress, self.EPCUserName, self.EPCPassword, '/tmp/' + pcap_log_file, '.') - self.copyout(self.eNBIPAddress, self.eNBUserName, self.eNBPassword, pcap_log_file, self.eNBSourceCodePath + '/cmake_targets/.') + copyin_res = self.copyin(self.EPCIPAddress, self.EPCUserName, self.EPCPassword, '/tmp/' + pcap_log_file, '.') + if (copyin_res == 0): + self.copyout(self.eNBIPAddress, self.eNBUserName, self.eNBPassword, pcap_log_file, self.eNBSourceCodePath + '/cmake_targets/.') sys.exit(1) else: self.command('stdbuf -o0 cat enb_' + self.testCase_id + '.log | egrep --text --color=never -i "wait|sync"', '\$', 4) @@ -1742,6 +1744,7 @@ class SSHConnection(): result = re.search('lte-softmodem', str(self.ssh.before)) if result is not None: self.command('echo ' + self.eNBPassword + ' | sudo -S killall --signal SIGKILL lte-softmodem || true', '\$', 5) + time.sleep(5) self.close() # If tracer options is on, stopping tshark on EPC side result = re.search('T_stdout', str(self.Initialize_eNB_args)) @@ -1774,7 +1777,13 @@ class SSHConnection(): else: result = re.search('enb_', str(self.eNBLogFile)) if result is not None: - self.copyin(self.eNBIPAddress, self.eNBUserName, self.eNBPassword, self.eNBSourceCodePath + '/cmake_targets/' + self.eNBLogFile, '.') + copyin_res = self.copyin(self.eNBIPAddress, self.eNBUserName, self.eNBPassword, self.eNBSourceCodePath + '/cmake_targets/' + self.eNBLogFile, '.') + if (copyin_res == -1): + logging.debug('\u001B[1;37;41m Could not copy eNB logfile to analyze it! \u001B[0m') + self.htmleNBFailureMsg = 'Could not copy eNB logfile to analyze it!' + self.CreateHtmlTestRow('N/A', 'KO', ENB_PROCESS_NOLOGFILE_TO_ANALYZE) + self.eNBLogFile = '' + return logging.debug('\u001B[1m Analyzing eNB logfile \u001B[0m') logStatus = self.AnalyzeLogFile_eNB(self.eNBLogFile) if (logStatus < 0): @@ -2190,7 +2199,9 @@ class SSHConnection(): elif (processesStatus == ENB_PROCESS_ASSERTION): self.htmlFile.write('
    KO - eNB process ended in AssertionKO - eNB process faced Real Time issue(s)/td>\n') + self.htmlFile.write(' KO - eNB process faced Real Time issue(s)OKKO - HSS process not found
    10000)]
    +        poll_pdu                 =  4;
    +
    +        # poll_byte = (kB) [25,50,75,100,125,250,375,500,750,1000,1250,1500,2000,3000,infinity(>10000)]
    +        poll_byte                =  99999;
    +
    +        # max_retx_threshold = [1, 2, 3, 4 , 6, 8, 16, 32]
    +        max_retx_threshold       =  4;
    +    }
    +
    +    # ------- SCTP definitions
    +    SCTP :
    +    {
    +        # Number of streams to use in input/output
    +        SCTP_INSTREAMS  = 2;
    +        SCTP_OUTSTREAMS = 2;
    +    };
    +
    +
    +    ////////// MME parameters:
    +    mme_ip_address      = ( { ipv4       = "CI_MME_IP_ADDR";
    +                              ipv6       = "192:168:30::17";
    +                              active     = "yes";
    +                              preference = "ipv4";
    +                            }
    +                          );
    +
    +    NETWORK_INTERFACES :
    +    {
    +        ENB_INTERFACE_NAME_FOR_S1_MME            = "ens3";
    +        ENB_IPV4_ADDRESS_FOR_S1_MME              = "CI_ENB_IP_ADDR";
    +        ENB_INTERFACE_NAME_FOR_S1U               = "ens3";
    +        ENB_IPV4_ADDRESS_FOR_S1U                 = "CI_ENB_IP_ADDR";
    +        ENB_PORT_FOR_S1U                         = 2152; # Spec 2152
    +        ENB_IPV4_ADDRESS_FOR_X2C                 = "CI_ENB_IP_ADDR";
    +        ENB_PORT_FOR_X2C                         = 36422; # Spec 36422
    +        
    +    };
    +  }
    +);
    +
    +MACRLCs = (
    +	{
    +	num_cc = 1;
    +      	local_s_if_name  = "lo:";			  
    +      	remote_s_address = "127.0.0.1";
    +    	local_s_address  = "127.0.0.2"; 
    +    	local_s_portc    = 50001;	
    +    	remote_s_portc   = 50000;
    +    	local_s_portd    = 50011;	
    +    	remote_s_portd   = 50010;
    +	tr_s_preference = "nfapi";
    +	tr_n_preference = "local_RRC";
    +        }  
    +);
    +
    +THREAD_STRUCT = (
    +  {
    +    #three config for level of parallelism "PARALLEL_SINGLE_THREAD", "PARALLEL_RU_L1_SPLIT", or "PARALLEL_RU_L1_TRX_SPLIT"
    +    parallel_config    = "PARALLEL_RU_L1_TRX_SPLIT";
    +    #two option for worker "WORKER_DISABLE" or "WORKER_ENABLE"
    +    worker_config      = "WORKER_ENABLE";
    +  }
    +);
    +
    +log_config =
    +    {
    +      global_log_level                      ="info";
    +      global_log_verbosity                  ="medium";
    +      hw_log_level                          ="info";
    +      hw_log_verbosity                      ="medium";
    +      phy_log_level                         ="info";
    +      phy_log_verbosity                     ="medium";
    +      mac_log_level                         ="info";
    +      mac_log_verbosity                     ="high";
    +      rlc_log_level                         ="info";
    +      rlc_log_verbosity                     ="medium";
    +      pdcp_log_level                        ="info";
    +      pdcp_log_verbosity                    ="medium";
    +      rrc_log_level                         ="info";
    +      rrc_log_verbosity                     ="medium";
    +   };
    diff --git a/ci-scripts/conf_files/ue.nfapi.conf b/ci-scripts/conf_files/ue.nfapi.conf
    new file mode 100644
    index 0000000000..ea0236cab4
    --- /dev/null
    +++ b/ci-scripts/conf_files/ue.nfapi.conf
    @@ -0,0 +1,44 @@
    +log_config = {
    +  global_log_level                      ="info";
    +  global_log_verbosity                  ="medium";
    +  hw_log_level                          ="info";
    +  hw_log_verbosity                      ="medium";
    +  phy_log_level                         ="info";
    +  phy_log_verbosity                     ="medium";
    +  mac_log_level                         ="info";
    +  mac_log_verbosity                     ="medium";
    +  rlc_log_level                         ="info";
    +  rlc_log_verbosity                     ="medium";
    +  pdcp_log_level                        ="info";
    +  pdcp_log_verbosity                    ="medium";
    +  rrc_log_level                         ="info";
    +  rrc_log_verbosity                     ="full";
    +};
    +
    +
    +L1s = (
    +    	{
    +	num_cc = 1;
    +	tr_n_preference = "nfapi";
    +    	local_n_if_name  = "lo";
    +      	remote_n_address = "127.0.0.2";
    +    	local_n_address  = "127.0.0.1";
    +    	local_n_portc    = 50000;
    +    	remote_n_portc   = 50001;
    +    	local_n_portd    = 50010;
    +    	remote_n_portd   = 50011;
    +        }  
    +);
    +
    +RUs = (
    +    {		  
    +       local_rf       = "yes"
    +       nb_tx          = 1
    +       nb_rx          = 1
    +       att_tx         = 90
    +       att_rx         = 0;
    +       bands          = [7,38,42,43];
    +       max_pdschReferenceSignalPower = -27;
    +       max_rxgain                    = 125;
    +    }		      
    +);
    diff --git a/ci-scripts/oai-ci-vm-tool b/ci-scripts/oai-ci-vm-tool
    index 8bf7853d0c..b787129302 100755
    --- a/ci-scripts/oai-ci-vm-tool
    +++ b/ci-scripts/oai-ci-vm-tool
    @@ -40,6 +40,7 @@ function variant_usage {
         echo "    --variant cppcheck     OR -v4"
         echo "    --variant enb-ethernet OR -v7"
         echo "    --variant ue-ethernet  OR -v8"
    +    echo "    --variant l2-sim       OR -v9"
         echo "    --variant flexran-rtc  OR -v10"
     }
     
    @@ -285,6 +286,18 @@ case $key in
         NBARGS=$[$NBARGS+256]
         shift
         ;;
    +    -v9)
    +    VM_NAME=ci-l2-sim
    +    VM_MEMORY=8192
    +    VM_CPU=8
    +    ARCHIVES_LOC=l2_sim
    +    LOG_PATTERN=.Rel14.txt
    +    NB_PATTERN_FILES=4
    +    BUILD_OPTIONS="--eNB -t ETHERNET"
    +    RUN_OPTIONS="complex"
    +    NBARGS=$[$NBARGS+256]
    +    shift
    +    ;;
         -v10)
         VM_NAME=ci-flexran-rtc
         ARCHIVES_LOC=flexran
    @@ -350,6 +363,18 @@ case $key in
             BUILD_OPTIONS="--UE -t ETHERNET --noS1"
             NBARGS=$[$NBARGS+256]
             ;;
    +        l2-sim)
    +        VM_NAME=ci-l2-sim
    +        VM_MEMORY=8192
    +        VM_CPU=8
    +        ARCHIVES_LOC=l2_sim
    +        LOG_PATTERN=.Rel14.txt
    +        NB_PATTERN_FILES=4
    +        BUILD_OPTIONS="--eNB -t ETHERNET"
    +        RUN_OPTIONS="complex"
    +        NBARGS=$[$NBARGS+256]
    +        shift
    +        ;;
             flexran-rtc)
             VM_NAME=ci-flexran-rtc
             ARCHIVES_LOC=flexran
    diff --git a/ci-scripts/runTestOnVM.sh b/ci-scripts/runTestOnVM.sh
    index bed46f0ace..4d87ba5791 100755
    --- a/ci-scripts/runTestOnVM.sh
    +++ b/ci-scripts/runTestOnVM.sh
    @@ -280,17 +280,171 @@ function recover_core_dump {
         fi
     }
     
    -function terminate_ltebox_epc {
    -    echo "echo \"cd /opt/ltebox/tools\"" > $1
    -    echo "cd /opt/ltebox/tools" >> $1
    -    echo "echo \"sudo ./stop_ltebox\"" >> $1
    -    echo "sudo ./stop_ltebox" >> $1
    -    echo "echo \"sudo daemon --name=simulated_hss --stop\"" >> $1
    -    echo "sudo daemon --name=simulated_hss --stop" >> $1
    -    echo "echo \"sudo killall --signal SIGKILL hss_sim\"" >> $1
    -    echo "sudo killall --signal SIGKILL hss_sim" >> $1
    -    ssh -o StrictHostKeyChecking=no ubuntu@$2 < $1
    -    rm $1
    +function install_epc_on_vm {
    +    local LOC_EPC_VM_NAME=$1
    +    local LOC_EPC_VM_CMDS=$2
    +
    +    if [ -d /opt/ltebox-archives/ ]
    +    then
    +        # Checking if all ltebox archives are available to run ltebx epc on a brand new VM
    +        if [ -f /opt/ltebox-archives/ltebox_2.2.70_16_04_amd64.deb ] && [ -f /opt/ltebox-archives/etc-conf.zip ] && [ -f /opt/ltebox-archives/hss-sim.zip ]
    +        then
    +            echo "############################################################"
    +            echo "Test EPC on VM ($EPC_VM_NAME) will be using ltebox"
    +            echo "############################################################"
    +            LTEBOX=1
    +        fi
    +    fi
    +    # Here we could have other types of EPC detection
    +
    +    # Do we need to start the EPC VM
    +    echo "EPC_VM_CMD_FILE     = $LOC_EPC_VM_CMDS"
    +    IS_EPC_VM_ALIVE=`uvt-kvm list | grep -c $LOC_EPC_VM_NAME`
    +    if [ $IS_EPC_VM_ALIVE -eq 0 ]
    +    then
    +        echo "############################################################"
    +        echo "Creating test EPC VM ($LOC_EPC_VM_NAME) on Ubuntu Cloud Image base"
    +        echo "############################################################"
    +        uvt-kvm create $LOC_EPC_VM_NAME release=xenial --unsafe-caching
    +    fi
    +
    +    uvt-kvm wait $LOC_EPC_VM_NAME --insecure
    +    local LOC_EPC_VM_IP_ADDR=`uvt-kvm ip $LOC_EPC_VM_NAME`
    +    echo "$LOC_EPC_VM_NAME has for IP addr = $LOC_EPC_VM_IP_ADDR"
    +    scp -o StrictHostKeyChecking=no /etc/apt/apt.conf.d/01proxy ubuntu@$LOC_EPC_VM_IP_ADDR:/home/ubuntu
    +
    +    # ltebox specific actions (install and start)
    +    LTE_BOX_TO_INSTALL=1
    +    if [ $LTEBOX -eq 1 ]
    +    then
    +        echo "ls -ls /opt/ltebox/tools/start_ltebox" > $LOC_EPC_VM_CMDS
    +        RESPONSE=`ssh -o StrictHostKeyChecking=no ubuntu@$LOC_EPC_VM_IP_ADDR < $LOC_EPC_VM_CMDS`
    +        NB_EXES=`echo $RESPONSE | grep -c ltebox`
    +        if [ $NB_EXES -eq 1 ]; then LTE_BOX_TO_INSTALL=0; fi
    +    fi
    +
    +    if [ $LTEBOX -eq 1 ] && [ $LTE_BOX_TO_INSTALL -eq 1 ]
    +    then
    +        echo "############################################################"
    +        echo "Copying ltebox archives into EPC VM ($LOC_EPC_VM_NAME)" 
    +        echo "############################################################"
    +        scp -o StrictHostKeyChecking=no /opt/ltebox-archives/ltebox_2.2.70_16_04_amd64.deb ubuntu@$LOC_EPC_VM_IP_ADDR:/home/ubuntu
    +        scp -o StrictHostKeyChecking=no /opt/ltebox-archives/etc-conf.zip ubuntu@$LOC_EPC_VM_IP_ADDR:/home/ubuntu
    +        scp -o StrictHostKeyChecking=no /opt/ltebox-archives/hss-sim.zip ubuntu@$LOC_EPC_VM_IP_ADDR:/home/ubuntu
    +
    +        echo "############################################################"
    +        echo "Install EPC on EPC VM ($LOC_EPC_VM_NAME)"
    +        echo "############################################################"
    +        echo "sudo cp 01proxy /etc/apt/apt.conf.d/" > $LOC_EPC_VM_CMDS
    +        echo "touch /home/ubuntu/.hushlogin" >> $LOC_EPC_VM_CMDS
    +        echo "echo \"sudo apt-get --yes --quiet install zip openjdk-8-jre libconfuse-dev libreadline-dev liblog4c-dev libgcrypt-dev libsctp-dev python2.7 python2.7-dev daemon iperf\"" >> $LOC_EPC_VM_CMDS
    +        echo "sudo apt-get update > zip-install.txt 2>&1" >> $LOC_EPC_VM_CMDS
    +        echo "sudo apt-get --yes install zip openjdk-8-jre libconfuse-dev libreadline-dev liblog4c-dev libgcrypt-dev libsctp-dev python2.7 python2.7-dev daemon iperf >> zip-install.txt 2>&1" >> $LOC_EPC_VM_CMDS
    +
    +        # Installing HSS
    +        echo "echo \"cd /opt\"" >> $LOC_EPC_VM_CMDS
    +        echo "cd /opt" >> $LOC_EPC_VM_CMDS
    +        echo "echo \"sudo unzip -qq /home/ubuntu/hss-sim.zip\"" >> $LOC_EPC_VM_CMDS
    +        echo "sudo unzip -qq /home/ubuntu/hss-sim.zip" >> $LOC_EPC_VM_CMDS
    +        echo "echo \"cd /opt/hss_sim0609\"" >> $LOC_EPC_VM_CMDS
    +        echo "cd /opt/hss_sim0609" >> $LOC_EPC_VM_CMDS
    +
    +        # Installing ltebox
    +        echo "echo \"cd /home/ubuntu\"" >> $LOC_EPC_VM_CMDS
    +        echo "cd /home/ubuntu" >> $LOC_EPC_VM_CMDS
    +        echo "echo \"sudo dpkg -i ltebox_2.2.70_16_04_amd64.deb \"" >> $LOC_EPC_VM_CMDS
    +        echo "sudo dpkg -i ltebox_2.2.70_16_04_amd64.deb >> zip-install.txt 2>&1" >> $LOC_EPC_VM_CMDS
    +
    +        echo "echo \"cd /opt/ltebox/etc/\"" >> $LOC_EPC_VM_CMDS
    +        echo "cd /opt/ltebox/etc/" >> $LOC_EPC_VM_CMDS
    +        echo "echo \"sudo unzip -qq -o /home/ubuntu/etc-conf.zip\"" >> $LOC_EPC_VM_CMDS
    +        echo "sudo unzip -qq -o /home/ubuntu/etc-conf.zip" >> $LOC_EPC_VM_CMDS
    +        echo "sudo sed -i  -e 's#EPC_VM_IP_ADDRESS#$LOC_EPC_VM_IP_ADDR#' gw.conf" >> $LOC_EPC_VM_CMDS
    +        echo "sudo sed -i  -e 's#EPC_VM_IP_ADDRESS#$LOC_EPC_VM_IP_ADDR#' mme.conf" >> $LOC_EPC_VM_CMDS
    +
    +        ssh -o StrictHostKeyChecking=no ubuntu@$LOC_EPC_VM_IP_ADDR < $LOC_EPC_VM_CMDS
    +        rm -f $LOC_EPC_VM_CMDS
    +    fi
    +}
    +
    +function start_epc {
    +    local LOC_EPC_VM_NAME=$1
    +    local LOC_EPC_VM_CMDS=$2
    +    local LOC_EPC_VM_IP_ADDR=$3
    +
    +    if [ $LTEBOX -eq 1 ]
    +    then
    +        echo "############################################################"
    +        echo "Start EPC on EPC VM ($LOC_EPC_VM_NAME)"
    +        echo "############################################################"
    +        echo "echo \"cd /opt/hss_sim0609\"" > $LOC_EPC_VM_CMDS
    +        echo "cd /opt/hss_sim0609" >> $LOC_EPC_VM_CMDS
    +        echo "echo \"sudo daemon --unsafe --name=simulated_hss --chdir=/opt/hss_sim0609 ./starthss_real\"" >> $LOC_EPC_VM_CMDS
    +        echo "sudo daemon --unsafe --name=simulated_hss --chdir=/opt/hss_sim0609 ./starthss_real" >> $LOC_EPC_VM_CMDS
    +
    +        echo "echo \"cd /opt/ltebox/tools/\"" >> $LOC_EPC_VM_CMDS
    +        echo "cd /opt/ltebox/tools/" >> $LOC_EPC_VM_CMDS
    +        echo "echo \"sudo ./start_ltebox\"" >> $LOC_EPC_VM_CMDS
    +        echo "nohup sudo ./start_ltebox > /home/ubuntu/ltebox.txt" >> $LOC_EPC_VM_CMDS
    +
    +        ssh -o StrictHostKeyChecking=no ubuntu@$LOC_EPC_VM_IP_ADDR < $LOC_EPC_VM_CMDS
    +        rm -f $LOC_EPC_VM_CMDS
    +
    +        i="0"
    +        echo "ifconfig tun5 | egrep -c \"inet addr\"" > $LOC_EPC_VM_CMDS
    +        while [ $i -lt 10 ]
    +        do
    +            sleep 2
    +            CONNECTED=`ssh -o StrictHostKeyChecking=no ubuntu@$LOC_EPC_VM_IP_ADDR < $LOC_EPC_VM_CMDS`
    +            if [ $CONNECTED -eq 1 ]
    +            then
    +                i="100"
    +            else
    +                i=$[$i+1]
    +            fi
    +        done
    +        rm $LOC_EPC_VM_CMDS
    +        if [ $i -lt 50 ]
    +        then
    +            echo "Problem w/ starting ltebox EPC"
    +            echo "TEST_KO" > $ARCHIVES_LOC/test_final_status.log
    +            exit -1
    +        fi
    +    fi
    +
    +    # HERE ADD ANY INSTALL ACTIONS FOR ANOTHER EPC
    +
    +}
    +
    +function retrieve_real_epc_ip_addr {
    +    local LOC_EPC_VM_NAME=$1
    +    local LOC_EPC_VM_CMDS=$2
    +    local LOC_EPC_VM_IP_ADDR=$3
    +
    +    if [ $LTEBOX -eq 1 ]
    +    then
    +        # in our configuration file, we are using pool 5
    +        echo "ifconfig tun5 | egrep \"inet addr\" | sed -e 's#^.*inet addr:##' -e 's#  P-t-P:.*\$##'" > $LOC_EPC_VM_CMDS
    +        REAL_EPC_IP_ADDR=`ssh -o StrictHostKeyChecking=no ubuntu@$LOC_EPC_VM_IP_ADDR < $LOC_EPC_VM_CMDS`
    +        echo "EPC IP Address     is : $REAL_EPC_IP_ADDR"
    +        rm $LOC_EPC_VM_CMDS
    +    fi
    +}
    +
    +function terminate_epc {
    +    if [ $LTEBOX -eq 1 ]
    +    then
    +        echo "echo \"cd /opt/ltebox/tools\"" > $1
    +        echo "cd /opt/ltebox/tools" >> $1
    +        echo "echo \"sudo ./stop_ltebox\"" >> $1
    +        echo "sudo ./stop_ltebox" >> $1
    +        echo "echo \"sudo daemon --name=simulated_hss --stop\"" >> $1
    +        echo "sudo daemon --name=simulated_hss --stop" >> $1
    +        echo "echo \"sudo killall --signal SIGKILL hss_sim\"" >> $1
    +        echo "sudo killall --signal SIGKILL hss_sim" >> $1
    +        ssh -o StrictHostKeyChecking=no ubuntu@$2 < $1
    +        rm $1
    +    fi
     }
     
     function start_flexran_ctrl {
    @@ -322,6 +476,85 @@ function query_flexran_ctrl_status {
         rm $1
     }
     
    +function build_ue_on_separate_folder {
    +    echo "mkdir tmp-ue" > $1
    +    echo "cd tmp-ue" >> $1
    +    echo "echo \"unzip -qq -DD ../localZip.zip\"" >> $1
    +    echo "unzip -qq -DD ../localZip.zip" >> $1
    +
    +    # We may have some adaptation to do
    +    if [ -f /opt/ltebox-archives/adapt_ue_l2_sim.txt ]
    +    then
    +        echo "############################################################"
    +        echo "Doing some adaptation on UE side"
    +        echo "############################################################"
    +        cat /opt/ltebox-archives/adapt_ue_l2_sim.txt >> $1
    +    fi
    +
    +    echo "echo \"source oaienv\"" >> $1
    +    echo "source oaienv" >> $1
    +    echo "cd cmake_targets/" >> $1
    +    echo "mkdir log" >> $1
    +    echo "chmod 777 log" >> $1
    +    echo "echo \"./build_oai --UE -t ETHERNET \"" >> $1
    +    echo "./build_oai --UE -t ETHERNET > log/ue-build.txt 2>&1" >> $1
    +    echo "cd tools" >> $1
    +    echo "sudo ifconfig lo: 127.0.0.2 netmask 255.0.0.0 up" >> $1
    +    echo "sudo chmod 666 /etc/iproute2/rt_tables" >> $1
    +    echo "source init_nas_s1 UE" >> $1
    +    echo "ifconfig" >> $1
    +    ssh -o StrictHostKeyChecking=no ubuntu@$2 < $1
    +    rm -f $1
    +}
    +
    +function start_l2_sim_enb {
    +    local LOC_VM_IP_ADDR=$2
    +    local LOC_EPC_IP_ADDR=$3
    +    local LOC_LOG_FILE=$4
    +    local LOC_NB_RBS=$5
    +    local LOC_CONF_FILE=$6
    +    echo "cd /home/ubuntu/tmp" > $1
    +    echo "echo \"sudo apt-get --yes --quiet install daemon \"" >> $1
    +    echo "sudo apt-get --yes install daemon >> /home/ubuntu/tmp/cmake_targets/log/daemon-install.txt 2>&1" >> $1
    +    echo "echo \"source oaienv\"" >> $1
    +    echo "source oaienv" >> $1
    +    echo "cd ci-scripts/conf_files/" >> $1
    +    echo "cp $LOC_CONF_FILE ci-$LOC_CONF_FILE" >> $1
    +    echo "sed -i -e 's#N_RB_DL.*=.*;#N_RB_DL                                         = $LOC_NB_RBS;#' -e 's#CI_MME_IP_ADDR#$LOC_EPC_IP_ADDR#' -e 's#CI_ENB_IP_ADDR#$LOC_VM_IP_ADDR#' ci-$LOC_CONF_FILE" >> $1
    +    echo "echo \"grep N_RB_DL ci-$LOC_CONF_FILE\"" >> $1
    +    echo "grep N_RB_DL ci-$LOC_CONF_FILE | sed -e 's#N_RB_DL.*=#N_RB_DL =#'" >> $1
    +    echo "echo \"cd /home/ubuntu/tmp/cmake_targets/lte_build_oai/build/\"" >> $1
    +    echo "sudo chmod 777 /home/ubuntu/tmp/cmake_targets/lte_build_oai/build/" >> $1
    +    echo "cd /home/ubuntu/tmp/cmake_targets/lte_build_oai/build/" >> $1
    +    echo "echo \"ulimit -c unlimited && ./lte-softmodem -O /home/ubuntu/tmp/ci-scripts/conf_files/ci-$LOC_CONF_FILE\" > ./my-lte-softmodem-run.sh " >> $1
    +    echo "chmod 775 ./my-lte-softmodem-run.sh" >> $1
    +    echo "cat ./my-lte-softmodem-run.sh" >> $1
    +    echo "if [ -e /home/ubuntu/tmp/cmake_targets/log/$LOC_LOG_FILE ]; then sudo sudo rm -f /home/ubuntu/tmp/cmake_targets/log/$LOC_LOG_FILE; fi" >> $1
    +    echo "sudo -E daemon --inherit --unsafe --name=enb_daemon --chdir=/home/ubuntu/tmp/cmake_targets/lte_build_oai/build/ -o /home/ubuntu/tmp/cmake_targets/log/$LOC_LOG_FILE ./my-lte-softmodem-run.sh" >> $1
    +
    +    ssh -o StrictHostKeyChecking=no ubuntu@$LOC_VM_IP_ADDR < $1
    +    sleep 10
    +    rm $1
    +}
    +
    +function start_l2_sim_ue {
    +    local LOC_VM_IP_ADDR=$2
    +    local LOC_LOG_FILE=$3
    +    local LOC_CONF_FILE=$4
    +    echo "echo \"cd /home/ubuntu/tmp-ue/cmake_targets/lte_build_oai/build/\"" >> $1
    +    echo "sudo chmod 777 /home/ubuntu/tmp-ue/cmake_targets/lte_build_oai/build/" >> $1
    +    echo "cd /home/ubuntu/tmp-ue/cmake_targets/lte_build_oai/build/" >> $1
    +    echo "echo \"ulimit -c unlimited && ./lte-uesoftmodem -O /home/ubuntu/tmp-ue/ci-scripts/conf_files/$LOC_CONF_FILE --L2-emul 3 --num-ues 1\" > ./my-lte-softmodem-run.sh " >> $1
    +    echo "chmod 775 ./my-lte-softmodem-run.sh" >> $1
    +    echo "cat ./my-lte-softmodem-run.sh" >> $1
    +    echo "if [ -e /home/ubuntu/tmp/cmake_targets/log/$LOC_LOG_FILE ]; then sudo sudo rm -f /home/ubuntu/tmp/cmake_targets/log/$LOC_LOG_FILE; fi" >> $1
    +    echo "sudo -E daemon --inherit --unsafe --name=ue_daemon --chdir=/home/ubuntu/tmp-ue/cmake_targets/lte_build_oai/build/ -o /home/ubuntu/tmp/cmake_targets/log/$LOC_LOG_FILE ./my-lte-softmodem-run.sh" >> $1
    +
    +    ssh -o StrictHostKeyChecking=no ubuntu@$LOC_VM_IP_ADDR < $1
    +    sleep 10
    +    rm $1
    +}
    +
     function run_test_on_vm {
         echo "############################################################"
         echo "OAI CI VM script"
    @@ -459,148 +692,26 @@ function run_test_on_vm {
             fi
             mkdir --parents $ARCHIVES_LOC
     
    +        # Creating a VM for EPC and installing SW
             EPC_VM_NAME=`echo $VM_NAME | sed -e "s#basic-sim#epc#"`
    +        EPC_VM_CMDS=${EPC_VM_NAME}_cmds.txt
             LTEBOX=0
    -        if [ -d /opt/ltebox-archives/ ]
    -        then
    -            # Checking if all ltebox archives are available to run ltebx epc on a brand new VM
    -            if [ -f /opt/ltebox-archives/ltebox_2.2.70_16_04_amd64.deb ] && [ -f /opt/ltebox-archives/etc-conf.zip ] && [ -f /opt/ltebox-archives/hss-sim.zip ]
    -            then
    -                echo "############################################################"
    -                echo "Test EPC on VM ($EPC_VM_NAME) will be using ltebox"
    -                echo "############################################################"
    -                LTEBOX=1
    -            fi
    -        fi
    -        # Here we could have other types of EPC detection
    -
    -        # Do we need to start the EPC VM
    -        EPC_VM_CMDS=`echo $VM_CMDS | sed -e "s#cmds#epc-cmds#"`
    -        echo "EPC_VM_CMD_FILE     = $EPC_VM_CMDS"
    -        IS_EPC_VM_ALIVE=`uvt-kvm list | grep -c $EPC_VM_NAME`
    -        if [ $IS_EPC_VM_ALIVE -eq 0 ]
    -        then
    -            echo "############################################################"
    -            echo "Creating test EPC VM ($EPC_VM_NAME) on Ubuntu Cloud Image base"
    -            echo "############################################################"
    -            uvt-kvm create $EPC_VM_NAME release=xenial --unsafe-caching
    -        fi
    -
    -        uvt-kvm wait $EPC_VM_NAME --insecure
    +        install_epc_on_vm $EPC_VM_NAME $EPC_VM_CMDS
             EPC_VM_IP_ADDR=`uvt-kvm ip $EPC_VM_NAME`
    -        echo "$EPC_VM_NAME has for IP addr = $EPC_VM_IP_ADDR"
    -        scp -o StrictHostKeyChecking=no /etc/apt/apt.conf.d/01proxy ubuntu@$EPC_VM_IP_ADDR:/home/ubuntu
    -
    -        # ltebox specific actions (install and start)
    -        LTE_BOX_TO_INSTALL=1
    -        if [ $LTEBOX -eq 1 ]
    -        then
    -            echo "ls -ls /opt/ltebox/tools/start_ltebox" > $EPC_VM_CMDS
    -            RESPONSE=`ssh -o StrictHostKeyChecking=no ubuntu@$EPC_VM_IP_ADDR < $EPC_VM_CMDS`
    -            NB_EXES=`echo $RESPONSE | grep -c ltebox`
    -            if [ $NB_EXES -eq 1 ]; then LTE_BOX_TO_INSTALL=0; fi
    -        fi
    -
    -        if [ $LTEBOX -eq 1 ] && [ $LTE_BOX_TO_INSTALL -eq 1 ]
    -        then
    -            echo "############################################################"
    -            echo "Copying ltebox archives into EPC VM ($EPC_VM_NAME)" 
    -            echo "############################################################"
    -            scp -o StrictHostKeyChecking=no /opt/ltebox-archives/ltebox_2.2.70_16_04_amd64.deb ubuntu@$EPC_VM_IP_ADDR:/home/ubuntu
    -            scp -o StrictHostKeyChecking=no /opt/ltebox-archives/etc-conf.zip ubuntu@$EPC_VM_IP_ADDR:/home/ubuntu
    -            scp -o StrictHostKeyChecking=no /opt/ltebox-archives/hss-sim.zip ubuntu@$EPC_VM_IP_ADDR:/home/ubuntu
    -
    -            echo "############################################################"
    -            echo "Install EPC on EPC VM ($EPC_VM_NAME)"
    -            echo "############################################################"
    -            echo "sudo cp 01proxy /etc/apt/apt.conf.d/" > $EPC_VM_CMDS
    -            echo "touch /home/ubuntu/.hushlogin" >> $EPC_VM_CMDS
    -            echo "echo \"sudo apt-get --yes --quiet install zip openjdk-8-jre libconfuse-dev libreadline-dev liblog4c-dev libgcrypt-dev libsctp-dev python2.7 python2.7-dev daemon iperf\"" >> $EPC_VM_CMDS
    -            echo "sudo apt-get update > zip-install.txt 2>&1" >> $EPC_VM_CMDS
    -            echo "sudo apt-get --yes install zip openjdk-8-jre libconfuse-dev libreadline-dev liblog4c-dev libgcrypt-dev libsctp-dev python2.7 python2.7-dev daemon iperf >> zip-install.txt 2>&1" >> $EPC_VM_CMDS
    -
    -            # Installing HSS
    -            echo "echo \"cd /opt\"" >> $EPC_VM_CMDS
    -            echo "cd /opt" >> $EPC_VM_CMDS
    -            echo "echo \"sudo unzip -qq /home/ubuntu/hss-sim.zip\"" >> $EPC_VM_CMDS
    -            echo "sudo unzip -qq /home/ubuntu/hss-sim.zip" >> $EPC_VM_CMDS
    -            echo "echo \"cd /opt/hss_sim0609\"" >> $EPC_VM_CMDS
    -            echo "cd /opt/hss_sim0609" >> $EPC_VM_CMDS
    -
    -            # Installing ltebox
    -            echo "echo \"cd /home/ubuntu\"" >> $EPC_VM_CMDS
    -            echo "cd /home/ubuntu" >> $EPC_VM_CMDS
    -            echo "echo \"sudo dpkg -i ltebox_2.2.70_16_04_amd64.deb \"" >> $EPC_VM_CMDS
    -            echo "sudo dpkg -i ltebox_2.2.70_16_04_amd64.deb >> zip-install.txt 2>&1" >> $EPC_VM_CMDS
    -
    -            echo "echo \"cd /opt/ltebox/etc/\"" >> $EPC_VM_CMDS
    -            echo "cd /opt/ltebox/etc/" >> $EPC_VM_CMDS
    -            echo "echo \"sudo unzip -qq -o /home/ubuntu/etc-conf.zip\"" >> $EPC_VM_CMDS
    -            echo "sudo unzip -qq -o /home/ubuntu/etc-conf.zip" >> $EPC_VM_CMDS
    -            echo "sudo sed -i  -e 's#EPC_VM_IP_ADDRESS#$EPC_VM_IP_ADDR#' gw.conf" >> $EPC_VM_CMDS
    -            echo "sudo sed -i  -e 's#EPC_VM_IP_ADDRESS#$EPC_VM_IP_ADDR#' mme.conf" >> $EPC_VM_CMDS
    -        fi
     
             # Starting EPC
    -        if [ $LTEBOX -eq 1 ]
    -        then
    -            echo "############################################################"
    -            echo "Start EPC on EPC VM ($EPC_VM_NAME)"
    -            echo "############################################################"
    -            echo "echo \"cd /opt/hss_sim0609\"" >> $EPC_VM_CMDS
    -            echo "cd /opt/hss_sim0609" >> $EPC_VM_CMDS
    -            echo "echo \"sudo daemon --unsafe --name=simulated_hss --chdir=/opt/hss_sim0609 ./starthss_real\"" >> $EPC_VM_CMDS
    -            echo "sudo daemon --unsafe --name=simulated_hss --chdir=/opt/hss_sim0609 ./starthss_real" >> $EPC_VM_CMDS
    -
    -            echo "echo \"cd /opt/ltebox/tools/\"" >> $EPC_VM_CMDS
    -            echo "cd /opt/ltebox/tools/" >> $EPC_VM_CMDS
    -            echo "echo \"sudo ./start_ltebox\"" >> $EPC_VM_CMDS
    -            echo "nohup sudo ./start_ltebox > /home/ubuntu/ltebox.txt" >> $EPC_VM_CMDS
    -
    -            ssh -o StrictHostKeyChecking=no ubuntu@$EPC_VM_IP_ADDR < $EPC_VM_CMDS
    -            rm -f $EPC_VM_CMDS
    -
    -            # We may have some adaptation to do
    -            if [ -f /opt/ltebox-archives/adapt_ue_sim.txt ]
    -            then
    -                echo "############################################################"
    -                echo "Doing some adaptation on UE side"
    -                echo "############################################################"
    -                ssh -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR < /opt/ltebox-archives/adapt_ue_sim.txt
    -            fi
    -
    -            i="0"
    -            echo "ifconfig tun5 | egrep -c \"inet addr\"" > $EPC_VM_CMDS
    -            while [ $i -lt 10 ]
    -            do
    -                sleep 2
    -                CONNECTED=`ssh -o StrictHostKeyChecking=no ubuntu@$EPC_VM_IP_ADDR < $EPC_VM_CMDS`
    -                if [ $CONNECTED -eq 1 ]
    -                then
    -                    i="100"
    -                else
    -                    i=$[$i+1]
    -                fi
    -            done
    -            rm $EPC_VM_CMDS
    -            if [ $i -lt 50 ]
    -            then
    -                echo "Problem w/ starting ltebox EPC"
    -                echo "TEST_KO" > $ARCHIVES_LOC/test_final_status.log
    -                exit -1
    -            fi
    -        fi
    -
    -        # HERE ADD ANY INSTALL ACTIONS FOR ANOTHER EPC
    +        start_epc $EPC_VM_NAME $EPC_VM_CMDS $EPC_VM_IP_ADDR
     
             # Retrieve EPC real IP address
    -        if [ $LTEBOX -eq 1 ]
    +        retrieve_real_epc_ip_addr $EPC_VM_NAME $EPC_VM_CMDS $EPC_VM_IP_ADDR
    +
    +        # We may have some adaptation to do
    +        if [ -f /opt/ltebox-archives/adapt_ue_sim.txt ]
             then
    -            # in our configuration file, we are using pool 5
    -            echo "ifconfig tun5 | egrep \"inet addr\" | sed -e 's#^.*inet addr:##' -e 's#  P-t-P:.*\$##'" > $EPC_VM_CMDS
    -            REAL_EPC_IP_ADDR=`ssh -o StrictHostKeyChecking=no ubuntu@$EPC_VM_IP_ADDR < $EPC_VM_CMDS`
    -            echo "EPC IP Address     is : $REAL_EPC_IP_ADDR"
    -            rm $EPC_VM_CMDS
    +            echo "############################################################"
    +            echo "Doing some adaptation on UE side"
    +            echo "############################################################"
    +            ssh -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR < /opt/ltebox-archives/adapt_ue_sim.txt
             fi
     
             echo "############################################################"
    @@ -621,7 +732,7 @@ function run_test_on_vm {
                 scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_ENB_LOG_FILE $ARCHIVES_LOC
                 scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_UE_LOG_FILE $ARCHIVES_LOC
                 recover_core_dump $VM_CMDS $VM_IP_ADDR $ARCHIVES_LOC/$CURRENT_ENB_LOG_FILE $ARCHIVES_LOC
    -            terminate_ltebox_epc $EPC_VM_CMDS $EPC_VM_IP_ADDR
    +            terminate_epc $EPC_VM_CMDS $EPC_VM_IP_ADDR
                 echo "TEST_KO" > $ARCHIVES_LOC/test_final_status.log
                 exit -1
             fi
    @@ -680,7 +791,7 @@ function run_test_on_vm {
                 scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_ENB_LOG_FILE $ARCHIVES_LOC
                 scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_UE_LOG_FILE $ARCHIVES_LOC
                 recover_core_dump $VM_CMDS $VM_IP_ADDR $ARCHIVES_LOC/$CURRENT_ENB_LOG_FILE $ARCHIVES_LOC
    -            terminate_ltebox_epc $EPC_VM_CMDS $EPC_VM_IP_ADDR
    +            terminate_epc $EPC_VM_CMDS $EPC_VM_IP_ADDR
                 echo "TEST_KO" > $ARCHIVES_LOC/test_final_status.log
                 exit -1
             fi
    @@ -739,7 +850,7 @@ function run_test_on_vm {
                 scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_ENB_LOG_FILE $ARCHIVES_LOC
                 scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_UE_LOG_FILE $ARCHIVES_LOC
                 recover_core_dump $VM_CMDS $VM_IP_ADDR $ARCHIVES_LOC/$CURRENT_ENB_LOG_FILE $ARCHIVES_LOC
    -            terminate_ltebox_epc $EPC_VM_CMDS $EPC_VM_IP_ADDR
    +            terminate_epc $EPC_VM_CMDS $EPC_VM_IP_ADDR
                 echo "TEST_KO" > $ARCHIVES_LOC/test_final_status.log
                 exit -1
             fi
    @@ -791,7 +902,7 @@ function run_test_on_vm {
                 if [ $j -lt 50 ]
                 then
                     echo "ERROR: compiling flexran controller on vm went wrong"
    -                terminate_ltebox_epc $EPC_VM_CMDS $EPC_VM_IP_ADDR
    +                terminate_epc $EPC_VM_CMDS $EPC_VM_IP_ADDR
                     echo "TEST_KO" > $ARCHIVES_LOC/test_final_status.log
                     exit -1
                 fi
    @@ -801,7 +912,7 @@ function run_test_on_vm {
                 if [ $IS_FLEXRAN_VM_ALIVE -eq 0 ]
                 then
                     echo "ERROR: Flexran Ctl VM is not alive"
    -                terminate_ltebox_epc $EPC_VM_CMDS $EPC_VM_IP_ADDR
    +                terminate_epc $EPC_VM_CMDS $EPC_VM_IP_ADDR
                     echo "TEST_KO" > $ARCHIVES_LOC/test_final_status.log
                     exit -1
                 fi
    @@ -835,7 +946,7 @@ function run_test_on_vm {
                     scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_ENB_LOG_FILE $ARCHIVES_LOC
                     scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_UE_LOG_FILE $ARCHIVES_LOC
                     recover_core_dump $VM_CMDS $VM_IP_ADDR $ARCHIVES_LOC/$CURRENT_ENB_LOG_FILE $ARCHIVES_LOC
    -                terminate_ltebox_epc $EPC_VM_CMDS $EPC_VM_IP_ADDR
    +                terminate_epc $EPC_VM_CMDS $EPC_VM_IP_ADDR
                     stop_flexran_ctrl $FLEXRAN_CTL_VM_CMDS $FLEXRAN_CTL_VM_IP_ADDR
                     echo "TEST_KO" > $ARCHIVES_LOC/test_final_status.log
                     exit -1
    @@ -878,7 +989,7 @@ function run_test_on_vm {
                 scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_ENB_LOG_FILE $ARCHIVES_LOC
                 scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_UE_LOG_FILE $ARCHIVES_LOC
                 recover_core_dump $VM_CMDS $VM_IP_ADDR $ARCHIVES_LOC/$CURRENT_ENB_LOG_FILE $ARCHIVES_LOC
    -            terminate_ltebox_epc $EPC_VM_CMDS $EPC_VM_IP_ADDR
    +            terminate_epc $EPC_VM_CMDS $EPC_VM_IP_ADDR
                 echo "TEST_KO" > $ARCHIVES_LOC/test_final_status.log
                 exit -1
             fi
    @@ -929,7 +1040,7 @@ function run_test_on_vm {
                 scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_ENB_LOG_FILE $ARCHIVES_LOC
                 scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_UE_LOG_FILE $ARCHIVES_LOC
                 recover_core_dump $VM_CMDS $VM_IP_ADDR $ARCHIVES_LOC/$CURRENT_ENB_LOG_FILE $ARCHIVES_LOC
    -            terminate_ltebox_epc $EPC_VM_CMDS $EPC_VM_IP_ADDR
    +            terminate_epc $EPC_VM_CMDS $EPC_VM_IP_ADDR
                 echo "TEST_KO" > $ARCHIVES_LOC/test_final_status.log
                 exit -1
             fi
    @@ -980,7 +1091,7 @@ function run_test_on_vm {
     #            scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_ENB_LOG_FILE $ARCHIVES_LOC
     #            scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_UE_LOG_FILE $ARCHIVES_LOC
     #            recover_core_dump $VM_CMDS $VM_IP_ADDR $ARCHIVES_LOC/$CURRENT_ENB_LOG_FILE $ARCHIVES_LOC
    -#            terminate_ltebox_epc $EPC_VM_CMDS $EPC_VM_IP_ADDR
    +#            terminate_epc $EPC_VM_CMDS $EPC_VM_IP_ADDR
     #            echo "TEST_KO" > $ARCHIVES_LOC/test_final_status.log
     #            exit -1
     #        fi
    @@ -1016,10 +1127,7 @@ function run_test_on_vm {
             echo "Terminate EPC"
             echo "############################################################"
     
    -        if [ $LTEBOX -eq 1 ]
    -        then
    -            terminate_ltebox_epc $EPC_VM_CMDS $EPC_VM_IP_ADDR
    -        fi
    +        terminate_epc $EPC_VM_CMDS $EPC_VM_IP_ADDR
     
             if [ $KEEP_VM_ALIVE -eq 0 ]
             then
    @@ -1051,4 +1159,78 @@ function run_test_on_vm {
                 echo "TEST_KO" > $ARCHIVES_LOC/test_final_status.log
             fi
         fi
    +
    +    if [[ "$RUN_OPTIONS" == "complex" ]] && [[ $VM_NAME =~ .*-l2-sim.* ]]
    +    then
    +        PING_STATUS=0
    +        IPERF_STATUS=0
    +        if [ -d $ARCHIVES_LOC ]
    +        then
    +            rm -Rf $ARCHIVES_LOC
    +        fi
    +        mkdir --parents $ARCHIVES_LOC
    +
    +        # Building UE elsewhere in VM
    +        build_ue_on_separate_folder $VM_CMDS $VM_IP_ADDR
    +
    +        # Creating a VM for EPC and installing SW
    +        EPC_VM_NAME=`echo $VM_NAME | sed -e "s#l2-sim#l2-epc#"`
    +        EPC_VM_CMDS=${EPC_VM_NAME}_cmds.txt
    +        LTEBOX=0
    +        install_epc_on_vm $EPC_VM_NAME $EPC_VM_CMDS
    +        EPC_VM_IP_ADDR=`uvt-kvm ip $EPC_VM_NAME`
    +
    +        # Starting EPC
    +        start_epc $EPC_VM_NAME $EPC_VM_CMDS $EPC_VM_IP_ADDR
    +
    +        # Retrieve EPC real IP address
    +        retrieve_real_epc_ip_addr $EPC_VM_NAME $EPC_VM_CMDS $EPC_VM_IP_ADDR
    +
    +        echo "############################################################"
    +        echo "Starting the eNB in FDD-5MHz mode"
    +        echo "############################################################"
    +        CURRENT_ENB_LOG_FILE=fdd_05MHz_enb.log
    +        start_l2_sim_enb $VM_CMDS $VM_IP_ADDR $EPC_VM_IP_ADDR $CURRENT_ENB_LOG_FILE 25 rcc.band7.tm1.nfapi.conf
    +
    +        echo "############################################################"
    +        echo "Starting the UEs"
    +        echo "############################################################"
    +        CURRENT_UE_LOG_FILE=fdd_05MHz_ue.log
    +        start_l2_sim_ue $VM_CMDS $VM_IP_ADDR $CURRENT_UE_LOG_FILE ue.nfapi.conf
    +
    +        sleep 30
    +        echo "ping -I oip1 -c 20 $REAL_EPC_IP_ADDR" > $VM_CMDS
    +        ssh -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR < $VM_CMDS
    +
    +        echo "############################################################"
    +        echo "Terminate enb/ue simulators"
    +        echo "############################################################"
    +        terminate_enb_ue_basic_sim $VM_CMDS $VM_IP_ADDR
    +        scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_ENB_LOG_FILE $ARCHIVES_LOC
    +        scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_UE_LOG_FILE $ARCHIVES_LOC
    +
    +        echo "############################################################"
    +        echo "Terminate EPC"
    +        echo "############################################################"
    +
    +        terminate_epc $EPC_VM_CMDS $EPC_VM_IP_ADDR
    +
    +        if [ $KEEP_VM_ALIVE -eq 0 ]
    +        then
    +            echo "############################################################"
    +            echo "Destroying VMs"
    +            echo "############################################################"
    +            uvt-kvm destroy $VM_NAME
    +            ssh-keygen -R $VM_IP_ADDR
    +            uvt-kvm destroy $EPC_VM_NAME
    +            ssh-keygen -R $EPC_VM_IP_ADDR
    +        fi
    +
    +        if [ $STATUS -eq 0 ]
    +        then
    +            echo "TEST_OK" > $ARCHIVES_LOC/test_final_status.log
    +        else
    +            echo "TEST_KO" > $ARCHIVES_LOC/test_final_status.log
    +        fi
    +    fi
     }
    
    From 9fbc3e8620f4f8978758c3704ce1a4d8a11af3b3 Mon Sep 17 00:00:00 2001
    From: Raphael Defosseux 
    Date: Tue, 22 Jan 2019 18:53:35 +0100
    Subject: [PATCH 231/233] CI: the timeout of eNB log file copy is due to the
     huge size of said-file    --> increase the timeout of copyin/copyout
     functions to 100 sec    Also changed the UHD driver version retrieval
    
    Signed-off-by: Raphael Defosseux 
    ---
     ci-scripts/main.py | 8 ++++----
     1 file changed, 4 insertions(+), 4 deletions(-)
    
    diff --git a/ci-scripts/main.py b/ci-scripts/main.py
    index 23e51960ca..62add8429b 100644
    --- a/ci-scripts/main.py
    +++ b/ci-scripts/main.py
    @@ -214,7 +214,7 @@ class SSHConnection():
     		copy_status = False
     		logging.debug('scp '+ username + '@' + ipaddress + ':' + source + ' ' + destination)
     		while count < 10:
    -			scp_spawn = pexpect.spawn('scp '+ username + '@' + ipaddress + ':' + source + ' ' + destination, timeout = 5)
    +			scp_spawn = pexpect.spawn('scp '+ username + '@' + ipaddress + ':' + source + ' ' + destination, timeout = 100)
     			scp_response = scp_spawn.expect(['Are you sure you want to continue connecting (yes/no)?', 'password:', pexpect.EOF, pexpect.TIMEOUT])
     			if scp_response == 0:
     				scp_spawn.sendline('yes')
    @@ -253,7 +253,7 @@ class SSHConnection():
     		copy_status = False
     		logging.debug('scp ' + source + ' ' + username + '@' + ipaddress + ':' + destination)
     		while count < 4:
    -			scp_spawn = pexpect.spawn('scp ' + source + ' ' + username + '@' + ipaddress + ':' + destination, timeout = 5)
    +			scp_spawn = pexpect.spawn('scp ' + source + ' ' + username + '@' + ipaddress + ':' + destination, timeout = 100)
     			scp_response = scp_spawn.expect(['Are you sure you want to continue connecting (yes/no)?', 'password:', pexpect.EOF, pexpect.TIMEOUT])
     			if scp_response == 0:
     				scp_spawn.sendline('yes')
    @@ -1977,8 +1977,8 @@ class SSHConnection():
     		if result is not None:
     			self.eNBKernelVersion = result.group('kernel_version')
     			logging.debug('Kernel Version is: ' + self.eNBKernelVersion)
    -		self.command('dpkg --list | egrep --color=never uhd-host', '\$', 5)
    -		result = re.search('uhd-host *(?P[0-9\.]+)', str(self.ssh.before))
    +		self.command('dpkg --list | egrep --color=never libuhd003', '\$', 5)
    +		result = re.search('libuhd003:amd64 *(?P[0-9\.]+)', str(self.ssh.before))
     		if result is not None:
     			self.eNBUhdVersion = result.group('uhd_version')
     			logging.debug('UHD Version is: ' + self.eNBUhdVersion)
    
    From 8260607ed6d9ae58d18cdd4d619a0c04ef89b3ed Mon Sep 17 00:00:00 2001
    From: Raphael Defosseux 
    Date: Tue, 22 Jan 2019 21:37:40 +0100
    Subject: [PATCH 232/233] CI: fix in L2-simulator VM build start script
    
    Signed-off-by: Raphael Defosseux 
    ---
     ci-scripts/oai-ci-vm-tool                      | 1 -
     cmake_targets/CMakeLists.txt                   | 0
     nfapi/oai_integration/nfapi_vnf.c              | 0
     nfapi/open-nFAPI/pnf/src/pnf.c                 | 0
     nfapi/open-nFAPI/pnf/src/pnf_p7.c              | 0
     nfapi/open-nFAPI/vnf/src/vnf_p7.c              | 0
     openair1/PHY/defs_UE.h                         | 0
     openair2/COMMON/platform_constants.h           | 0
     openair2/LAYER2/MAC/eNB_scheduler_RA.c         | 0
     openair2/LAYER2/MAC/eNB_scheduler_fairRR.c     | 0
     openair2/LAYER2/MAC/eNB_scheduler_primitives.c | 0
     openair2/LAYER2/MAC/mac_extern.h               | 0
     openair2/LAYER2/MAC/mac_vars.h                 | 0
     openair2/LAYER2/MAC/main_ue.c                  | 0
     openair2/LAYER2/MAC/ue_procedures.c            | 0
     openair2/LAYER2/PDCP_v10.1.0/pdcp.c            | 0
     openair2/LAYER2/PDCP_v10.1.0/pdcp.h            | 0
     openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c       | 0
     openair2/LAYER2/RLC/rlc.c                      | 0
     openair2/NETWORK_DRIVER/MESH/local.h           | 0
     openair2/PHY_INTERFACE/IF_Module.h             | 0
     openair2/PHY_INTERFACE/phy_stub_UE.c           | 0
     openair2/PHY_INTERFACE/phy_stub_UE.h           | 0
     openair2/RRC/LTE/rrc_extern.h                  | 0
     openair2/RRC/LTE/rrc_vars.h                    | 0
     openair3/NAS/UE/ESM/esm_ebr_context.c          | 0
     openair3/NAS/UE/nas_ue_task.c                  | 0
     targets/COMMON/openairinterface5g_limits.h     | 0
     targets/RT/USER/lte-enb.c                      | 0
     targets/RT/USER/lte-ru.c                       | 0
     targets/RT/USER/lte-softmodem.c                | 0
     targets/RT/USER/lte-softmodem.h                | 0
     targets/RT/USER/lte-ue.c                       | 0
     targets/RT/USER/lte-uesoftmodem.c              | 0
     34 files changed, 1 deletion(-)
     mode change 100755 => 100644 cmake_targets/CMakeLists.txt
     mode change 100755 => 100644 nfapi/oai_integration/nfapi_vnf.c
     mode change 100755 => 100644 nfapi/open-nFAPI/pnf/src/pnf.c
     mode change 100755 => 100644 nfapi/open-nFAPI/pnf/src/pnf_p7.c
     mode change 100755 => 100644 nfapi/open-nFAPI/vnf/src/vnf_p7.c
     mode change 100755 => 100644 openair1/PHY/defs_UE.h
     mode change 100755 => 100644 openair2/COMMON/platform_constants.h
     mode change 100755 => 100644 openair2/LAYER2/MAC/eNB_scheduler_RA.c
     mode change 100755 => 100644 openair2/LAYER2/MAC/eNB_scheduler_fairRR.c
     mode change 100755 => 100644 openair2/LAYER2/MAC/eNB_scheduler_primitives.c
     mode change 100755 => 100644 openair2/LAYER2/MAC/mac_extern.h
     mode change 100755 => 100644 openair2/LAYER2/MAC/mac_vars.h
     mode change 100755 => 100644 openair2/LAYER2/MAC/main_ue.c
     mode change 100755 => 100644 openair2/LAYER2/MAC/ue_procedures.c
     mode change 100755 => 100644 openair2/LAYER2/PDCP_v10.1.0/pdcp.c
     mode change 100755 => 100644 openair2/LAYER2/PDCP_v10.1.0/pdcp.h
     mode change 100755 => 100644 openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c
     mode change 100755 => 100644 openair2/LAYER2/RLC/rlc.c
     mode change 100755 => 100644 openair2/NETWORK_DRIVER/MESH/local.h
     mode change 100755 => 100644 openair2/PHY_INTERFACE/IF_Module.h
     mode change 100755 => 100644 openair2/PHY_INTERFACE/phy_stub_UE.c
     mode change 100755 => 100644 openair2/PHY_INTERFACE/phy_stub_UE.h
     mode change 100755 => 100644 openair2/RRC/LTE/rrc_extern.h
     mode change 100755 => 100644 openair2/RRC/LTE/rrc_vars.h
     mode change 100755 => 100644 openair3/NAS/UE/ESM/esm_ebr_context.c
     mode change 100755 => 100644 openair3/NAS/UE/nas_ue_task.c
     mode change 100755 => 100644 targets/COMMON/openairinterface5g_limits.h
     mode change 100755 => 100644 targets/RT/USER/lte-enb.c
     mode change 100755 => 100644 targets/RT/USER/lte-ru.c
     mode change 100755 => 100644 targets/RT/USER/lte-softmodem.c
     mode change 100755 => 100644 targets/RT/USER/lte-softmodem.h
     mode change 100755 => 100644 targets/RT/USER/lte-ue.c
     mode change 100755 => 100644 targets/RT/USER/lte-uesoftmodem.c
    
    diff --git a/ci-scripts/oai-ci-vm-tool b/ci-scripts/oai-ci-vm-tool
    index b787129302..6e0a83e07d 100755
    --- a/ci-scripts/oai-ci-vm-tool
    +++ b/ci-scripts/oai-ci-vm-tool
    @@ -373,7 +373,6 @@ case $key in
             BUILD_OPTIONS="--eNB -t ETHERNET"
             RUN_OPTIONS="complex"
             NBARGS=$[$NBARGS+256]
    -        shift
             ;;
             flexran-rtc)
             VM_NAME=ci-flexran-rtc
    diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt
    old mode 100755
    new mode 100644
    diff --git a/nfapi/oai_integration/nfapi_vnf.c b/nfapi/oai_integration/nfapi_vnf.c
    old mode 100755
    new mode 100644
    diff --git a/nfapi/open-nFAPI/pnf/src/pnf.c b/nfapi/open-nFAPI/pnf/src/pnf.c
    old mode 100755
    new mode 100644
    diff --git a/nfapi/open-nFAPI/pnf/src/pnf_p7.c b/nfapi/open-nFAPI/pnf/src/pnf_p7.c
    old mode 100755
    new mode 100644
    diff --git a/nfapi/open-nFAPI/vnf/src/vnf_p7.c b/nfapi/open-nFAPI/vnf/src/vnf_p7.c
    old mode 100755
    new mode 100644
    diff --git a/openair1/PHY/defs_UE.h b/openair1/PHY/defs_UE.h
    old mode 100755
    new mode 100644
    diff --git a/openair2/COMMON/platform_constants.h b/openair2/COMMON/platform_constants.h
    old mode 100755
    new mode 100644
    diff --git a/openair2/LAYER2/MAC/eNB_scheduler_RA.c b/openair2/LAYER2/MAC/eNB_scheduler_RA.c
    old mode 100755
    new mode 100644
    diff --git a/openair2/LAYER2/MAC/eNB_scheduler_fairRR.c b/openair2/LAYER2/MAC/eNB_scheduler_fairRR.c
    old mode 100755
    new mode 100644
    diff --git a/openair2/LAYER2/MAC/eNB_scheduler_primitives.c b/openair2/LAYER2/MAC/eNB_scheduler_primitives.c
    old mode 100755
    new mode 100644
    diff --git a/openair2/LAYER2/MAC/mac_extern.h b/openair2/LAYER2/MAC/mac_extern.h
    old mode 100755
    new mode 100644
    diff --git a/openair2/LAYER2/MAC/mac_vars.h b/openair2/LAYER2/MAC/mac_vars.h
    old mode 100755
    new mode 100644
    diff --git a/openair2/LAYER2/MAC/main_ue.c b/openair2/LAYER2/MAC/main_ue.c
    old mode 100755
    new mode 100644
    diff --git a/openair2/LAYER2/MAC/ue_procedures.c b/openair2/LAYER2/MAC/ue_procedures.c
    old mode 100755
    new mode 100644
    diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp.c b/openair2/LAYER2/PDCP_v10.1.0/pdcp.c
    old mode 100755
    new mode 100644
    diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp.h b/openair2/LAYER2/PDCP_v10.1.0/pdcp.h
    old mode 100755
    new mode 100644
    diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c b/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c
    old mode 100755
    new mode 100644
    diff --git a/openair2/LAYER2/RLC/rlc.c b/openair2/LAYER2/RLC/rlc.c
    old mode 100755
    new mode 100644
    diff --git a/openair2/NETWORK_DRIVER/MESH/local.h b/openair2/NETWORK_DRIVER/MESH/local.h
    old mode 100755
    new mode 100644
    diff --git a/openair2/PHY_INTERFACE/IF_Module.h b/openair2/PHY_INTERFACE/IF_Module.h
    old mode 100755
    new mode 100644
    diff --git a/openair2/PHY_INTERFACE/phy_stub_UE.c b/openair2/PHY_INTERFACE/phy_stub_UE.c
    old mode 100755
    new mode 100644
    diff --git a/openair2/PHY_INTERFACE/phy_stub_UE.h b/openair2/PHY_INTERFACE/phy_stub_UE.h
    old mode 100755
    new mode 100644
    diff --git a/openair2/RRC/LTE/rrc_extern.h b/openair2/RRC/LTE/rrc_extern.h
    old mode 100755
    new mode 100644
    diff --git a/openair2/RRC/LTE/rrc_vars.h b/openair2/RRC/LTE/rrc_vars.h
    old mode 100755
    new mode 100644
    diff --git a/openair3/NAS/UE/ESM/esm_ebr_context.c b/openair3/NAS/UE/ESM/esm_ebr_context.c
    old mode 100755
    new mode 100644
    diff --git a/openair3/NAS/UE/nas_ue_task.c b/openair3/NAS/UE/nas_ue_task.c
    old mode 100755
    new mode 100644
    diff --git a/targets/COMMON/openairinterface5g_limits.h b/targets/COMMON/openairinterface5g_limits.h
    old mode 100755
    new mode 100644
    diff --git a/targets/RT/USER/lte-enb.c b/targets/RT/USER/lte-enb.c
    old mode 100755
    new mode 100644
    diff --git a/targets/RT/USER/lte-ru.c b/targets/RT/USER/lte-ru.c
    old mode 100755
    new mode 100644
    diff --git a/targets/RT/USER/lte-softmodem.c b/targets/RT/USER/lte-softmodem.c
    old mode 100755
    new mode 100644
    diff --git a/targets/RT/USER/lte-softmodem.h b/targets/RT/USER/lte-softmodem.h
    old mode 100755
    new mode 100644
    diff --git a/targets/RT/USER/lte-ue.c b/targets/RT/USER/lte-ue.c
    old mode 100755
    new mode 100644
    diff --git a/targets/RT/USER/lte-uesoftmodem.c b/targets/RT/USER/lte-uesoftmodem.c
    old mode 100755
    new mode 100644
    
    From 5e35d909747e31698d1e69b00c6bdd1ec35cb127 Mon Sep 17 00:00:00 2001
    From: Raphael Defosseux 
    Date: Wed, 23 Jan 2019 16:53:52 +0100
    Subject: [PATCH 233/233] CI: adding L2-NFAPI simulator test results to HTML
     report
    
    Signed-off-by: Raphael Defosseux 
    ---
     ci-scripts/Jenkinsfile-gitlab   |   8 +--
     ci-scripts/reportTestLocally.sh | 124 ++++++++++++++++++++++++++++++++
     ci-scripts/runTestOnVM.sh       |  86 ++++++++++++++++++++--
     nfapi/open-nFAPI/pnf/src/pnf.c  |   5 +-
     4 files changed, 212 insertions(+), 11 deletions(-)
    
    diff --git a/ci-scripts/Jenkinsfile-gitlab b/ci-scripts/Jenkinsfile-gitlab
    index b050eff60e..fc0290fc44 100644
    --- a/ci-scripts/Jenkinsfile-gitlab
    +++ b/ci-scripts/Jenkinsfile-gitlab
    @@ -41,7 +41,7 @@ pipeline {
             disableConcurrentBuilds()
             timestamps()
             gitLabConnection('OAI GitLab')
    -        gitlabBuilds(builds: ["Build eNb-USRP", "Build basic-sim", "Build phy-sim", "Build eNb-ethernet", "Build UE-ethernet", "Analysis with cppcheck", "Test phy-sim", "Test basic-sim", "Test-FDD-Band7", "Test-TDD-Band40", "Test-IF4p5-FDD-Band7", "Test-IF4p5-TDD-Band40"])
    +        gitlabBuilds(builds: ["Build eNb-USRP", "Build basic-sim", "Build phy-sim", "Build eNb-ethernet", "Build UE-ethernet", "Analysis with cppcheck", "Test phy-sim", "Test basic-sim", "Test L2-sim", "Test-FDD-Band7", "Test-TDD-Band40", "Test-IF4p5-FDD-Band7", "Test-IF4p5-TDD-Band40"])
             ansiColor('xterm')
         }
     
    @@ -332,11 +332,11 @@ pipeline {
                     }
                     stage ("Test L2 simulator") {
                         steps {
    -                        //gitlabCommitStatus(name: "Test basic-sim") {
    +                        gitlabCommitStatus(name: "Test L2-sim") {
                                 timeout (time: 30, unit: 'MINUTES') {
                                     sh "./ci-scripts/oai-ci-vm-tool test --workspace $WORKSPACE --variant l2-sim --job-name ${JOB_NAME} --build-id ${BUILD_ID}"
                                 }
    -                        //}
    +                        }
                         }
                     }
                     stage ("Build Flexran Controller") {
    @@ -534,7 +534,7 @@ pipeline {
                     always {
                         script {
                             dir ('archives') {
    -                            sh "if [ -d basic_sim/test ] || [ -d phy_sim/test ]; then zip -r -qq vm_tests_logs.zip */test ; fi"
    +                            sh "if [ -d basic_sim/test ] || [ -d phy_sim/test ] || [ -d l2_sim/test ]; then zip -r -qq vm_tests_logs.zip */test ; fi"
                             }
                             if(fileExists('archives/vm_tests_logs.zip')) {
                                 archiveArtifacts artifacts: 'archives/vm_tests_logs.zip'
    diff --git a/ci-scripts/reportTestLocally.sh b/ci-scripts/reportTestLocally.sh
    index 60dcb1e421..004e021de1 100755
    --- a/ci-scripts/reportTestLocally.sh
    +++ b/ci-scripts/reportTestLocally.sh
    @@ -417,6 +417,130 @@ function report_test {
             echo "   " >> ./test_simulator_results.html
         fi
     
    +    ARCHIVES_LOC=archives/l2_sim/test
    +    if [ -d $ARCHIVES_LOC ]
    +    then
    +        echo "   

    L2-NFAPI Simulator Check

    " >> ./test_simulator_results.html + + if [ -f $ARCHIVES_LOC/test_final_status.log ] + then + if [ `grep -c TEST_OK $ARCHIVES_LOC/test_final_status.log` -eq 1 ] + then + echo "
    " >> ./test_simulator_results.html + echo " TEST was SUCCESSFUL " >> ./test_simulator_results.html + echo "
    " >> ./test_simulator_results.html + else + echo "
    " >> ./test_simulator_results.html + echo " TEST was a FAILURE! " >> ./test_simulator_results.html + echo "
    " >> ./test_simulator_results.html + fi + else + echo "
    " >> ./test_simulator_results.html + echo " COULD NOT DETERMINE TEST FINAL STATUS! " >> ./test_simulator_results.html + echo "
    " >> ./test_simulator_results.html + fi + + echo " " >> ./test_simulator_results.html + echo "
    " >> ./test_simulator_results.html + echo " " >> ./test_simulator_results.html + echo " " >> ./test_simulator_results.html + echo " " >> ./test_simulator_results.html + echo " " >> ./test_simulator_results.html + echo " " >> ./test_simulator_results.html + echo " " >> ./test_simulator_results.html + echo " " >> ./test_simulator_results.html + + TRANS_MODES=("fdd") + BW_CASES=(05) + for TMODE in ${TRANS_MODES[@]} + do + for BW in ${BW_CASES[@]} + do + ENB_LOG=$ARCHIVES_LOC/${TMODE}_${BW}MHz_enb.log + UE_LOG=`echo $ENB_LOG | sed -e "s#enb#ue#"` + if [ -f $ENB_LOG ] && [ -f $UE_LOG ] + then + NAME_ENB=`echo $ENB_LOG | sed -e "s#$ARCHIVES_LOC/##"` + NAME_UE=`echo $UE_LOG | sed -e "s#$ARCHIVES_LOC/##"` + echo " " >> ./test_simulator_results.html + echo " " >> ./test_simulator_results.html + echo " " >> ./test_simulator_results.html + NB_ENB_GOT_SYNC=`egrep -c "got sync" $ENB_LOG` + NB_UE_GOT_SYNC=`egrep -c "got sync" $UE_LOG` + NB_ENB_SYNCED_WITH_UE=`egrep -c "Sending NFAPI_START_RESPONSE" $UE_LOG` + if [ $NB_ENB_GOT_SYNC -eq 1 ] && [ $NB_UE_GOT_SYNC -eq 3 ] && [ $NB_ENB_SYNCED_WITH_UE -eq 1 ] + then + echo " " >> ./test_simulator_results.html + else + echo " " >> ./test_simulator_results.html + fi + echo " " >> ./test_simulator_results.html + echo " " >> ./test_simulator_results.html + fi + PING_CASE=$ARCHIVES_LOC/${TMODE}_${BW}MHz_ping_epc.txt + if [ -f $PING_CASE ] + then + echo " " >> ./test_simulator_results.html + NAME=`echo $PING_CASE | sed -e "s#$ARCHIVES_LOC/##"` + echo " " >> ./test_simulator_results.html + CMD=`egrep "COMMAND IS" $PING_CASE | sed -e "s#COMMAND IS: ##"` + echo " " >> ./test_simulator_results.html + FILE_COMPLETE=`egrep -c "ping statistics" $PING_CASE` + if [ $FILE_COMPLETE -eq 0 ] + then + echo " " >> ./test_simulator_results.html + echo " " >> ./test_simulator_results.html + else + NB_TR_PACKETS=`egrep "packets transmitted" $PING_CASE | sed -e "s# packets transmitted.*##"` + NB_RC_PACKETS=`egrep "packets transmitted" $PING_CASE | sed -e "s#^.*packets transmitted, ##" -e "s# received,.*##"` + if [ $NB_TR_PACKETS -eq $NB_RC_PACKETS ] + then + echo " " >> ./test_simulator_results.html + else + echo " " >> ./test_simulator_results.html + fi + echo " " >> ./test_simulator_results.html + fi + echo " " >> ./test_simulator_results.html + fi + + done + done + + echo "
    Log File NameCommandStatusStatistics
    $NAME_ENB --- $NAME_UEN/AOKKO
    " >> ./test_simulator_results.html
    +                    if [ $NB_ENB_GOT_SYNC -eq 1 ]
    +                    then
    +                        echo "- eNB --> got sync" >> ./test_simulator_results.html
    +                    else
    +                        echo "- eNB NEVER got sync" >> ./test_simulator_results.html
    +                    fi
    +                    if [ $NB_UE_GOT_SYNC -eq 3 ]
    +                    then
    +                        echo "- UE --> got sync" >> ./test_simulator_results.html
    +                    else
    +                        echo "- UE NEVER got sync" >> ./test_simulator_results.html
    +                    fi
    +                    if [ $NB_ENB_SYNCED_WITH_UE -eq 1 ]
    +                    then
    +                        echo "- UE attached to eNB" >> ./test_simulator_results.html
    +                    else
    +                        echo "- UE NEVER attached to eNB" >> ./test_simulator_results.html
    +                    fi
    +                    echo "        
    $NAME$CMDKON/AOKKO" >> ./test_simulator_results.html + echo "
    " >> ./test_simulator_results.html
    +                        STATS=`egrep "packets transmitted" $PING_CASE | sed -e "s#^.*received, ##" -e "s#, time.*##" -e "s# packet loss##"`
    +                        echo "Packet Loss : $STATS" >> ./test_simulator_results.html
    +                        RTTMIN=`egrep "rtt min" $PING_CASE | awk '{split($4,a,"/"); print a[1] " " $5}'`
    +                        echo "RTT Minimal : $RTTMIN" >> ./test_simulator_results.html
    +                        RTTAVG=`egrep "rtt min" $PING_CASE | awk '{split($4,a,"/"); print a[2] " " $5}'`
    +                        echo "RTT Average : $RTTAVG" >> ./test_simulator_results.html
    +                        RTTMAX=`egrep "rtt min" $PING_CASE | awk '{split($4,a,"/"); print a[3] " " $5}'`
    +                        echo "RTT Maximal : $RTTMAX" >> ./test_simulator_results.html
    +                        echo "            
    " >> ./test_simulator_results.html + echo "
    " >> ./test_simulator_results.html + echo "
    " >> ./test_simulator_results.html + fi + ARCHIVES_LOC=archives/phy_sim/test if [ -d $ARCHIVES_LOC ] then diff --git a/ci-scripts/runTestOnVM.sh b/ci-scripts/runTestOnVM.sh index 4d87ba5791..7ff04e23f8 100755 --- a/ci-scripts/runTestOnVM.sh +++ b/ci-scripts/runTestOnVM.sh @@ -148,6 +148,15 @@ function ping_ue_ip_addr { rm -f $1 } +function ping_epc_ip_addr { + echo "echo \"COMMAND IS: ping -I oip1 -c 20 $3\" > $4" > $1 + echo "rm -f $4" >> $1 + echo "ping -I oip1 -c 20 $3 | tee -a $4" >> $1 + cat $1 + ssh -o StrictHostKeyChecking=no ubuntu@$2 < $1 + rm -f $1 +} + function check_ping_result { local LOC_PING_FILE=$1 local LOC_NB_PINGS=$2 @@ -157,16 +166,19 @@ function check_ping_result { if [ $FILE_COMPLETE -eq 0 ] then PING_STATUS=-1 + echo "ping file incomplete" else local ALL_PACKET_RECEIVED=`egrep -c "$LOC_NB_PINGS received" $LOC_PING_FILE` if [ $ALL_PACKET_RECEIVED -eq 1 ] then echo "got all ping packets" else + echo "got NOT all ping packets" PING_STATUS=-1 fi fi else + echo "ping file not present" PING_STATUS=-1 fi } @@ -533,8 +545,30 @@ function start_l2_sim_enb { echo "sudo -E daemon --inherit --unsafe --name=enb_daemon --chdir=/home/ubuntu/tmp/cmake_targets/lte_build_oai/build/ -o /home/ubuntu/tmp/cmake_targets/log/$LOC_LOG_FILE ./my-lte-softmodem-run.sh" >> $1 ssh -o StrictHostKeyChecking=no ubuntu@$LOC_VM_IP_ADDR < $1 - sleep 10 rm $1 + + local i="0" + echo "egrep -c \"Waiting for PHY_config_req\" /home/ubuntu/tmp/cmake_targets/log/$LOC_LOG_FILE" > $1 + while [ $i -lt 10 ] + do + sleep 5 + CONNECTED=`ssh -o StrictHostKeyChecking=no ubuntu@$LOC_VM_IP_ADDR < $1` + if [ $CONNECTED -ne 0 ] + then + i="100" + else + i=$[$i+1] + fi + done + rm $1 + if [ $i -lt 50 ] + then + ENB_SYNC=0 + echo "L2-SIM eNB is NOT sync'ed: process still alive?" + else + ENB_SYNC=1 + echo "L2-SIM eNB is sync'ed: waiting for UE(s) to connect" + fi } function start_l2_sim_ue { @@ -551,8 +585,31 @@ function start_l2_sim_ue { echo "sudo -E daemon --inherit --unsafe --name=ue_daemon --chdir=/home/ubuntu/tmp-ue/cmake_targets/lte_build_oai/build/ -o /home/ubuntu/tmp/cmake_targets/log/$LOC_LOG_FILE ./my-lte-softmodem-run.sh" >> $1 ssh -o StrictHostKeyChecking=no ubuntu@$LOC_VM_IP_ADDR < $1 - sleep 10 rm $1 + + local i="0" + echo "egrep -c \"Received NFAPI_START_REQ\" /home/ubuntu/tmp/cmake_targets/log/$LOC_LOG_FILE" > $1 + while [ $i -lt 10 ] + do + sleep 5 + CONNECTED=`ssh -o StrictHostKeyChecking=no ubuntu@$LOC_VM_IP_ADDR < $1` + if [ $CONNECTED -eq 1 ] + then + i="100" + else + i=$[$i+1] + fi + done + rm $1 + if [ $i -lt 50 ] + then + UE_SYNC=0 + echo "L2-SIM UE is NOT sync'ed w/eNB" + else + UE_SYNC=1 + echo "L2-SIM UE is sync'ed w/eNB" + fi + sleep 10 } function run_test_on_vm { @@ -1197,10 +1254,24 @@ function run_test_on_vm { echo "############################################################" CURRENT_UE_LOG_FILE=fdd_05MHz_ue.log start_l2_sim_ue $VM_CMDS $VM_IP_ADDR $CURRENT_UE_LOG_FILE ue.nfapi.conf + if [ $UE_SYNC -eq 0 ] + then + echo "Problem w/ eNB and UE not syncing" + terminate_enb_ue_basic_sim $VM_CMDS $VM_IP_ADDR + scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_ENB_LOG_FILE $ARCHIVES_LOC + scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/tmp/cmake_targets/log/$CURRENT_UE_LOG_FILE $ARCHIVES_LOC + terminate_epc $EPC_VM_CMDS $EPC_VM_IP_ADDR + echo "TEST_KO" > $ARCHIVES_LOC/test_final_status.log + exit -1 + fi - sleep 30 - echo "ping -I oip1 -c 20 $REAL_EPC_IP_ADDR" > $VM_CMDS - ssh -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR < $VM_CMDS + echo "############################################################" + echo "Pinging the EPC from UE" + echo "############################################################" + PING_LOG_FILE=fdd_05MHz_ping_epc.txt + ping_epc_ip_addr $VM_CMDS $VM_IP_ADDR $REAL_EPC_IP_ADDR $PING_LOG_FILE + scp -o StrictHostKeyChecking=no ubuntu@$VM_IP_ADDR:/home/ubuntu/$PING_LOG_FILE $ARCHIVES_LOC + check_ping_result $ARCHIVES_LOC/$PING_LOG_FILE 20 echo "############################################################" echo "Terminate enb/ue simulators" @@ -1226,6 +1297,11 @@ function run_test_on_vm { ssh-keygen -R $EPC_VM_IP_ADDR fi + echo "############################################################" + echo "Checking run status" + echo "############################################################" + + if [ $PING_STATUS -ne 0 ]; then STATUS=-1; fi if [ $STATUS -eq 0 ] then echo "TEST_OK" > $ARCHIVES_LOC/test_final_status.log diff --git a/nfapi/open-nFAPI/pnf/src/pnf.c b/nfapi/open-nFAPI/pnf/src/pnf.c index 0cacf8c66f..eec9ff80c3 100644 --- a/nfapi/open-nFAPI/pnf/src/pnf.c +++ b/nfapi/open-nFAPI/pnf/src/pnf.c @@ -1237,11 +1237,11 @@ int pnf_connect(pnf_t* pnf) } struct addrinfo *p = servinfo; - int i = 0; int connected = 0; while(p != NULL && connected == 0) { +#ifdef NFAPI_TRACE_ENABLED char* family = "Unknown"; char* address = "Unknown"; char _addr[128]; @@ -1260,7 +1260,8 @@ int pnf_connect(pnf_t* pnf) address = inet_ntoa(addr->sin_addr); } - //NFAPI_TRACE(NFAPI_TRACE_NOTE, "Host address info %d Family:%s Address:%s\n", i++, family, address); + NFAPI_TRACE(NFAPI_TRACE_NOTE, "Host address info %d Family:%s Address:%s\n", i++, family, address); +#endif if (pnf->sctp) {

    +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⁡US7kWP%|AhE2Dn?+s%* z@+$eRUjsj`5@@jOB{Gh(-|F}K2Jy3jniqXRjqPsOc)_P?+|f}&zY7`%BIb0UE#{LDatES7`{U_(`LSHv_+0 ze?rx!2DB8-1H!f&85VDDySr!rC%-oxw!N@6BaV|{R6Lb-)2^QhXJqOw*&FQ!_?@!R zI#7dnM-%q^7F^|1QEh60p(PpB?$+nMTA6Vt!E zFB^GuSHaQgXHKY}dXLhHvS+hD@L9HLJYZuk$c;--V9VVeyvMghQLOUguJFUM@BE_m zMhW`DJ#HhP!t|Tp@RhH6w7af|FGkGyHKh86U`mmOctYG}M6PCSD~{t!?0NaA#|#uz z@kB0ZFmM$8WQq~dbR_C|aOpDOzPdHQj_PQwKtD;iS2XfDB*Pop zLz`5d^@RTv5R9Vn#PVj-f>wOy)NFDLkE3iDya^EW;7nzmLItLG zeT@G5CzG8VE3v)u%2k`$GZjc4hq&RT(^B!XGsfUl= zl*9Ftes~nUSePRLcfOLY%<$}#`vK7O_czS1MwU;+ZWfr!2Qm%@%!jzFx*|CASt9*{ zZevi)P*ub%q0)QaezD!TMfl?7((rUNuH|WY9k^NcL+X%WTck1#TR~Bz_ABApx&L;1 z1#8iM5`jQrhLs2NlKhD+UF1H^^RL}SfnW}tTf@!e4r5!fqmkJ>{t_3q35G=|vbn57 znw~MhP0Vy?D5Z!}b^#&9E%=dGyjd6>)GtC%esv|XA97AZvXAs)Y?}IWSHQV(r zm;5^-3orOuw&m1?Y7C|#!qh0aTIc9kMi8^3jt1PbWq$GF{29h>_ep(km?U%Q`=&(! zedMb5(}_B#>_Ifo;k~7p5B-=HeZ=Mj(|_>lnB1T0W-z<@3Xq7e$w2RHaS>UkBxF#& zqIpYS_AFLdCYOy^BRRQ2wuTdUn$Gce3Unf~zep%3N1^wvxEIA|aVho)eBmn1E7VA7 z7>Q|IY_c1Wr3KZ zGg3mq*tsv~Ib{{4mqVwej2zsS%g|dwRPw>O(QOTsD}p+>AP2IMCc|dR@queNV~0oM zzwsEO4g(DlC;A3F-;To@V8Aifnw76^&=d8k6rmJZ;G_hDDxvqd*OCcZOD9o2R=6Qj zrb4x`kty7K2ZJ84NzoY$#zXGJ8?V+OVs>aaXu6k=&_I!3N|=s)j7)r#{e8suIx|^y zU!rfq+=ESaA7JX=m4m#JU||le-xvJ`XpN8q7chAk& z>z?|ICJV50$rJCBf-;+_;>cX@DN!3T?Eg-F|Ydiqb5asT|DU_P>d|yS}15FkG8ko14?`>T<4M4kktKbS!f?8g8K#>wm#PeTs`Q65=a@laq4l4pY8N&N(X8ug#H2 z8?4G;Mmg%aw<49V{6r|3R?O~0D|b4x=qTscSo@`2otXMtNvmopDATzYm7>Ry9y&$D zL~*E;+^aX%_cdJ!q4-sXiGY#8lr_#oguy`v>k=Q1m~~8{0S*%-vV7@|appl=>xyK@#IZQ&nNTeqPqj;ouuKH-i8b+BZTX+BnJL6h&J)3sYAzqs=g<~%~`tzx|9 zBpf;MVuiW7Bz zydD2{jQ%-R!=;!*Zq;E~)JfF%A~MglSoA0XhzDg-^7VE}F1FswnyS6V8mNj(M@Gpv zLL@MY{TwwWt!l}n%+JSdm=GVh*OSgo9SO+Nmh@*UMMfcg`*~33*7JQpW;)Z$PkB|E z4Gx|r0s`VmWK(4Iv``w%?)r`Qx#T2!_RI_~d1=t|kss+1=myApO!l`$4$=$qAbBuB zvbi)Q$YqzvZ^y_VrE4C7k{B#Pb%S0EvOtve!9d^}>n38usDS`~O8YBQv{89syqq9p zAw-mctvE4IT6EdI%>F{&yJEepfw83-$&0SzUbJA0^R5)hgw{a^$e0_gTZQeH4jZbM zk${Tq@9)Vj=e!d_;idv0k9*en z*UTV+uCytqK<=t)?)*XAPV6V9gXr0NcqWGl335c(U}THoT%Qp~ACW=ROd4~9VqHaq zxWSk$w4Y>$N~1oca>s!C0KYd{Q$Dl}5N_<<0ckeD1#G%!Fqbq4FLV_HGh2*)|0f~a z_ff0tRG=NV=v0iX!&)#V4e(%xGnAxrv8#rB_Z>ERvFEbF(xQ+%Ux9;Cg9f=A4NUNU zy0cB!T8bo}L+L+%ZFNkA>pA54604$a5Z@{y%?l?bgIWIB8y&1QF|l+>Ht)|g)mYT@ zlV&R_2c20J3Bo|NW{EO5zAIA0vEnpAw2z6f@tP;8QzK?6TQ@-AAT8A_3h9S0_5rHT z$l2g~m2L4ne9{y;O35UegNPXyS%4$9{|!4;XwB2Q#X!t^j)h~o<5hIXp;h9BHy^_I z;pnUichX%414n(C>PdjT7suMY>g`TvVUiPvJCKw=B z>4jLxc8%hHSV}w#{`FAQ5Ax;LE`0~*|8xU~XHyRcAPhjIvp~bUn-yoD9*im%Um~<7 z&~rY$+DS%&Xfl1=ws5I9`QmN|NPRVfQnFg~&^+mX;SVd54)>kaRZHXrsKfb$BizECyr1 zPT2it(UUP(T357dNN*QEy{*r$*9>{cb7jrBq@A^31dMATnoy_BBI(xRl>~l)yPtgf z3<%(Uj{719s-(h@1xnQu&3JpppJ&J*jwC>2^bINVO;ro?(@BxtY2PzzGVO#AGYBt^ z!3P8r%~i66DE~p2IVY?JZfGi>FC;1e377Zh0;1)iZFaGRYeg9*p#d3`=;OeTQlTF9GBm-it-ZTq;OVzfo6tOQm9`ca|R+B~x zdXyZWLXjO+z2@++gHi@Qxe8-60*guNo1>PJuW75>@`oOMN{UJ8fRsF0=SWUDhObsZ z(cE;vz%;~n(-G@q2ZhO1fl`1i!p{WLj*T`nFdEgHKB7eCr7eXP$Jm2K0UMH6QaM0- zUXn5k2X8<->akjAB@Gfx3TOGF)ej^}s+?8cy20Rims~UiIv-&YA1CAj3b9P@@>g7| zF_j9@UWFMM(Z3hXa!pF5SM`TfgeGws2J&e}(8BVS0jhYNRQ(bqAj)kplQ%n^9XvqK zj1*KZKA1oPyj&2n^r`-uyA^9A=7sq#5uJ<^!dVG=B|Eny4cdUQ7{6z-IySmq)YPm=z+ABv=U%(xR>}D1;-^DK78{mR!SRcUf1mQLN$H&KasAy;m|EhR@5p9nA zxcL?d+=-B;MFfIG1f2Q3n&%nPRxM$T0ybnG@66db3Ph<*+=*lXTjovAA+soGXS7Kh z%?qi5<|G}NUU3gfb5t?054o)`seYU`wi7qul#aLz704mBpd(lc7-xL}zZGmLE-#nU z&%CWeC%H5Geu9wJOSr9C$sw5@ofH+j*jB^x7lRax#s*Eh&j@{NY1$!JG~R zd}@ND&F!)hW#4kpAIF?a(0;3%qpX&Dq64J`qH}Gt$V|^rzaW*z@0`OM88gdp4CX^KjN=uJQ6rx$Bfct98>A6RLg`PT$Hi2vs`|6Rgg%UWN`4BzGpxJ zGsNh<1&876rCt8U_?kB*bE5saJ*@=J+4PXy9BY~VVw*x@Vx-hk*Qa`g=A4NX437vJ z7$v$7BgdEDS$gj?%W0xmXY`X;5u@lN^6^ zPrCz1Yrym#W-JhDkkXL8i_K}!u17UiC4q~z1J=`!FHkKG9%zb9&P(BS@0s8uZ32J| zu5i{l1QTWdf)9xDws-nV?)vfN)wlx6)rDhIfdDP72?>)$NASahY+>*a>hQc?~wbziLmrB_by$zwLGY3l#|z zKMCe;i(VyZ!W!d)Dcj2M+J_ih62L$3;7WwZbWuoPT2A0WDZC9^icUmL8=J6f!N+L-k3f{VM3G>e&BOd z=_0NfQVk(~U>Qx^S^udDAk83k6^Kp|sRG{yBlG;wI!=KB3ylaFvNnpS9b{`D?oKI& zti)_-Vy33_UD#bBkD@9d(eV|RJ;p$GXM&h)#*>aD;79@Tp~~@oJN4#I#ZOjg5A+9a zg{{bgH$Kj$d3#xk@u2JrUQHd{GX={Q{x>TJqyeg2_z6Y}nw`LmEB);}7sqWmp$}W* zsuyD8-3IoMJ@v?zv7TIVg=}*t^Le<^o}dH%?F?xK+YH6;=UxZA*%Y!}qE`qIgbd&1 zlHj8EWDd5;mmRzSUm5`k@T;VtL|0q;>Py-|oJJ35MLW5~td^jtlyCQ>Wc-1Jcn)d> zkD`9eaRBz2N3}_yjg&l!0v^{X552lKID#fu(eIzBJ4;y6!AA5b;L2+*4(fUGRyIAQ z6{92@t!n9PbuNGrXd$DN{f=O%^rtWh9ylK#Ck_>p+ zak8<82iVV0TE|cu4&C37d8#@wGS8xcfBP_+uY=J!DP%IP_wDWD@S*<2$TAcwhFtH=YD|G%J3HCBuA0LMK3EYGqQz?rT;|@V8*1KT`ru%u? z^XQ54g53F;6d$-)=xM^~A*I?lG=)bzI%JWYIo2bL!lqLX2nZW9)^%u2R1O5Q49OKQ z{_f)BV!vhiZW;FA{oF(bV2~nCU5pODkdh*3o9bdS1sp+X1z8cZWg3?6ZO}&cm*FFy;+wnEj`BGlKAVrKQ z(-eYt{aT^B-QSczV`TVS81rLIN5KU7kDGwqQHFR7CqF-g<9y$N%;mw&5n_b&pL}U~ z?_)Bf6ym_CsxO_onTe}j{z*cy&|Avi(R^*$k+7$tjnZ?!+OO+(l?;so71xNbsIz5E z=MYR6#|%YsMMT{)*p^_4yZ^%yBNebOM%(MiisOA`3-ckgTB7Z(E7 zgr;FgEQY&M!fcv0DO zFw^Gynf|`gWrdOJV_w@^rHFp=6{h11ULdMFUTD)>WkUEq+4cQ|)bzwunX@8aDigyC z*)e4*L}iTdP|w0o8bsB)aYCy4Vt(NU4`4skr8GT$&Yzgy4W+ zl)S(Y8`e_N&9qp2Fym(wtCZgeGQx;bCT~B<32nbzNXJyX@ICYq?DtSMP8majI1u!N z*Yd$Spt!dZ9Tv9aH`8e#c_t7Y2cS36mjJMq(*qPK0l4H|l>bCi@VpEgc|dH;Ahfu@ zA*WJW0QE9lRlY|Sy|Vf~SC;#PcYRFI(N{8=g8EwiUB5cJ;8)p>Wkz82+VlGyDNO1j zDd2T?F(!Zx_GAQT9*Ic+diqD-H`Aef%c=w-kk~?apE>TwhG>y{7u<(29_gUuKT|w?vsTL;#|kF(fg-?`I5ePqi#<) z2y}*lT8SV!QvgGsEoz`LwcJ#!9%ktu{V>F@yYKHB{emIiV`~{lX|Eogb87Z4F)