diff --git a/ci-scripts/xml_files/lte_2x2_tm1_quectel.xml b/ci-scripts/xml_files/lte_2x2_tm1_quectel.xml
index 6aa53200c85ec8e484da718b6ae1dc8a25f5514d..0d18a52839b47278f383ae36329d8f627f0e448a 100644
--- a/ci-scripts/xml_files/lte_2x2_tm1_quectel.xml
+++ b/ci-scripts/xml_files/lte_2x2_tm1_quectel.xml
@@ -88,7 +88,7 @@
 		<id>nrmodule2_quectel</id>
 		<ping_args>-c 20</ping_args>
 		<ping_packetloss_threshold>1</ping_packetloss_threshold>
-		<ping_rttavg_threshold>40</ping_rttavg_threshold>
+		<ping_rttavg_threshold>60</ping_rttavg_threshold>
 	</testCase>
 	<testCase id="050001">
 		<class>Ping</class>
@@ -96,7 +96,7 @@
 		<id>nrmodule2_quectel</id>
 		<ping_args>-c 100 -s 1024 -i 0,2</ping_args>
 		<ping_packetloss_threshold>1</ping_packetloss_threshold>
-		<ping_rttavg_threshold>40</ping_rttavg_threshold>
+		<ping_rttavg_threshold>60</ping_rttavg_threshold>
 	</testCase>
 
 
diff --git a/ci-scripts/xml_files/lte_2x2_tm2_quectel.xml b/ci-scripts/xml_files/lte_2x2_tm2_quectel.xml
index 84aa87aa235eaaa28d220111c8157b77616106e0..f84691ab488420f520969ed41cc695b0f19335ae 100644
--- a/ci-scripts/xml_files/lte_2x2_tm2_quectel.xml
+++ b/ci-scripts/xml_files/lte_2x2_tm2_quectel.xml
@@ -88,7 +88,7 @@
 		<id>nrmodule2_quectel</id>
 		<ping_args>-c 20</ping_args>
 		<ping_packetloss_threshold>1</ping_packetloss_threshold>
-		<ping_rttavg_threshold>40</ping_rttavg_threshold>
+		<ping_rttavg_threshold>60</ping_rttavg_threshold>
 	</testCase>
 	<testCase id="050003">
 		<class>Ping</class>
@@ -96,7 +96,7 @@
 		<id>nrmodule2_quectel</id>
 		<ping_args>-c 100 -s 1024 -i 0,2</ping_args>
 		<ping_packetloss_threshold>1</ping_packetloss_threshold>
-		<ping_rttavg_threshold>40</ping_rttavg_threshold>
+		<ping_rttavg_threshold>60</ping_rttavg_threshold>
 	</testCase>
 
 
diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt
index 669f7764611e2955d4414daa91af34c7fc14ef49..c08d9378b848933a619cdbaf65eb98175713b4a2 100644
--- a/cmake_targets/CMakeLists.txt
+++ b/cmake_targets/CMakeLists.txt
@@ -1542,9 +1542,10 @@ set(PHY_SRC_UE
 
   set(PHY_NR_SRC_COMMON
   ${OPENAIR1_DIR}/PHY/NR_TRANSPORT/nr_prach_common.c
-  ${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/srs_modulation_nr.c
+  ${OPENAIR1_DIR}/PHY/NR_TRANSPORT/nr_csi_rs.c
   ${OPENAIR1_DIR}/PHY/NR_TRANSPORT/nr_scrambling.c
   ${OPENAIR1_DIR}/PHY/NR_REFSIG/scrambling_luts.c
+  ${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/srs_modulation_nr.c
   )
 
   set(PHY_NR_SRC
@@ -1568,7 +1569,6 @@ set(PHY_SRC_UE
   ${OPENAIR1_DIR}/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c
   ${OPENAIR1_DIR}/PHY/NR_REFSIG/ul_ref_seq_nr.c
   ${OPENAIR1_DIR}/PHY/NR_REFSIG/nr_dmrs_rx.c
-  ${OPENAIR1_DIR}/PHY/NR_TRANSPORT/nr_csi_rs.c
   ${OPENAIR1_DIR}/PHY/NR_REFSIG/nr_gold.c
   ${OPENAIR1_DIR}/PHY/NR_REFSIG/nr_gen_mod_table.c
   ${OPENAIR1_DIR}/PHY/NR_REFSIG/dmrs_nr.c
@@ -1616,6 +1616,7 @@ set(PHY_SRC_UE
   ${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/dci_nr.c
   ${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/dci_tools_nr.c
   ${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/pucch_nr.c
+  ${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/csi_rx.c
   ${OPENAIR1_DIR}/PHY/NR_TRANSPORT/nr_uci_tools_common.c
   ${OPENAIR1_DIR}/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c
   ${OPENAIR1_DIR}/PHY/NR_REFSIG/ul_ref_seq_nr.c
diff --git a/cmake_targets/build_oai b/cmake_targets/build_oai
index 5cafb95cba61913ec9535bfcdb9aef9ddb5a79b3..6e788c9676692c1419be71219e01352e70f147f0 100755
--- a/cmake_targets/build_oai
+++ b/cmake_targets/build_oai
@@ -713,11 +713,11 @@ function main() {
 	# simlist="ldpctest"
     for f in $simlist ; do
       compilations \
-        ran_build $f \
+        $BUILD_DIR $f \
 	    $f $dbin/$f.$REL
     done
     compilations \
-      ran_build coding \
+      $BUILD_DIR coding \
       libcoding.so $dbin/libcoding.so
   fi
 
@@ -729,7 +729,7 @@ function main() {
     simlist="secu_knas_encrypt_eia1 secu_kenb aes128_ctr_encrypt aes128_ctr_decrypt secu_knas_encrypt_eea2 secu_knas secu_knas_encrypt_eea1 kdf aes128_cmac_encrypt secu_knas_encrypt_eia2"
     for f in $simlist ; do
       compilations \
-	    ran_build test_$f \
+	    $BUILD_DIR test_$f \
 	    test_$f $dbin/test_$f.$REL
     done
   fi
diff --git a/common/utils/nr/nr_common.c b/common/utils/nr/nr_common.c
index 1e76d2e949ea3d40da1d15a72aab1de7f5f065e6..af31c83d6e1f5dce62d2b54818a74dab3fac8c16 100644
--- a/common/utils/nr/nr_common.c
+++ b/common/utils/nr/nr_common.c
@@ -442,7 +442,6 @@ int get_nr_table_idx(int nr_bandP, uint8_t scs_index) {
   return i;
 }
 
-
 int get_subband_size(int NPRB,int size) {
   // implements table  5.2.1.4-2 from 36.214
   //
diff --git a/executables/main-ocp.c b/executables/main-ocp.c
index c9388e179d167e9fef5da4a1908fa3e4ecd68445..5d949d5a287a1b10e11e12dc1540c7badca78c7b 100644
--- a/executables/main-ocp.c
+++ b/executables/main-ocp.c
@@ -173,7 +173,7 @@ void init_transport(PHY_VARS_eNB *eNB) {
   }
 
   for (int i=0; i<NUMBER_OF_ULSCH_MAX; i++) {
-    LOG_D(PHY,"Allocating Transport Channel Buffer for ULSCH, UE %d\n",i);
+    LOG_D(PHY,"Allocating Transport Channel Buffers for ULSCH, UE %d\n",i);
     AssertFatal((eNB->ulsch[1+i] = new_eNB_ulsch(MAX_TURBO_ITERATIONS,fp->N_RB_UL, 0)) != NULL,
                 "Can't get eNB ulsch structures\n");
     // this is the transmission mode for the signalling channels
diff --git a/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h b/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h
index 7e443339f9dc85a1474c70f9164b7dcb753a3401..fd9af0172091531ad9451a51736f675df6a39f6d 100644
--- a/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h
+++ b/nfapi/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h
@@ -481,20 +481,20 @@ typedef struct {
 
 
 typedef struct {
-  uint16_t bwp_size;//
-  uint16_t bwp_start;//
-  uint8_t  subcarrier_spacing;//
-  uint8_t  cyclic_prefix;//
-  uint16_t start_rb;
-  uint16_t nr_of_rbs;
-  uint8_t  csi_type;//Value: 0:TRS 1:CSI-RS NZP 2:CSI-RS ZP
-  uint8_t  row;//Row entry into the CSI Resource location table. [TS38.211, sec 7.4.1.5.3 and table 7.4.1.5.3-1] Value: 1-18
-  uint16_t freq_domain;//Value: Up to the 12 LSBs, actual size is determined by the Row parameter
-  uint8_t  symb_l0;//The time domain location l0 and firstOFDMSymbolInTimeDomain Value: 0->13
-  uint8_t  symb_l1;//
-  uint8_t  cdm_type;
-  uint8_t  freq_density;//The density field, p and comb offset (for dot5).0: dot5 (even RB), 1: dot5 (odd RB), 2: one, 3: three
-  uint16_t scramb_id;//ScramblingID of the CSI-RS [TS38.214, sec 5.2.2.3.1] Value: 0->1023
+  uint8_t subcarrier_spacing;       // subcarrierSpacing [3GPP TS 38.211, sec 4.2], Value:0->4
+  uint8_t cyclic_prefix;            // Cyclic prefix type [3GPP TS 38.211, sec 4.2], 0: Normal; 1: Extended
+  uint16_t start_rb;                // PRB where this CSI resource starts related to common resource block #0 (CRB#0). Only multiples of 4 are allowed. [3GPP TS 38.331, sec 6.3.2 parameter CSIFrequencyOccupation], Value: 0 ->274
+  uint16_t nr_of_rbs;               // Number of PRBs across which this CSI resource spans. Only multiples of 4 are allowed. [3GPP TS 38.331, sec 6.3.2 parameter CSI-FrequencyOccupation], Value: 24 -> 276
+  uint8_t csi_type;                 // CSI Type [3GPP TS 38.211, sec 7.4.1.5], Value: 0:TRS; 1:CSI-RS NZP; 2:CSI-RS ZP
+  uint8_t row;                      // Row entry into the CSI Resource location table. [3GPP TS 38.211, sec 7.4.1.5.3 and table 7.4.1.5.3-1], Value: 1-18
+  uint16_t freq_domain;             // Bitmap defining the frequencyDomainAllocation [3GPP TS 38.211, sec 7.4.1.5.3] [3GPP TS 38.331 CSIResourceMapping], Value: Up to the 12 LSBs, actual size is determined by the Row parameter
+  uint8_t symb_l0;                  // The time domain location l0 and firstOFDMSymbolInTimeDomain [3GPP TS 38.211, sec 7.4.1.5.3], Value: 0->13
+  uint8_t symb_l1;                  // The time domain location l1 and firstOFDMSymbolInTimeDomain2 [3GPP TS 38.211, sec 7.4.1.5.3], Value: 2->12
+  uint8_t cdm_type;                 // The cdm-Type field [3GPP TS 38.211, sec 7.4.1.5.3 and table 7.4.1.5.3-1], Value: 0: noCDM; 1: fd-CDM2; 2: cdm4-FD2-TD2; 3: cdm8-FD2-TD4
+  uint8_t freq_density;             // The density field, p and comb offset (for dot5). [3GPP TS 38.211, sec 7.4.1.5.3 and table 7.4.1.5.3-1], Value: 0: dot5 (even RB); 1: dot5 (odd RB); 2: one; 3: three
+  uint16_t scramb_id;               // ScramblingID of the CSI-RS [3GPP TS 38.214, sec 5.2.2.3.1], Value: 0->1023
+  uint8_t power_control_offset;     // Ratio of PDSCH EPRE to NZP CSI-RSEPRE [3GPP TS 38.214, sec 5.2.2.3.1], Value: 0->23 representing -8 to 15 dB in 1dB steps; 255: L1 is configured with ProfileSSS
+  uint8_t power_control_offset_ss;  // Ratio of NZP CSI-RS EPRE to SSB/PBCH block EPRE [3GPP TS 38.214, sec 5.2.2.3.1], Values: 0: -3dB; 1: 0dB; 2: 3dB; 3: 6dB; 255: L1 is configured with ProfileSSS
 } fapi_nr_dl_config_csirs_pdu_rel15_t;
 
 
diff --git a/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h b/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h
index a44a7f2a0c57cf9e39bf693c97a56c6043044b23..488129ceecaf03f5d2a4ed222eb772693d6df164 100644
--- a/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h
+++ b/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h
@@ -925,32 +925,24 @@ typedef struct
 } nfapi_nr_dlsch_pdu_t;
 */
 
-//for csi-rs_pdu:
-
-//table 3-39
 typedef struct
 {
-  uint16_t bwp_size;//
-  uint16_t bwp_start;//
-  uint8_t  subcarrier_spacing;//
-  uint8_t  cyclic_prefix;//
-  uint16_t start_rb;
-  uint16_t nr_of_rbs;
-  uint8_t  csi_type;//Value: 0:TRS 1:CSI-RS NZP 2:CSI-RS ZP
-  uint8_t  row;//Row entry into the CSI Resource location table. [TS38.211, sec 7.4.1.5.3 and table 7.4.1.5.3-1] Value: 1-18
-  uint16_t freq_domain;//Value: Up to the 12 LSBs, actual size is determined by the Row parameter
-  uint8_t  symb_l0;//The time domain location l0 and firstOFDMSymbolInTimeDomain Value: 0->13
-  uint8_t  symb_l1;//
-  uint8_t  cdm_type;
-  uint8_t  freq_density;//The density field, p and comb offset (for dot5).0: dot5 (even RB), 1: dot5 (odd RB), 2: one, 3: three
-  uint16_t scramb_id;//ScramblingID of the CSI-RS [TS38.214, sec 5.2.2.3.1] Value: 0->1023
-  //tx power info
-  uint8_t  power_control_offset;//Ratio of PDSCH EPRE to NZP CSI-RSEPRE Value :0->23 representing -8 to 15 dB in 1dB steps
-  uint8_t  power_control_offset_ss;//Ratio of SSB/PBCH block EPRE to NZP CSI-RS EPRES 0: -3dB, 1: 0dB, 2: 3dB, 3: 6dB
-
+  uint8_t subcarrier_spacing;       // subcarrierSpacing [3GPP TS 38.211, sec 4.2], Value:0->4
+  uint8_t cyclic_prefix;            // Cyclic prefix type [3GPP TS 38.211, sec 4.2], 0: Normal; 1: Extended
+  uint16_t start_rb;                // PRB where this CSI resource starts related to common resource block #0 (CRB#0). Only multiples of 4 are allowed. [3GPP TS 38.331, sec 6.3.2 parameter CSIFrequencyOccupation], Value: 0 ->274
+  uint16_t nr_of_rbs;               // Number of PRBs across which this CSI resource spans. Only multiples of 4 are allowed. [3GPP TS 38.331, sec 6.3.2 parameter CSI-FrequencyOccupation], Value: 24 -> 276
+  uint8_t csi_type;                 // CSI Type [3GPP TS 38.211, sec 7.4.1.5], Value: 0:TRS; 1:CSI-RS NZP; 2:CSI-RS ZP
+  uint8_t row;                      // Row entry into the CSI Resource location table. [3GPP TS 38.211, sec 7.4.1.5.3 and table 7.4.1.5.3-1], Value: 1-18
+  uint16_t freq_domain;             // Bitmap defining the frequencyDomainAllocation [3GPP TS 38.211, sec 7.4.1.5.3] [3GPP TS 38.331 CSIResourceMapping], Value: Up to the 12 LSBs, actual size is determined by the Row parameter
+  uint8_t symb_l0;                  // The time domain location l0 and firstOFDMSymbolInTimeDomain [3GPP TS 38.211, sec 7.4.1.5.3], Value: 0->13
+  uint8_t symb_l1;                  // The time domain location l1 and firstOFDMSymbolInTimeDomain2 [3GPP TS 38.211, sec 7.4.1.5.3], Value: 2->12
+  uint8_t cdm_type;                 // The cdm-Type field [3GPP TS 38.211, sec 7.4.1.5.3 and table 7.4.1.5.3-1], Value: 0: noCDM; 1: fd-CDM2; 2: cdm4-FD2-TD2; 3: cdm8-FD2-TD4
+  uint8_t freq_density;             // The density field, p and comb offset (for dot5). [3GPP TS 38.211, sec 7.4.1.5.3 and table 7.4.1.5.3-1], Value: 0: dot5 (even RB); 1: dot5 (odd RB); 2: one; 3: three
+  uint16_t scramb_id;               // ScramblingID of the CSI-RS [3GPP TS 38.214, sec 5.2.2.3.1], Value: 0->1023
+  uint8_t power_control_offset;     // Ratio of PDSCH EPRE to NZP CSI-RSEPRE [3GPP TS 38.214, sec 5.2.2.3.1], Value: 0->23 representing -8 to 15 dB in 1dB steps; 255: L1 is configured with ProfileSSS
+  uint8_t power_control_offset_ss;  // Ratio of NZP CSI-RS EPRE to SSB/PBCH block EPRE [3GPP TS 38.214, sec 5.2.2.3.1], Values: 0: -3dB; 1: 0dB; 2: 3dB; 3: 6dB; 255: L1 is configured with ProfileSSS
 } nfapi_nr_dl_tti_csi_rs_pdu_rel15_t;
 
-//for ssb_pdu: 
 
 typedef struct
 {
diff --git a/nfapi/open-nFAPI/nfapi/src/nfapi_p7.c b/nfapi/open-nFAPI/nfapi/src/nfapi_p7.c
index 3adde23e7dab995bb0cd19c97f26a6087e67ef67..98f89f599c83955496c1d8503e32d739f3d4aba3 100644
--- a/nfapi/open-nFAPI/nfapi/src/nfapi_p7.c
+++ b/nfapi/open-nFAPI/nfapi/src/nfapi_p7.c
@@ -200,8 +200,6 @@ static uint8_t pack_tpm_value(nfapi_dl_config_dci_dl_tpm_t *value, uint8_t **ppW
 static uint8_t pack_dl_tti_csi_rs_pdu_rel15_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end) {
   nfapi_nr_dl_tti_csi_rs_pdu_rel15_t *value = (nfapi_nr_dl_tti_csi_rs_pdu_rel15_t *)tlv;
   return(
-          push16(value->bwp_size, ppWritePackedMsg, end) &&
-          push16(value->bwp_start, ppWritePackedMsg, end) &&
           push8(value->subcarrier_spacing, ppWritePackedMsg, end) &&
           push8(value->cyclic_prefix, ppWritePackedMsg, end) &&
           push16(value->start_rb, ppWritePackedMsg, end) &&
@@ -3663,8 +3661,6 @@ int nfapi_p7_message_pack(void *pMessageBuf, void *pPackedBuf, uint32_t packedBu
 static uint8_t unpack_dl_tti_csi_rs_pdu_rel15_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end) {
   nfapi_nr_dl_tti_csi_rs_pdu_rel15_t *value = (nfapi_nr_dl_tti_csi_rs_pdu_rel15_t *)tlv;
   return(
-          pull16(ppReadPackedMsg, &value->bwp_size, end) &&
-          pull16(ppReadPackedMsg, &value->bwp_start, end) &&
           pull8(ppReadPackedMsg, &value->subcarrier_spacing, end) &&
           pull8(ppReadPackedMsg, &value->cyclic_prefix, end) &&
           pull16(ppReadPackedMsg, &value->start_rb, end) &&
diff --git a/openair1/PHY/INIT/nr_init.c b/openair1/PHY/INIT/nr_init.c
index 8a060b69f41404490f2e5697882c7c4815e2dfe0..6973b5f29b965ae02f74916031a33613c93d382a 100644
--- a/openair1/PHY/INIT/nr_init.c
+++ b/openair1/PHY/INIT/nr_init.c
@@ -593,26 +593,23 @@ int phy_init_nr_gNB(PHY_VARS_gNB *gNB,
     nr_gold_pusch(gNB, nscid, gNB->pusch_gold_init[nscid]);
   }
 
-  //CSI RS init
-  gNB->nr_gold_csi_rs = (uint32_t ***)malloc16(fp->slots_per_frame*sizeof(uint32_t **));
-  uint32_t ***csi_rs = gNB->nr_gold_csi_rs;
-  AssertFatal(csi_rs!=NULL, "NR init: csi reference signal malloc failed\n");
-
+  // CSI RS init
   // ceil((NB_RB*8(max allocation per RB)*2(QPSK))/32)
   int csi_dmrs_init_length =  ((fp->N_RB_DL<<4)>>5)+1;
-
+  gNB->nr_csi_rs_info = (nr_csi_rs_info_t *)malloc16_clear(sizeof(nr_csi_rs_info_t));
+  gNB->nr_csi_rs_info->nr_gold_csi_rs = (uint32_t ***)malloc16(fp->slots_per_frame*sizeof(uint32_t **));
+  AssertFatal(gNB->nr_csi_rs_info->nr_gold_csi_rs!=NULL, "NR init: csi reference signal malloc failed\n");
   for (int slot=0; slot<fp->slots_per_frame; slot++) {
-    csi_rs[slot] = (uint32_t **)malloc16(fp->symbols_per_slot*sizeof(uint32_t *));
-    AssertFatal(csi_rs[slot]!=NULL, "NR init: csi reference signal for slot %d - malloc failed\n", slot);
-
+    gNB->nr_csi_rs_info->nr_gold_csi_rs[slot] = (uint32_t **)malloc16(fp->symbols_per_slot*sizeof(uint32_t *));
+    AssertFatal(gNB->nr_csi_rs_info->nr_gold_csi_rs[slot]!=NULL, "NR init: csi reference signal for slot %d - malloc failed\n", slot);
     for (int symb=0; symb<fp->symbols_per_slot; symb++) {
-      csi_rs[slot][symb] = (uint32_t *)malloc16(csi_dmrs_init_length*sizeof(uint32_t));
-      AssertFatal(csi_rs[slot][symb]!=NULL, "NR init: csi reference signal for slot %d symbol %d - malloc failed\n", slot, symb);
+      gNB->nr_csi_rs_info->nr_gold_csi_rs[slot][symb] = (uint32_t *)malloc16(csi_dmrs_init_length*sizeof(uint32_t));
+      AssertFatal(gNB->nr_csi_rs_info->nr_gold_csi_rs[slot][symb]!=NULL, "NR init: csi reference signal for slot %d symbol %d - malloc failed\n", slot, symb);
     }
   }
 
-  gNB->csi_gold_init = cfg->cell_config.phy_cell_id.value;
-  nr_init_csi_rs(gNB, cfg->cell_config.phy_cell_id.value);
+  gNB->nr_csi_rs_info->csi_gold_init = cfg->cell_config.phy_cell_id.value;
+  nr_init_csi_rs(&gNB->frame_parms, gNB->nr_csi_rs_info->nr_gold_csi_rs, cfg->cell_config.phy_cell_id.value);
 
   for (int id=0; id<NUMBER_OF_NR_SRS_MAX; id++) {
     gNB->nr_srs_info[id] = (nr_srs_info_t *)malloc16_clear(sizeof(nr_srs_info_t));
@@ -782,13 +779,14 @@ void phy_free_nr_gNB(PHY_VARS_gNB *gNB)
   }
   free_and_zero(pusch_dmrs);
 
-  uint32_t ***csi_rs = gNB->nr_gold_csi_rs;
+  uint32_t ***nr_gold_csi_rs = gNB->nr_csi_rs_info->nr_gold_csi_rs;
   for (int slot = 0; slot < fp->slots_per_frame; slot++) {
     for (int symb = 0; symb < fp->symbols_per_slot; symb++)
-      free_and_zero(csi_rs[slot][symb]);
-    free_and_zero(csi_rs[slot]);
+      free_and_zero(nr_gold_csi_rs[slot][symb]);
+    free_and_zero(nr_gold_csi_rs[slot]);
   }
-  free_and_zero(csi_rs);
+  free_and_zero(nr_gold_csi_rs);
+  free_and_zero(gNB->nr_csi_rs_info);
 
   for (int id = 0; id < NUMBER_OF_NR_SRS_MAX; id++) {
     for (int i = 0; i < Prx; i++) {
@@ -1058,7 +1056,7 @@ void init_nr_transport(PHY_VARS_gNB *gNB) {
 
   for (int i=0; i<gNB->number_of_nr_ulsch_max; i++) {
 
-    LOG_I(PHY,"Allocating Transport Channel Buffer for ULSCH  %d/%d\n",i,gNB->number_of_nr_ulsch_max);
+    LOG_I(PHY,"Allocating Transport Channel Buffers for ULSCH  %d/%d\n",i,gNB->number_of_nr_ulsch_max);
 
     gNB->ulsch[i] = new_gNB_ulsch(MAX_LDPC_ITERATIONS, fp->N_RB_UL);
 
diff --git a/openair1/PHY/INIT/nr_init_ru.c b/openair1/PHY/INIT/nr_init_ru.c
index 0e7c29800a20468220c342890457930749041356..b1a01fb3dc8531e6cdd6aa22a493f738b97f177c 100644
--- a/openair1/PHY/INIT/nr_init_ru.c
+++ b/openair1/PHY/INIT/nr_init_ru.c
@@ -124,9 +124,10 @@ int nr_phy_init_RU(RU_t *ru) {
 		ru->num_gNB,NUMBER_OF_gNB_MAX);
 
     LOG_I(PHY,"[INIT] %s() ru->num_gNB:%d \n", __FUNCTION__, ru->num_gNB);
-    if (ru->do_precoding == 1) { 
+
+    if (ru->do_precoding == 1) {
       int beam_count = 0;
-      if (ru->nb_tx>1) {//Enable beamforming when nb_tx > 1
+      if (ru->nb_tx>1) { //Enable beamforming when nb_tx > 1
 
         for (p=0;p<ru->nb_log_antennas;p++) {
           //if ((fp->L_ssb >> (63-p)) & 0x01)//64 bit-map with the MSB @2⁶³ corresponds to SSB ssb_index 0
@@ -149,7 +150,7 @@ int nr_phy_init_RU(RU_t *ru) {
             } // for j
           //}
           } // for p
-        } //for i
+        } // for i
       }
 
       ru->common.beam_id = (uint8_t**)malloc16_clear(ru->nb_tx*sizeof(uint8_t*));
diff --git a/openair1/PHY/INIT/nr_init_ue.c b/openair1/PHY/INIT/nr_init_ue.c
index fcbbd49b445a206811c8df13ba89b0c4b3c4670c..15a868fdd4dd83b5d8ca3a14defb544fc5e9d9dd 100644
--- a/openair1/PHY/INIT/nr_init_ue.c
+++ b/openair1/PHY/INIT/nr_init_ue.c
@@ -155,10 +155,12 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue, int nb_connected_gNB)
   NR_UE_COMMON *const common_vars        = &ue->common_vars;
   NR_UE_PBCH  **const pbch_vars          = ue->pbch_vars;
   NR_UE_PRACH **const prach_vars         = ue->prach_vars;
-  int i,slot,symb, gNB_id, th_id;
-
+  NR_UE_CSI_IM **const csiim_vars        = ue->csiim_vars;
+  NR_UE_CSI_RS **const csirs_vars        = ue->csirs_vars;
   NR_UE_SRS **const srs_vars             = ue->srs_vars;
 
+  int i, j, slot, symb, gNB_id, th_id;
+
   LOG_I(PHY, "Initializing UE vars for gNB TXant %u, UE RXant %u\n", fp->nb_antennas_tx, fp->nb_antennas_rx);
 
   phy_init_nr_top(ue);
@@ -335,9 +337,45 @@ int init_nr_ue_signal(PHY_VARS_NR_UE *ue, int nb_connected_gNB)
 
     prach_vars[gNB_id] = (NR_UE_PRACH *)malloc16_clear(sizeof(NR_UE_PRACH));
     pbch_vars[gNB_id] = (NR_UE_PBCH *)malloc16_clear(sizeof(NR_UE_PBCH));
+    csiim_vars[gNB_id] = (NR_UE_CSI_IM *)malloc16_clear(sizeof(NR_UE_CSI_IM));
+    csirs_vars[gNB_id] = (NR_UE_CSI_RS *)malloc16_clear(sizeof(NR_UE_CSI_RS));
     srs_vars[gNB_id] = (NR_UE_SRS *)malloc16_clear(sizeof(NR_UE_SRS));
 
+    csiim_vars[gNB_id]->active = false;
+    csirs_vars[gNB_id]->active = false;
     srs_vars[gNB_id]->active = false;
+
+    // ceil((NB_RB*8(max allocation per RB)*2(QPSK))/32)
+    int csi_dmrs_init_length =  ((fp->N_RB_DL<<4)>>5)+1;
+    ue->nr_csi_rs_info = (nr_csi_rs_info_t *)malloc16_clear(sizeof(nr_csi_rs_info_t));
+    ue->nr_csi_rs_info->nr_gold_csi_rs = (uint32_t ***)malloc16(fp->slots_per_frame*sizeof(uint32_t **));
+    AssertFatal(ue->nr_csi_rs_info->nr_gold_csi_rs!=NULL, "NR init: csi reference signal malloc failed\n");
+    for (int slot=0; slot<fp->slots_per_frame; slot++) {
+      ue->nr_csi_rs_info->nr_gold_csi_rs[slot] = (uint32_t **)malloc16(fp->symbols_per_slot*sizeof(uint32_t *));
+      AssertFatal(ue->nr_csi_rs_info->nr_gold_csi_rs[slot]!=NULL, "NR init: csi reference signal for slot %d - malloc failed\n", slot);
+      for (int symb=0; symb<fp->symbols_per_slot; symb++) {
+        ue->nr_csi_rs_info->nr_gold_csi_rs[slot][symb] = (uint32_t *)malloc16(csi_dmrs_init_length*sizeof(uint32_t));
+        AssertFatal(ue->nr_csi_rs_info->nr_gold_csi_rs[slot][symb]!=NULL, "NR init: csi reference signal for slot %d symbol %d - malloc failed\n", slot, symb);
+      }
+    }
+    ue->nr_csi_rs_info->noise_power = (uint32_t*)malloc16_clear(sizeof(uint32_t));
+    ue->nr_csi_rs_info->csi_rs_generated_signal = (int32_t **)malloc16(NR_MAX_NB_PORTS * sizeof(int32_t *) );
+    for (i=0; i<NR_MAX_NB_PORTS; i++) {
+      ue->nr_csi_rs_info->csi_rs_generated_signal[i] = (int32_t *) malloc16_clear(fp->samples_per_frame_wCP * sizeof(int32_t));
+    }
+    ue->nr_csi_rs_info->csi_rs_received_signal = (int32_t **)malloc16(fp->nb_antennas_rx * sizeof(int32_t *) );
+    ue->nr_csi_rs_info->csi_rs_ls_estimated_channel = (int32_t ***)malloc16(fp->nb_antennas_rx * sizeof(int32_t **) );
+    ue->nr_csi_rs_info->csi_rs_estimated_channel_freq = (int32_t ***)malloc16(fp->nb_antennas_rx * sizeof(int32_t **) );
+    for (i=0; i<fp->nb_antennas_rx; i++) {
+      ue->nr_csi_rs_info->csi_rs_received_signal[i] = (int32_t *) malloc16_clear(fp->samples_per_frame_wCP * sizeof(int32_t));
+      ue->nr_csi_rs_info->csi_rs_ls_estimated_channel[i] = (int32_t **) malloc16_clear(NR_MAX_NB_PORTS * sizeof(int32_t *));
+      ue->nr_csi_rs_info->csi_rs_estimated_channel_freq[i] = (int32_t **) malloc16_clear(NR_MAX_NB_PORTS * sizeof(int32_t *));
+      for (j=0; j<NR_MAX_NB_PORTS; j++) {
+        ue->nr_csi_rs_info->csi_rs_ls_estimated_channel[i][j] = (int32_t *) malloc16_clear(fp->ofdm_symbol_size * sizeof(int32_t));
+        ue->nr_csi_rs_info->csi_rs_estimated_channel_freq[i][j] = (int32_t *) malloc16_clear(fp->ofdm_symbol_size * sizeof(int32_t));
+      }
+    }
+
     ue->nr_srs_info = (nr_srs_info_t *)malloc16_clear(sizeof(nr_srs_info_t));
     ue->nr_srs_info->sc_list = (uint16_t *) malloc16_clear(6*fp->N_RB_UL*sizeof(uint16_t));
     ue->nr_srs_info->srs_generated_signal = (int32_t *) malloc16_clear( (2*(fp->samples_per_frame)+2048)*sizeof(int32_t) );
@@ -456,6 +494,32 @@ void term_nr_ue_signal(PHY_VARS_NR_UE *ue, int nb_connected_gNB)
       free_and_zero(ue->pdcch_vars[th_id][gNB_id]);
     }
 
+    for (int i=0; i<NR_MAX_NB_PORTS; i++) {
+      free_and_zero(ue->nr_csi_rs_info->csi_rs_generated_signal[i]);
+    }
+    for (int i = 0; i < fp->nb_antennas_rx; i++) {
+      free_and_zero(ue->nr_csi_rs_info->csi_rs_received_signal[i]);
+      for (int j=0; j<NR_MAX_NB_PORTS; j++) {
+        free_and_zero(ue->nr_csi_rs_info->csi_rs_ls_estimated_channel[i][j]);
+        free_and_zero(ue->nr_csi_rs_info->csi_rs_estimated_channel_freq[i][j]);
+      }
+      free_and_zero(ue->nr_csi_rs_info->csi_rs_ls_estimated_channel[i]);
+      free_and_zero(ue->nr_csi_rs_info->csi_rs_estimated_channel_freq[i]);
+    }
+    for (int slot=0; slot<fp->slots_per_frame; slot++) {
+      for (int symb=0; symb<fp->symbols_per_slot; symb++) {
+        free_and_zero(ue->nr_csi_rs_info->nr_gold_csi_rs[slot][symb]);
+      }
+      free_and_zero(ue->nr_csi_rs_info->nr_gold_csi_rs[slot]);
+    }
+    free_and_zero(ue->nr_csi_rs_info->noise_power);
+    free_and_zero(ue->nr_csi_rs_info->nr_gold_csi_rs);
+    free_and_zero(ue->nr_csi_rs_info->csi_rs_generated_signal);
+    free_and_zero(ue->nr_csi_rs_info->csi_rs_received_signal);
+    free_and_zero(ue->nr_csi_rs_info->csi_rs_ls_estimated_channel);
+    free_and_zero(ue->nr_csi_rs_info->csi_rs_estimated_channel_freq);
+    free_and_zero(ue->nr_csi_rs_info);
+
     for (int i = 0; i < fp->nb_antennas_rx; i++) {
       free_and_zero(ue->nr_srs_info->srs_received_signal[i]);
       free_and_zero(ue->nr_srs_info->srs_ls_estimated_channel[i]);
@@ -473,6 +537,8 @@ void term_nr_ue_signal(PHY_VARS_NR_UE *ue, int nb_connected_gNB)
     free_and_zero(ue->nr_srs_info->srs_estimated_channel_time_shifted);
     free_and_zero(ue->nr_srs_info);
 
+    free_and_zero(ue->csiim_vars[gNB_id]);
+    free_and_zero(ue->csirs_vars[gNB_id]);
     free_and_zero(ue->srs_vars[gNB_id]);
 
     free_and_zero(ue->pbch_vars[gNB_id]);
diff --git a/openair1/PHY/NR_REFSIG/nr_gold.c b/openair1/PHY/NR_REFSIG/nr_gold.c
index 279afc8110c215a33e8fcde415a1964c17e6db79..9b4cc50953b430b698bd0d5a060ddef8c58d84c1 100644
--- a/openair1/PHY/NR_REFSIG/nr_gold.c
+++ b/openair1/PHY/NR_REFSIG/nr_gold.c
@@ -123,27 +123,3 @@ void nr_gold_pusch(PHY_VARS_gNB* gNB, int nscid, uint32_t nid) {
     }
   }
 }
-
-
-void nr_init_csi_rs(PHY_VARS_gNB* gNB, uint32_t Nid)
-{
-  NR_DL_FRAME_PARMS *fp = &gNB->frame_parms;
-  uint32_t ***csi_rs = gNB->nr_gold_csi_rs;
-  uint32_t x1, x2;
-  uint8_t reset;
-  int csi_dmrs_init_length =  ((fp->N_RB_DL<<4)>>5)+1;
-
-  for (uint8_t slot=0; slot<fp->slots_per_frame; slot++) {
-    for (uint8_t symb=0; symb<fp->symbols_per_slot; symb++) {
-
-      reset = 1;
-      x2 = ((1<<10) * (fp->symbols_per_slot*slot+symb+1) * ((Nid<<1)+1) + (Nid));
-
-      for (uint32_t n=0; n<csi_dmrs_init_length; n++) {
-        csi_rs[slot][symb][n] = lte_gold_generic(&x1, &x2, reset);
-        reset = 0;
-      }
-    }  
-  }
-
-}
diff --git a/openair1/PHY/NR_REFSIG/nr_refsig.h b/openair1/PHY/NR_REFSIG/nr_refsig.h
index ad632431ebfa2069c834abb11e619857eda34900..d4d91d7060987bd7438b57dabf92b359a4b86935 100644
--- a/openair1/PHY/NR_REFSIG/nr_refsig.h
+++ b/openair1/PHY/NR_REFSIG/nr_refsig.h
@@ -38,7 +38,7 @@ void nr_init_pbch_dmrs(PHY_VARS_gNB* gNB);
  */
 void nr_init_pdcch_dmrs(PHY_VARS_gNB* gNB, uint32_t Nid);
 void nr_init_pdsch_dmrs(PHY_VARS_gNB* gNB, uint8_t nscid, uint32_t Nid);
-void nr_init_csi_rs(PHY_VARS_gNB* gNB, uint32_t Nid);
+void nr_init_csi_rs(NR_DL_FRAME_PARMS *fp, uint32_t ***csi_rs, uint32_t Nid);
 
 void nr_gold_pusch(PHY_VARS_gNB* gNB, int nscid, uint32_t nid);
 
diff --git a/openair1/PHY/NR_REFSIG/refsig_defs_ue.h b/openair1/PHY/NR_REFSIG/refsig_defs_ue.h
index cd19e5ebcac29ea805d33270419f825251acb224..eb5c57336829135ee249785ac36756578d08e19b 100644
--- a/openair1/PHY/NR_REFSIG/refsig_defs_ue.h
+++ b/openair1/PHY/NR_REFSIG/refsig_defs_ue.h
@@ -68,4 +68,6 @@ void nr_init_pusch_dmrs(PHY_VARS_NR_UE* ue,
                         uint16_t N_n_scid,
                         uint8_t n_scid);
 
+void nr_init_csi_rs(NR_DL_FRAME_PARMS *fp, uint32_t ***csi_rs, uint32_t Nid);
+
 #endif
diff --git a/openair1/PHY/NR_TRANSPORT/nr_csi_rs.c b/openair1/PHY/NR_TRANSPORT/nr_csi_rs.c
index 694617c4441019c8a00b3bbb21907178b9d197db..ab8d915d6e6b452079b193fd923816cf9705a7f1 100644
--- a/openair1/PHY/NR_TRANSPORT/nr_csi_rs.c
+++ b/openair1/PHY/NR_TRANSPORT/nr_csi_rs.c
@@ -27,20 +27,53 @@
 //#define NR_CSIRS_DEBUG
 
 
-void nr_generate_csi_rs(PHY_VARS_gNB *gNB,
+void nr_init_csi_rs(NR_DL_FRAME_PARMS *fp, uint32_t ***csi_rs, uint32_t Nid) {
+  uint32_t x1, x2;
+  uint8_t reset;
+  int csi_dmrs_init_length =  ((fp->N_RB_DL<<4)>>5)+1;
+  for (uint8_t slot=0; slot<fp->slots_per_frame; slot++) {
+    for (uint8_t symb=0; symb<fp->symbols_per_slot; symb++) {
+      reset = 1;
+      x2 = ((1<<10) * (fp->symbols_per_slot*slot+symb+1) * ((Nid<<1)+1) + (Nid));
+      for (uint32_t n=0; n<csi_dmrs_init_length; n++) {
+        csi_rs[slot][symb][n] = lte_gold_generic(&x1, &x2, reset);
+        reset = 0;
+      }
+    }
+  }
+}
+
+void nr_generate_csi_rs(NR_DL_FRAME_PARMS frame_parms,
+                        int32_t **dataF,
                         int16_t amp,
-                        nfapi_nr_dl_tti_csi_rs_pdu_rel15_t csi_params,
+                        nr_csi_rs_info_t *nr_csi_rs_info,
+                        nfapi_nr_dl_tti_csi_rs_pdu_rel15_t *csi_params,
                         int slot){
 
-  NR_DL_FRAME_PARMS frame_parms=gNB->frame_parms;
-  int32_t **txdataF = gNB->common_vars.txdataF;
-  int txdataF_offset = slot*frame_parms.samples_per_slot_wCP;
-  uint32_t **gold_csi_rs = gNB->nr_gold_csi_rs[slot];
+#ifdef NR_CSIRS_DEBUG
+  LOG_I(NR_PHY, "csi_params->subcarrier_spacing = %i\n", csi_params->subcarrier_spacing);
+  LOG_I(NR_PHY, "csi_params->cyclic_prefix = %i\n", csi_params->cyclic_prefix);
+  LOG_I(NR_PHY, "csi_params->start_rb = %i\n", csi_params->start_rb);
+  LOG_I(NR_PHY, "csi_params->nr_of_rbs = %i\n", csi_params->nr_of_rbs);
+  LOG_I(NR_PHY, "csi_params->csi_type = %i (0:TRS, 1:CSI-RS NZP, 2:CSI-RS ZP)\n", csi_params->csi_type);
+  LOG_I(NR_PHY, "csi_params->row = %i\n", csi_params->row);
+  LOG_I(NR_PHY, "csi_params->freq_domain = %i\n", csi_params->freq_domain);
+  LOG_I(NR_PHY, "csi_params->symb_l0 = %i\n", csi_params->symb_l0);
+  LOG_I(NR_PHY, "csi_params->symb_l1 = %i\n", csi_params->symb_l1);
+  LOG_I(NR_PHY, "csi_params->cdm_type = %i\n", csi_params->cdm_type);
+  LOG_I(NR_PHY, "csi_params->freq_density = %i (0: dot5 (even RB), 1: dot5 (odd RB), 2: one, 3: three)\n", csi_params->freq_density);
+  LOG_I(NR_PHY, "csi_params->scramb_id = %i\n", csi_params->scramb_id);
+  LOG_I(NR_PHY, "csi_params->power_control_offset = %i\n", csi_params->power_control_offset);
+  LOG_I(NR_PHY, "csi_params->power_control_offset_ss = %i\n", csi_params->power_control_offset_ss);
+#endif
+
+  int dataF_offset = slot*frame_parms.samples_per_slot_wCP;
+  uint32_t **nr_gold_csi_rs = nr_csi_rs_info->nr_gold_csi_rs[slot];
   //*8(max allocation per RB)*2(QPSK))
   int csi_rs_length =  frame_parms.N_RB_DL<<4;
-  int16_t mod_csi[frame_parms.symbols_per_slot][csi_rs_length>>1] __attribute__((aligned(16)));;
-  uint16_t b = csi_params.freq_domain;
-  uint16_t n, csi_bw, csi_start, p, k, l, mprime, na, kpn, csi_length;
+  int16_t mod_csi[frame_parms.symbols_per_slot][csi_rs_length>>1] __attribute__((aligned(16)));
+  uint16_t b = csi_params->freq_domain;
+  uint16_t n, p, k, l, mprime, na, kpn;
   uint8_t size, ports, kprime, lprime, i, gs;
   uint8_t j[16], k_n[6], koverline[16], loverline[16];
   int found = 0;
@@ -48,16 +81,17 @@ void nr_generate_csi_rs(PHY_VARS_gNB *gNB,
   uint8_t fi = 0;
   double rho, alpha;
   uint32_t beta = amp;
+  nr_csi_rs_info->csi_rs_generated_signal_bits = log2_approx(amp);
 
   AssertFatal(b!=0, "Invalid CSI frequency domain mapping: no bit selected in bitmap\n");
 
   // if the scrambling id is not the one previously used to initialize we need to re-initialize the rs
-  if (csi_params.scramb_id != gNB->csi_gold_init) {
-    gNB->csi_gold_init = csi_params.scramb_id;
-    nr_init_csi_rs(gNB, csi_params.scramb_id);
+  if (csi_params->scramb_id != nr_csi_rs_info->csi_gold_init) {
+    nr_csi_rs_info->csi_gold_init = csi_params->scramb_id;
+    nr_init_csi_rs(&frame_parms, nr_csi_rs_info->nr_gold_csi_rs, csi_params->scramb_id);
   }
 
-  switch (csi_params.row) {
+  switch (csi_params->row) {
   // implementation of table 7.4.1.5.3-1 of 38.211
   // lprime and kprime are the max value of l' and k'
   case 1:
@@ -75,7 +109,7 @@ void nr_generate_csi_rs(PHY_VARS_gNB *gNB,
     }
     for (i=0; i<size; i++) {
       j[i] = 0;
-      loverline[i] = csi_params.symb_l0;
+      loverline[i] = csi_params->symb_l0;
       koverline[i] = k_n[0] + (i<<2);
     }
     break;
@@ -95,7 +129,7 @@ void nr_generate_csi_rs(PHY_VARS_gNB *gNB,
     }
     for (i=0; i<size; i++) {
       j[i] = 0;
-      loverline[i] = csi_params.symb_l0;
+      loverline[i] = csi_params->symb_l0;
       koverline[i] = k_n[0];
     }
     break;
@@ -115,7 +149,7 @@ void nr_generate_csi_rs(PHY_VARS_gNB *gNB,
     }
     for (i=0; i<size; i++) {
       j[i] = 0;
-      loverline[i] = csi_params.symb_l0;
+      loverline[i] = csi_params->symb_l0;
       koverline[i] = k_n[0];
     }
     break;
@@ -135,7 +169,7 @@ void nr_generate_csi_rs(PHY_VARS_gNB *gNB,
     }
     for (i=0; i<size; i++) {
       j[i] = i;
-      loverline[i] = csi_params.symb_l0;
+      loverline[i] = csi_params->symb_l0;
       koverline[i] = k_n[0] + (i<<1);
     }
     break;
@@ -155,7 +189,7 @@ void nr_generate_csi_rs(PHY_VARS_gNB *gNB,
     }
     for (i=0; i<size; i++) {
       j[i] = i;
-      loverline[i] = csi_params.symb_l0 + i;
+      loverline[i] = csi_params->symb_l0 + i;
       koverline[i] = k_n[0];
     }
     break;
@@ -174,7 +208,7 @@ void nr_generate_csi_rs(PHY_VARS_gNB *gNB,
     }
     for (i=0; i<size; i++) {
       j[i] = i;
-      loverline[i] = csi_params.symb_l0;
+      loverline[i] = csi_params->symb_l0;
       koverline[i] = k_n[i];
     }
     break;
@@ -193,7 +227,7 @@ void nr_generate_csi_rs(PHY_VARS_gNB *gNB,
     }
     for (i=0; i<size; i++) {
       j[i] = i;
-      loverline[i] = csi_params.symb_l0 + (i>>1);
+      loverline[i] = csi_params->symb_l0 + (i>>1);
       koverline[i] = k_n[i%2];
     }
     break;
@@ -212,7 +246,7 @@ void nr_generate_csi_rs(PHY_VARS_gNB *gNB,
     }
     for (i=0; i<size; i++) {
       j[i] = i;
-      loverline[i] = csi_params.symb_l0;
+      loverline[i] = csi_params->symb_l0;
       koverline[i] = k_n[i];
     }
     break;
@@ -231,7 +265,7 @@ void nr_generate_csi_rs(PHY_VARS_gNB *gNB,
     }
     for (i=0; i<size; i++) {
       j[i] = i;
-      loverline[i] = csi_params.symb_l0;
+      loverline[i] = csi_params->symb_l0;
       koverline[i] = k_n[i];
     }
     break;
@@ -250,7 +284,7 @@ void nr_generate_csi_rs(PHY_VARS_gNB *gNB,
     }
     for (i=0; i<size; i++) {
       j[i] = i;
-      loverline[i] = csi_params.symb_l0;
+      loverline[i] = csi_params->symb_l0;
       koverline[i] = k_n[i];
     }
     break;
@@ -269,7 +303,7 @@ void nr_generate_csi_rs(PHY_VARS_gNB *gNB,
     }
     for (i=0; i<size; i++) {
       j[i] = i;
-      loverline[i] = csi_params.symb_l0 + (i>>2);
+      loverline[i] = csi_params->symb_l0 + (i>>2);
       koverline[i] = k_n[i%4];
     }
     break;
@@ -288,7 +322,7 @@ void nr_generate_csi_rs(PHY_VARS_gNB *gNB,
     }
     for (i=0; i<size; i++) {
       j[i] = i;
-      loverline[i] = csi_params.symb_l0;
+      loverline[i] = csi_params->symb_l0;
       koverline[i] = k_n[i];
     }
     break;
@@ -308,9 +342,9 @@ void nr_generate_csi_rs(PHY_VARS_gNB *gNB,
     for (i=0; i<size; i++) {
       j[i] = i;
       if (i<6)
-        loverline[i] = csi_params.symb_l0 + i/3;
+        loverline[i] = csi_params->symb_l0 + i/3;
       else
-        loverline[i] = csi_params.symb_l1 + i/9;
+        loverline[i] = csi_params->symb_l1 + i/9;
       koverline[i] = k_n[i%3];
     }
     break;
@@ -330,9 +364,9 @@ void nr_generate_csi_rs(PHY_VARS_gNB *gNB,
     for (i=0; i<size; i++) {
       j[i] = i;
       if (i<3)
-        loverline[i] = csi_params.symb_l0;
+        loverline[i] = csi_params->symb_l0;
       else
-        loverline[i] = csi_params.symb_l1;
+        loverline[i] = csi_params->symb_l1;
       koverline[i] = k_n[i%3];
     }
     break;
@@ -351,7 +385,7 @@ void nr_generate_csi_rs(PHY_VARS_gNB *gNB,
     }
     for (i=0; i<size; i++) {
       j[i] = i;
-      loverline[i] = csi_params.symb_l0;
+      loverline[i] = csi_params->symb_l0;
       koverline[i] = k_n[i];
     }
     break;
@@ -371,9 +405,9 @@ void nr_generate_csi_rs(PHY_VARS_gNB *gNB,
     for (i=0; i<size; i++) {
       j[i] = i;
       if (i<8)
-        loverline[i] = csi_params.symb_l0 + (i>>2);
+        loverline[i] = csi_params->symb_l0 + (i>>2);
       else
-        loverline[i] = csi_params.symb_l1 + (i/12);
+        loverline[i] = csi_params->symb_l1 + (i/12);
       koverline[i] = k_n[i%4];
     }
     break;
@@ -393,9 +427,9 @@ void nr_generate_csi_rs(PHY_VARS_gNB *gNB,
     for (i=0; i<size; i++) {
       j[i] = i;
       if (i<4)
-        loverline[i] = csi_params.symb_l0;
+        loverline[i] = csi_params->symb_l0;
       else
-        loverline[i] = csi_params.symb_l1;
+        loverline[i] = csi_params->symb_l1;
       koverline[i] = k_n[i%4];
     }
     break;
@@ -414,17 +448,17 @@ void nr_generate_csi_rs(PHY_VARS_gNB *gNB,
     }
     for (i=0; i<size; i++) {
       j[i] = i;
-      loverline[i] = csi_params.symb_l0;
+      loverline[i] = csi_params->symb_l0;
       koverline[i] = k_n[i];
     }
     break;
 
   default:
-    AssertFatal(0==1, "Row %d is not valid for CSI Table 7.4.1.5.3-1\n", csi_params.row);
+    AssertFatal(0==1, "Row %d is not valid for CSI Table 7.4.1.5.3-1\n", csi_params->row);
   }
 
 #ifdef NR_CSIRS_DEBUG
-  printf(" row %d, n. of ports %d\n k' ",csi_params.row,ports);
+  printf(" row %d, n. of ports %d\n k' ",csi_params->row,ports);
   for (kp=0; kp<=kprime; kp++)
     printf("%d, ",kp);
   printf("l' ");
@@ -441,7 +475,7 @@ void nr_generate_csi_rs(PHY_VARS_gNB *gNB,
 
 
   // setting the frequency density from its index
-  switch (csi_params.freq_density) {
+  switch (csi_params->freq_density) {
   
   case 0:
     rho = 0.5;
@@ -473,7 +507,7 @@ void nr_generate_csi_rs(PHY_VARS_gNB *gNB,
 #endif
 
   // CDM group size from CDM type index
-  switch (csi_params.cdm_type) {
+  switch (csi_params->cdm_type) {
   
   case 0:
     gs = 1;
@@ -495,39 +529,31 @@ void nr_generate_csi_rs(PHY_VARS_gNB *gNB,
     AssertFatal(0==1, "Invalid cdm type index for CSI\n");
   }
 
-  // according to 38.214 5.2.2.3.1 last paragraph
-  if (csi_params.start_rb<csi_params.bwp_start)
-    csi_start = csi_params.bwp_start;
-  else 
-    csi_start = csi_params.start_rb;
-  if (csi_params.nr_of_rbs > (csi_params.bwp_start+csi_params.bwp_size-csi_start))
-    csi_bw = csi_params.bwp_start+csi_params.bwp_size-csi_start;
-  else
-    csi_bw = csi_params.nr_of_rbs;
-
+  uint16_t csi_length;
   if (rho < 1) {
-    if (csi_params.freq_density == 0)
-      csi_length = (((csi_bw + csi_start)>>1)<<kprime)<<1;
-    else
-      csi_length = ((((csi_bw + csi_start)>>1)<<kprime)+1)<<1;
+    if (csi_params->freq_density == 0) {
+      csi_length = (((csi_params->start_rb + csi_params->nr_of_rbs)>>1)<<kprime)<<1;
+    } else {
+      csi_length = ((((csi_params->start_rb + csi_params->nr_of_rbs)>>1)<<kprime)+1)<<1;
+    }
+  } else {
+    csi_length = (((uint16_t) rho*(csi_params->start_rb + csi_params->nr_of_rbs))<<kprime)<<1;
   }
-  else
-    csi_length = (((uint16_t) rho*(csi_bw + csi_start))<<kprime)<<1;
 
 #ifdef NR_CSIRS_DEBUG
-    printf(" start rb %d, n. rbs %d, csi length %d\n",csi_start,csi_bw,csi_length);
+    printf(" start rb %d, nr of rbs %d, csi length %d\n", csi_params->start_rb, csi_params->nr_of_rbs, csi_length);
 #endif
 
 
   // TRS
-  if (csi_params.csi_type == 0) {
+  if (csi_params->csi_type == 0) {
     // ???
   }
 
   // NZP CSI RS
-  if (csi_params.csi_type == 1) {
+  if (csi_params->csi_type == 1) {
     // assuming amp is the amplitude of SSB channels
-    switch (csi_params.power_control_offset_ss) {
+    switch (csi_params->power_control_offset_ss) {
     case 0:
       beta = (amp*ONE_OVER_SQRT2_Q15)>>15;
       break;
@@ -545,15 +571,15 @@ void nr_generate_csi_rs(PHY_VARS_gNB *gNB,
     }
 
     for (lp=0; lp<=lprime; lp++){
-      symb = csi_params.symb_l0;
-      nr_modulation(gold_csi_rs[symb+lp], csi_length, DMRS_MOD_ORDER, mod_csi[symb+lp]);
-      if ((csi_params.row == 5) || (csi_params.row == 7) || (csi_params.row == 11) || (csi_params.row == 13) || (csi_params.row == 16))
-        nr_modulation(gold_csi_rs[symb+1], csi_length, DMRS_MOD_ORDER, mod_csi[symb+1]);
-      if ((csi_params.row == 14) || (csi_params.row == 13) || (csi_params.row == 16) || (csi_params.row == 17)) {
-        symb = csi_params.symb_l1;
-        nr_modulation(gold_csi_rs[symb+lp], csi_length, DMRS_MOD_ORDER, mod_csi[symb+lp]);
-        if ((csi_params.row == 13) || (csi_params.row == 16))
-          nr_modulation(gold_csi_rs[symb+1], csi_length, DMRS_MOD_ORDER, mod_csi[symb+1]);
+      symb = csi_params->symb_l0;
+      nr_modulation(nr_gold_csi_rs[symb+lp], csi_length, DMRS_MOD_ORDER, mod_csi[symb+lp]);
+      if ((csi_params->row == 5) || (csi_params->row == 7) || (csi_params->row == 11) || (csi_params->row == 13) || (csi_params->row == 16))
+        nr_modulation(nr_gold_csi_rs[symb+1], csi_length, DMRS_MOD_ORDER, mod_csi[symb+1]);
+      if ((csi_params->row == 14) || (csi_params->row == 13) || (csi_params->row == 16) || (csi_params->row == 17)) {
+        symb = csi_params->symb_l1;
+        nr_modulation(nr_gold_csi_rs[symb+lp], csi_length, DMRS_MOD_ORDER, mod_csi[symb+lp]);
+        if ((csi_params->row == 13) || (csi_params->row == 16))
+          nr_modulation(nr_gold_csi_rs[symb+1], csi_length, DMRS_MOD_ORDER, mod_csi[symb+1]);
       }
     }
   }
@@ -561,14 +587,14 @@ void nr_generate_csi_rs(PHY_VARS_gNB *gNB,
   uint16_t start_sc = frame_parms.first_carrier_offset;
 
   // resource mapping according to 38.211 7.4.1.5.3
-  for (n=csi_start; n<(csi_start+csi_bw); n++) {
-   if ( (csi_params.freq_density > 1) || (csi_params.freq_density == (n%2))) {  // for freq density 0.5 checks if even or odd RB
+  for (n=csi_params->start_rb; n<(csi_params->start_rb+csi_params->nr_of_rbs); n++) {
+   if ( (csi_params->freq_density > 1) || (csi_params->freq_density == (n%2))) {  // for freq density 0.5 checks if even or odd RB
     for (int ji=0; ji<size; ji++) { // loop over CDM groups
       for (int s=0 ; s<gs; s++)  { // loop over each CDM group size
         p = s+j[ji]*gs; // port index
         for (kp=0; kp<=kprime; kp++) { // loop over frequency resource elements within a group
           k = (start_sc+(n*NR_NB_SC_PER_RB)+koverline[ji]+kp)%(frame_parms.ofdm_symbol_size);  // frequency index of current resource element
-          // wf according to tables 7.4.5.3-2 to 7.4.5.3-5 
+          // wf according to tables 7.4.5.3-2 to 7.4.5.3-5
           if (kp == 0)
             wf = 1;
           else
@@ -591,24 +617,44 @@ void nr_generate_csi_rs(PHY_VARS_gNB *gNB,
               else
                 wt = -1;
             }
+
             // ZP CSI RS
-            if (csi_params.csi_type == 2) {
-              ((int16_t*)txdataF[p])[((l*frame_parms.ofdm_symbol_size + k)<<1)+(2*txdataF_offset)] = 0;
-              ((int16_t*)txdataF[p])[((l*frame_parms.ofdm_symbol_size + k)<<1)+1+(2*txdataF_offset)] = 0;
+            if (csi_params->csi_type == 2) {
+              ((int16_t*)dataF[p])[((l*frame_parms.ofdm_symbol_size + k)<<1)+(2*dataF_offset)] = 0;
+              ((int16_t*)dataF[p])[((l*frame_parms.ofdm_symbol_size + k)<<1)+1+(2*dataF_offset)] = 0;
             }
             else {
-              ((int16_t*)txdataF[p])[((l*frame_parms.ofdm_symbol_size + k)<<1)+(2*txdataF_offset)] = (beta*wt*wf*mod_csi[l][mprime<<1]) >> 15;
-              ((int16_t*)txdataF[p])[((l*frame_parms.ofdm_symbol_size + k)<<1)+1+(2*txdataF_offset)] = (beta*wt*wf*mod_csi[l][(mprime<<1) + 1]) >> 15;
+              ((int16_t*)dataF[p])[((l*frame_parms.ofdm_symbol_size + k)<<1)+(2*dataF_offset)] = (beta*wt*wf*mod_csi[l][mprime<<1]) >> 15;
+              ((int16_t*)dataF[p])[((l*frame_parms.ofdm_symbol_size + k)<<1)+1+(2*dataF_offset)] = (beta*wt*wf*mod_csi[l][(mprime<<1) + 1]) >> 15;
             }
 #ifdef NR_CSIRS_DEBUG
-            printf("l,k (%d %d)  seq. index %d \t port %d \t (%d,%d)\n",l,k,mprime,p+3000,
-                   ((int16_t*)txdataF[p])[((l*frame_parms.ofdm_symbol_size + k)<<1)+(2*txdataF_offset)],
-                   ((int16_t*)txdataF[p])[((l*frame_parms.ofdm_symbol_size + k)<<1)+1+(2*txdataF_offset)]);
+            printf("l,k (%d,%d)  seq. index %d \t port %d \t (%d,%d)\n",l,k,mprime,p+3000,
+                   ((int16_t*)dataF[p])[((l*frame_parms.ofdm_symbol_size + k)<<1)+(2*dataF_offset)],
+                   ((int16_t*)dataF[p])[((l*frame_parms.ofdm_symbol_size + k)<<1)+1+(2*dataF_offset)]);
 #endif
           }
         }
-      }    
+      }
     }
    }
-  } 
+  }
+  nr_csi_rs_info->N_cdm_groups = size;
+  nr_csi_rs_info->CDM_group_size = gs;
+  nr_csi_rs_info->kprime = kprime;
+  nr_csi_rs_info->lprime = lprime;
+  nr_csi_rs_info->N_ports = ports;
+  memcpy(nr_csi_rs_info->j,j,16*sizeof(uint8_t));
+  memcpy(nr_csi_rs_info->koverline,koverline,16*sizeof(uint8_t));
+  memcpy(nr_csi_rs_info->loverline,loverline,16*sizeof(uint8_t));
+
+#ifdef NR_CSIRS_DEBUG
+  LOG_I(NR_PHY, "nr_csi_rs_info->N_ports = %d\n", nr_csi_rs_info->N_ports);
+  LOG_I(NR_PHY, "nr_csi_rs_info->N_cdm_groups = %d\n", nr_csi_rs_info->N_cdm_groups);
+  LOG_I(NR_PHY, "nr_csi_rs_info->CDM_group_size = %d\n", nr_csi_rs_info->CDM_group_size);
+  LOG_I(NR_PHY, "nr_csi_rs_info->kprime = %d\n", nr_csi_rs_info->kprime);
+  LOG_I(NR_PHY, "nr_csi_rs_info->lprime = %d\n", nr_csi_rs_info->lprime);
+  for(int ji=0; ji<nr_csi_rs_info->N_cdm_groups; ji++) {
+    LOG_I(NR_PHY, "(CDM group %d) j = %d, koverline = %d, loverline = %d\n", ji, nr_csi_rs_info->j[ji], nr_csi_rs_info->koverline[ji], nr_csi_rs_info->loverline[ji]);
+  }
+#endif
 }
diff --git a/openair1/PHY/NR_TRANSPORT/nr_dlsch.c b/openair1/PHY/NR_TRANSPORT/nr_dlsch.c
index d975c1d38bfe75ee6b468339458e311b40941341..45125c8db439eddfd5300d0952bf9d7172bebfc8 100644
--- a/openair1/PHY/NR_TRANSPORT/nr_dlsch.c
+++ b/openair1/PHY/NR_TRANSPORT/nr_dlsch.c
@@ -214,6 +214,7 @@ void nr_generate_pdsch(processingData_L1tx_t *msgTx,
 #endif
 
     stop_meas(&gNB->dlsch_layer_mapping_stats); 
+
     /// Resource mapping
     
     // Non interleaved VRB to PRB mapping
@@ -235,6 +236,7 @@ void nr_generate_pdsch(processingData_L1tx_t *msgTx,
     for (int nl=0; nl<rel15->nrOfLayers; nl++) {
 
       int dmrs_port = get_dmrs_port(nl,rel15->dmrsPorts);
+
       // DMRS params for this dmrs port
       get_Wt(Wt, dmrs_port, dmrs_Type);
       get_Wf(Wf, dmrs_port, dmrs_Type);
@@ -312,7 +314,8 @@ void nr_generate_pdsch(processingData_L1tx_t *msgTx,
           for (int i=0; i<rel15->rbSize*NR_NB_SC_PER_RB; i++) {
             /* check if cuurent RE is PTRS RE*/
             is_ptrs_re = 0;
-            if (ptrs_symbol)
+            /* check for PTRS symbol and set flag for PTRS RE */
+            if(ptrs_symbol){
               is_ptrs_re = is_ptrs_subcarrier(k,
                                               rel15->rnti,
                                               nl,
@@ -322,6 +325,7 @@ void nr_generate_pdsch(processingData_L1tx_t *msgTx,
                                               rel15->PTRSReOffset,
                                               start_sc,
                                               frame_parms->ofdm_symbol_size);
+            }
             /* Map DMRS Symbol */
             if ( (dmrs_symbol_map & (1 << l)) &&
                  (k == ((start_sc+get_dmrs_freq_idx(n, k_prime, delta, dmrs_Type))%(frame_parms->ofdm_symbol_size)))) {
@@ -337,6 +341,7 @@ void nr_generate_pdsch(processingData_L1tx_t *msgTx,
               k_prime&=1;
               n+=(k_prime)?0:1;
             }
+            /* Map PTRS Symbol */
             else if(is_ptrs_re){
               txdataF_precoding[nl][((l*frame_parms->ofdm_symbol_size + k)<<1)    ] = (beta_ptrs*amp*mod_ptrs[ptrs_idx<<1]) >> 15;
               txdataF_precoding[nl][((l*frame_parms->ofdm_symbol_size + k)<<1) + 1] = (beta_ptrs*amp*mod_ptrs[(ptrs_idx<<1) + 1])>> 15;
diff --git a/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h b/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h
index 3ee2a8ad5a042a74f6b899b433016d56011dcee0..e3b7efacfb8d53b30221eb452754d7676488386f 100644
--- a/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h
+++ b/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h
@@ -337,9 +337,11 @@ void init_prach_ru_list(RU_t *ru);
 void free_nr_ru_prach_entry(RU_t *ru, int prach_id);
 uint8_t get_nr_prach_duration(uint8_t prach_format);
 
-void nr_generate_csi_rs(PHY_VARS_gNB *gNB,
+void nr_generate_csi_rs(NR_DL_FRAME_PARMS frame_parms,
+                        int32_t **dataF,
                         int16_t amp,
-                        nfapi_nr_dl_tti_csi_rs_pdu_rel15_t csi_params,
+                        nr_csi_rs_info_t *nr_csi_rs_info,
+                        nfapi_nr_dl_tti_csi_rs_pdu_rel15_t *csi_params,
                         int slot);
 
 void free_nr_prach_entry(PHY_VARS_gNB *gNB, int prach_id);
diff --git a/openair1/PHY/NR_TRANSPORT/pucch_rx.c b/openair1/PHY/NR_TRANSPORT/pucch_rx.c
index 83093494916429ced83b20d46448cda2f533de47..5617b8e58bb48784273981ee7dcd9ae892ec68c3 100644
--- a/openair1/PHY/NR_TRANSPORT/pucch_rx.c
+++ b/openair1/PHY/NR_TRANSPORT/pucch_rx.c
@@ -1545,7 +1545,7 @@ void nr_decode_pucch2(PHY_VARS_gNB *gNB,
 #ifdef DEBUG_NR_PUCCH_RX
     printf("cw_ML %d, metric %d dB\n",cw_ML,corr_dB);
 #endif
-    LOG_D(PHY,"slot %d PUCCH2 cw_ML %d, metric %d dB\n",slot,cw_ML,corr_dB);
+    LOG_D(PHY,"slot %d PUCCH2 cw_ML %d, metric %d dB\n", slot, cw_ML, corr_dB);
 
     decodedPayload[0]=(uint64_t)cw_ML;
   }
diff --git a/openair1/PHY/NR_UE_ESTIMATION/filt16a_32.c b/openair1/PHY/NR_UE_ESTIMATION/filt16a_32.c
index af62f0b34af4998977bafea135e635297856cdd4..624894aeb99710e27914891692773964eaef0b33 100644
--- a/openair1/PHY/NR_UE_ESTIMATION/filt16a_32.c
+++ b/openair1/PHY/NR_UE_ESTIMATION/filt16a_32.c
@@ -282,4 +282,17 @@ short filt16_middle4[16] = {
     4096,8192,8192,8192,8192,8192,8192,8192,4096,0,0,0,0,0,0,0};
 
 short filt16_end[16] = {
-    4096,8192,8192,8192,12288,16384,16384,16384,0,0,0,0,0,0,0,0};
\ No newline at end of file
+    4096,8192,8192,8192,12288,16384,16384,16384,0,0,0,0,0,0,0,0};
+
+// CSI-RS
+short filt24_start[24] = {
+    12288,11605,10923,10240,9557,8875,8192,7509,6827,6144,5461,4779,
+    0,0,0,0,0,0,0,0,0,0,0,0};
+
+short filt24_end[24] = {
+    4096,4779,5461,6144,6827,7509,8192,8875,9557,10240,10923,11605,
+    16384,16384,16384,16384,16384,16384,16384,16384,16384,16384,16384,16384};
+
+short filt24_middle[24] = {
+    4096,4779,5461,6144,6827,7509,8192,8875,9557,10240,10923,11605,
+    12288,11605,10923,10240,9557,8875,8192,7509,6827,6144,5461,4779};
\ No newline at end of file
diff --git a/openair1/PHY/NR_UE_ESTIMATION/filt16a_32.h b/openair1/PHY/NR_UE_ESTIMATION/filt16a_32.h
index 72d1318545509905aed6c27e6d3a207311876a3a..41109cb7bb6d909af398b1485ecefd4049db4603 100644
--- a/openair1/PHY/NR_UE_ESTIMATION/filt16a_32.h
+++ b/openair1/PHY/NR_UE_ESTIMATION/filt16a_32.h
@@ -193,4 +193,10 @@ extern short filt8_end[8];
 extern short filt16_start[16];
 extern short filt16_middle4[16];
 extern short filt16_end[16];
+
+/*CSI-RS*/
+extern short filt24_start[24];
+extern short filt24_end[24];
+extern short filt24_middle[24];
+
 #endif
diff --git a/openair1/PHY/NR_UE_TRANSPORT/csi_rx.c b/openair1/PHY/NR_UE_TRANSPORT/csi_rx.c
new file mode 100644
index 0000000000000000000000000000000000000000..79fd7a3dd2352bce0d8a27fa5ee85e62a3cd7435
--- /dev/null
+++ b/openair1/PHY/NR_UE_TRANSPORT/csi_rx.c
@@ -0,0 +1,380 @@
+/*
+ * 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
+ */
+
+/***********************************************************************
+*
+* FILENAME    :  csi_rx.c
+*
+* MODULE      :
+*
+* DESCRIPTION :  function to receive the channel state information
+*
+************************************************************************/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "nr_transport_proto_ue.h"
+#include "PHY/phy_extern_nr_ue.h"
+#include "common/utils/nr/nr_common.h"
+#include "PHY/NR_TRANSPORT/nr_transport_proto.h"
+#include "PHY/NR_UE_ESTIMATION/filt16a_32.h"
+
+
+//#define NR_CSIRS_DEBUG
+
+bool is_csi_rs_in_symbol(fapi_nr_dl_config_csirs_pdu_rel15_t csirs_config_pdu, int symbol) {
+
+  bool ret = false;
+
+  // 38.211-Table 7.4.1.5.3-1: CSI-RS locations within a slot
+  switch(csirs_config_pdu.row){
+    case 1:
+    case 2:
+    case 3:
+    case 4:
+    case 6:
+    case 9:
+      if(symbol == csirs_config_pdu.symb_l0) {
+        ret = true;
+      }
+      break;
+    case 5:
+    case 7:
+    case 8:
+    case 10:
+    case 11:
+    case 12:
+      if(symbol == csirs_config_pdu.symb_l0 || symbol == (csirs_config_pdu.symb_l0+1) ) {
+        ret = true;
+      }
+      break;
+    case 13:
+    case 14:
+    case 16:
+    case 17:
+      if(symbol == csirs_config_pdu.symb_l0 || symbol == (csirs_config_pdu.symb_l0+1) ||
+          symbol == csirs_config_pdu.symb_l1 || symbol == (csirs_config_pdu.symb_l1+1)) {
+        ret = true;
+      }
+      break;
+    case 15:
+    case 18:
+      if(symbol == csirs_config_pdu.symb_l0 || symbol == (csirs_config_pdu.symb_l0+1) || symbol == (csirs_config_pdu.symb_l0+2) ) {
+        ret = true;
+      }
+      break;
+    default:
+      AssertFatal(0==1, "Row %d is not valid for CSI Table 7.4.1.5.3-1\n", csirs_config_pdu.row);
+  }
+
+  return ret;
+}
+
+int nr_get_csi_rs_signal(PHY_VARS_NR_UE *ue,
+                         UE_nr_rxtx_proc_t *proc,
+                         fapi_nr_dl_config_csirs_pdu_rel15_t *csirs_config_pdu,
+                         nr_csi_rs_info_t *nr_csi_rs_info,
+                         int32_t **csi_rs_received_signal) {
+
+  int32_t **rxdataF  =  ue->common_vars.common_vars_rx_data_per_thread[proc->thread_id].rxdataF;
+  NR_DL_FRAME_PARMS *frame_parms = &ue->frame_parms;
+
+  for (int ant_rx = 0; ant_rx < frame_parms->nb_antennas_rx; ant_rx++) {
+    memset(csi_rs_received_signal[ant_rx], 0, frame_parms->samples_per_frame_wCP*sizeof(int32_t));
+
+    for (int rb = csirs_config_pdu->start_rb; rb < (csirs_config_pdu->start_rb+csirs_config_pdu->nr_of_rbs); rb++) {
+
+      // for freq density 0.5 checks if even or odd RB
+      if(csirs_config_pdu->freq_density <= 1 && csirs_config_pdu->freq_density != (rb % 2)) {
+        continue;
+      }
+
+      for (int cdm_id = 0; cdm_id < nr_csi_rs_info->N_cdm_groups; cdm_id++) {
+        for (int s = 0; s < nr_csi_rs_info->CDM_group_size; s++)  {
+
+          // loop over frequency resource elements within a group
+          for (int kp = 0; kp <= nr_csi_rs_info->kprime; kp++) {
+
+            uint16_t k = (frame_parms->first_carrier_offset + (rb*NR_NB_SC_PER_RB)+nr_csi_rs_info->koverline[cdm_id] + kp) % frame_parms->ofdm_symbol_size;
+
+            // loop over time resource elements within a group
+            for (int lp = 0; lp <= nr_csi_rs_info->lprime; lp++) {
+              uint16_t symb = lp + nr_csi_rs_info->loverline[cdm_id];
+              uint64_t symbol_offset = symb*frame_parms->ofdm_symbol_size;
+              int16_t *rx_signal = (int16_t*)&rxdataF[ant_rx][symbol_offset];
+              int16_t *rx_csi_rs_signal = (int16_t*)&csi_rs_received_signal[ant_rx][symbol_offset];
+              rx_csi_rs_signal[k<<1] = rx_signal[k<<1];
+              rx_csi_rs_signal[(k<<1)+1] = rx_signal[(k<<1)+1];
+
+#ifdef NR_CSIRS_DEBUG
+              int dataF_offset = proc->nr_slot_rx*ue->frame_parms.samples_per_slot_wCP;
+              uint16_t port_tx = s+nr_csi_rs_info->j[cdm_id]*nr_csi_rs_info->CDM_group_size;
+              int16_t *tx_csi_rs_signal = (int16_t*)&nr_csi_rs_info->csi_rs_generated_signal[port_tx][symbol_offset+dataF_offset];
+              LOG_I(NR_PHY, "l,k (%2d,%4d) |\tport_tx %d (%4d,%4d)\tant_rx %d (%4d,%4d)\n",
+                    symb,
+                    k,
+                    port_tx+3000,
+                    tx_csi_rs_signal[k<<1],
+                    tx_csi_rs_signal[(k<<1)+1],
+                    ant_rx,
+                    rx_csi_rs_signal[k<<1],
+                    rx_csi_rs_signal[(k<<1)+1]);
+#endif
+            }
+          }
+        }
+      }
+    }
+  }
+
+  return 0;
+}
+
+uint32_t calc_power_csirs(uint16_t *x, fapi_nr_dl_config_csirs_pdu_rel15_t *csirs_config_pdu) {
+  uint64_t sum_x = 0;
+  uint64_t sum_x2 = 0;
+  uint16_t size = 0;
+  for (int rb = csirs_config_pdu->start_rb; rb < (csirs_config_pdu->start_rb+csirs_config_pdu->nr_of_rbs); rb++) {
+    if (csirs_config_pdu->freq_density <= 1 && csirs_config_pdu->freq_density != (rb % 2)) {
+      continue;
+    }
+    sum_x = sum_x + x[rb-csirs_config_pdu->start_rb];
+    sum_x2 = sum_x2 + x[rb]*x[rb-csirs_config_pdu->start_rb];
+    size++;
+  }
+  return sum_x2/size - (sum_x/size)*(sum_x/size);
+}
+
+int nr_csi_rs_channel_estimation(PHY_VARS_NR_UE *ue,
+                                 UE_nr_rxtx_proc_t *proc,
+                                 fapi_nr_dl_config_csirs_pdu_rel15_t *csirs_config_pdu,
+                                 nr_csi_rs_info_t *nr_csi_rs_info,
+                                 int32_t **csi_rs_generated_signal,
+                                 int32_t **csi_rs_received_signal,
+                                 int32_t ***csi_rs_estimated_channel_freq,
+                                 uint32_t *noise_power) {
+
+  NR_DL_FRAME_PARMS *frame_parms = &ue->frame_parms;
+  int dataF_offset = proc->nr_slot_rx*ue->frame_parms.samples_per_slot_wCP;
+  *noise_power = 0;
+
+  for (int ant_rx = 0; ant_rx < frame_parms->nb_antennas_rx; ant_rx++) {
+
+    /// LS channel estimation
+
+    for(uint16_t port_tx = 0; port_tx<nr_csi_rs_info->N_ports; port_tx++) {
+      memset(nr_csi_rs_info->csi_rs_ls_estimated_channel[ant_rx][port_tx], 0, frame_parms->ofdm_symbol_size*sizeof(int32_t));
+    }
+
+    for (int rb = csirs_config_pdu->start_rb; rb < (csirs_config_pdu->start_rb+csirs_config_pdu->nr_of_rbs); rb++) {
+
+      // for freq density 0.5 checks if even or odd RB
+      if(csirs_config_pdu->freq_density <= 1 && csirs_config_pdu->freq_density != (rb % 2)) {
+        continue;
+      }
+
+      for (int cdm_id = 0; cdm_id < nr_csi_rs_info->N_cdm_groups; cdm_id++) {
+        for (int s = 0; s < nr_csi_rs_info->CDM_group_size; s++)  {
+
+          uint16_t port_tx = s+nr_csi_rs_info->j[cdm_id]*nr_csi_rs_info->CDM_group_size;
+
+          // loop over frequency resource elements within a group
+          for (int kp = 0; kp <= nr_csi_rs_info->kprime; kp++) {
+
+            uint16_t kinit = (frame_parms->first_carrier_offset + rb*NR_NB_SC_PER_RB) % frame_parms->ofdm_symbol_size;
+            uint16_t k = kinit + nr_csi_rs_info->koverline[cdm_id] + kp;
+
+            // loop over time resource elements within a group
+            for (int lp = 0; lp <= nr_csi_rs_info->lprime; lp++) {
+              uint16_t symb = lp + nr_csi_rs_info->loverline[cdm_id];
+              uint64_t symbol_offset = symb*frame_parms->ofdm_symbol_size;
+              int16_t *tx_csi_rs_signal = (int16_t*)&csi_rs_generated_signal[port_tx][symbol_offset+dataF_offset];
+              int16_t *rx_csi_rs_signal = (int16_t*)&csi_rs_received_signal[ant_rx][symbol_offset];
+              int16_t *csi_rs_ls_estimated_channel = (int16_t*)&nr_csi_rs_info->csi_rs_ls_estimated_channel[ant_rx][port_tx][0];
+
+              int16_t csi_rs_ls_estimated_channel_re = (int16_t)(((int32_t)tx_csi_rs_signal[k<<1]*rx_csi_rs_signal[k<<1] + (int32_t)tx_csi_rs_signal[(k<<1)+1]*rx_csi_rs_signal[(k<<1)+1])>>nr_csi_rs_info->csi_rs_generated_signal_bits);
+              int16_t csi_rs_ls_estimated_channel_im = (int16_t)(((int32_t)tx_csi_rs_signal[k<<1]*rx_csi_rs_signal[(k<<1)+1] - (int32_t)tx_csi_rs_signal[(k<<1)+1]*rx_csi_rs_signal[k<<1])>>nr_csi_rs_info->csi_rs_generated_signal_bits);
+
+              // This is not just the LS estimation for each (k,l), but also the sum of the different contributions
+              // for the sake of optimizing the memory used.
+              csi_rs_ls_estimated_channel[kinit<<1] += csi_rs_ls_estimated_channel_re;
+              csi_rs_ls_estimated_channel[(kinit<<1)+1] += csi_rs_ls_estimated_channel_im;
+            }
+          }
+        }
+      }
+    }
+
+#ifdef NR_CSIRS_DEBUG
+    for(int symb = 0; symb < NR_SYMBOLS_PER_SLOT; symb++) {
+      if(!is_csi_rs_in_symbol(*csirs_config_pdu,symb)) {
+        continue;
+      }
+      for(int k = 0; k<frame_parms->ofdm_symbol_size; k++) {
+        LOG_I(NR_PHY, "l,k (%2d,%4d) | ", symb, k);
+        for(uint16_t port_tx = 0; port_tx<nr_csi_rs_info->N_ports; port_tx++) {
+          uint64_t symbol_offset = symb*frame_parms->ofdm_symbol_size;
+          int16_t *tx_csi_rs_signal = (int16_t*)&csi_rs_generated_signal[port_tx][symbol_offset+dataF_offset];
+          int16_t *rx_csi_rs_signal = (int16_t*)&csi_rs_received_signal[ant_rx][symbol_offset];
+          int16_t *csi_rs_ls_estimated_channel = (int16_t*)&nr_csi_rs_info->csi_rs_ls_estimated_channel[ant_rx][port_tx][0];
+          printf("port_tx %d --> ant_rx %d, tx (%4d,%4d), rx (%4d,%4d), ls (%4d,%4d) | ",
+                 port_tx+3000, ant_rx,
+                 tx_csi_rs_signal[k<<1], tx_csi_rs_signal[(k<<1)+1],
+                 rx_csi_rs_signal[k<<1], rx_csi_rs_signal[(k<<1)+1],
+                 csi_rs_ls_estimated_channel[k<<1], csi_rs_ls_estimated_channel[(k<<1)+1]);
+        }
+        printf("\n");
+      }
+    }
+#endif
+
+    /// Channel interpolation
+
+    for(uint16_t port_tx = 0; port_tx<nr_csi_rs_info->N_ports; port_tx++) {
+      memset(csi_rs_estimated_channel_freq[ant_rx][port_tx], 0, frame_parms->ofdm_symbol_size*sizeof(int32_t));
+    }
+
+    for (int rb = csirs_config_pdu->start_rb; rb < (csirs_config_pdu->start_rb+csirs_config_pdu->nr_of_rbs); rb++) {
+
+      // for freq density 0.5 checks if even or odd RB
+      if(csirs_config_pdu->freq_density <= 1 && csirs_config_pdu->freq_density != (rb % 2)) {
+        continue;
+      }
+
+      uint16_t k = (frame_parms->first_carrier_offset + rb*NR_NB_SC_PER_RB) % frame_parms->ofdm_symbol_size;
+      for(uint16_t port_tx = 0; port_tx<nr_csi_rs_info->N_ports; port_tx++) {
+        int16_t *csi_rs_ls_estimated_channel = (int16_t*)&nr_csi_rs_info->csi_rs_ls_estimated_channel[ant_rx][port_tx][k];
+        int16_t *csi_rs_estimated_channel16 = (int16_t *)&csi_rs_estimated_channel_freq[ant_rx][port_tx][k];
+        if( (k == 0) || (k == frame_parms->first_carrier_offset) ) { // Start of OFDM symbol case or first occupied subcarrier case
+          multadd_real_vector_complex_scalar(filt24_start, csi_rs_ls_estimated_channel, csi_rs_estimated_channel16, 24);
+        } else if( ( (k + NR_NB_SC_PER_RB) >= frame_parms->ofdm_symbol_size) ||
+                   (rb == (csirs_config_pdu->start_rb+csirs_config_pdu->nr_of_rbs-1)) ) { // End of OFDM symbol case or Last occupied subcarrier case
+          multadd_real_vector_complex_scalar(filt24_end, csi_rs_ls_estimated_channel, csi_rs_estimated_channel16 - 3*sizeof(uint64_t), 24);
+        } else { // Middle case
+          multadd_real_vector_complex_scalar(filt24_middle, csi_rs_ls_estimated_channel, csi_rs_estimated_channel16 - 3*sizeof(uint64_t), 24);
+        }
+      }
+    }
+
+    /// Power noise estimation
+    uint16_t noise_real[frame_parms->nb_antennas_rx][nr_csi_rs_info->N_ports][csirs_config_pdu->nr_of_rbs];
+    uint16_t noise_imag[frame_parms->nb_antennas_rx][nr_csi_rs_info->N_ports][csirs_config_pdu->nr_of_rbs];
+    for (int rb = csirs_config_pdu->start_rb; rb < (csirs_config_pdu->start_rb+csirs_config_pdu->nr_of_rbs); rb++) {
+      if (csirs_config_pdu->freq_density <= 1 && csirs_config_pdu->freq_density != (rb % 2)) {
+        continue;
+      }
+      uint16_t k = (frame_parms->first_carrier_offset + rb*NR_NB_SC_PER_RB) % frame_parms->ofdm_symbol_size;
+      for(uint16_t port_tx = 0; port_tx<nr_csi_rs_info->N_ports; port_tx++) {
+        int16_t *csi_rs_ls_estimated_channel = (int16_t*)&nr_csi_rs_info->csi_rs_ls_estimated_channel[ant_rx][port_tx][k];
+        int16_t *csi_rs_estimated_channel16 = (int16_t *)&csi_rs_estimated_channel_freq[ant_rx][port_tx][k];
+        noise_real[ant_rx][port_tx][rb-csirs_config_pdu->start_rb] = abs(csi_rs_ls_estimated_channel[0]-csi_rs_estimated_channel16[0]);
+        noise_imag[ant_rx][port_tx][rb-csirs_config_pdu->start_rb] = abs(csi_rs_ls_estimated_channel[1]-csi_rs_estimated_channel16[1]);
+      }
+    }
+    for(uint16_t port_tx = 0; port_tx<nr_csi_rs_info->N_ports; port_tx++) {
+      *noise_power += (calc_power_csirs(noise_real[ant_rx][port_tx], csirs_config_pdu) + calc_power_csirs(noise_imag[ant_rx][port_tx],csirs_config_pdu));
+    }
+
+#ifdef NR_CSIRS_DEBUG
+    for(int k = 0; k<frame_parms->ofdm_symbol_size; k++) {
+      int rb = k >= frame_parms->first_carrier_offset ?
+               (k - frame_parms->first_carrier_offset)/NR_NB_SC_PER_RB :
+               (k + frame_parms->ofdm_symbol_size - frame_parms->first_carrier_offset)/NR_NB_SC_PER_RB;
+      LOG_I(NR_PHY, "(k = %4d) |\t", k);
+      for(uint16_t port_tx = 0; port_tx<nr_csi_rs_info->N_ports; port_tx++) {
+        int16_t *csi_rs_ls_estimated_channel = (int16_t*)&nr_csi_rs_info->csi_rs_ls_estimated_channel[ant_rx][port_tx][0];
+        int16_t *csi_rs_estimated_channel16 = (int16_t *)&csi_rs_estimated_channel_freq[ant_rx][port_tx][0];
+        printf("Channel port_tx %d --> ant_rx %d : ls (%4d,%4d), int (%4d,%4d), noise (%4d,%4d) | ",
+               port_tx+3000, ant_rx,
+               csi_rs_ls_estimated_channel[k<<1], csi_rs_ls_estimated_channel[(k<<1)+1],
+               csi_rs_estimated_channel16[k<<1], csi_rs_estimated_channel16[(k<<1)+1],
+               rb >= csirs_config_pdu->start_rb+csirs_config_pdu->nr_of_rbs ? 0 : noise_real[ant_rx][port_tx][rb-csirs_config_pdu->start_rb],
+               rb >= csirs_config_pdu->start_rb+csirs_config_pdu->nr_of_rbs ? 0 : noise_imag[ant_rx][port_tx][rb-csirs_config_pdu->start_rb]);
+      }
+      printf("\n");
+    }
+#endif
+
+  }
+
+  *noise_power /= (frame_parms->nb_antennas_rx*nr_csi_rs_info->N_ports);
+
+#ifdef NR_CSIRS_DEBUG
+  LOG_I(NR_PHY, "Noise power estimation based on CSI-RS: %i\n", *noise_power);
+#endif
+
+  return 0;
+}
+
+int nr_ue_csi_im_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, uint8_t gNB_id) {
+  return 0;
+}
+
+int nr_ue_csi_rs_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, uint8_t gNB_id) {
+
+  if(!ue->csirs_vars[gNB_id]->active) {
+    return -1;
+  }
+
+  fapi_nr_dl_config_csirs_pdu_rel15_t *csirs_config_pdu = (fapi_nr_dl_config_csirs_pdu_rel15_t*)&ue->csirs_vars[gNB_id]->csirs_config_pdu;
+
+#ifdef NR_CSIRS_DEBUG
+  LOG_I(NR_PHY, "csirs_config_pdu->subcarrier_spacing = %i\n", csirs_config_pdu->subcarrier_spacing);
+  LOG_I(NR_PHY, "csirs_config_pdu->cyclic_prefix = %i\n", csirs_config_pdu->cyclic_prefix);
+  LOG_I(NR_PHY, "csirs_config_pdu->start_rb = %i\n", csirs_config_pdu->start_rb);
+  LOG_I(NR_PHY, "csirs_config_pdu->nr_of_rbs = %i\n", csirs_config_pdu->nr_of_rbs);
+  LOG_I(NR_PHY, "csirs_config_pdu->csi_type = %i (0:TRS, 1:CSI-RS NZP, 2:CSI-RS ZP)\n", csirs_config_pdu->csi_type);
+  LOG_I(NR_PHY, "csirs_config_pdu->row = %i\n", csirs_config_pdu->row);
+  LOG_I(NR_PHY, "csirs_config_pdu->freq_domain = %i\n", csirs_config_pdu->freq_domain);
+  LOG_I(NR_PHY, "csirs_config_pdu->symb_l0 = %i\n", csirs_config_pdu->symb_l0);
+  LOG_I(NR_PHY, "csirs_config_pdu->symb_l1 = %i\n", csirs_config_pdu->symb_l1);
+  LOG_I(NR_PHY, "csirs_config_pdu->cdm_type = %i\n", csirs_config_pdu->cdm_type);
+  LOG_I(NR_PHY, "csirs_config_pdu->freq_density = %i (0: dot5 (even RB), 1: dot5 (odd RB), 2: one, 3: three)\n", csirs_config_pdu->freq_density);
+  LOG_I(NR_PHY, "csirs_config_pdu->scramb_id = %i\n", csirs_config_pdu->scramb_id);
+  LOG_I(NR_PHY, "csirs_config_pdu->power_control_offset = %i\n", csirs_config_pdu->power_control_offset);
+  LOG_I(NR_PHY, "csirs_config_pdu->power_control_offset_ss = %i\n", csirs_config_pdu->power_control_offset_ss);
+#endif
+
+  nr_generate_csi_rs(ue->frame_parms,
+                     ue->nr_csi_rs_info->csi_rs_generated_signal,
+                     AMP,
+                     ue->nr_csi_rs_info,
+                     (nfapi_nr_dl_tti_csi_rs_pdu_rel15_t *) csirs_config_pdu,
+                     proc->nr_slot_rx);
+
+  nr_get_csi_rs_signal(ue,
+                       proc,
+                       csirs_config_pdu,
+                       ue->nr_csi_rs_info,
+                       ue->nr_csi_rs_info->csi_rs_received_signal);
+
+  nr_csi_rs_channel_estimation(ue,
+                               proc,
+                               csirs_config_pdu,
+                               ue->nr_csi_rs_info,
+                               ue->nr_csi_rs_info->csi_rs_generated_signal,
+                               ue->nr_csi_rs_info->csi_rs_received_signal,
+                               ue->nr_csi_rs_info->csi_rs_estimated_channel_freq,
+                               ue->nr_csi_rs_info->noise_power);
+  return 0;
+}
diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c b/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c
index e248ce87cb23ca88ddcf34a506be282e61d46b32..5f3af5bb3958aa5b80f3338b06d503ffb4c08091 100644
--- a/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c
+++ b/openair1/PHY/NR_UE_TRANSPORT/nr_initial_sync.c
@@ -362,6 +362,8 @@ int nr_initial_sync(UE_nr_rxtx_proc_t *proc,
           nr_gold_pdsch(ue, i, ue->scramblingID_dlsch[i]);
         }
 
+        nr_init_csi_rs(fp, ue->nr_csi_rs_info->nr_gold_csi_rs, fp->Nid_cell);
+
         // initialize the pusch dmrs
         for (int i=0; i<NR_NB_NSCID; i++) {
           ue->scramblingID_ulsch[i]=fp->Nid_cell;
diff --git a/openair1/PHY/defs_gNB.h b/openair1/PHY/defs_gNB.h
index 647619819ff96be882fb131fbb435f70432320ac..ace4cf120b3ec87d51104365b5a142c477c9bb3e 100644
--- a/openair1/PHY/defs_gNB.h
+++ b/openair1/PHY/defs_gNB.h
@@ -763,6 +763,9 @@ typedef struct PHY_VARS_gNB_s {
   /// SRS variables
   nr_srs_info_t *nr_srs_info[NUMBER_OF_NR_SRS_MAX];
 
+  /// CSI-RS variables
+  nr_csi_rs_info_t *nr_csi_rs_info;
+
   uint8_t pbch_configured;
   char gNB_generate_rar;
 
@@ -794,9 +797,6 @@ typedef struct PHY_VARS_gNB_s {
   // Mask of occupied RBs, per symbol and PRB
   uint32_t rb_mask_ul[14][9];
 
-  /// CSI  RS sequence
-  uint32_t ***nr_gold_csi_rs;
-
   /// Indicator set to 0 after first SR
   uint8_t first_sr[NUMBER_OF_NR_SR_MAX];
 
@@ -833,7 +833,6 @@ typedef struct PHY_VARS_gNB_s {
   /// counter to average prach energh over first 100 prach opportunities
   int prach_energy_counter;
 
-  int csi_gold_init;
   int pdcch_gold_init;
   int pdsch_gold_init[2];
   int pusch_gold_init[2];
diff --git a/openair1/PHY/defs_nr_UE.h b/openair1/PHY/defs_nr_UE.h
index baf8dff8a8ef24c4e68864cc30c8dc4449946cb8..259367a994f69f408be9520bea8bee4db695a9b9 100644
--- a/openair1/PHY/defs_nr_UE.h
+++ b/openair1/PHY/defs_nr_UE.h
@@ -594,6 +594,16 @@ typedef struct {
   fapi_nr_ul_config_prach_pdu prach_pdu;
 } NR_UE_PRACH;
 
+typedef struct {
+  bool active;
+  fapi_nr_dl_config_csiim_pdu_rel15_t csiim_config_pdu;
+} NR_UE_CSI_IM;
+
+typedef struct {
+  bool active;
+  fapi_nr_dl_config_csirs_pdu_rel15_t csirs_config_pdu;
+} NR_UE_CSI_RS;
+
 typedef struct {
   bool active;
   fapi_nr_ul_config_srs_pdu srs_config_pdu;
@@ -707,6 +717,8 @@ typedef struct {
   NR_UE_PBCH      *pbch_vars[NUMBER_OF_CONNECTED_gNB_MAX];
   NR_UE_PDCCH     *pdcch_vars[RX_NB_TH_MAX][NUMBER_OF_CONNECTED_gNB_MAX];
   NR_UE_PRACH     *prach_vars[NUMBER_OF_CONNECTED_gNB_MAX];
+  NR_UE_CSI_IM    *csiim_vars[NUMBER_OF_CONNECTED_gNB_MAX];
+  NR_UE_CSI_RS    *csirs_vars[NUMBER_OF_CONNECTED_gNB_MAX];
   NR_UE_SRS       *srs_vars[NUMBER_OF_CONNECTED_gNB_MAX];
   NR_UE_PUCCH     *pucch_vars[RX_NB_TH_MAX][NUMBER_OF_CONNECTED_gNB_MAX];
   NR_UE_DLSCH_t   *dlsch[RX_NB_TH_MAX][NUMBER_OF_CONNECTED_gNB_MAX][NR_MAX_NB_LAYERS>4 ? 2:1]; // two RxTx Threads
@@ -865,6 +877,9 @@ typedef struct {
   /// SRS variables
   nr_srs_info_t *nr_srs_info;
 
+  /// CSI-RS variables
+  nr_csi_rs_info_t *nr_csi_rs_info;
+
   //#if defined(UPGRADE_RAT_NR)
 #if 1
   SystemInformationBlockType1_nr_t systemInformationBlockType1_nr;
diff --git a/openair1/PHY/defs_nr_common.h b/openair1/PHY/defs_nr_common.h
index 098c0478751181ed7af188d9174e1e5a1a7fce4f..657d05fc6eb7781489850dc4bd0c7cfec970bda9 100644
--- a/openair1/PHY/defs_nr_common.h
+++ b/openair1/PHY/defs_nr_common.h
@@ -81,6 +81,7 @@
 #define NR_MAX_NB_RBG 18
 
 #define NR_MAX_NB_LAYERS 4 // 8
+#define NR_MAX_NB_PORTS 32
 
 #define NR_MAX_NB_HARQ_PROCESSES 16
 
@@ -255,6 +256,25 @@ typedef struct {
   int8_t *snr;
 } nr_srs_info_t;
 
+typedef struct {
+  uint8_t N_cdm_groups;
+  uint8_t CDM_group_size;
+  uint8_t kprime;
+  uint8_t lprime;
+  uint8_t N_ports;
+  uint8_t j[16];
+  uint8_t koverline[16];
+  uint8_t loverline[16];
+  uint16_t csi_gold_init;
+  uint32_t ***nr_gold_csi_rs;
+  uint8_t csi_rs_generated_signal_bits;
+  int32_t **csi_rs_generated_signal;
+  int32_t **csi_rs_received_signal;
+  int32_t ***csi_rs_ls_estimated_channel;
+  int32_t ***csi_rs_estimated_channel_freq;
+  uint32_t *noise_power;
+} nr_csi_rs_info_t;
+
 typedef struct NR_DL_FRAME_PARMS NR_DL_FRAME_PARMS;
 
 typedef uint32_t (*get_samples_per_slot_t)(int slot, NR_DL_FRAME_PARMS* fp);
diff --git a/openair1/SCHED_NR/phy_procedures_nr_gNB.c b/openair1/SCHED_NR/phy_procedures_nr_gNB.c
index a8e5f84d9c0bb460778d8ff52a54467d782a33c9..dcf2b967f4de8ce5603373b61f32016d5e4f93a6 100644
--- a/openair1/SCHED_NR/phy_procedures_nr_gNB.c
+++ b/openair1/SCHED_NR/phy_procedures_nr_gNB.c
@@ -179,8 +179,8 @@ void phy_procedures_gNB_TX(processingData_L1tx_t *msgTx,
     NR_gNB_CSIRS_t *csirs = &msgTx->csirs_pdu[i];
     if (csirs->active == 1) {
       LOG_D(PHY, "CSI-RS generation started in frame %d.%d\n",frame,slot);
-      nfapi_nr_dl_tti_csi_rs_pdu_rel15_t csi_params = csirs->csirs_pdu.csi_rs_pdu_rel15;
-      nr_generate_csi_rs(gNB, AMP, csi_params, slot);
+      nfapi_nr_dl_tti_csi_rs_pdu_rel15_t *csi_params = &csirs->csirs_pdu.csi_rs_pdu_rel15;
+      nr_generate_csi_rs(gNB->frame_parms, gNB->common_vars.txdataF, AMP, gNB->nr_csi_rs_info, csi_params, slot);
       csirs->active = 0;
     }
   }
diff --git a/openair1/SCHED_NR_UE/defs.h b/openair1/SCHED_NR_UE/defs.h
index 9bcf659eac83b4a279521acdc6cbeece4e980109..7672aee8a25a7121e0061b5060f41cb16817d1ef 100644
--- a/openair1/SCHED_NR_UE/defs.h
+++ b/openair1/SCHED_NR_UE/defs.h
@@ -373,6 +373,7 @@ int get_tx_harq_id(NR_UE_ULSCH_t *ulsch, int slot_tx);
 
 int is_pbch_in_slot(fapi_nr_config_request_t *config, int frame, int slot, NR_DL_FRAME_PARMS *fp);
 int is_ssb_in_slot(fapi_nr_config_request_t *config, int frame, int slot, NR_DL_FRAME_PARMS *fp);
+bool is_csi_rs_in_symbol(fapi_nr_dl_config_csirs_pdu_rel15_t csirs_config_pdu, int symbol);
 
 /*! \brief This function prepares the dl indication to pass to the MAC
     @param
@@ -427,6 +428,9 @@ int nr_ue_pdcch_procedures(uint8_t gNB_id,
                            NR_UE_PDCCH_CONFIG *phy_pdcch_config,
                            int n_ss);
 
+int nr_ue_csi_im_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, uint8_t gNB_id);
+
+int nr_ue_csi_rs_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, uint8_t gNB_id);
 
 #endif
 
diff --git a/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c b/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c
index 74f8c7b56a1fd531ef04b2b90a4c7e449521c95a..046f67a7d000c15f034ea1d90f8de53f1f340610 100644
--- a/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c
+++ b/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c
@@ -44,7 +44,7 @@
 
 extern PHY_VARS_NR_UE ***PHY_vars_UE_g;
 
-const char *dl_pdu_type[]={"DCI", "DLSCH", "RA_DLSCH", "SI_DLSCH", "P_DLSCH"};
+const char *dl_pdu_type[]={"DCI", "DLSCH", "RA_DLSCH", "SI_DLSCH", "P_DLSCH", "CSI_RS", "CSI_IM"};
 const char *ul_pdu_type[]={"PRACH", "PUCCH", "PUSCH", "SRS"};
 queue_t nr_rx_ind_queue;
 queue_t nr_crc_ind_queue;
@@ -360,12 +360,16 @@ int8_t nr_ue_scheduled_response(nr_scheduled_response_t *scheduled_response){
     NR_UE_DLSCH_t *dlsch0 = NULL;
     NR_UE_ULSCH_t *ulsch = PHY_vars_UE_g[module_id][cc_id]->ulsch[thread_id][0];
     NR_UE_PUCCH *pucch_vars = PHY_vars_UE_g[module_id][cc_id]->pucch_vars[thread_id][0];
+    NR_UE_CSI_IM *csiim_vars = PHY_vars_UE_g[module_id][cc_id]->csiim_vars[0];
+    NR_UE_CSI_RS *csirs_vars = PHY_vars_UE_g[module_id][cc_id]->csirs_vars[0];
     NR_UE_PDCCH_CONFIG *phy_pdcch_config = NULL;
 
     if(scheduled_response->dl_config != NULL){
       fapi_nr_dl_config_request_t *dl_config = scheduled_response->dl_config;
       fapi_nr_dl_config_dlsch_pdu_rel15_t *dlsch_config_pdu;
       fapi_nr_dl_config_dci_dl_pdu_rel15_t *pdcch_config;
+      fapi_nr_dl_config_csiim_pdu_rel15_t *csiim_config_pdu;
+      fapi_nr_dl_config_csirs_pdu_rel15_t *csirs_config_pdu;
 
       for (int i = 0; i < dl_config->number_pdus; ++i){
         AssertFatal(dl_config->number_pdus < FAPI_NR_DL_CONFIG_LIST_NUM,"dl_config->number_pdus %d out of bounds\n",dl_config->number_pdus);
@@ -387,10 +391,14 @@ int8_t nr_ue_scheduled_response(nr_scheduled_response_t *scheduled_response){
             LOG_D(PHY,"Number of DCI SearchSpaces %d\n",phy_pdcch_config->nb_search_space);
             break;
           case FAPI_NR_DL_CONFIG_TYPE_CSI_IM:
-            LOG_I(PHY,"Received CSI-IM PDU at FAPI\n");
+            csiim_config_pdu = &dl_config->dl_config_list[i].csiim_config_pdu.csiim_config_rel15;
+            memcpy((void*)&(csiim_vars->csiim_config_pdu), (void*)csiim_config_pdu, sizeof(fapi_nr_dl_config_csiim_pdu_rel15_t));
+            csirs_vars->active = true;
             break;
           case FAPI_NR_DL_CONFIG_TYPE_CSI_RS:
-            LOG_I(PHY,"Received CSI-RS PDU at FAPI\n");
+            csirs_config_pdu = &dl_config->dl_config_list[i].csirs_config_pdu.csirs_config_rel15;
+            memcpy((void*)&(csirs_vars->csirs_config_pdu), (void*)csirs_config_pdu, sizeof(fapi_nr_dl_config_csirs_pdu_rel15_t));
+            csirs_vars->active = true;
             break;
           case FAPI_NR_DL_CONFIG_TYPE_RA_DLSCH:
             dlsch_config_pdu = &dl_config->dl_config_list[i].dlsch_config_pdu.dlsch_config_rel15;
diff --git a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c
index 6ee9a95b59ef104df0b898db4fe25ab0e5165b71..e38668000f6996c9803999a90bee2f26b4cb04a0 100644
--- a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c
+++ b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c
@@ -1379,7 +1379,6 @@ int is_pbch_in_slot(fapi_nr_config_request_t *config, int frame, int slot, NR_DL
   }
 }
 
-
 int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue,
                            UE_nr_rxtx_proc_t *proc,
                            uint8_t gNB_id,
@@ -1681,6 +1680,23 @@ int phy_procedures_nrUE_RX(PHY_VARS_NR_UE *ue,
 
  }
 
+  // do procedures for CSI-IM
+  if ((ue->csiim_vars[gNB_id]) && (ue->csiim_vars[gNB_id]->active == 1)) {
+    nr_ue_csi_im_procedures(ue, proc, gNB_id);
+    ue->csiim_vars[gNB_id]->active = 0;
+  }
+
+  // do procedures for CSI-RS
+  if ((ue->csirs_vars[gNB_id]) && (ue->csirs_vars[gNB_id]->active == 1)) {
+    for(int symb = 0; symb < NR_SYMBOLS_PER_SLOT; symb++) {
+      if(is_csi_rs_in_symbol(ue->csirs_vars[gNB_id]->csirs_config_pdu,symb)) {
+        nr_slot_fep(ue, proc, symb, nr_slot_rx);
+      }
+    }
+    nr_ue_csi_rs_procedures(ue, proc, gNB_id);
+    ue->csirs_vars[gNB_id]->active = 0;
+  }
+
   start_meas(&ue->generic_stat);
 
   if (nr_slot_rx==9) {
diff --git a/openair1/SIMULATION/NR_PHY/ulsim.c b/openair1/SIMULATION/NR_PHY/ulsim.c
index 248c4084e0667c1ad1c231236e2c4fa84e0844a0..9a3b29a637588485547a82027df24a76e7349b14 100644
--- a/openair1/SIMULATION/NR_PHY/ulsim.c
+++ b/openair1/SIMULATION/NR_PHY/ulsim.c
@@ -613,7 +613,7 @@ int main(int argc, char **argv)
       //printf("-C Generate Calibration information for Abstraction (effective SNR adjustment to remove Pe bias w.r.t. AWGN)\n");
       printf("-F Input filename (.txt format) for RX conformance testing\n");
       printf("-G Offset of samples to read from file (0 default)\n");
-      printf("-L <log level, 0(errors), 1(warning), 2(info) 3(debug) 4 (trace)>\n"); 
+      printf("-L <log level, 0(errors), 1(warning), 2(info) 3(debug) 4 (trace)>\n");
       printf("-M Multiple SSB positions in burst\n");
       printf("-N Nid_cell\n");
       printf("-O oversampling factor (1,2,4,8,16)\n");
diff --git a/openair2/COMMON/rrc_messages_types.h b/openair2/COMMON/rrc_messages_types.h
index 5b214cf95a9ce515f04da6ec91e235be43b3711a..67b0b610ccafcc35d8643016c6a1630adc0527ff 100644
--- a/openair2/COMMON/rrc_messages_types.h
+++ b/openair2/COMMON/rrc_messages_types.h
@@ -167,7 +167,7 @@ typedef struct RadioResourceConfig_s {
   long                    ue_TransmissionMode;
   long                    ue_multiple_max;
   //SIB2 BR Options
-  long       *preambleTransMax_CE_r13;
+  long       preambleTransMax_CE_r13;
   BOOLEAN_t     prach_ConfigCommon_v1310;
   BOOLEAN_t            *mpdcch_startSF_CSS_RA_r13;
   long        mpdcch_startSF_CSS_RA_r13_val;
diff --git a/openair2/ENB_APP/enb_config_eMTC.c b/openair2/ENB_APP/enb_config_eMTC.c
index cfd057bad8d9abc3755b4dea18e4530d55adece0..2e71f17e9d871365b39eec6bea908caaf01c0bb3 100644
--- a/openair2/ENB_APP/enb_config_eMTC.c
+++ b/openair2/ENB_APP/enb_config_eMTC.c
@@ -681,6 +681,58 @@ void fill_eMTC_configuration(MessageDef *msg_p,  ccparams_eMTC_t *eMTCconfig, in
 		 "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for rach_maxHARQ_Msg3Tx choice: 1..8!\n",
 		 config_fname, cell_idx,eMTCconfig->ccparams.rach_maxHARQ_Msg3Tx);
 
+  switch (eMTCconfig->preambleTransMax_CE_r13) {
+  case 3:
+    RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].preambleTransMax_CE_r13=  LTE_PreambleTransMax_n3;
+    break;
+
+  case 4:
+    RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].preambleTransMax_CE_r13=  LTE_PreambleTransMax_n4;
+    break;
+
+  case 5:
+    RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].preambleTransMax_CE_r13=  LTE_PreambleTransMax_n5;
+    break;
+
+  case 6:
+    RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].preambleTransMax_CE_r13=  LTE_PreambleTransMax_n6;
+    break;
+
+  case 7:
+    RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].preambleTransMax_CE_r13=  LTE_PreambleTransMax_n7;
+    break;
+
+  case 8:
+    RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].preambleTransMax_CE_r13=  LTE_PreambleTransMax_n8;
+    break;
+
+  case 10:
+    RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].preambleTransMax_CE_r13=  LTE_PreambleTransMax_n10;
+    break;
+
+  case 20:
+    RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].preambleTransMax_CE_r13=  LTE_PreambleTransMax_n20;
+    break;
+
+  case 50:
+    RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].preambleTransMax_CE_r13=  LTE_PreambleTransMax_n50;
+    break;
+
+  case 100:
+    RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].preambleTransMax_CE_r13=  LTE_PreambleTransMax_n100;
+    break;
+
+  case 200:
+    RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].preambleTransMax_CE_r13=  LTE_PreambleTransMax_n200;
+    break;
+
+  default:
+    AssertFatal (0,
+		 "Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for rach_preambleTransMax_CE_r13 choice: 3,4,5,6,7,8,10,20,50,100,200!\n",
+		 config_fname, cell_idx,eMTCconfig->preambleTransMax_CE_r13);
+    break;
+  }
+
   switch (eMTCconfig->ccparams.pcch_defaultPagingCycle) {
   case 32:
     RRC_CONFIGURATION_REQ (msg_p).radioresourceconfig_BR[cc_idx].pcch_defaultPagingCycle= LTE_PCCH_Config__defaultPagingCycle_rf32;
diff --git a/openair2/ENB_APP/enb_paramdef_emtc.h b/openair2/ENB_APP/enb_paramdef_emtc.h
index de774c4ea694d13c5bc75173072606e95f157594..928c9d22e303c011e41a707dc26499b4ee583cc3 100644
--- a/openair2/ENB_APP/enb_paramdef_emtc.h
+++ b/openair2/ENB_APP/enb_paramdef_emtc.h
@@ -147,7 +147,7 @@ typedef struct ccparams_eMTC_s {
   int            interval_DLHoppingConfigCommonModeA_r13_val;
   int            interval_DLHoppingConfigCommonModeB_r13_val;
   int            mpdcch_pdsch_HoppingOffset_r13;
-  char          *preambleTransMax_CE_r13;
+  int            preambleTransMax_CE_r13;
   int            prach_HoppingOffset_r13;
   int            schedulingInfoSIB1_BR_r13;
   int64_t        fdd_DownlinkOrTddSubframeBitmapBR_val_r13;
@@ -253,7 +253,7 @@ typedef struct ccparams_eMTC_s {
 {ENB_CONFIG_STRING_INTERVAL_DL_HOPPING_CONFIG_COMMON_MODE_B_R13,         NULL,   0,           strptr:&eMTCconfig->interval_DLHoppingConfigCommonModeB_r13,   defstrval:"interval-FDD-r13",      TYPE_STRING,       0}, \
 {ENB_CONFIG_STRING_INTERVAL_DL_HOPPING_CONFIG_COMMON_MODE_B_R13_VAL,     NULL,   0,           iptr:&eMTCconfig->interval_DLHoppingConfigCommonModeB_r13_val, defintval:0,                       TYPE_UINT,         0}, \
 {ENB_CONFIG_STRING_MPDCCH_PDSCH_HOPPING_OFFSET_R13,                      NULL,   0,           iptr:&eMTCconfig->mpdcch_pdsch_HoppingOffset_r13,              defintval:1,                       TYPE_UINT,         0}, \
-{ENB_CONFIG_STRING_PREAMBLE_TRANSMAX_CE_R13,                             NULL,   0,           strptr:&eMTCconfig->preambleTransMax_CE_r13,                   defstrval:"n10",                   TYPE_STRING,       0},  \
+{ENB_CONFIG_STRING_PREAMBLE_TRANSMAX_CE_R13,                             NULL,   0,           iptr:&eMTCconfig->preambleTransMax_CE_r13,                   defintval:10,                   TYPE_UINT,       0},  \
 {ENB_CONFIG_STRING_PUCCH_NUM_REPETITION_CE_MSG4_LEVEL0,                  NULL,   0,           strptr:&eMTCconfig->pucch_NumRepetitionCE_Msg4_Level0_r13,     defstrval:"n1",                    TYPE_STRING,     0}, \
 {ENB_CONFIG_STRING_PUCCH_NUM_REPETITION_CE_MSG4_LEVEL1,                  NULL,   0,           strptr:&eMTCconfig->pucch_NumRepetitionCE_Msg4_Level1_r13,     defstrval:"",                      TYPE_STRING,     0}, \
 {ENB_CONFIG_STRING_PUCCH_NUM_REPETITION_CE_MSG4_LEVEL2,                  NULL,   0,           strptr:&eMTCconfig->pucch_NumRepetitionCE_Msg4_Level2_r13,     defstrval:"",                      TYPE_STRING,     0}, \
diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c
index 3fd1802432a75b72901c4ef2d71f069ed281f25c..bb80ff2a3c228efa3427bc5a877b55a57b037936 100644
--- a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c
+++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c
@@ -3938,25 +3938,17 @@ void fill_searchSpaceZero(NR_SearchSpace_t *ss0, NR_Type0_PDCCH_CSS_config_t *ty
   if(ss0->searchSpaceType->choice.common->dci_Format0_0_AndFormat1_0 == NULL)
     ss0->searchSpaceType->choice.common->dci_Format0_0_AndFormat1_0 = calloc(1,sizeof(*ss0->searchSpaceType->choice.common->dci_Format0_0_AndFormat1_0));
 
-  uint32_t duration,periodicity,offset;
-  uint16_t symbols,max_agg;
-
   AssertFatal(type0_PDCCH_CSS_config!=NULL,"No type0 CSS configuration\n");
 
-  max_agg = (type0_PDCCH_CSS_config->num_symbols*type0_PDCCH_CSS_config->num_rbs)/6;
-
-  symbols = (1-(1<<type0_PDCCH_CSS_config->num_symbols))<<type0_PDCCH_CSS_config->first_symbol_index;
-  duration = type0_PDCCH_CSS_config->search_space_duration;
-  periodicity = type0_PDCCH_CSS_config->search_space_frame_period;
-  if (type0_PDCCH_CSS_config->type0_pdcch_ss_mux_pattern == 1)
-    offset = type0_PDCCH_CSS_config->n_0;
-  else
-    offset = type0_PDCCH_CSS_config->n_c;
+  const uint32_t periodicity = type0_PDCCH_CSS_config->search_space_frame_period;
+  const uint32_t offset = type0_PDCCH_CSS_config->type0_pdcch_ss_mux_pattern == 1
+      ? type0_PDCCH_CSS_config->n_0 : type0_PDCCH_CSS_config->n_c;
 
   ss0->searchSpaceId = 0;
   *ss0->controlResourceSetId = 0;
   ss0->monitoringSlotPeriodicityAndOffset = calloc(1,sizeof(*ss0->monitoringSlotPeriodicityAndOffset));
   set_monitoring_periodicity_offset(ss0,periodicity,offset);
+  const uint32_t duration = type0_PDCCH_CSS_config->search_space_duration;
   if (duration==1)
     ss0->duration = NULL;
   else{
@@ -3964,6 +3956,7 @@ void fill_searchSpaceZero(NR_SearchSpace_t *ss0, NR_Type0_PDCCH_CSS_config_t *ty
     *ss0->duration = duration;
   }
 
+  const uint16_t symbols = SL_to_bitmap(type0_PDCCH_CSS_config->first_symbol_index, type0_PDCCH_CSS_config->num_symbols);
   ss0->monitoringSymbolsWithinSlot->size = 2;
   ss0->monitoringSymbolsWithinSlot->bits_unused = 2;
   ss0->monitoringSymbolsWithinSlot->buf[1] = 0;
@@ -3973,6 +3966,7 @@ void fill_searchSpaceZero(NR_SearchSpace_t *ss0, NR_Type0_PDCCH_CSS_config_t *ty
     ss0->monitoringSymbolsWithinSlot->buf[0] |= ((symbols>>i)&0x01)<<(7-i);
   }
 
+  const uint16_t max_agg = (type0_PDCCH_CSS_config->num_symbols*type0_PDCCH_CSS_config->num_rbs)/6;
   // max values are set according to TS38.213 Section 10.1 Table 10.1-1
   ss0->nrofCandidates->aggregationLevel1 = NR_SearchSpace__nrofCandidates__aggregationLevel1_n0;
   ss0->nrofCandidates->aggregationLevel2 = NR_SearchSpace__nrofCandidates__aggregationLevel2_n0;
diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c
index 06ffb1c285af42bcec7945ab78458d8afa92402c..6b8dce9c9a1f1d37d38f26d20ecbccb1b5c8323f 100644
--- a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c
+++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c
@@ -2566,7 +2566,8 @@ uint8_t nr_get_csi_payload(NR_UE_MAC_INST_t *mac,
     case NR_CSI_ReportConfig__reportQuantity_PR_cri_RI_i1_CQI:
     case NR_CSI_ReportConfig__reportQuantity_PR_cri_RI_CQI:
     case NR_CSI_ReportConfig__reportQuantity_PR_cri_RI_LI_PMI_CQI:
-      AssertFatal(1==0,"Measurement report based on CSI-RS not availalble\n");
+      LOG_E(NR_MAC,"Measurement report based on CSI-RS not available\n");
+      break;
     default:
       AssertFatal(1==0,"Invalid CSI report quantity type %d\n",csi_reportconfig->reportQuantity.present);
   }
diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c
index 2dec0664f344a34756369c149b1821549151f614..409f9388301c2feeab9ef2873b92a8bf14ed9871 100644
--- a/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c
+++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_scheduler.c
@@ -1080,9 +1080,6 @@ NR_UE_L2_STATE_t nr_ue_scheduler(nr_downlink_indication_t *dl_info, nr_uplink_in
 
     if(mac->cg != NULL){ // we have a cg
 
-      nr_schedule_csirs_reception(mac, rx_frame, rx_slot);
-      nr_schedule_csi_for_im(mac, rx_frame, rx_slot);
-
       dcireq.module_id = mod_id;
       dcireq.gNB_index = gNB_index;
       dcireq.cc_id     = cc_id;
@@ -1092,6 +1089,10 @@ NR_UE_L2_STATE_t nr_ue_scheduler(nr_downlink_indication_t *dl_info, nr_uplink_in
       nr_ue_dcireq(&dcireq); //to be replaced with function pointer later
       mac->dl_config_request = dcireq.dl_config_req;
 
+      nr_schedule_csirs_reception(mac, rx_frame, rx_slot);
+      nr_schedule_csi_for_im(mac, rx_frame, rx_slot);
+      dcireq.dl_config_req = mac->dl_config_request;
+
       fill_scheduled_response(&scheduled_response, &dcireq.dl_config_req, NULL, NULL, mod_id, cc_id, rx_frame, rx_slot, dl_info->thread_id, dl_info->phy_data);
       if(mac->if_module != NULL && mac->if_module->scheduled_response != NULL)
         LOG_D(NR_MAC,"1# scheduled_response transmitted, %d, %d\n", rx_frame, rx_slot);
@@ -2403,9 +2404,17 @@ void nr_schedule_csi_for_im(NR_UE_MAC_INST_t *mac, int frame, int slot) {
   NR_CSI_IM_Resource_t *imcsi;
   int period, offset;
   NR_BWP_Id_t dl_bwp_id = mac->DL_BWP_Id;
-  int mu = mac->DLbwp[dl_bwp_id-1] ?
-    mac->DLbwp[dl_bwp_id-1]->bwp_Common->genericParameters.subcarrierSpacing :
-    mac->scc_SIB->downlinkConfigCommon.initialDownlinkBWP.genericParameters.subcarrierSpacing;
+
+  NR_BWP_t *genericParameters = NULL;
+  if(dl_bwp_id > 0 && mac->DLbwp[dl_bwp_id-1]) {
+    genericParameters = &mac->DLbwp[dl_bwp_id-1]->bwp_Common->genericParameters;
+  } else {
+    genericParameters = &mac->scc_SIB->downlinkConfigCommon.initialDownlinkBWP.genericParameters;
+  }
+
+  int mu = genericParameters->subcarrierSpacing;
+  uint16_t bwp_size = NRRIV2BW(genericParameters->locationAndBandwidth, MAX_BWP_SIZE);
+  uint16_t bwp_start = NRRIV2PRBOFFSET(genericParameters->locationAndBandwidth, MAX_BWP_SIZE);
 
   for (int id = 0; id < csi_measconfig->csi_IM_ResourceToAddModList->list.count; id++){
     imcsi = csi_measconfig->csi_IM_ResourceToAddModList->list.array[id];
@@ -2413,11 +2422,8 @@ void nr_schedule_csi_for_im(NR_UE_MAC_INST_t *mac, int frame, int slot) {
     if((frame*nr_slots_per_frame[mu]+slot-offset)%period != 0)
       continue;
     fapi_nr_dl_config_csiim_pdu_rel15_t *csiim_config_pdu = &dl_config->dl_config_list[dl_config->number_pdus].csiim_config_pdu.csiim_config_rel15;
-    const NR_BWP_Downlink_t *dlbwp = mac->DLbwp[dl_bwp_id-1];
-    const int locationAndBandwidth = dlbwp != NULL ? dlbwp->bwp_Common->genericParameters.locationAndBandwidth:
-                                     mac->scc_SIB->downlinkConfigCommon.initialDownlinkBWP.genericParameters.locationAndBandwidth;
-    csiim_config_pdu->bwp_size = NRRIV2BW(locationAndBandwidth, MAX_BWP_SIZE);
-    csiim_config_pdu->bwp_start = NRRIV2PRBOFFSET(locationAndBandwidth, MAX_BWP_SIZE);
+    csiim_config_pdu->bwp_size = bwp_size;
+    csiim_config_pdu->bwp_start = bwp_start;
     csiim_config_pdu->subcarrier_spacing = mu;
     csiim_config_pdu->start_rb = imcsi->freqBand->startingRB;
     csiim_config_pdu->nr_of_rbs = imcsi->freqBand->nrofRBs;
@@ -2439,7 +2445,7 @@ void nr_schedule_csi_for_im(NR_UE_MAC_INST_t *mac, int frame, int slot) {
         AssertFatal(1==0, "Invalid CSI-IM pattern\n");
     }
     dl_config->dl_config_list[dl_config->number_pdus].pdu_type = FAPI_NR_DL_CONFIG_TYPE_CSI_IM;
-    dl_config->number_pdus = dl_config->number_pdus + 1;
+    dl_config->number_pdus += 1;
   }
 }
 
@@ -2463,9 +2469,17 @@ void nr_schedule_csirs_reception(NR_UE_MAC_INST_t *mac, int frame, int slot) {
   NR_NZP_CSI_RS_Resource_t *nzpcsi;
   int period, offset;
   NR_BWP_Id_t dl_bwp_id = mac->DL_BWP_Id;
-  int mu = mac->DLbwp[dl_bwp_id-1] ?
-    mac->DLbwp[dl_bwp_id-1]->bwp_Common->genericParameters.subcarrierSpacing :
-    mac->scc_SIB->downlinkConfigCommon.initialDownlinkBWP.genericParameters.subcarrierSpacing;
+
+  NR_BWP_t *genericParameters = NULL;
+  if(dl_bwp_id > 0 && mac->DLbwp[dl_bwp_id-1]) {
+    genericParameters = &mac->DLbwp[dl_bwp_id-1]->bwp_Common->genericParameters;
+  } else {
+    genericParameters = &mac->scc_SIB->downlinkConfigCommon.initialDownlinkBWP.genericParameters;
+  }
+
+  int mu = genericParameters->subcarrierSpacing;
+  uint16_t bwp_size = NRRIV2BW(genericParameters->locationAndBandwidth, MAX_BWP_SIZE);
+  uint16_t bwp_start = NRRIV2PRBOFFSET(genericParameters->locationAndBandwidth, MAX_BWP_SIZE);
 
   for (int id = 0; id < csi_measconfig->nzp_CSI_RS_ResourceToAddModList->list.count; id++){
     nzpcsi = csi_measconfig->nzp_CSI_RS_ResourceToAddModList->list.array[id];
@@ -2474,17 +2488,23 @@ void nr_schedule_csirs_reception(NR_UE_MAC_INST_t *mac, int frame, int slot) {
       continue;
     LOG_D(MAC,"Scheduling reception of CSI-RS in frame %d slot %d\n",frame,slot);
     fapi_nr_dl_config_csirs_pdu_rel15_t *csirs_config_pdu = &dl_config->dl_config_list[dl_config->number_pdus].csirs_config_pdu.csirs_config_rel15;
-
     NR_CSI_RS_ResourceMapping_t  resourceMapping = nzpcsi->resourceMapping;
-
-    const NR_BWP_Downlink_t *dlbwp = mac->DLbwp[dl_bwp_id-1];
-    const int locationAndBandwidth = dlbwp != NULL ? dlbwp->bwp_Common->genericParameters.locationAndBandwidth:
-                                     mac->scc_SIB->downlinkConfigCommon.initialDownlinkBWP.genericParameters.locationAndBandwidth;
-    csirs_config_pdu->bwp_size = NRRIV2BW(locationAndBandwidth, MAX_BWP_SIZE);
-    csirs_config_pdu->bwp_start = NRRIV2PRBOFFSET(locationAndBandwidth, MAX_BWP_SIZE);
     csirs_config_pdu->subcarrier_spacing = mu;
-    csirs_config_pdu->start_rb = resourceMapping.freqBand.startingRB;
-    csirs_config_pdu->nr_of_rbs = resourceMapping.freqBand.nrofRBs;
+    csirs_config_pdu->cyclic_prefix = genericParameters->cyclicPrefix ? *genericParameters->cyclicPrefix : 0;
+
+    // According to last paragraph of TS 38.214 5.2.2.3.1
+    if (resourceMapping.freqBand.startingRB < bwp_start) {
+      csirs_config_pdu->start_rb = bwp_start;
+    } else {
+      csirs_config_pdu->start_rb = resourceMapping.freqBand.startingRB;
+    }
+    if (resourceMapping.freqBand.nrofRBs > (bwp_start + bwp_size - csirs_config_pdu->start_rb)) {
+      csirs_config_pdu->nr_of_rbs = bwp_start + bwp_size - csirs_config_pdu->start_rb;
+    } else {
+      csirs_config_pdu->nr_of_rbs = resourceMapping.freqBand.nrofRBs;
+    }
+    AssertFatal(csirs_config_pdu->nr_of_rbs >= 24, "CSI-RS has %d RBs, but the minimum is 24\n", csirs_config_pdu->nr_of_rbs);
+
     csirs_config_pdu->csi_type = 1; // NZP-CSI-RS
     csirs_config_pdu->symb_l0 = resourceMapping.firstOFDMSymbolInTimeDomain;
     if (resourceMapping.firstOFDMSymbolInTimeDomain2)
@@ -2495,6 +2515,11 @@ void nr_schedule_csirs_reception(NR_UE_MAC_INST_t *mac, int frame, int slot) {
         && (resourceMapping.density.choice.dot5 == NR_CSI_RS_ResourceMapping__density__dot5_evenPRBs))
       csirs_config_pdu->freq_density--;
     csirs_config_pdu->scramb_id = nzpcsi->scramblingID;
+    csirs_config_pdu->power_control_offset = nzpcsi->powerControlOffset + 8;
+    if (nzpcsi->powerControlOffsetSS)
+      csirs_config_pdu->power_control_offset_ss = *nzpcsi->powerControlOffsetSS;
+    else
+      csirs_config_pdu->power_control_offset_ss = 1; // 0 dB
     switch(resourceMapping.frequencyDomainAllocation.present){
       case NR_CSI_RS_ResourceMapping__frequencyDomainAllocation_PR_row1:
         csirs_config_pdu->row = 1;
@@ -2575,7 +2600,7 @@ void nr_schedule_csirs_reception(NR_UE_MAC_INST_t *mac, int frame, int slot) {
         AssertFatal(1==0,"Invalid freqency domain allocation in CSI-RS resource\n");
     }
     dl_config->dl_config_list[dl_config->number_pdus].pdu_type = FAPI_NR_DL_CONFIG_TYPE_CSI_RS;
-    dl_config->number_pdus = dl_config->number_pdus + 1;
+    dl_config->number_pdus += 1;
   }
 }
 
diff --git a/openair2/LAYER2/NR_MAC_gNB/config.c b/openair2/LAYER2/NR_MAC_gNB/config.c
index 0e55b519abb7c24720c50837f24b538ca4ff4956..19845c708b5982b02fef1e96119f9704a76518a2 100644
--- a/openair2/LAYER2/NR_MAC_gNB/config.c
+++ b/openair2/LAYER2/NR_MAC_gNB/config.c
@@ -594,11 +594,11 @@ int rrc_mac_config_req_gNB(module_id_t Mod_idP,
 
     if (add_ue == 1 && get_softmodem_params()->phy_test) {
       NR_UE_info_t* UE = add_new_nr_ue(RC.nrmac[Mod_idP], rnti, CellGroup);
-      if (UE)
-	LOG_I(NR_MAC,"Added new UE %x with initial CellGroup\n", rnti);
-      else {
-	LOG_E(NR_MAC,"Error adding UE %04x\n", rnti);
-	return -1;
+      if (UE) {
+        LOG_I(NR_MAC,"Added new UE %x with initial CellGroup\n", rnti);
+      } else {
+        LOG_E(NR_MAC,"Error adding UE %04x\n", rnti);
+        return -1;
       }
       process_CellGroup(CellGroup,&UE->UE_sched_ctrl);
     } else if (add_ue == 1 && !get_softmodem_params()->phy_test) {
@@ -649,8 +649,8 @@ int rrc_mac_config_req_gNB(module_id_t Mod_idP,
       NR_ServingCellConfigCommon_t *scc = RC.nrmac[Mod_idP]->common_channels[0].ServingCellConfigCommon;
       NR_UE_info_t * UE = find_nr_UE(&RC.nrmac[Mod_idP]->UE_info,rnti);
       if (!UE) {
-	LOG_E(NR_MAC, "Can't find UE %04x\n", rnti);
-	return -1;
+        LOG_E(NR_MAC, "Can't find UE %04x\n", rnti);
+        return -1;
       }
       int target_ss;
 
@@ -689,12 +689,13 @@ int rrc_mac_config_req_gNB(module_id_t Mod_idP,
                                                     genericParameters,
                                                     RC.nrmac[Mod_idP]->type0_PDCCH_CSS_config);
       sched_ctrl->maxL = 2;
+
       if (CellGroup->spCellConfig &&
           CellGroup->spCellConfig->spCellConfigDedicated &&
           CellGroup->spCellConfig->spCellConfigDedicated->csi_MeasConfig &&
-          CellGroup->spCellConfig->spCellConfigDedicated->csi_MeasConfig->choice.setup
-        )
-      compute_csi_bitlen (CellGroup->spCellConfig->spCellConfigDedicated->csi_MeasConfig->choice.setup, UE);
+          CellGroup->spCellConfig->spCellConfigDedicated->csi_MeasConfig->choice.setup) {
+        compute_csi_bitlen(CellGroup->spCellConfig->spCellConfigDedicated->csi_MeasConfig->choice.setup, UE);
+      }
     }
   }
   VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RRC_MAC_CONFIG, VCD_FUNCTION_OUT);
diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c
index 302685bfaf7a9e9ebf2b8ff1fec73bfd46ede8fe..eb05ec5e83569751a8f1bc6711bd8fb28217c265 100644
--- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c
+++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c
@@ -1387,7 +1387,8 @@ void nr_generate_Msg2(module_id_t module_idP, int CC_id, frame_t frameP, sub_fra
                                                     nr_mac->common_channels->ServingCellConfigCommon->dmrs_TypeA_Position,
                                                     nrOfSymbols,
                                                     startSymbolIndex,
-                                                    mappingtype, 1);
+                                                    mappingtype,
+                                                    1);
 
     uint8_t tb_scaling = 0;
     int R, Qm;
@@ -1684,7 +1685,8 @@ void nr_generate_Msg4(module_id_t module_idP, int CC_id, frame_t frameP, sub_fra
                                             scc->dmrs_TypeA_Position,
                                             nrOfSymbols,
                                             startSymbolIndex,
-                                            mappingtype, 1);
+                                            mappingtype,
+                                            1);
 
     uint16_t N_DMRS_SLOT = get_num_dmrs(dlDmrsSymbPos);
 
diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c
index 95834e84c5a8e4112fd683b3ff37d8f5c3bfb71d..4b71b406620c82fe0d6e7505a32e4a45293354af 100644
--- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c
+++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_dlsch.c
@@ -60,7 +60,7 @@ const int get_dl_tda(const gNB_MAC_INST *nrmac, const NR_ServingCellConfigCommon
 
   // Use special TDA in case of CSI-RS
   if(nrmac->UE_info.sched_csirs)
-      return 1;
+    return 1;
 
   if (tdd && tdd->nrofDownlinkSymbols > 1) { // if there is a mixed slot where we can transmit DL
     const int nr_slots_period = tdd->nrofDownlinkSlots + tdd->nrofUplinkSlots + 1;
@@ -370,7 +370,7 @@ bool allocate_dl_retransmission(module_id_t module_id,
                                 sub_frame_t slot,
                                 uint16_t *rballoc_mask,
                                 int *n_rb_sched,
-                                NR_UE_info_t * UE,
+                                NR_UE_info_t *UE,
                                 int current_harq_pid) {
 
   gNB_MAC_INST *nr_mac = RC.nrmac[module_id];
@@ -589,7 +589,7 @@ void pf_dl(module_id_t module_id,
     NR_pdsch_semi_static_t *ps = &sched_ctrl->pdsch_semi_static;
     /* get the PID of a HARQ process awaiting retrnasmission, or -1 otherwise */
     sched_pdsch->dl_harq_pid = sched_ctrl->retrans_dl_harq.head;
-    UE->layers = ps->nrOfLayers; // initialization of layers to the previous value in the strcuture
+    UE->layers = ps->nrOfLayers; // initialization of layers to the previous value in the structure
     /* Calculate Throughput */
     const float a = 0.0005f; // corresponds to 200ms window
     const uint32_t b = UE->mac_stats.dl.current_bytes;
@@ -608,10 +608,11 @@ void pf_dl(module_id_t module_id,
       /* reduce max_num_ue once we are sure UE can be allocated, i.e., has CCE */
       remainUEs--;
 
+      // we have filled all with mandatory retransmissions
+      // no need to schedule new transmissions
       if (remainUEs == 0)
-	// we have filled all with mandatory retransmissions
-	// no need to schedule new transmissions
-	return;
+        return;
+
     } else {
       /* Check DL buffer and skip this UE if no bytes and no TA necessary */
       if (sched_ctrl->num_total_bytes == 0 && frame != (sched_ctrl->ta_frame + 10) % 1024)
@@ -1277,7 +1278,7 @@ void nr_schedule_ue_spec(module_id_t module_id,
             /* limit requested number of bytes to what preprocessor specified, or
              * such that TBS is full */
             const rlc_buffer_occupancy_t ndata = min(sched_ctrl->rlc_status[lcid].bytes_in_buffer,
-                                                 bufEnd-buf-sizeof(NR_MAC_SUBHEADER_LONG));
+                                                     bufEnd-buf-sizeof(NR_MAC_SUBHEADER_LONG));
             tbs_size_t len = mac_rlc_data_req(module_id,
                                               rnti,
                                               module_id,
diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c
index aff03a5323f79eeaea11761b3f64b0b57b354525..56d14b1458490b7e829cf25dd875427660361917 100644
--- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c
+++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c
@@ -160,7 +160,8 @@ void nr_schedule_css_dlsch_phytest(module_id_t   module_idP,
                                                     scc->dmrs_TypeA_Position,
                                                     NrOfSymbols,
                                                     StartSymbolIndex,
-                                                    mappingtype, 1);
+                                                    mappingtype,
+                                                    1);
 
     nr_mac->DL_req[CC_id].dl_tti_request_body.nPDUs+=2;
     
diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c
index 65d2ce09c5044ef5f9165396dd63ca55c79ac6d5..295d81bcd6f049b408d3cf68132e53241ae7f21f 100644
--- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c
+++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c
@@ -288,7 +288,7 @@ NR_PDSCH_TimeDomainResourceAllocationList_t *get_pdsch_TimeDomainAllocationList(
 }
 
 
-NR_ControlResourceSet_t *get_coreset(gNB_MAC_INST    *nrmac,
+NR_ControlResourceSet_t *get_coreset(gNB_MAC_INST *nrmac,
                                      NR_ServingCellConfigCommon_t *scc,
                                      void *bwp,
                                      NR_SearchSpace_t *ss,
@@ -529,7 +529,6 @@ void fill_pdcch_vrb_map(gNB_MAC_INST *mac,
   }
 }
 
-
 bool nr_find_nb_rb(uint16_t Qm,
                    uint16_t R,
                    uint8_t nrOfLayers,
@@ -590,8 +589,7 @@ void nr_set_pdsch_semi_static(const NR_SIB1_t *sib1,
 {
   bool reset_dmrs = false;
 
-  NR_BWP_DownlinkDedicated_t *bwpd;
-
+  NR_BWP_DownlinkDedicated_t *bwpd = NULL;
   if (bwp && bwp->bwp_Dedicated) {
     bwpd = bwp->bwp_Dedicated;
   } else {
@@ -607,10 +605,11 @@ void nr_set_pdsch_semi_static(const NR_SIB1_t *sib1,
         bwpd->pdsch_Config &&
         bwpd->pdsch_Config->choice.setup &&
         bwpd->pdsch_Config->choice.setup->mcs_Table) {
-      if (*bwpd->pdsch_Config->choice.setup->mcs_Table == 0)
+      if (*bwpd->pdsch_Config->choice.setup->mcs_Table == 0) {
         ps->mcsTableIdx = 1;
-      else
+      } else {
         ps->mcsTableIdx = 2;
+      }
     } else {
       ps->mcsTableIdx = 0;
     }
@@ -658,8 +657,8 @@ void nr_set_pdsch_semi_static(const NR_SIB1_t *sib1,
     ps->nrOfLayers = 1;
   }
   else {
-    if (ps->nrOfLayers != layers ||
-        ps->numDmrsCdmGrpsNoData == 0) {
+    LOG_D(NR_MAC,"checking layers\n");
+    if (ps->nrOfLayers != layers || ps->numDmrsCdmGrpsNoData == 0) {
       reset_dmrs = true;
       ps->nrOfLayers = layers;
       set_dl_dmrs_ports(ps);
@@ -1078,10 +1077,10 @@ void config_uldci(const NR_SIB1_t *sib1,
       else if (pusch_pdu->nrOfLayers == 4)
         dci_pdu_rel15->precoding_information.val = 11;
 
-      // antenna_ports.val = 0 for transform precoder is disabled, dmrs-Type=1, maxLength=1, Rank=1/2/3/4 
+      // antenna_ports.val = 0 for transform precoder is disabled, dmrs-Type=1, maxLength=1, Rank=1/2/3/4
       // Antenna Ports
-      dci_pdu_rel15->antenna_ports.val = 0; 
-      
+      dci_pdu_rel15->antenna_ports.val = 0;
+
       // DMRS sequence initialization
       dci_pdu_rel15->dmrs_sequence_initialization.val = pusch_pdu->scid;
       break;
@@ -1117,8 +1116,6 @@ int nr_get_default_pucch_res(int pucch_ResourceCommon) {
   return(default_pucch_csset[pucch_ResourceCommon]);
 }
 
-
-
 void nr_configure_pdcch(nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu,
                         NR_ControlResourceSet_t *coreset,
                         NR_BWP_t *bwp,
@@ -2193,7 +2190,7 @@ void destroy_nr_list(NR_list_t *list)
 {
   free(list->next);
 }
-//------------------------------------------------------------------------------
+
 /*
  * Add an ID to an NR_list at the end, traversing the whole list. Note:
  * add_tail_nr_list() is a faster alternative, but this implementation ensures
@@ -2267,8 +2264,7 @@ void remove_front_nr_list(NR_list_t *listP)
     listP->tail = -1;
 }
 
-NR_UE_info_t * find_nr_UE(NR_UEs_t* UEs, rnti_t rntiP)
-//------------------------------------------------------------------------------
+NR_UE_info_t *find_nr_UE(NR_UEs_t *UEs, rnti_t rntiP)
 {
   UE_iterator(UEs->list, UE) {
     if (UE->rnti == rntiP) {
@@ -2417,13 +2413,16 @@ NR_UE_info_t *add_new_nr_ue(gNB_MAC_INST *nr_mac, rnti_t rntiP, NR_CellGroupConf
     UE->Msg4_ACKed = true;
   else
     UE->Msg4_ACKed = false;
+
   if (CellGroup &&
       CellGroup->spCellConfig &&
       CellGroup->spCellConfig->spCellConfigDedicated &&
       CellGroup->spCellConfig->spCellConfigDedicated->csi_MeasConfig &&
-      CellGroup->spCellConfig->spCellConfigDedicated->csi_MeasConfig->choice.setup)
-    compute_csi_bitlen (CellGroup->spCellConfig->spCellConfigDedicated->csi_MeasConfig->choice.setup, UE);
-  NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl;
+      CellGroup->spCellConfig->spCellConfigDedicated->csi_MeasConfig->choice.setup) {
+    compute_csi_bitlen(CellGroup->spCellConfig->spCellConfigDedicated->csi_MeasConfig->choice.setup, UE);
+  }
+
+    NR_UE_sched_ctrl_t *sched_ctrl = &UE->UE_sched_ctrl;
     memset(sched_ctrl, 0, sizeof(*sched_ctrl));
     sched_ctrl->dl_max_mcs = 28; /* do not limit MCS for individual UEs */
     sched_ctrl->set_pmi = false;
@@ -2593,7 +2592,7 @@ uint8_t nr_get_tpc(int target, uint8_t cqi, int incr) {
 }
 
 
-void get_pdsch_to_harq_feedback( NR_UE_info_t * UE,
+void get_pdsch_to_harq_feedback(NR_UE_info_t *UE,
                                 int bwp_id,
                                 NR_SearchSpace__searchSpaceType_PR ss_type,
                                 int *max_fb_time,
@@ -2662,7 +2661,6 @@ void get_pdsch_to_harq_feedback( NR_UE_info_t * UE,
         pdsch_to_harq_feedback[i] = i+1;
         if(pdsch_to_harq_feedback[i]>*max_fb_time)
           *max_fb_time = pdsch_to_harq_feedback[i];
-
       }
     }
     else {
@@ -2680,8 +2678,6 @@ void get_pdsch_to_harq_feedback( NR_UE_info_t * UE,
   }
 }
 
-
-
 void nr_csirs_scheduling(int Mod_idP,
                          frame_t frame,
                          sub_frame_t slot,
@@ -2734,16 +2730,27 @@ void nr_csirs_scheduling(int Mod_idP,
 
           nfapi_nr_dl_tti_csi_rs_pdu_rel15_t *csirs_pdu_rel15 = &dl_tti_csirs_pdu->csi_rs_pdu.csi_rs_pdu_rel15;
 
-          csirs_pdu_rel15->bwp_size  = NRRIV2BW(genericParameters->locationAndBandwidth,275);
-          csirs_pdu_rel15->bwp_start = NRRIV2PRBOFFSET(genericParameters->locationAndBandwidth,275);
           csirs_pdu_rel15->subcarrier_spacing = genericParameters->subcarrierSpacing;
           if (genericParameters->cyclicPrefix)
             csirs_pdu_rel15->cyclic_prefix = *genericParameters->cyclicPrefix;
           else
             csirs_pdu_rel15->cyclic_prefix = 0;
 
-          csirs_pdu_rel15->start_rb = resourceMapping.freqBand.startingRB;
-          csirs_pdu_rel15->nr_of_rbs = resourceMapping.freqBand.nrofRBs;
+          // According to last paragraph of TS 38.214 5.2.2.3.1
+          uint16_t BWPSize = NRRIV2BW(genericParameters->locationAndBandwidth, MAX_BWP_SIZE);
+          uint16_t BWPStart = NRRIV2PRBOFFSET(genericParameters->locationAndBandwidth, MAX_BWP_SIZE);
+          if (resourceMapping.freqBand.startingRB < BWPStart) {
+            csirs_pdu_rel15->start_rb = BWPStart;
+          } else {
+            csirs_pdu_rel15->start_rb = resourceMapping.freqBand.startingRB;
+          }
+          if (resourceMapping.freqBand.nrofRBs > (BWPStart + BWPSize - csirs_pdu_rel15->start_rb)) {
+            csirs_pdu_rel15->nr_of_rbs = BWPStart + BWPSize - csirs_pdu_rel15->start_rb;
+          } else {
+            csirs_pdu_rel15->nr_of_rbs = resourceMapping.freqBand.nrofRBs;
+          }
+          AssertFatal(csirs_pdu_rel15->nr_of_rbs >= 24, "CSI-RS has %d RBs, but the minimum is 24\n", csirs_pdu_rel15->nr_of_rbs);
+
           csirs_pdu_rel15->csi_type = 1; // NZP-CSI-RS
           csirs_pdu_rel15->symb_l0 = resourceMapping.firstOFDMSymbolInTimeDomain;
           if (resourceMapping.firstOFDMSymbolInTimeDomain2)
@@ -2764,20 +2771,20 @@ void nr_csirs_scheduling(int Mod_idP,
               csirs_pdu_rel15->row = 1;
               csirs_pdu_rel15->freq_domain = ((resourceMapping.frequencyDomainAllocation.choice.row1.buf[0])>>4)&0x0f;
               for (int rb = csirs_pdu_rel15->start_rb; rb < (csirs_pdu_rel15->start_rb + csirs_pdu_rel15->nr_of_rbs); rb++)
-                vrb_map[rb+csirs_pdu_rel15->bwp_start] |= SL_to_bitmap(csirs_pdu_rel15->symb_l0, 1);
+                vrb_map[rb] |= SL_to_bitmap(csirs_pdu_rel15->symb_l0, 1);
               break;
             case NR_CSI_RS_ResourceMapping__frequencyDomainAllocation_PR_row2:
               csirs_pdu_rel15->row = 2;
               csirs_pdu_rel15->freq_domain = (((resourceMapping.frequencyDomainAllocation.choice.row2.buf[1]>>4)&0x0f) |
                                              ((resourceMapping.frequencyDomainAllocation.choice.row2.buf[0]<<4)&0xff0));
               for (int rb = csirs_pdu_rel15->start_rb; rb < (csirs_pdu_rel15->start_rb + csirs_pdu_rel15->nr_of_rbs); rb++)
-                vrb_map[rb+csirs_pdu_rel15->bwp_start] |= SL_to_bitmap(csirs_pdu_rel15->symb_l0, 1);
+                vrb_map[rb] |= SL_to_bitmap(csirs_pdu_rel15->symb_l0, 1);
               break;
             case NR_CSI_RS_ResourceMapping__frequencyDomainAllocation_PR_row4:
               csirs_pdu_rel15->row = 4;
               csirs_pdu_rel15->freq_domain = ((resourceMapping.frequencyDomainAllocation.choice.row4.buf[0])>>5)&0x07;
               for (int rb = csirs_pdu_rel15->start_rb; rb < (csirs_pdu_rel15->start_rb + csirs_pdu_rel15->nr_of_rbs); rb++)
-                vrb_map[rb+csirs_pdu_rel15->bwp_start] |= SL_to_bitmap(csirs_pdu_rel15->symb_l0, 1);
+                vrb_map[rb] |= SL_to_bitmap(csirs_pdu_rel15->symb_l0, 1);
               break;
             case NR_CSI_RS_ResourceMapping__frequencyDomainAllocation_PR_other:
               csirs_pdu_rel15->freq_domain = ((resourceMapping.frequencyDomainAllocation.choice.other.buf[0])>>2)&0x3f;
@@ -2789,18 +2796,18 @@ void nr_csirs_scheduling(int Mod_idP,
                 case NR_CSI_RS_ResourceMapping__nrofPorts_p2:
                   csirs_pdu_rel15->row = 3;
                   for (int rb = csirs_pdu_rel15->start_rb; rb < (csirs_pdu_rel15->start_rb + csirs_pdu_rel15->nr_of_rbs); rb++)
-                    vrb_map[rb+csirs_pdu_rel15->bwp_start] |= SL_to_bitmap(csirs_pdu_rel15->symb_l0, 1);
+                    vrb_map[rb] |= SL_to_bitmap(csirs_pdu_rel15->symb_l0, 1);
                   break;
                 case NR_CSI_RS_ResourceMapping__nrofPorts_p4:
                   csirs_pdu_rel15->row = 5;
                   for (int rb = csirs_pdu_rel15->start_rb; rb < (csirs_pdu_rel15->start_rb + csirs_pdu_rel15->nr_of_rbs); rb++)
-                    vrb_map[rb+csirs_pdu_rel15->bwp_start] |= SL_to_bitmap(csirs_pdu_rel15->symb_l0, 2);
+                    vrb_map[rb] |= SL_to_bitmap(csirs_pdu_rel15->symb_l0, 2);
                   break;
                 case NR_CSI_RS_ResourceMapping__nrofPorts_p8:
                   if (resourceMapping.cdm_Type == NR_CSI_RS_ResourceMapping__cdm_Type_cdm4_FD2_TD2) {
                     csirs_pdu_rel15->row = 8;
                     for (int rb = csirs_pdu_rel15->start_rb; rb < (csirs_pdu_rel15->start_rb + csirs_pdu_rel15->nr_of_rbs); rb++)
-                      vrb_map[rb+csirs_pdu_rel15->bwp_start] |= SL_to_bitmap(csirs_pdu_rel15->symb_l0, 2);
+                      vrb_map[rb] |= SL_to_bitmap(csirs_pdu_rel15->symb_l0, 2);
                   }
                   else{
                     int num_k = 0;
@@ -2809,12 +2816,12 @@ void nr_csirs_scheduling(int Mod_idP,
                     if(num_k==4) {
                       csirs_pdu_rel15->row = 6;
                       for (int rb = csirs_pdu_rel15->start_rb; rb < (csirs_pdu_rel15->start_rb + csirs_pdu_rel15->nr_of_rbs); rb++)
-                        vrb_map[rb+csirs_pdu_rel15->bwp_start] |= SL_to_bitmap(csirs_pdu_rel15->symb_l0, 1);
+                        vrb_map[rb] |= SL_to_bitmap(csirs_pdu_rel15->symb_l0, 1);
                     }
                     else {
                       csirs_pdu_rel15->row = 7;
                       for (int rb = csirs_pdu_rel15->start_rb; rb < (csirs_pdu_rel15->start_rb + csirs_pdu_rel15->nr_of_rbs); rb++)
-                        vrb_map[rb+csirs_pdu_rel15->bwp_start] |= SL_to_bitmap(csirs_pdu_rel15->symb_l0, 2);
+                        vrb_map[rb] |= SL_to_bitmap(csirs_pdu_rel15->symb_l0, 2);
                     }
                   }
                   break;
@@ -2822,12 +2829,12 @@ void nr_csirs_scheduling(int Mod_idP,
                   if (resourceMapping.cdm_Type == NR_CSI_RS_ResourceMapping__cdm_Type_cdm4_FD2_TD2) {
                     csirs_pdu_rel15->row = 10;
                     for (int rb = csirs_pdu_rel15->start_rb; rb < (csirs_pdu_rel15->start_rb + csirs_pdu_rel15->nr_of_rbs); rb++)
-                      vrb_map[rb+csirs_pdu_rel15->bwp_start] |= SL_to_bitmap(csirs_pdu_rel15->symb_l0, 2);
+                      vrb_map[rb] |= SL_to_bitmap(csirs_pdu_rel15->symb_l0, 2);
                   }
                   else {
                     csirs_pdu_rel15->row = 9;
                     for (int rb = csirs_pdu_rel15->start_rb; rb < (csirs_pdu_rel15->start_rb + csirs_pdu_rel15->nr_of_rbs); rb++)
-                      vrb_map[rb+csirs_pdu_rel15->bwp_start] |= SL_to_bitmap(csirs_pdu_rel15->symb_l0, 1);
+                      vrb_map[rb] |= SL_to_bitmap(csirs_pdu_rel15->symb_l0, 1);
                   }
                   break;
                 case NR_CSI_RS_ResourceMapping__nrofPorts_p16:
@@ -2836,24 +2843,24 @@ void nr_csirs_scheduling(int Mod_idP,
                   else
                     csirs_pdu_rel15->row = 11;
                   for (int rb = csirs_pdu_rel15->start_rb; rb < (csirs_pdu_rel15->start_rb + csirs_pdu_rel15->nr_of_rbs); rb++)
-                    vrb_map[rb+csirs_pdu_rel15->bwp_start] |= SL_to_bitmap(csirs_pdu_rel15->symb_l0, 2);
+                    vrb_map[rb] |= SL_to_bitmap(csirs_pdu_rel15->symb_l0, 2);
                   break;
                 case NR_CSI_RS_ResourceMapping__nrofPorts_p24:
                   if (resourceMapping.cdm_Type == NR_CSI_RS_ResourceMapping__cdm_Type_cdm4_FD2_TD2) {
                     csirs_pdu_rel15->row = 14;
                     for (int rb = csirs_pdu_rel15->start_rb; rb < (csirs_pdu_rel15->start_rb + csirs_pdu_rel15->nr_of_rbs); rb++)
-                      vrb_map[rb+csirs_pdu_rel15->bwp_start] |= (SL_to_bitmap(csirs_pdu_rel15->symb_l0, 2) | SL_to_bitmap(csirs_pdu_rel15->symb_l1, 2));
+                      vrb_map[rb] |= (SL_to_bitmap(csirs_pdu_rel15->symb_l0, 2) | SL_to_bitmap(csirs_pdu_rel15->symb_l1, 2));
                   }
                   else{
                     if (resourceMapping.cdm_Type == NR_CSI_RS_ResourceMapping__cdm_Type_cdm8_FD2_TD4) {
                       csirs_pdu_rel15->row = 15;
                       for (int rb = csirs_pdu_rel15->start_rb; rb < (csirs_pdu_rel15->start_rb + csirs_pdu_rel15->nr_of_rbs); rb++)
-                        vrb_map[rb+csirs_pdu_rel15->bwp_start] |= SL_to_bitmap(csirs_pdu_rel15->symb_l0, 3);
+                        vrb_map[rb] |= SL_to_bitmap(csirs_pdu_rel15->symb_l0, 3);
                     }
                     else {
                       csirs_pdu_rel15->row = 13;
                       for (int rb = csirs_pdu_rel15->start_rb; rb < (csirs_pdu_rel15->start_rb + csirs_pdu_rel15->nr_of_rbs); rb++)
-                        vrb_map[rb+csirs_pdu_rel15->bwp_start] |= (SL_to_bitmap(csirs_pdu_rel15->symb_l0, 2) | SL_to_bitmap(csirs_pdu_rel15->symb_l1, 2));
+                        vrb_map[rb] |= (SL_to_bitmap(csirs_pdu_rel15->symb_l0, 2) | SL_to_bitmap(csirs_pdu_rel15->symb_l1, 2));
                     }
                   }
                   break;
@@ -2861,18 +2868,18 @@ void nr_csirs_scheduling(int Mod_idP,
                   if (resourceMapping.cdm_Type == NR_CSI_RS_ResourceMapping__cdm_Type_cdm4_FD2_TD2) {
                     csirs_pdu_rel15->row = 17;
                     for (int rb = csirs_pdu_rel15->start_rb; rb < (csirs_pdu_rel15->start_rb + csirs_pdu_rel15->nr_of_rbs); rb++)
-                      vrb_map[rb+csirs_pdu_rel15->bwp_start] |= (SL_to_bitmap(csirs_pdu_rel15->symb_l0, 2) | SL_to_bitmap(csirs_pdu_rel15->symb_l1, 2));
+                      vrb_map[rb] |= (SL_to_bitmap(csirs_pdu_rel15->symb_l0, 2) | SL_to_bitmap(csirs_pdu_rel15->symb_l1, 2));
                   }
                   else{
                     if (resourceMapping.cdm_Type == NR_CSI_RS_ResourceMapping__cdm_Type_cdm8_FD2_TD4) {
                       csirs_pdu_rel15->row = 18;
                       for (int rb = csirs_pdu_rel15->start_rb; rb < (csirs_pdu_rel15->start_rb + csirs_pdu_rel15->nr_of_rbs); rb++)
-                        vrb_map[rb+csirs_pdu_rel15->bwp_start] |= SL_to_bitmap(csirs_pdu_rel15->symb_l0, 3);
+                        vrb_map[rb] |= SL_to_bitmap(csirs_pdu_rel15->symb_l0, 3);
                     }
                     else {
                       csirs_pdu_rel15->row = 16;
                       for (int rb = csirs_pdu_rel15->start_rb; rb < (csirs_pdu_rel15->start_rb + csirs_pdu_rel15->nr_of_rbs); rb++)
-                        vrb_map[rb+csirs_pdu_rel15->bwp_start] |= (SL_to_bitmap(csirs_pdu_rel15->symb_l0, 2) | SL_to_bitmap(csirs_pdu_rel15->symb_l1, 2));
+                        vrb_map[rb] |= (SL_to_bitmap(csirs_pdu_rel15->symb_l0, 2) | SL_to_bitmap(csirs_pdu_rel15->symb_l1, 2));
                     }
                   }
                   break;
diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c
index a86767ffbce097ee61c6324195a01ff050bf893a..3e36611c66ac7644effa3e66970d517cacfc4825 100644
--- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c
+++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_uci.c
@@ -39,7 +39,7 @@ extern RAN_CONTEXT_t RC;
 
 
 
-static void nr_fill_nfapi_pucch(gNB_MAC_INST *nrmac, 
+static void nr_fill_nfapi_pucch(gNB_MAC_INST *nrmac,
                                 frame_t frame,
                                 sub_frame_t slot,
                                 const NR_sched_pucch_t *pucch,
@@ -160,7 +160,7 @@ void nr_schedule_pucch(gNB_MAC_INST *nrmac,
           || slotP != curr_pucch->ul_slot)
         continue;
 
-      if (O_csi > 0) 
+      if (O_csi > 0)
          LOG_D(NR_MAC,"Scheduling PUCCH[%d] RX for UE %04x in %4d.%2d O_ack %d, O_sr %d, O_csi %d\n",
                i,UE->rnti,curr_pucch->frame,curr_pucch->ul_slot,O_ack,O_sr,O_csi);
       nr_fill_nfapi_pucch(nrmac, frameP, slotP, curr_pucch, UE);
@@ -290,7 +290,6 @@ void compute_li_bitlen(struct NR_CSI_ReportConfig *csi_reportconfig,
   }
 }
 
-
 void get_n1n2_o1o2_singlepanel(int *n1, int *n2, int *o1, int *o2,
                                struct NR_CodebookConfig__codebookType__type1__subType__typeI_SinglePanel__nrOfAntennaPorts__moreThanTwo *morethantwo) {
 
@@ -562,7 +561,6 @@ void compute_cqi_bitlen(struct NR_CSI_ReportConfig *csi_reportconfig,
     AssertFatal(1==0,"Sub-band CQI reporting not yet supported");
 }
 
-
 //!TODO : same function can be written to handle csi_resources
 void compute_csi_bitlen(NR_CSI_MeasConfig_t *csi_MeasConfig, NR_UE_info_t *UE){
   uint8_t csi_report_id = 0;
@@ -748,7 +746,7 @@ void nr_csi_meas_reporting(int Mod_idP,
         if (*pucchresset->resourceList.list.array[res_index] == pucchcsires->pucch_Resource)
           break;
       AssertFatal(res_index < n,
-                  "CSI pucch resource %ld not found among PUCCH resources\n",pucchcsires->pucch_Resource);
+                  "CSI pucch resource %ld not found among PUCCH resources\n", pucchcsires->pucch_Resource);
 
       // find free PUCCH that is in order with possibly existing PUCCH
       // schedulings (other CSI, SR)
@@ -762,8 +760,7 @@ void nr_csi_meas_reporting(int Mod_idP,
       curr_pucch->frame = frame;
       curr_pucch->ul_slot = sched_slot;
       curr_pucch->resource_indicator = res_index;
-      curr_pucch->csi_bits +=
-          nr_get_csi_bitlen(UE,csi_report_id);
+      curr_pucch->csi_bits += nr_get_csi_bitlen(UE,csi_report_id);
 
       const NR_SIB1_t *sib1 = RC.nrmac[Mod_idP]->common_channels[0].sib1 ? RC.nrmac[Mod_idP]->common_channels[0].sib1->message.choice.c1->choice.systemInformationBlockType1 : NULL;
       NR_BWP_t *genericParameters = get_ul_bwp_genericParameters(sched_ctrl->active_ubwp,
@@ -1608,7 +1605,7 @@ bool test_acknack_vrb_occupation(NR_UE_sched_ctrl_t *sched_ctrl,
 // if the function returns -1 it was not possible to schedule acknack
 // when current pucch is ready to be scheduled nr_fill_nfapi_pucch is called
 int nr_acknack_scheduling(int mod_id,
-                          NR_UE_info_t * UE,
+                          NR_UE_info_t *UE,
                           frame_t frame,
                           sub_frame_t slot,
                           int r_pucch,
@@ -1667,10 +1664,10 @@ int nr_acknack_scheduling(int mod_id,
     const int s = pucch->ul_slot;
     LOG_D(NR_MAC, "In %s: %4d.%2d DAI = 2 pucch currently in %4d.%2d, advancing by 1 slot\n", __FUNCTION__, frame, slot, f, s);
 
-    if (!(csi_pucch 
+    if (!(csi_pucch
           && csi_pucch->csi_bits > 0
           && csi_pucch->frame == f
-          && csi_pucch->ul_slot == s)) 
+          && csi_pucch->ul_slot == s))
     nr_fill_nfapi_pucch(RC.nrmac[mod_id], frame, slot, pucch, UE);
 
     memset(pucch, 0, sizeof(*pucch));
@@ -1781,7 +1778,6 @@ int nr_acknack_scheduling(int mod_id,
                 UE->rnti, frame, slot, pucch->sr_flag, pucch->dai_c, pucch->frame, pucch->ul_slot);
     const int s = next_ul_slot;
     pucch->frame = s < n_slots_frame ? frame : (frame + 1) % 1024;
-
     pucch->ul_slot = s % n_slots_frame;
   }
 
@@ -1973,8 +1969,7 @@ void nr_sr_reporting(gNB_MAC_INST *nrmac, frame_t SFN, sub_frame_t slot)
           pdu->sr_flag = 1;
           nfapi_allocated = true;
           break;
-        }
-        else if (pdu->rnti == UE->rnti
+        } else if (pdu->rnti == UE->rnti
             && pdu->format_type == 2 // does not use NR_PUCCH_Resource__format_PR_format0
             && pdu->nr_of_symbols == pucch_res->format.choice.format2->nrofSymbols
             && pdu->start_symbol_index == pucch_res->format.choice.format2->startingSymbolIndex) {
@@ -1982,9 +1977,7 @@ void nr_sr_reporting(gNB_MAC_INST *nrmac, frame_t SFN, sub_frame_t slot)
           pdu->sr_flag = 1;
           nfapi_allocated = true;
           break;
-
-        }
-        else if (pdu->rnti == UE->rnti
+        } else if (pdu->rnti == UE->rnti
             && pdu->format_type == 1 // does not use NR_PUCCH_Resource__format_PR_format0
             && pdu->nr_of_symbols == pucch_res->format.choice.format1->nrofSymbols
             && pdu->start_symbol_index == pucch_res->format.choice.format1->startingSymbolIndex) {
@@ -1992,9 +1985,7 @@ void nr_sr_reporting(gNB_MAC_INST *nrmac, frame_t SFN, sub_frame_t slot)
           pdu->sr_flag = 1;
           nfapi_allocated = true;
           break;
-
-        }
-        else if (pdu->rnti == UE->rnti
+        } else if (pdu->rnti == UE->rnti
             && pdu->format_type == 3 // does not use NR_PUCCH_Resource__format_PR_format0
             && pdu->nr_of_symbols == pucch_res->format.choice.format3->nrofSymbols
             && pdu->start_symbol_index == pucch_res->format.choice.format3->startingSymbolIndex) {
@@ -2002,9 +1993,7 @@ void nr_sr_reporting(gNB_MAC_INST *nrmac, frame_t SFN, sub_frame_t slot)
           pdu->sr_flag = 1;
           nfapi_allocated = true;
           break;
-
-        }
-        else if (pdu->rnti == UE->rnti
+        } else if (pdu->rnti == UE->rnti
             && pdu->format_type == 4 // does not use NR_PUCCH_Resource__format_PR_format0
             && pdu->nr_of_symbols == pucch_res->format.choice.format4->nrofSymbols
             && pdu->start_symbol_index == pucch_res->format.choice.format4->startingSymbolIndex) {
@@ -2012,7 +2001,6 @@ void nr_sr_reporting(gNB_MAC_INST *nrmac, frame_t SFN, sub_frame_t slot)
           pdu->sr_flag = 1;
           nfapi_allocated = true;
           break;
-
         }
       }
 
diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c
index ad7db304bf9db6823f1afe6a7f4eb71c9b9a75c4..a3ce5fc435bc4fc2865ce3d6e5f406aa1020e147 100644
--- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c
+++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c
@@ -333,7 +333,7 @@ int nr_process_mac_pdu( instance_t module_idP,
                               0);
           break;
 
-        case UL_SCH_LCID_DTCH:
+        case UL_SCH_LCID_DTCH ... (UL_SCH_LCID_DTCH + 28):
           //  check if LCID is valid at current time.
 	  if (!get_mac_len(pduP, pdu_len, &mac_len, &mac_subheader_len))
 	    return 0;
@@ -855,8 +855,7 @@ static bool nr_UE_is_to_be_scheduled(const NR_ServingCellConfigCommon_t *scc,
   if (tdd) { // Force the default transmission in a full slot as early as possible in the UL portion of TDD period (last_ul_slot)
     num_slots_per_period = n*tdd_period_len[tdd->dl_UL_TransmissionPeriodicity]/10000;
     last_ul_slot=1+tdd->nrofDownlinkSlots;
-  }
-  else {
+  } else {
     num_slots_per_period = n;
     last_ul_slot = sched_ctrl->last_ul_slot;
   }
diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c b/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c
index b5cea6bdb99e2c48eafbff91e4ad92f9680ca691..ea4b7e80c7651445bb0989e5dfd0abbea017ff5f 100644
--- a/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c
+++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c
@@ -977,11 +977,6 @@ static void add_drb_am(int is_gnb, int rnti, struct NR_DRB_ToAddMod *s,
     exit(1);
   }
 
-  if (drb_id != 1) {
-    LOG_E(PDCP, "%s:%d:%s: fatal, bad drb id %d\n",
-          __FILE__, __LINE__, __FUNCTION__, drb_id);
-    exit(1);
-  }
 
   nr_pdcp_manager_lock(nr_pdcp_ue_manager);
   ue = nr_pdcp_manager_get_ue(nr_pdcp_ue_manager, rnti);
diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c b/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c
index 0a8e03fc1e871f1c4d0813e7a0794437ecf28d1b..7ba08aaa71a5d314dd21de8f0453a80a723155bd 100644
--- a/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c
+++ b/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c
@@ -123,7 +123,7 @@ void nr_drb_config(struct NR_RLC_Config *rlc_Config, NR_RLC_Config_PR rlc_config
       rlc_Config->choice.am->dl_AM_RLC.t_StatusProhibit = NR_T_StatusProhibit_ms15;
       break;
     default:
-      LOG_E (RLC, "Error in %s: RLC config type %d is not handled\n", __FUNCTION__, rlc_config_pr);
+      AssertFatal(0, "RLC config type %d not handled\n", rlc_config_pr);
       break;
     }
 
diff --git a/openair2/RRC/LTE/MESSAGES/asn1_msg.c b/openair2/RRC/LTE/MESSAGES/asn1_msg.c
index bd09540627aba805ec9a02378ece258cbefc442d..c34c65b19503fca2515d973575fa97316e062756 100644
--- a/openair2/RRC/LTE/MESSAGES/asn1_msg.c
+++ b/openair2/RRC/LTE/MESSAGES/asn1_msg.c
@@ -1331,10 +1331,8 @@ uint8_t do_SIB23(uint8_t Mod_id,
     (*sib2)->radioResourceConfigCommon.rach_ConfigCommon.ext1 = calloc(1, sizeof(struct LTE_RACH_ConfigCommon__ext1));
     memset((*sib2)->radioResourceConfigCommon.rach_ConfigCommon.ext1, 0, sizeof(struct LTE_RACH_ConfigCommon__ext1));
 
-    if (rrconfig->preambleTransMax_CE_r13) {
-      (*sib2)->radioResourceConfigCommon.rach_ConfigCommon.ext1->preambleTransMax_CE_r13 = calloc(1, sizeof(LTE_PreambleTransMax_t));
-      *(*sib2)->radioResourceConfigCommon.rach_ConfigCommon.ext1->preambleTransMax_CE_r13 = *rrconfig->preambleTransMax_CE_r13; // to be re-initialized when we find the enum
-    } else (*sib2)->radioResourceConfigCommon.rach_ConfigCommon.ext1->preambleTransMax_CE_r13 = NULL;
+    (*sib2)->radioResourceConfigCommon.rach_ConfigCommon.ext1->preambleTransMax_CE_r13 = calloc(1, sizeof(LTE_PreambleTransMax_t));
+    *(*sib2)->radioResourceConfigCommon.rach_ConfigCommon.ext1->preambleTransMax_CE_r13 = rrconfig->preambleTransMax_CE_r13; // to be re-initialized when we find the enum
 
     (*sib2)->radioResourceConfigCommon.rach_ConfigCommon.ext1->rach_CE_LevelInfoList_r13 = calloc(1, sizeof(LTE_RACH_CE_LevelInfoList_r13_t));
     memset((*sib2)->radioResourceConfigCommon.rach_ConfigCommon.ext1->rach_CE_LevelInfoList_r13, 0, sizeof(LTE_RACH_CE_LevelInfoList_r13_t));
diff --git a/openair2/RRC/NR/MESSAGES/asn1_msg.c b/openair2/RRC/NR/MESSAGES/asn1_msg.c
index 75563e5093065c043ad29c8d6f12d903e74fad01..09aa5e7076f8f52ca84db2993899775683e07d02 100755
--- a/openair2/RRC/NR/MESSAGES/asn1_msg.c
+++ b/openair2/RRC/NR/MESSAGES/asn1_msg.c
@@ -1252,18 +1252,26 @@ void fill_default_uplinkBWP(NR_BWP_Uplink_t *ubwp,
   pucch_Config->resourceSetToAddModList = calloc(1,sizeof(*pucch_Config->resourceSetToAddModList));
   pucch_Config->resourceSetToReleaseList = NULL;
   NR_PUCCH_ResourceSet_t *pucchresset0=calloc(1,sizeof(*pucchresset0));
+  NR_PUCCH_ResourceSet_t *pucchresset1=calloc(1,sizeof(*pucchresset1));
   pucchresset0->pucch_ResourceSetId = 0;
-  NR_PUCCH_ResourceId_t *pucchres0id0=calloc(1,sizeof(*pucchres0id0));
-  *pucchres0id0=ubwp->bwp_Id; // To uniquely identify each pucchresource lets derive it from the BWPId
-  ASN_SEQUENCE_ADD(&pucchresset0->resourceList.list,pucchres0id0);
+  NR_PUCCH_ResourceId_t *pucchresset0id0=calloc(1,sizeof(*pucchresset0id0));
+  *pucchresset0id0=0;
+  ASN_SEQUENCE_ADD(&pucchresset0->resourceList.list,pucchresset0id0);
   pucchresset0->maxPayloadSize=NULL;
   ASN_SEQUENCE_ADD(&pucch_Config->resourceSetToAddModList->list,pucchresset0);
+  pucchresset1->pucch_ResourceSetId = 1;
+  NR_PUCCH_ResourceId_t *pucchresset1id0=calloc(1,sizeof(*pucchresset1id0));
+  *pucchresset1id0=1;
+  ASN_SEQUENCE_ADD(&pucchresset1->resourceList.list,pucchresset1id0);
+  pucchresset1->maxPayloadSize=NULL;
+  ASN_SEQUENCE_ADD(&pucch_Config->resourceSetToAddModList->list,pucchresset1);
   pucch_Config->resourceToAddModList = calloc(1,sizeof(*pucch_Config->resourceToAddModList));
   pucch_Config->resourceToReleaseList = NULL;
   int curr_bwp = NRRIV2BW(ubwp->bwp_Common->genericParameters.locationAndBandwidth,MAX_BWP_SIZE);
   NR_PUCCH_Resource_t *pucchres0=calloc(1,sizeof(*pucchres0));
-  pucchres0->pucch_ResourceId=*pucchres0id0;
-  pucchres0->startingPRB=(8+uid) % curr_bwp;
+  pucchres0->pucch_ResourceId=0;
+  pucchres0->startingPRB=(8+uid) % (curr_bwp/2);
+  LOG_D(NR_RRC, "pucchres0->startPRB %ld uid %d curr_bwp %d\n", pucchres0->startingPRB, uid, curr_bwp);
   pucchres0->intraSlotFrequencyHopping=NULL;
   pucchres0->secondHopPRB=NULL;
   pucchres0->format.present= NR_PUCCH_Resource__format_PR_format0;
@@ -1272,8 +1280,17 @@ void fill_default_uplinkBWP(NR_BWP_Uplink_t *ubwp,
   pucchres0->format.choice.format0->nrofSymbols=1;
   pucchres0->format.choice.format0->startingSymbolIndex=13;
   ASN_SEQUENCE_ADD(&pucch_Config->resourceToAddModList->list,pucchres0);
-
-/*
+  NR_PUCCH_Resource_t *pucchres2=calloc(1,sizeof(*pucchres2));
+  pucchres2->pucch_ResourceId=1;
+  pucchres2->startingPRB=0;
+  pucchres2->intraSlotFrequencyHopping=NULL;
+  pucchres2->secondHopPRB=NULL;
+  pucchres2->format.present= NR_PUCCH_Resource__format_PR_format2;
+  pucchres2->format.choice.format2=calloc(1,sizeof(*pucchres2->format.choice.format2));
+  pucchres2->format.choice.format2->nrofPRBs=8;
+  pucchres2->format.choice.format2->nrofSymbols=1;
+  pucchres2->format.choice.format2->startingSymbolIndex=13;
+  ASN_SEQUENCE_ADD(&pucch_Config->resourceToAddModList->list,pucchres2);
   pucch_Config->format2=calloc(1,sizeof(*pucch_Config->format2));
   pucch_Config->format2->present=NR_SetupRelease_PUCCH_FormatConfig_PR_setup;
   NR_PUCCH_FormatConfig_t *pucchfmt2 = calloc(1,sizeof(*pucchfmt2));
@@ -1286,7 +1303,6 @@ void fill_default_uplinkBWP(NR_BWP_Uplink_t *ubwp,
   pucchfmt2->pi2BPSK=NULL;
   pucchfmt2->simultaneousHARQ_ACK_CSI=calloc(1,sizeof(*pucchfmt2->simultaneousHARQ_ACK_CSI));
   *pucchfmt2->simultaneousHARQ_ACK_CSI=NR_PUCCH_FormatConfig__simultaneousHARQ_ACK_CSI_true;
-*/
 
   // PUCCH config - Scheduling request configuration
   pucch_Config->schedulingRequestResourceToAddModList = calloc(1,sizeof(*pucch_Config->schedulingRequestResourceToAddModList));
@@ -1305,7 +1321,7 @@ void fill_default_uplinkBWP(NR_BWP_Uplink_t *ubwp,
               "TDD period != 5ms : %ld\n",scc->tdd_UL_DL_ConfigurationCommon->pattern1.dl_UL_TransmissionPeriodicity);
   schedulingRequestResourceConfig->periodicityAndOffset->choice.sl40 = 8;
   schedulingRequestResourceConfig->resource = calloc(1,sizeof(*schedulingRequestResourceConfig->resource));
-  *schedulingRequestResourceConfig->resource = *pucchres0id0;
+  *schedulingRequestResourceConfig->resource = 0;
   ASN_SEQUENCE_ADD(&pucch_Config->schedulingRequestResourceToAddModList->list,schedulingRequestResourceConfig);
   pucch_Config->schedulingRequestResourceToReleaseList=NULL;
 
@@ -1607,7 +1623,6 @@ void fill_initial_SpCellConfig(int uid,
   pucchspatial->closedLoopIndex = NR_PUCCH_SpatialRelationInfo__closedLoopIndex_i0;
   ASN_SEQUENCE_ADD(&pucch_Config->spatialRelationInfoToAddModList->list,pucchspatial);
 
-
   initialUplinkBWP->pusch_Config = calloc(1,sizeof(*initialUplinkBWP->pusch_Config));
   initialUplinkBWP->pusch_Config->present = NR_SetupRelease_PUSCH_Config_PR_setup;
   NR_PUSCH_Config_t *pusch_Config = calloc(1,sizeof(*pusch_Config));
@@ -1936,7 +1951,7 @@ void fill_initial_SpCellConfig(int uid,
      *csirep1->reportFreqConfiguration->cqi_FormatIndicator=NR_CSI_ReportConfig__reportFreqConfiguration__cqi_FormatIndicator_widebandCQI;
      csirep1->reportFreqConfiguration->pmi_FormatIndicator = calloc(1,sizeof(*csirep1->reportFreqConfiguration->pmi_FormatIndicator));
      *csirep1->reportFreqConfiguration->pmi_FormatIndicator=NR_CSI_ReportConfig__reportFreqConfiguration__pmi_FormatIndicator_widebandPMI;
-     csirep1->reportFreqConfiguration->csi_ReportingBand = NULL; 
+     csirep1->reportFreqConfiguration->csi_ReportingBand = NULL;
      /*calloc(1,sizeof(*csirep1->reportFreqConfiguration->csi_ReportingBand));
      csirep1->reportFreqConfiguration->csi_ReportingBand->present = NR_CSI_ReportConfig__reportFreqConfiguration__csi_ReportingBand_PR_subbands7;
      csirep1->reportFreqConfiguration->csi_ReportingBand->choice.subbands7.size=1;
@@ -2062,25 +2077,19 @@ void fill_initial_SpCellConfig(int uid,
 
 }
 
-void fill_mastercellGroupConfig(NR_CellGroupConfig_t *cellGroupConfig, NR_CellGroupConfig_t *ue_context_mastercellGroup,int use_rlc_um_for_drb) {
-
-  cellGroupConfig->cellGroupId = 0;
-  cellGroupConfig->rlc_BearerToReleaseList = NULL;
-  cellGroupConfig->rlc_BearerToAddModList = calloc(1, sizeof(*cellGroupConfig->rlc_BearerToAddModList));
-
-  // RLC Bearer Config
-  // TS38.331 9.2.1 Default SRB configurations
-  NR_RLC_BearerConfig_t *rlc_BearerConfig                          = NULL;
-  NR_RLC_Config_t *rlc_Config                                      = NULL;
-  NR_LogicalChannelConfig_t *logicalChannelConfig                  = NULL;
-  long *logicalChannelGroup                                        = NULL;
+NR_RLC_BearerConfig_t *get_SRB_RLC_BearerConfig(long channelId,
+                                                long priority,
+                                                e_NR_LogicalChannelConfig__ul_SpecificParameters__bucketSizeDuration bucketSizeDuration)
+{
+  NR_RLC_BearerConfig_t *rlc_BearerConfig = NULL;
   rlc_BearerConfig                                                 = calloc(1, sizeof(NR_RLC_BearerConfig_t));
-  rlc_BearerConfig->logicalChannelIdentity                         = 2;
+  rlc_BearerConfig->logicalChannelIdentity                         = channelId;
   rlc_BearerConfig->servedRadioBearer                              = calloc(1, sizeof(*rlc_BearerConfig->servedRadioBearer));
   rlc_BearerConfig->servedRadioBearer->present                     = NR_RLC_BearerConfig__servedRadioBearer_PR_srb_Identity;
-  rlc_BearerConfig->servedRadioBearer->choice.srb_Identity         = 2;
+  rlc_BearerConfig->servedRadioBearer->choice.srb_Identity         = channelId;
   rlc_BearerConfig->reestablishRLC                                 = NULL;
-  rlc_Config                                                       = calloc(1, sizeof(NR_RLC_Config_t));
+
+  NR_RLC_Config_t *rlc_Config                                      = calloc(1, sizeof(NR_RLC_Config_t));
   rlc_Config->present                                              = NR_RLC_Config_PR_am;
   rlc_Config->choice.am                                            = calloc(1, sizeof(*rlc_Config->choice.am));
   rlc_Config->choice.am->dl_AM_RLC.sn_FieldLength                  = calloc(1, sizeof(NR_SN_FieldLengthAM_t));
@@ -2094,12 +2103,14 @@ void fill_mastercellGroupConfig(NR_CellGroupConfig_t *cellGroupConfig, NR_CellGr
   rlc_Config->choice.am->ul_AM_RLC.pollByte                        = NR_PollByte_infinity;
   rlc_Config->choice.am->ul_AM_RLC.maxRetxThreshold                = NR_UL_AM_RLC__maxRetxThreshold_t8;
   rlc_BearerConfig->rlc_Config                                     = rlc_Config;
-  logicalChannelConfig                                             = calloc(1, sizeof(NR_LogicalChannelConfig_t));
+
+  NR_LogicalChannelConfig_t *logicalChannelConfig                  = calloc(1, sizeof(NR_LogicalChannelConfig_t));
   logicalChannelConfig->ul_SpecificParameters                      = calloc(1, sizeof(*logicalChannelConfig->ul_SpecificParameters));
-  logicalChannelConfig->ul_SpecificParameters->priority            = 3;
+  logicalChannelConfig->ul_SpecificParameters->priority            = priority;
   logicalChannelConfig->ul_SpecificParameters->prioritisedBitRate  = NR_LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_infinity;
-  logicalChannelConfig->ul_SpecificParameters->bucketSizeDuration  = NR_LogicalChannelConfig__ul_SpecificParameters__bucketSizeDuration_ms5;
-  logicalChannelGroup                                              = CALLOC(1, sizeof(long));
+  logicalChannelConfig->ul_SpecificParameters->bucketSizeDuration  = bucketSizeDuration;
+
+  long *logicalChannelGroup                                        = CALLOC(1, sizeof(long));
   *logicalChannelGroup                                             = 0;
   logicalChannelConfig->ul_SpecificParameters->logicalChannelGroup = logicalChannelGroup;
   logicalChannelConfig->ul_SpecificParameters->schedulingRequestID = CALLOC(1, sizeof(*logicalChannelConfig->ul_SpecificParameters->schedulingRequestID));
@@ -2107,41 +2118,62 @@ void fill_mastercellGroupConfig(NR_CellGroupConfig_t *cellGroupConfig, NR_CellGr
   logicalChannelConfig->ul_SpecificParameters->logicalChannelSR_Mask = 0;
   logicalChannelConfig->ul_SpecificParameters->logicalChannelSR_DelayTimerApplied = 0;
   rlc_BearerConfig->mac_LogicalChannelConfig                       = logicalChannelConfig;
-  ASN_SEQUENCE_ADD(&cellGroupConfig->rlc_BearerToAddModList->list, rlc_BearerConfig);
-  ASN_SEQUENCE_ADD(&ue_context_mastercellGroup->rlc_BearerToAddModList->list, rlc_BearerConfig);
+
+  return rlc_BearerConfig;
+}
+
+NR_RLC_BearerConfig_t *get_DRB_RLC_BearerConfig(long lcChannelId, long drbId, NR_RLC_Config_PR rlc_conf, long priority)
+{
+  NR_RLC_BearerConfig_t *rlc_BearerConfig                  = calloc(1, sizeof(NR_RLC_BearerConfig_t));
+  rlc_BearerConfig->logicalChannelIdentity                 = lcChannelId;
+  rlc_BearerConfig->servedRadioBearer                      = calloc(1, sizeof(*rlc_BearerConfig->servedRadioBearer));
+  rlc_BearerConfig->servedRadioBearer->present             = NR_RLC_BearerConfig__servedRadioBearer_PR_drb_Identity;
+  rlc_BearerConfig->servedRadioBearer->choice.drb_Identity = drbId;
+  rlc_BearerConfig->reestablishRLC                         = NULL;
+
+  NR_RLC_Config_t *rlc_Config  = calloc(1, sizeof(NR_RLC_Config_t));
+  nr_drb_config(rlc_Config, rlc_conf);
+  rlc_BearerConfig->rlc_Config = rlc_Config;
+
+  NR_LogicalChannelConfig_t *logicalChannelConfig                 = calloc(1, sizeof(NR_LogicalChannelConfig_t));
+  logicalChannelConfig->ul_SpecificParameters                     = calloc(1, sizeof(*logicalChannelConfig->ul_SpecificParameters));
+  logicalChannelConfig->ul_SpecificParameters->priority           = priority;
+  logicalChannelConfig->ul_SpecificParameters->prioritisedBitRate = NR_LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_kBps8;
+  logicalChannelConfig->ul_SpecificParameters->bucketSizeDuration = NR_LogicalChannelConfig__ul_SpecificParameters__bucketSizeDuration_ms100;
+
+  long *logicalChannelGroup                                          = CALLOC(1, sizeof(long));
+  *logicalChannelGroup                                               = 1;
+  logicalChannelConfig->ul_SpecificParameters->logicalChannelGroup   = logicalChannelGroup;
+  logicalChannelConfig->ul_SpecificParameters->schedulingRequestID   = CALLOC(1, sizeof(*logicalChannelConfig->ul_SpecificParameters->schedulingRequestID));
+  *logicalChannelConfig->ul_SpecificParameters->schedulingRequestID  = 0;
+  logicalChannelConfig->ul_SpecificParameters->logicalChannelSR_Mask = 0;
+  logicalChannelConfig->ul_SpecificParameters->logicalChannelSR_DelayTimerApplied = 0;
+  rlc_BearerConfig->mac_LogicalChannelConfig                         = logicalChannelConfig;
+
+  return rlc_BearerConfig;
+}
+
+void fill_mastercellGroupConfig(NR_CellGroupConfig_t *cellGroupConfig, NR_CellGroupConfig_t *ue_context_mastercellGroup, int use_rlc_um_for_drb, uint8_t configure_srb, uint8_t bearer_id_start, uint8_t nb_bearers_to_setup, long *priority ) {
+
+  cellGroupConfig->cellGroupId = 0;
+  cellGroupConfig->rlc_BearerToReleaseList = NULL;
+  cellGroupConfig->rlc_BearerToAddModList = calloc(1, sizeof(*cellGroupConfig->rlc_BearerToAddModList));
+
+  // RLC Bearer Config
+  // TS38.331 9.2.1 Default SRB configurations
+  if (configure_srb){
+    NR_RLC_BearerConfig_t *rlc_BearerConfig = get_SRB_RLC_BearerConfig(2, 3, NR_LogicalChannelConfig__ul_SpecificParameters__bucketSizeDuration_ms5);
+    ASN_SEQUENCE_ADD(&cellGroupConfig->rlc_BearerToAddModList->list, rlc_BearerConfig);
+    ASN_SEQUENCE_ADD(&ue_context_mastercellGroup->rlc_BearerToAddModList->list, rlc_BearerConfig);
+  }
 
   // DRB Configuration
-  NR_RLC_BearerConfig_t *rlc_BearerConfig_drb                      = NULL;
-  NR_RLC_Config_t *rlc_Config_drb                                  = NULL;
-  NR_LogicalChannelConfig_t *logicalChannelConfig_drb              = NULL;
-  long *logicalChannelGroup_drb                                    = NULL;
-  rlc_BearerConfig_drb                                             = calloc(1, sizeof(NR_RLC_BearerConfig_t));
-  rlc_BearerConfig_drb->logicalChannelIdentity                     = 4;
-  rlc_BearerConfig_drb->servedRadioBearer                          = calloc(1, sizeof(*rlc_BearerConfig_drb->servedRadioBearer));
-  rlc_BearerConfig_drb->servedRadioBearer->present                 = NR_RLC_BearerConfig__servedRadioBearer_PR_drb_Identity;
-  rlc_BearerConfig_drb->servedRadioBearer->choice.drb_Identity     = 1;
-  rlc_BearerConfig_drb->reestablishRLC                             = NULL;
-  rlc_Config_drb                                                   = calloc(1, sizeof(NR_RLC_Config_t));
-
-  if (use_rlc_um_for_drb) nr_drb_config(rlc_Config_drb, NR_RLC_Config_PR_um_Bi_Directional);
-  else                    nr_drb_config(rlc_Config_drb, NR_RLC_Config_PR_am);
-
-  rlc_BearerConfig_drb->rlc_Config                                 = rlc_Config_drb;
-  logicalChannelConfig_drb                                             = calloc(1, sizeof(NR_LogicalChannelConfig_t));
-  logicalChannelConfig_drb->ul_SpecificParameters                      = calloc(1, sizeof(*logicalChannelConfig_drb->ul_SpecificParameters));
-  logicalChannelConfig_drb->ul_SpecificParameters->priority            = 13;
-  logicalChannelConfig_drb->ul_SpecificParameters->prioritisedBitRate  = NR_LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_kBps8;
-  logicalChannelConfig_drb->ul_SpecificParameters->bucketSizeDuration  = NR_LogicalChannelConfig__ul_SpecificParameters__bucketSizeDuration_ms100;
-  logicalChannelGroup_drb                                              = CALLOC(1, sizeof(long));
-  *logicalChannelGroup_drb                                             = 1;
-  logicalChannelConfig_drb->ul_SpecificParameters->logicalChannelGroup = logicalChannelGroup_drb;
-  logicalChannelConfig_drb->ul_SpecificParameters->schedulingRequestID = CALLOC(1, sizeof(*logicalChannelConfig_drb->ul_SpecificParameters->schedulingRequestID));
-  *logicalChannelConfig_drb->ul_SpecificParameters->schedulingRequestID = 0;
-  logicalChannelConfig_drb->ul_SpecificParameters->logicalChannelSR_Mask = 0;
-  logicalChannelConfig_drb->ul_SpecificParameters->logicalChannelSR_DelayTimerApplied = 0;
-  rlc_BearerConfig_drb->mac_LogicalChannelConfig                       = logicalChannelConfig_drb;
-  ASN_SEQUENCE_ADD(&cellGroupConfig->rlc_BearerToAddModList->list, rlc_BearerConfig_drb);
-  ASN_SEQUENCE_ADD(&ue_context_mastercellGroup->rlc_BearerToAddModList->list, rlc_BearerConfig_drb);
+  for (int i = bearer_id_start; i < bearer_id_start + nb_bearers_to_setup; i++ ){
+    const NR_RLC_Config_PR rlc_conf = use_rlc_um_for_drb ? NR_RLC_Config_PR_um_Bi_Directional : NR_RLC_Config_PR_am;
+    NR_RLC_BearerConfig_t *rlc_BearerConfig = get_DRB_RLC_BearerConfig(3 + i, i, rlc_conf, priority[i-bearer_id_start]);
+    ASN_SEQUENCE_ADD(&cellGroupConfig->rlc_BearerToAddModList->list, rlc_BearerConfig);
+    ASN_SEQUENCE_ADD(&ue_context_mastercellGroup->rlc_BearerToAddModList->list, rlc_BearerConfig);
+  }
 }
 
 void update_cellGroupConfig(NR_CellGroupConfig_t *cellGroupConfig,
@@ -2194,50 +2226,15 @@ void fill_initial_cellGroupConfig(int uid,
                                   NR_ServingCellConfig_t *servingcellconfigdedicated,
                                   const gNB_RrcConfigurationReq *configuration)
 {
-  NR_RLC_BearerConfig_t                            *rlc_BearerConfig     = NULL;
-  NR_RLC_Config_t                                  *rlc_Config           = NULL;
-  NR_LogicalChannelConfig_t                        *logicalChannelConfig = NULL;
   NR_MAC_CellGroupConfig_t                         *mac_CellGroupConfig  = NULL;
   NR_PhysicalCellGroupConfig_t	                   *physicalCellGroupConfig = NULL;
-  long *logicalChannelGroup = NULL;
   
   cellGroupConfig->cellGroupId = 0;
   
   /* Rlc Bearer Config */
   /* TS38.331 9.2.1	Default SRB configurations */
   cellGroupConfig->rlc_BearerToAddModList                          = calloc(1, sizeof(*cellGroupConfig->rlc_BearerToAddModList));
-  rlc_BearerConfig                                                 = calloc(1, sizeof(NR_RLC_BearerConfig_t));
-  rlc_BearerConfig->logicalChannelIdentity                         = 1;
-  rlc_BearerConfig->servedRadioBearer                              = calloc(1, sizeof(*rlc_BearerConfig->servedRadioBearer));
-  rlc_BearerConfig->servedRadioBearer->present                     = NR_RLC_BearerConfig__servedRadioBearer_PR_srb_Identity;
-  rlc_BearerConfig->servedRadioBearer->choice.srb_Identity         = 1;
-  rlc_BearerConfig->reestablishRLC                                 = NULL;
-  rlc_Config = calloc(1, sizeof(NR_RLC_Config_t));
-  rlc_Config->present                                              = NR_RLC_Config_PR_am;
-  rlc_Config->choice.am                                            = calloc(1, sizeof(*rlc_Config->choice.am));
-  rlc_Config->choice.am->dl_AM_RLC.sn_FieldLength                  = calloc(1, sizeof(NR_SN_FieldLengthAM_t));
-  *(rlc_Config->choice.am->dl_AM_RLC.sn_FieldLength)               = NR_SN_FieldLengthAM_size12;
-  rlc_Config->choice.am->dl_AM_RLC.t_Reassembly                    = NR_T_Reassembly_ms35;
-  rlc_Config->choice.am->dl_AM_RLC.t_StatusProhibit                = NR_T_StatusProhibit_ms0;
-  rlc_Config->choice.am->ul_AM_RLC.sn_FieldLength                  = calloc(1, sizeof(NR_SN_FieldLengthAM_t));
-  *(rlc_Config->choice.am->ul_AM_RLC.sn_FieldLength)               = NR_SN_FieldLengthAM_size12;
-  rlc_Config->choice.am->ul_AM_RLC.t_PollRetransmit                = NR_T_PollRetransmit_ms45;
-  rlc_Config->choice.am->ul_AM_RLC.pollPDU                         = NR_PollPDU_infinity;
-  rlc_Config->choice.am->ul_AM_RLC.pollByte                        = NR_PollByte_infinity;
-  rlc_Config->choice.am->ul_AM_RLC.maxRetxThreshold                = NR_UL_AM_RLC__maxRetxThreshold_t8;
-  rlc_BearerConfig->rlc_Config                                     = rlc_Config;
-  logicalChannelConfig                                             = calloc(1, sizeof(NR_LogicalChannelConfig_t));
-  logicalChannelConfig->ul_SpecificParameters                      = calloc(1, sizeof(*logicalChannelConfig->ul_SpecificParameters));
-  logicalChannelConfig->ul_SpecificParameters->priority            = 1;
-  logicalChannelConfig->ul_SpecificParameters->prioritisedBitRate  = NR_LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_infinity;
-  logicalChannelGroup                                              = CALLOC(1, sizeof(long));
-  *logicalChannelGroup                                             = 0;
-  logicalChannelConfig->ul_SpecificParameters->logicalChannelGroup = logicalChannelGroup;
-  logicalChannelConfig->ul_SpecificParameters->schedulingRequestID = CALLOC(1, sizeof(*logicalChannelConfig->ul_SpecificParameters->schedulingRequestID));
-  *logicalChannelConfig->ul_SpecificParameters->schedulingRequestID = 0;
-  logicalChannelConfig->ul_SpecificParameters->logicalChannelSR_Mask = 0;
-  logicalChannelConfig->ul_SpecificParameters->logicalChannelSR_DelayTimerApplied = 0;
-  rlc_BearerConfig->mac_LogicalChannelConfig                       = logicalChannelConfig;
+  NR_RLC_BearerConfig_t *rlc_BearerConfig = get_SRB_RLC_BearerConfig(1, 1, NR_LogicalChannelConfig__ul_SpecificParameters__bucketSizeDuration_ms1000);
   ASN_SEQUENCE_ADD(&cellGroupConfig->rlc_BearerToAddModList->list, rlc_BearerConfig);
   
   cellGroupConfig->rlc_BearerToReleaseList = NULL;
@@ -2400,7 +2397,7 @@ int16_t do_RRCSetup(rrc_gNB_ue_context_t          *const ue_context_pP,
       return -1;
     }
     
-    LOG_I(NR_RRC,"RRCSetup Encoded %zd bits (%zd bytes)\n",
+    LOG_D(NR_RRC,"RRCSetup Encoded %zd bits (%zd bytes)\n",
             enc_rval.encoded,(enc_rval.encoded+7)/8);
     return((enc_rval.encoded+7)/8);
 }
diff --git a/openair2/RRC/NR/MESSAGES/asn1_msg.h b/openair2/RRC/NR/MESSAGES/asn1_msg.h
index 6a85cf6cbbf061136875795d1200e655edb048e2..3b881231b0c347b41889aed1e795f6deef608756 100644
--- a/openair2/RRC/NR/MESSAGES/asn1_msg.h
+++ b/openair2/RRC/NR/MESSAGES/asn1_msg.h
@@ -118,7 +118,13 @@ void update_cellGroupConfig(NR_CellGroupConfig_t *cellGroupConfig,
                             NR_UE_NR_Capability_t *uecap,
                             const gNB_RrcConfigurationReq *configuration);
 
-void fill_mastercellGroupConfig(NR_CellGroupConfig_t *cellGroupConfig, NR_CellGroupConfig_t *ue_context_mastercellGroup, int use_rlc_um_for_drb);
+void fill_mastercellGroupConfig(NR_CellGroupConfig_t *cellGroupConfig,
+                                NR_CellGroupConfig_t *ue_context_mastercellGroup,
+                                int use_rlc_um_for_drb,
+                                uint8_t configure_srb,
+                                uint8_t bearer_id_start,
+                                uint8_t nb_bearers_to_setup,
+                                long *priority);
 
 int16_t do_RRCSetup(rrc_gNB_ue_context_t         *const ue_context_pP,
                     uint8_t                      *const buffer,
diff --git a/openair2/RRC/NR/nr_rrc_config.c b/openair2/RRC/NR/nr_rrc_config.c
index e59f7d5caceee6c83e8c6de625da2dd89d810418..eb2dd828a9ff727d1604e712230529fab2140649 100644
--- a/openair2/RRC/NR/nr_rrc_config.c
+++ b/openair2/RRC/NR/nr_rrc_config.c
@@ -158,7 +158,8 @@ void config_csirs(NR_ServingCellConfigCommon_t *servingcellconfigcommon,
     *nzpcsi0->powerControlOffsetSS = NR_NZP_CSI_RS_Resource__powerControlOffsetSS_db0;
     nzpcsi0->scramblingID = *servingcellconfigcommon->physCellId;
     set_csirs_periodicity(nzpcsi0, uid, nb_slots_per_period);
-    nzpcsi0->qcl_InfoPeriodicCSI_RS = NULL;
+    nzpcsi0->qcl_InfoPeriodicCSI_RS = calloc(1,sizeof(*nzpcsi0->qcl_InfoPeriodicCSI_RS));
+    *nzpcsi0->qcl_InfoPeriodicCSI_RS = 0;
     ASN_SEQUENCE_ADD(&csi_MeasConfig->nzp_CSI_RS_ResourceToAddModList->list,nzpcsi0);
   }
   else {
@@ -429,8 +430,7 @@ void prepare_sim_uecap(NR_UE_NR_Capability_t *cap,
     }
     fs_cc->supportedModulationOrderDL = CALLOC(1,sizeof(*fs_cc->supportedModulationOrderDL));
     *fs_cc->supportedModulationOrderDL = NR_ModulationOrder_qam256;
-    ASN_SEQUENCE_ADD(&fs->featureSetsDownlinkPerCC->list,
-                     fs_cc);
+    ASN_SEQUENCE_ADD(&fs->featureSetsDownlinkPerCC->list, fs_cc);
   }
 }
 
@@ -520,7 +520,6 @@ void nr_rrc_config_ul_tda(NR_ServingCellConfigCommon_t *scc, int min_fb_delay){
   }
 }
 
-
 void set_dl_mcs_table(int scs, NR_UE_NR_Capability_t *cap,
                       NR_SpCellConfig_t *SpCellConfig,
                       NR_BWP_DownlinkDedicated_t *bwp_Dedicated,
@@ -577,5 +576,3 @@ void set_dl_mcs_table(int scs, NR_UE_NR_Capability_t *cap,
     bwp_Dedicated->pdsch_Config->choice.setup->mcs_Table = NULL;
 }
 
-
-
diff --git a/openair2/RRC/NR/nr_rrc_defs.h b/openair2/RRC/NR/nr_rrc_defs.h
index 0d859ab6ff8f127de8d0a2d46d7a5ecaea90abd8..89ae9c1d2b2a2cac0b940815c91b73cbdfc29874 100644
--- a/openair2/RRC/NR/nr_rrc_defs.h
+++ b/openair2/RRC/NR/nr_rrc_defs.h
@@ -290,10 +290,10 @@ typedef struct gNB_RRC_UE_s {
   NR_DRB_ToReleaseList_t            *DRB_Release_configList2[RRC_TRANSACTION_IDENTIFIER_NUMBER];
   uint8_t                            DRB_active[8];
 
-  NR_SRB_INFO                           SI;
-  NR_SRB_INFO                           Srb0;
-  NR_SRB_INFO_TABLE_ENTRY               Srb1;
-  NR_SRB_INFO_TABLE_ENTRY               Srb2;
+  NR_SRB_INFO                       SI;
+  NR_SRB_INFO                       Srb0;
+  NR_SRB_INFO_TABLE_ENTRY           Srb1;
+  NR_SRB_INFO_TABLE_ENTRY           Srb2;
   NR_MeasConfig_t                   *measConfig;
   HANDOVER_INFO                     *handover_info;
   NR_MeasResults_t                  *measResults;
diff --git a/openair2/RRC/NR/rrc_gNB.c b/openair2/RRC/NR/rrc_gNB.c
index f5879a0c49aa675899b1951abc1e796bbd4a4937..9c4eba15a7e06672fffc72f03323836efbc626cb 100755
--- a/openair2/RRC/NR/rrc_gNB.c
+++ b/openair2/RRC/NR/rrc_gNB.c
@@ -845,6 +845,9 @@ rrc_gNB_generate_dedicatedRRCReconfiguration(
   int                            qos_flow_index = 0;
   int                            pdu_sessions_done = 0;
   int i;
+  uint8_t drb_id_to_setup_start = 1;
+  uint8_t nb_drb_to_setup = 0;
+  long drb_priority[1] = {13}; // For now, we assume only one drb per pdu sessions with a default preiority (will be dynamique in future)
   NR_CellGroupConfig_t *cellGroupConfig;
 
   uint8_t xid = rrc_gNB_get_next_transaction_identifier(ctxt_pP->module_id);
@@ -887,6 +890,8 @@ rrc_gNB_generate_dedicatedRRCReconfiguration(
 
     DRB_config = CALLOC(1, sizeof(*DRB_config));
     DRB_config->drb_Identity = i+1;
+    if (drb_id_to_setup_start == 1) drb_id_to_setup_start = DRB_config->drb_Identity;
+    nb_drb_to_setup++;
     DRB_config->cnAssociation = CALLOC(1, sizeof(*DRB_config->cnAssociation));
     DRB_config->cnAssociation->present = NR_DRB_ToAddMod__cnAssociation_PR_sdap_Config;
     // sdap_Config
@@ -1000,8 +1005,8 @@ rrc_gNB_generate_dedicatedRRCReconfiguration(
 
   memset(buffer, 0, sizeof(buffer));
   cellGroupConfig = calloc(1, sizeof(NR_CellGroupConfig_t));
-  fill_mastercellGroupConfig(cellGroupConfig, ue_context_pP->ue_context.masterCellGroup,
-                             rrc->um_on_default_drb);
+
+  fill_mastercellGroupConfig(cellGroupConfig, ue_context_pP->ue_context.masterCellGroup, rrc->um_on_default_drb, (drb_id_to_setup_start < 2) ? 1 : 0, drb_id_to_setup_start, nb_drb_to_setup, drb_priority);
   size = do_RRCReconfiguration(ctxt_pP, buffer, sizeof(buffer),
                                 xid,
                                 *SRB_configList2,
@@ -3245,10 +3250,9 @@ static void rrc_DU_process_ue_context_setup_request(MessageDef *msg_p, const cha
   f1ap_ue_context_setup_t * resp=&F1AP_UE_CONTEXT_SETUP_RESP(message_p);
   uint32_t incoming_teid = 0;
 
-
-  NR_CellGroupConfig_t *cellGroupConfig;
-  cellGroupConfig = calloc(1, sizeof(NR_CellGroupConfig_t));
-  fill_mastercellGroupConfig(cellGroupConfig, ue_context_p->ue_context.masterCellGroup,rrc->um_on_default_drb);
+  uint8_t drb_id_to_setup_start = 0;
+  uint8_t nb_drb_to_setup = 0;
+  long drb_priority[1] = {13}; // For now, we assume only one drb per pdu sessions with a default preiority (will be dynamique in future)
 
   /* Configure SRB2 */
   NR_SRB_ToAddMod_t            *SRB2_config          = NULL;
@@ -3277,6 +3281,7 @@ static void rrc_DU_process_ue_context_setup_request(MessageDef *msg_p, const cha
       ue_context_p->ue_context.DRB_configList = CALLOC(1, sizeof(*ue_context_p->ue_context.DRB_configList));
     }
     DRB_configList = ue_context_p->ue_context.DRB_configList;
+    nb_drb_to_setup = req->drbs_to_be_setup_length;
     for (int i=0; i<req->drbs_to_be_setup_length; i++){
       DRB_config = CALLOC(1, sizeof(*DRB_config));
       DRB_config->drb_Identity = req->drbs_to_be_setup[i].drb_id;
@@ -3286,6 +3291,7 @@ static void rrc_DU_process_ue_context_setup_request(MessageDef *msg_p, const cha
       memcpy(addr.buffer, &drb_p.up_ul_tnl[0].tl_address, sizeof(drb_p.up_ul_tnl[0].tl_address));
       addr.length=sizeof(drb_p.up_ul_tnl[0].tl_address)*8;
       extern instance_t DUuniqInstance;
+      if (!drb_id_to_setup_start) drb_id_to_setup_start = drb_p.drb_id;
       incoming_teid=newGtpuCreateTunnel(DUuniqInstance,
           req->rnti,
           drb_p.drb_id,
@@ -3297,6 +3303,10 @@ static void rrc_DU_process_ue_context_setup_request(MessageDef *msg_p, const cha
     }
   }
 
+  NR_CellGroupConfig_t *cellGroupConfig;
+  cellGroupConfig = calloc(1, sizeof(NR_CellGroupConfig_t));
+  fill_mastercellGroupConfig(cellGroupConfig, ue_context_p->ue_context.masterCellGroup, rrc->um_on_default_drb, SRB2_config ? 1 : 0, drb_id_to_setup_start, nb_drb_to_setup, drb_priority);
+
   apply_macrlc_config(rrc, ue_context_p, &ctxt);
   /* Fill the UE context setup response ITTI message to send to F1AP */
   resp->gNB_CU_ue_id = req->gNB_CU_ue_id;
@@ -3632,7 +3642,6 @@ void nr_rrc_subframe_process(protocol_ctxt_t *const ctxt_pP, const int CC_id) {
 
   if (fd) fclose(fd);
 
-
   /* send a tick to x2ap */
   if (is_x2ap_enabled()){
     msg = itti_alloc_new_message(TASK_RRC_ENB, 0, X2AP_SUBFRAME_PROCESS);
diff --git a/openair2/RRC/NR/rrc_gNB_NGAP.c b/openair2/RRC/NR/rrc_gNB_NGAP.c
index c73c3d9649df3bdd81b2eda5e497db748662adb7..96ec63443357cd81563d8664595030ac188f03d5 100644
--- a/openair2/RRC/NR/rrc_gNB_NGAP.c
+++ b/openair2/RRC/NR/rrc_gNB_NGAP.c
@@ -905,7 +905,7 @@ rrc_gNB_send_NGAP_PDUSESSION_SETUP_RESP(
   for (pdusession = 0; pdusession < ue_context_pP->ue_context.setup_pdu_sessions; pdusession++) {
     // if (xid == ue_context_pP->ue_context.pdusession[pdusession].xid) {
       if (ue_context_pP->ue_context.pduSession[pdusession].status == PDU_SESSION_STATUS_DONE) {
-        pdusession_setup_t * tmp=&NGAP_PDUSESSION_SETUP_RESP(msg_p).pdusessions[pdusession];
+        pdusession_setup_t * tmp=&NGAP_PDUSESSION_SETUP_RESP(msg_p).pdusessions[pdu_sessions_done];
         tmp->pdusession_id = ue_context_pP->ue_context.pduSession[pdusession].param.pdusession_id;
         // tmp->pdusession_id = 1;
         tmp->nb_of_qos_flow = ue_context_pP->ue_context.pduSession[pdusession].param.nb_qos;
diff --git a/openair2/RRC/NR/rrc_gNB_reconfig.c b/openair2/RRC/NR/rrc_gNB_reconfig.c
index 2f63a63b8a25fc5e36c22bccd19c08c1ba5e3961..de62035b4889748bd27462f96866e86647838053 100644
--- a/openair2/RRC/NR/rrc_gNB_reconfig.c
+++ b/openair2/RRC/NR/rrc_gNB_reconfig.c
@@ -1457,7 +1457,6 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco
   }
 }
 
-
 void fill_default_reconfig(NR_ServingCellConfigCommon_t *servingcellconfigcommon,
                            NR_ServingCellConfig_t *servingcellconfigdedicated,
                            NR_RRCReconfiguration_IEs_t *reconfig,
diff --git a/openair2/RRC/NR_UE/rrc_UE.c b/openair2/RRC/NR_UE/rrc_UE.c
index 5c55b4131a8ab932e757515c9ba070045a321596..50ec32772de354c87f7722aebe23abbe918238a0 100644
--- a/openair2/RRC/NR_UE/rrc_UE.c
+++ b/openair2/RRC/NR_UE/rrc_UE.c
@@ -1340,13 +1340,6 @@ static void rrc_ue_generate_RRCSetupComplete(
   uint8_t size;
   const char *nas_msg;
   int   nas_msg_length;
-  NR_UE_MAC_INST_t *mac = get_mac_inst(0);
-
-  if (mac->cg &&
-      mac->cg->spCellConfig &&
-      mac->cg->spCellConfig->spCellConfigDedicated &&
-      mac->cg->spCellConfig->spCellConfigDedicated->csi_MeasConfig)
-    AssertFatal(1==0,"2 > csi_MeasConfig is not null\n");
 
  if (AMF_MODE_ENABLED) {
 #if defined(ITTI_SIM)
diff --git a/openair2/SDAP/nr_sdap/nr_sdap_entity.c b/openair2/SDAP/nr_sdap/nr_sdap_entity.c
index c5d1c1d6fe1dd1d630c464dd9e7fb2f79a491301..79532748d2895107a9a0e6717af3cb62c0987e59 100644
--- a/openair2/SDAP/nr_sdap/nr_sdap_entity.c
+++ b/openair2/SDAP/nr_sdap/nr_sdap_entity.c
@@ -450,7 +450,7 @@ nr_sdap_entity_t *nr_sdap_get_entity(uint16_t rnti, int pdusession_id) {
   if(sdap_entity == NULL)
     return NULL;
 
-  while(sdap_entity->rnti != rnti && sdap_entity->next_entity != NULL) {
+  while(( sdap_entity->rnti != rnti || sdap_entity->pdusession_id != pdusession_id ) && sdap_entity->next_entity != NULL) {
     sdap_entity = sdap_entity->next_entity;
   }
 
@@ -460,6 +460,7 @@ nr_sdap_entity_t *nr_sdap_get_entity(uint16_t rnti, int pdusession_id) {
   return NULL;
 }
 
+
 void delete_nr_sdap_entity(uint16_t rnti) {
   nr_sdap_entity_t *entityPtr, *entityPrev = NULL;
   entityPtr = sdap_info.sdap_entity_llist;
diff --git a/openair3/ocp-gtpu/gtp_itf.cpp b/openair3/ocp-gtpu/gtp_itf.cpp
index 7b8ba308bfb41a979b97c5244dc9052befe74a05..9537f9e18ae6142bb67514abda3d563f141c7d78 100644
--- a/openair3/ocp-gtpu/gtp_itf.cpp
+++ b/openair3/ocp-gtpu/gtp_itf.cpp
@@ -462,7 +462,7 @@ teid_t newGtpuCreateTunnel(instance_t instance, rnti_t rnti, int incoming_bearer
   auto inst=&globGtp.instances[instance];
   auto it=inst->ue2te_mapping.find(rnti);
 
-  if ( it != inst->ue2te_mapping.end() ) {
+  if ( it != inst->ue2te_mapping.end() &&  it->second.bearers.find(outgoing_bearer_id) != it->second.bearers.end()) {
     LOG_W(GTPU,"[%ld] Create a config for a already existing GTP tunnel (rnti %x)\n", instance, rnti);
     inst->ue2te_mapping.erase(it);
   }
diff --git a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band41.fr1.106PRB.usrpb210.conf b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band41.fr1.106PRB.usrpb210.conf
index 78b62b78ea4c4783ac73f6c5fba392940114ef27..cd84e699c77f6a6ae14b257723564ceb24742f48 100644
--- a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band41.fr1.106PRB.usrpb210.conf
+++ b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band41.fr1.106PRB.usrpb210.conf
@@ -30,6 +30,7 @@ gNBs =
 
     ssb_SubcarrierOffset                                      = 0;
     min_rxtxtime                                              = 2;
+    do_CSIRS                                                  = 1;
     do_SRS                                                    = 1;
 
      pdcch_ConfigSIB1 = (
diff --git a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.2x2.usrpn300.conf b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.2x2.usrpn300.conf
index 169ece990bf903bd17277744077ced472000c01c..f80cec49ca9e7c7f2137320fed80a7c479f04ed9 100644
--- a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.2x2.usrpn300.conf
+++ b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.2x2.usrpn300.conf
@@ -31,6 +31,7 @@ gNBs =
     ssb_SubcarrierOffset                                      = 0;
     pdsch_AntennaPorts_N1                                     = 2;
     pusch_AntennaPorts                                        = 2;
+    do_CSIRS                                                  = 1;
     do_SRS                                                    = 1;
     ul_prbblacklist                                           = "51,52,53,54"
 
diff --git a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.usrpb210.conf b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.usrpb210.conf
index 2eb4581a19a49eb1108c6b9318a3b9ce03038643..8914b872e3e15e299097e66840b29b90acdef9a2 100644
--- a/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.usrpb210.conf
+++ b/targets/PROJECTS/GENERIC-NR-5GC/CONF/gnb.sa.band78.fr1.106PRB.usrpb210.conf
@@ -30,6 +30,7 @@ gNBs =
 
     ssb_SubcarrierOffset                                      = 0;
     min_rxtxtime                                              = 2;
+    do_CSIRS                                                  = 1;
     do_SRS                                                    = 1;
 
      pdcch_ConfigSIB1 = (
diff --git a/targets/RT/USER/lte-enb.c b/targets/RT/USER/lte-enb.c
index 49f7db2867334cfb0d6c26d053e93a789958fc5f..a3048995a53f1de81d41aff08a83848eb698d52c 100644
--- a/targets/RT/USER/lte-enb.c
+++ b/targets/RT/USER/lte-enb.c
@@ -1135,7 +1135,7 @@ void init_transport(PHY_VARS_eNB *eNB) {
     }
     for (int i=0;i<NUMBER_OF_ULSCH_MAX; i++) {
 
-      LOG_I(PHY,"Allocating Transport Channel Buffer for ULSCH %d/%d\n",i,NUMBER_OF_ULSCH_MAX);
+      LOG_I(PHY,"Allocating Transport Channel Buffers for ULSCH %d/%d\n",i,NUMBER_OF_ULSCH_MAX);
       eNB->ulsch[i] = new_eNB_ulsch(MAX_TURBO_ITERATIONS,fp->N_RB_UL, 0);
 
       if (!eNB->ulsch[i]) {